X-Git-Url: https://git.teslayout.com/public/public/public/?a=blobdiff_plain;f=include%2Fanna%2Fdbos%2FObjectFacade.hpp;fp=include%2Fanna%2Fdbos%2FObjectFacade.hpp;h=18577f03026527664a87cd43cba404cf03792666;hb=78be86969d2f26a9084b0c4af6ce43d5fa4ed3fd;hp=0000000000000000000000000000000000000000;hpb=a3b95648bd76140ef55e0b5941d423eee6c3856f;p=anna.git diff --git a/include/anna/dbos/ObjectFacade.hpp b/include/anna/dbos/ObjectFacade.hpp new file mode 100644 index 0000000..18577f0 --- /dev/null +++ b/include/anna/dbos/ObjectFacade.hpp @@ -0,0 +1,406 @@ +// ANNA - Anna is Not Nothingness Anymore // +// // +// (c) Copyright 2005-2015 Eduardo Ramos Testillano & Francisco Ruiz Rayo // +// // +// See project site at http://redmine.teslayout.com/projects/anna-suite // +// See accompanying file LICENSE or copy at http://www.teslayout.com/projects/public/anna.LICENSE // + + +#ifndef anna_dbos_ObjectFacade_hpp +#define anna_dbos_ObjectFacade_hpp + +#include + +#include + +#include +#include +#include +#include +#include + +namespace anna { + +namespace dbms { +class Connection; +} + +namespace dbos { + +class Object; + +/** + Clase que facilita el acceso y uso de las clases encargadas de la instanciacion de objetos a partir de los datos + contenidos en un medio fisico, que normalmente seria la tabla de una base de datos. + + \param T clase debe ser heredada de anna::dbos::Object. + + Ejemplo de definicion de una clase usando esta interfaz: + + \include dbos_demo.p/oodb.d/hdrs/dbos_demo.oodb.Table01.h + + Ejemplo de implementacion de la clase correspondiente a la definicion: + + \include dbos_demo.p/oodb.d/oodb.Table01.cc + + \see dbos_declare_object + \see dbos_prepare_object +*/ +template class ObjectFacade { +public: + /** + Devuelve un numerico que puede ser usado en la definicion del area de almacenamiento. + + \return Un numerico que puede ser usado en la definicion del area de almacenamiento. + \see Database::createStorageArea + */ + static StorageId getStorageAreaId() throw() { return (StorageId) anna_ptrnumber_cast(&st_storageArea); } + + /** + Devuelve el area de almacenamiento asociado a esta clase. + \return Devuelve el area de almacenamiento asociado a esta clase. + */ + static StorageArea* getStorageArea() throw() { return st_storageArea; } + + /** + Establece el area de almacenamiento asociado a esta clase, que deberiaser creado mediante la invocacin al metodo + Database::createStorageArea. + + \param storageArea area de almacenamiento asociada esta clase. + + \warning El area de almacenamiento debe establecerse antes de invocar a cualquier otro metodo de esta clase. + */ + static void setStorageArea(StorageArea* storageArea) throw() { + (st_storageArea = storageArea)->setSizeof(sizeof(T)); + } + + /** + Carga la informacion de un objeto contenida en un medio fisico y la interpreta para adecuarla a + una clase C++. + + Este cargador deberia tener todos los datos necesarios para localizar la informacion del objeto que + debe cargar. Por ejemplo, en caso de tener que obtener el objeto a partir de los datos contenidos + en una tabla de una base de datos deberia conocer la clave primaria del objeto a cargar, o alguna + otra combinacion de columnas que lo identifiquen univocamente. + + \param connection Conexion usada si fuera necesario extraer los datos del medio fisico. + \param loader Cargador de clase encargado de localizar y obtener la informacion referente al objeto + que deseamos cargar en memoria. + + \return Una instancia que cumple el patron establecido por el cargador. Puede ser NULL en caso de + que al inicializar el area de almacenamiento asociado a esta clase se halla indicado un \em errorCode + igual a -1 en otro caso si no encuentra el objeto que cumpla el patron devolveria una + excepcion. + + \warning Cada llamada a este metodo deberia tener su correspondiente liberacion invocando a #release + cuando dejemos de usar la instancia. + */ + static T* instance(dbms::Connection& connection, Loader& loader) + throw(RuntimeException, dbms::DatabaseException) { + if(st_storageArea == NULL) { + std::string msg(loader.asString()); + msg += " | ObjectFacade uninitialized "; + throw RuntimeException(msg, ANNA_FILE_LOCATION); + } + + return static_cast (st_storageArea->instance(connection, loader)); + } + + /** + Carga la informacion de un objeto contenida en un medio fisico y la interpreta para adecuarla a + una clase C++. + + Este cargador deberia tener todos los datos necesarios para localizar la informacion del objeto que + debe cargar. + + \param loader Cargador de clase encargado de localizar y obtener la informacion referente al objeto + que deseamos cargar en memoria. + + \return Una instancia que cumple el patron establecido por el cargador. Puede ser NULL en caso de + que al inicializar el area de almacenamiento asociado a esta clase se halla indicado un \em errorCode + igual a -1 en otro caso si no encuentra el objeto que cumpla el patron devolveria una + excepcion. + + \warning Cada llamada a este metodo deberia tener su correspondiente liberacion invocando a #release + cuando dejemos de usar la instancia. + */ + static T* instance(Loader& loader) + throw(RuntimeException, dbms::DatabaseException) { + if(st_storageArea == NULL) { + std::string msg(loader.asString()); + msg += " | ObjectFacade uninitialized "; + throw RuntimeException(msg, ANNA_FILE_LOCATION); + } + + return static_cast (st_storageArea->instance(loader)); + } + + /** + Carga la informacion de un objeto contenida en un medio fisico y la interpreta para adecuarla a + una clase C++. + + Este cargador deberia tener todos los datos necesarios para localizar la informacion del objeto que + debe cargar. Por ejemplo, en caso de tener que obtener el objeto a partir de los datos contenidos + en una tabla de una base de datos deberia conocer la clave primaria del objeto a cargar, o alguna + otra combinacion de columnas que lo identifiquen univocamente. + + \param connection Conexion usada si fuera necesario extraer los datos del medio fisico. + \param crossedLoader Cargador encargado de encontrar la clave principal a aplicar con el #Loader + recibido como parámetro en base a una clave alternativa contenida en el mismo. + \param loader Cargador de clase encargado de localizar y obtener la informacion referente al objeto + que deseamos cargar en memoria. + + \return Una instancia que cumple el patron establecido por el cargador. Puede ser NULL en caso de + que al inicializar esta clase \em errorCode se halla indicado un #NoExceptionWhenNotFound en otro + caso si no encuentra el objeto que cumpla el patron devolveria una excepcion de ejecucion. + + \warning Cada llamada a este método deberia tener su correspondiente liberacion invocando a #release + cuando dejemos de usar la instancia. + */ + static T* instance(dbms::Connection& connection, CrossedLoader& crossedLoader, Loader& loader) + throw(RuntimeException, dbms::DatabaseException) { + if(st_storageArea == NULL) { + std::string msg(loader.asString()); + msg += " | ObjectFacade uninitialized "; + throw RuntimeException(msg, ANNA_FILE_LOCATION); + } + + return static_cast (st_storageArea->instance(connection, crossedLoader, loader)); + } + + /** + Crea un objeto en el area de almacenamiento un y lo prepara para ser transferido al medio fisico + si fuera necesario. + + Este cargador deberia tener todos los datos necesarios para localizar la informacion del objeto que + debe cargar. Por ejemplo, en caso de tener que obtener el objeto a partir de los datos contenidos + en una tabla de una base de datos deberia conocer la clave primaria del objeto a cargar, o alguna + otra combinacion de columnas que lo identifiquen univocamente. + + \param connection Conexion usada si fuera necesario acceder al medio fisico. + \param creator Creador encargado de generar el objeto de forma que sea facil de localizar posteriormente + en el area de almacenamiento. + + \return La nueva instancia que cumple el patron establecido por el creador. + + \warning Cada llamada a este metodo deberia tener su correspondiente liberacion invocando a #release + cuando dejemos de usar la instancia. + */ + static T* create(dbms::Connection& connection, Creator& creator) + throw(RuntimeException, dbms::DatabaseException) { + if(st_storageArea == NULL) { + std::string msg(creator.asString()); + msg += " | ObjectFacade uninitialized "; + throw RuntimeException(msg, ANNA_FILE_LOCATION); + } + + return static_cast (st_storageArea->create(connection, creator)); + } + + /** + Devuelve la informacion de un objeto cargado desde el medio fisico. + + Este cargador deberia tener todos los datos necesarios para localizar la informacion del objeto que + debe buscar. Por ejemplo, en caso de tener que obtener el objeto a partir de los datos contenidos + en una tabla de una base de datos deberia conocer la clave primaria del objeto a cargar, o alguna + otra combinacion de columnas que lo identifiquen univocamente. + + \param loader Cargador de clase encargado de localizar la informacion referente al objeto buscado. + + \return Una instancia que cumple el patron establecido por el cargador. Puede ser NULL si el + objeto no fue cargado en el area de almacenamiento. + + \warning Cada llamada a este metodo deberia tener su correspondiente liberacion invocando a #release + cuando dejemos de usar la instancia. + */ + static T* find(Loader& loader) + throw(RuntimeException) { + if(st_storageArea == NULL) { + std::string msg(loader.asString()); + msg += " | ObjectFacade uninitialized "; + throw RuntimeException(msg, ANNA_FILE_LOCATION); + } + + return static_cast (st_storageArea->find(loader)); + } + + /** + Habilita la reutilizacion del espacio de memoria ocupado por un objeto alojado en el area de almacenamiento. + + Este metodo no saca al objeto de la memoria de almacenamiento, sino que marca su espacio de memoria + como subceptible de ser reutilizado. De esta forma, si el numero de objetos cargados en memoria se + acerca al tamao maximo indicado en la inicializacion, se intentara reusar espacios libres en vez + de continuar ampliando la memoria reservada. + + \param t Instancia del tipo T que vamos a liberar. + + \warning Si el objeto recibido como parametro no fue reservado mediate alguno de los metodos de reserva de + objetos ofrecidos por esta clase no tendra ningun efecto. + */ + static void release(T*& t) + throw() { + if(st_storageArea == NULL) + return; + + try { + st_storageArea->release(reinterpret_cast (&t)); + } catch(RuntimeException& ex) { + ex.trace(); + } + } + + /** + Descarga todos los objetos contenidos en el area de almacenamiento. + */ + static void clear() + throw(RuntimeException) { + if(st_storageArea == NULL) + throw RuntimeException("ObjectFacade uninitialized ", ANNA_FILE_LOCATION); + + st_storageArea->clear(); + } + + /** + Devuelve de una copia del objeto recibido como parametro e incrementa la cuenta de utilizacion + asociada a la instancia. + + \param t Instancia del tipo T obtenida mediate el metodo #instance. + + \return Una copia del objeto recibido como parametro. Si el parametro recibido es NULL devolveria NULL. + + \warning Cada llamada a este metodo deberia tener su correspondiente liberacion invocando a #release + cuando dejemos de usar la instancia. + */ + static T* duplicate(const T* t) + throw(RuntimeException) { + if(st_storageArea == NULL) + throw RuntimeException("ObjectFacade uninitialized ", ANNA_FILE_LOCATION); + + return static_cast (st_storageArea->duplicate(t)); + } + + /** + Permite conocer si un determinado objeto esta alojado en el area de almacenamiento. + + \param loader Cargador de clase encargado de localizar la informacion referente al objeto buscado. + + \return \em true Si el objeto identificado por el Loader esta en el area de almacenamiento o + \em false en otro caso. + */ + static bool isLoaded(const Loader& loader) + throw(RuntimeException) { + if(st_storageArea == NULL) + throw RuntimeException("ObjectFacade uninitialized ", ANNA_FILE_LOCATION); + + return st_storageArea->isLoaded(loader); + } + + /** + Transfiere la informacion del objeto recibido como parametro al medio fisico usando el Recorder + recibido como parametro. + + \param connection Conexion usada si fuera necesario extraer los datos del medio fisico. + \param recorder Grabador usado para transferir los datos al medio fisico. + */ + static void apply(dbms::Connection& connection, Recorder& recorder) + throw(RuntimeException, dbms::DatabaseException) { + if(st_storageArea == NULL) { + std::string msg(recorder.asString()); + msg += " | ObjectFacade uninitialized"; + throw RuntimeException(msg, ANNA_FILE_LOCATION); + } + + st_storageArea->apply(connection, recorder); + } + + /** + Elimina la informacion del objeto recibido como parametro del medio fisico usando el Eraser + recibido como parametro. + + \param connection Conexion usada si fuera necesario extraer los datos del medio fisico. + \param eraser Objecto usado para eliminar los datos al medio fisico. + + \warning Si la cuanta de utilizacion de T es 1 se liberaria en otro caso se devolveria una excepcion. + */ + static void apply(dbms::Connection& connection, Eraser& eraser) + throw(RuntimeException, dbms::DatabaseException) { + if(st_storageArea == NULL) { + std::string msg(eraser.asString()); + msg += " | ObjectFacade uninitialized"; + throw RuntimeException(msg, ANNA_FILE_LOCATION); + } + + st_storageArea->apply(connection, eraser); + } + + /** + Elimina toda la informacion referente al objeto recibido como parametro, siempre y cuando + solo tenga un unica referencia activa. Descarga el objeto de la memoria de almacenamiento, + + \param t Instancia del tipo T que vamos a descargar de la memoria de almacenamiento. + + \warning \li Si el objeto recibido como parametro no fue reservado mediate #instance no tiene + ningun efecto. \li La instancia a liberar solo puede tener 1 en su cuenta de utilizacion. + \li La memoria asignada a la instancia recibida es liberada, por lo que podemos evitar la invocacion + al metodo #release para esta instancia. + */ + static void erase(T*& t) + throw(RuntimeException) { + if(st_storageArea == NULL) + return; + + st_storageArea->erase(reinterpret_cast (&t)); + } + + /** + Devuelve el puntero sobre el que estaria posicionado el iterador recibido como parametro. + \return El puntero sobre el que estaria posicionado el iterador recibido como parametro. + */ + static T* data(StorageArea::iterator& ii) throw() { return static_cast (StorageArea::data(ii)); } + + /** + Devuelve el puntero sobre el que estaria posicionado el iterador recibido como parametro. + \return El puntero sobre el que estaria posicionado el iterador recibido como parametro. + */ + static const T* data(StorageArea::const_iterator& ii) throw() { return static_cast (StorageArea::data(ii)); } + + /** + Metodo creador de nuevas instancias de la clase T. + \return Una nueva instancia del tipo de objeto T. + \warning Solo deberia ser llamado desde anna::comm::StorageArea cuando sea preciso crear + nuevas instancias de objetos. + */ + static Object* allocator() throw() { return new T; } + +protected: + static StorageArea* st_storageArea; + + /** + Constructor. + */ + ObjectFacade() {} +}; + +} +} + +/** + Definicion a la que hay que invocar en la implementacion de la clase que hereda + de anna::dbos::ObjectFacade. + + \param T Nombre de la clase que vamos a tratar en el ambito de C++. +*/ +#define dbos_prepare_object(T) \ + template <> anna::dbos::StorageArea* anna::dbos::ObjectFacade< T >::st_storageArea = NULL + +/** + Definicion a la que hay que invocar dentro de la definicion de la clase que hereda + de anna::dbos::ObjectFacade. + + \param T Nombre de la clase que vamos a tratar en el ambito de C++. +*/ +#define dbos_declare_object(T) \ + friend class anna::dbos::ObjectFacade + + +#endif