Revert "Remove mysql and oracle resources for anna-ericsson project"
[anna.git] / include / anna / dbos / ObjectFacade.hpp
diff --git a/include/anna/dbos/ObjectFacade.hpp b/include/anna/dbos/ObjectFacade.hpp
new file mode 100644 (file)
index 0000000..18577f0
--- /dev/null
@@ -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 <anna/core/RuntimeException.hpp>
+
+#include <anna/dbms/DatabaseException.hpp>
+
+#include <anna/dbos/StorageArea.hpp>
+#include <anna/dbos/Creator.hpp>
+#include <anna/dbos/Loader.hpp>
+#include <anna/dbos/Recorder.hpp>
+#include <anna/dbos/Eraser.hpp>
+
+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 <typename T> 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 <T*>(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 <T*>(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 <T*>(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 <T*>(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 <T*>(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 <Object**>(&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 <T*>(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 <Object**>(&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 <T*>(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 <const T*>(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 <T>
+
+
+#endif