/*

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
*/

/*!
	\since v.1.0.9
	\file
	\brief Базовый класс образа загруженного в ОП содержимого
		раздела БД.
*/

#if !defined( _OESS_1__DB__CLN__SLICE_IMAGE_BASE_HPP_ )
#define _OESS_1__DB__CLN__SLICE_IMAGE_BASE_HPP_

#include <exception>

#include <oess_1/db/h/declspec.hpp>

#include <oess_1/db/cln/h/db.hpp>

namespace oess_1
{

namespace db
{

namespace cln
{

namespace impl
{
	struct	slice_image_base_data_t;
} /* namespace impl */

class	slice_index_base_t;

/*!
	\since v.1.0.9
	\brief Базовый класс образа загруженного в ОП содержимого
		раздела БД.

	Класс не предназначен для непосредственного использования.
	Предполагается, что настройку на конкретные типы хранимых
	в разделе объектов будут осуществлять производные классы.
	Поэтому основные методы, которые требуют работы с
	конкретными типами объектов реализованы в protected-части
	класса.
*/
class OESS_1__DB__TYPE	slice_image_base_t
{
public:
    virtual ~slice_image_base_t();

	//! Битовые флаги, определяющие различные
	//! операции над образом раздела.
	enum
	{
		//! Содержимое раздела должно быть автоматически
		//! загружено в ОП.
		auto_load = 0x1,
		//! Индекс раздела должен быть автоматически
		//! уничтожен в деструкторе.
		auto_destroy_index = 0x2
	};

    /*! Добавить активный индекс.

		Значения объектов раздела в индекс не добавляются.
		Это задача производных классов.
    */
    virtual void
    attach(
		slice_index_base_t & index,
		//! Битовые флаги, определяющие, что нужно делать
		//! с индексом.
		//! Если установлен флаг auto_destroy_index, то
		//! индекс автоматически уничтожается в деструкторе.
		unsigned int flags );

    /*!
    	Изъять активный индекс. Изъятый индекс не уничтожается
    	даже если при его добавлении был указан флаг
    	auto_destroy_index.
    */
    virtual void
    detach(
        slice_index_base_t & index );

	//! База, с которой осуществляется работа.
	oess_1::db::cln::db_t &
	query_db() const;

	//! Раздел, с которым осуществляется работа.
	const std::string &
	slice_name() const;

protected :
    /*! Содержимое раздела не загружается даже,
    	если установлен флаг auto_load (из-за того, что
    	в базовом классе нет реализации метода
    	make_real_obj().

    	Раздел автоматически создается в БД. */
    slice_image_base_t(
			oess_1::db::cln::db_t & db,
			const std::string & slice_name,
			//! Битовые флаги, определяющие, что нужно
			//! делать с содержимым раздела.
			unsigned int flags )
	    throw( std::exception );

    /*! Выгружает содержимое раздела.

    	Все активные индексы так же очищаются, но остаются
    	привязанными к образу раздела.
    */
    void
    lo_clear();

    /*! Добавляет объект в раздел и, автоматически,
		во все активные индексы. */
    ent_id_t
    lo_insert( const oess_1::stdsn::serializable_t & o )
	throw( std::exception );

    /*! Изымает объект из раздела и, автоматически,
		из всех активных индексов. */
    void
    lo_erase( const oess_1::ent_id_t & id )
	throw( std::exception );

    /*! Обновляет содержимое объекта в ОП, в разделе
		и во всех активных индексах. */
    void
    lo_update( const oess_1::ent_id_t & id,
        const oess_1::stdsn::serializable_t & o )
	throw( std::exception );

	/*! Добавляет объект во все активные индексы при
		помощи метода slice_index_base_t::on_insert. */
	void
	lo_refresh_indexes(
		const oess_1::ent_id_t & id,
		const oess_1::stdsn::serializable_t & o );

private :
	//! Реальные данные образа раздела.
	auto_ptr_3::obj_ptr_t< impl::slice_image_base_data_t >	m_data;

private :
/*! \name Защита от копирования. */
/*! \{ */
	slice_image_base_t(
		const slice_image_base_t & o );
	slice_image_base_t &
	operator=(
		const slice_image_base_t & o );
/* \} */
};

/*!
	\since v.1.0.9
	\brief Интерфейс типизированного образа раздела в БД.
*/
template< class Item >
class	slice_image_iface_t :
	public slice_image_base_t
{
public :
	virtual ~slice_image_iface_t()
	{}

	/*! Добавляет объект в раздел и, автоматически,
		во все активные индексы. */
	virtual oess_1::ent_id_t
	insert( const Item & o ) = 0;

	/*! Удаляет объект из раздела и из всех активных индексов. */
	virtual void
	erase( const oess_1::ent_id_t & id ) = 0;

	/*! Обновляет содержимое объекта в ОП, в разделе
		и во всех активных индексах. */
	virtual void
	update(
		const ent_id_t & id,
		const Item & o ) = 0;

	/*! Извлекает значение объекта. */
	virtual void
	get(
		const ent_id_t & id,
		auto_ptr_3::soft_obj_ptr_t< Item > & o ) const = 0;

protected :
    slice_image_iface_t(
		oess_1::db::cln::db_t & db,
		const std::string & slice_name,
		//! Битовые флаги, определяющие, что нужно
		//! делать с содержимым раздела.
		unsigned int flags )
	throw( std::exception )
	:
		slice_image_base_t( db, slice_name, flags )
	{}
};

} /* namespace cln */

} /* namespace db */

} /* namespace oess_1 */

#endif
