/*

Copyright (c) 2002-2005, Yauheni Akhotnikau
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

- Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.

- Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.

- The name of the author may not be used to endorse or promote products derived
from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
OF SUCH DAMAGE.

*/

/*
	ObjESSty-1
*/

#if !defined( _OESS_1__DB__SITE__IMPL__STD__LOCALHOST_HPP_ )
#define _OESS_1__DB__SITE__IMPL__STD__LOCALHOST_HPP_

#include <map>

#include <ace/Thread_Mutex.h>

#include <smart_ref_3/h/smart_ref.hpp>

#include <oess_1/db/impl/db_content/h/db_content.hpp>

#include <oess_1/db/site/h/localhost.hpp>

#include <oess_1/db/site/impl/h/attach_cmd.hpp>
#include <oess_1/db/site/impl/h/detach_cmd.hpp>
#include <oess_1/db/site/impl/h/ent_create_cmd.hpp>
#include <oess_1/db/site/impl/h/ent_destroy_cmd.hpp>
#include <oess_1/db/site/impl/h/ent_destroy_all_cmd.hpp>
#include <oess_1/db/site/impl/h/ent_load_cmd.hpp>
#include <oess_1/db/site/impl/h/ent_update_cmd.hpp>
#include <oess_1/db/site/impl/h/ent_find_next_cmd.hpp>
#include <oess_1/db/site/impl/h/slice_create_cmd.hpp>
#include <oess_1/db/site/impl/h/slice_destroy_cmd.hpp>
#include <oess_1/db/site/impl/h/slice_is_exists_cmd.hpp>
#include <oess_1/db/site/impl/h/slice_names_cmd.hpp>
#include <oess_1/db/site/impl/h/transaction_cmd.hpp>

namespace oess_1 {

namespace db {

namespace site {

namespace impl {

//
// ref_db_content_t
//
SMART_REF_3_DECL_REF_FULL(
	oess_1::db::impl::db_content::db_content_t,
	ref_db_content_t,
	class
)

//
// ref_db_content_map_t
//
typedef std::map< std::string, ref_db_content_t >
	ref_db_content_map_t;

//
// db_info_t
//

/*!
	Описание одной БД, доступной на данной локальной машине.
*/
struct	db_info_t {
	std::string	m_physic_name;
	oess_1::db::storage::config_t	m_config;
	bool	m_is_read_only;
	bool	m_is_auto_repair_enabled;

	db_info_t();
	db_info_t(
		const std::string & physic_name,
		const oess_1::db::storage::config_t & config,
		bool is_read_only,
		bool is_auto_repair_enabled );
	db_info_t( const db_info_t & o );
	~db_info_t();

	db_info_t &
	operator=( const db_info_t & o );
};

//
// db_info_map_t
//
typedef std::map< std::string, db_info_t >
	db_info_map_t;

//
// std_localhost_t
//

/*!
	Стандартная реализация интерфейса localhost_t.
*/
class	std_localhost_t :
	public localhost_t
{
	public :
		std_localhost_t();
		virtual ~std_localhost_t();

	//! \name Реализация унаследованных методов.
	//! \{
		virtual void
		db_create(
			const std::string & physic_name,
			oess_1::uint_t creation_mode );

		virtual void
		db_create(
			const std::string & physic_name,
			const oess_1::db::storage::config_t & config,
			oess_1::uint_t creation_mode );

		virtual void
		db_describe(
			const std::string & logic_name,
			const std::string & physic_name,
			oess_1::uint_t cache_size,
			bool is_read_only,
			bool is_auto_repair_enabled );

		virtual void
		db_describe(
			const std::string & logic_name,
			const std::string & physic_name,
			const oess_1::db::storage::config_t & config,
			bool is_read_only,
			bool is_auto_repair_enabled );

		virtual void
		db_flush_all();

		virtual bool
		db_set_auto_flush(
			const std::string & logic_name,
			bool is_on );

		virtual response_t *
		process(
			const request_t & req );
	//! \}

	private :
		ACE_Thread_Mutex	m_lock;

		db_info_map_t	m_db_info_map;
		ref_db_content_map_t	m_db_content_map;

		//
		// Обработчики запросов.
		//

		response_t *
		on_attach_cmd(
			const attach_cmd_t & req );

		response_t *
		on_detach_cmd(
			const detach_cmd_t & req );

		response_t *
		on_ent_create_cmd(
			const ent_create_cmd_t & req );

		response_t *
		on_ent_destroy_cmd(
			const ent_destroy_cmd_t & req );

		response_t *
		on_ent_destroy_all_cmd(
			const ent_destroy_all_cmd_t & req );

		response_t *
		on_ent_load_cmd(
			const ent_load_cmd_t & req );

		response_t *
		on_ent_update_cmd(
			const ent_update_cmd_t & req );

		response_t *
		on_ent_find_next_cmd(
			const ent_find_next_cmd_t & req );

		//! Запрос на создание раздела в БД.
		/*! \since v.1.1.0 */
		response_t *
		on_slice_create_cmd(
			const slice_create_cmd_t & req );

		//! Запрос на удаление раздела в БД.
		/*! \since v.1.4.0 */
		response_t *
		on_slice_destroy_cmd(
			const slice_destroy_cmd_t & req );

		//! Запрос на проверку существования раздела в БД.
		/*! \since v.1.4.0 */
		response_t *
		on_slice_is_exists_cmd(
			const slice_is_exists_cmd_t & req );

		//! Запрос на получения списка существующих разделов в БД.
		/*! \since v.1.4.0 */
		response_t *
		on_slice_names_cmd(
			const slice_names_cmd_t & req );

		//! Запрос на выполнении команды, связанной с транзакцией.
		/*! \since v.1.1.0 */
		response_t *
		on_transaction_cmd(
			const transaction_cmd_t & req );

		//
		// Вспомогательные методы.
		//

		//! Если описание БД не найдено, порождается исключение.
		const db_info_t &
		find_db_info(
			const std::string & db_logic_name ) const;

		//! Если БД не открыта, то открыть ее.
		/*! Возвращает ссылку на открытую БД. */
		oess_1::db::impl::db_content::db_content_t &
		open_db_if_needed(
			const std::string & db_logic_name,
			const db_info_t & db_info );

		//! Если нет открытой БД с таким именем, то
		//! порождается исключение.
		oess_1::db::impl::db_content::db_content_t &
		find_opened_db(
			const std::string & db_logic_name );

		//! Закрыть БД и удалить из списка открытых.
		void
		close_db(
			const std::string & db_logic_name );
};

} /* namespace impl */

} /* namespace site */

} /* namespace db */

} /* namespace oess_1 */

#endif
