Revert "Remove mysql and oracle resources for anna-ericsson project"
[anna.git] / include / anna / dbms / Connection.hpp
diff --git a/include/anna/dbms/Connection.hpp b/include/anna/dbms/Connection.hpp
new file mode 100644 (file)
index 0000000..4744128
--- /dev/null
@@ -0,0 +1,194 @@
+// 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_dbms_Connection_hpp
+#define anna_dbms_Connection_hpp
+
+#include <anna/comm/Resource.hpp>
+
+#include <anna/dbms/DatabaseException.hpp>
+#include <anna/dbms/ResultCode.hpp>
+
+namespace anna {
+
+namespace xml {
+class Node;
+}
+
+namespace dbms {
+
+class Database;
+class Statement;
+
+/**
+   Clase que modela la conexion con la base de datos.
+
+   Para crear una nueva conexion hay que invocar al Metodo Database::createConnection de la base de datos
+   contra la que deseamos establecer la conexion.
+
+   Para obtener una conexion a una determinada base de datos habria que instanciar dicha base de datos
+   e invocar al Metodo Database::createConnection. Independientemente del tipo de conexion particular que la base
+   de datos retorne, debemos asignarlo a un puntero de tipo anna::dbms::Connection.
+*/
+class Connection : public comm::Resource {
+public:
+  /**
+     Devuelve la instancia de la base de datos asociada a esta conexion.
+  */
+  Database& getDatabase() const throw() { return a_database; }
+
+  /**
+   * Devuelve el usuario con el que fué realizada esta conexión.
+   * \return el usuario con el que fué realizada esta conexión.
+   */
+  const std::string& getUser() const throw() { return a_user; }
+
+  /**
+   * Devuelve el password del usuario con el que fué realizada esta conexión.
+   * \return el password del usuario con el que fué realizada esta conexión.
+   */
+  const std::string& getPassword() const throw() { return a_password; }
+
+  /**
+   * Establece el password del usuario de esta conexión
+   * \param password Codigo de acceso del usuario.
+   */
+  void setPassword(const char* password) throw() { a_password = password; }
+
+  /**
+     Establece el periodo de grabacion de esta conexion. Damos la posibilidad de que la conexion confirme
+     cambios realizados hasta el momento sin que termine la seccion critica que debemos establecer antes
+     de usar la conexion.
+     \param maxCommitPending Numero de transacciones que pueden estar pedientes de confirmacion antes
+     de invocar a #commit. Un valor 0, desactiva el periodo.
+     \return El periodo de grabacion que habia antes de invocar a este metodo.
+     \warning La invocacion a este metodo debera hacerse con una seccion critica activada sobre la
+     esta conexion.
+  */
+  int setMaxCommitPending(const int maxCommitPending) throw() {
+    const int result = a_maxCommitPending;
+    a_maxCommitPending = maxCommitPending;
+    return result;
+  }
+
+  /**
+     Desactiva el indicador de que la conexion requiere una invocacion a #rollback.
+     \warning La invocacion a este metodo debera hacerse con una seccion critica activada sobre la
+     esta conexion.
+  */
+  void resetRollbackPending() throw() { a_rollbackPending =  false; }
+
+  /**
+     Activa de forma externa el indicador de que la conexion requiere una invocacion a #rollback.
+     \warning La invocacion a este metodo debera hacerse con una seccion critica activada sobre la
+     esta conexion.
+  */
+  void activateRollbackPending() throw() { a_rollbackPending = true; }
+
+  /**
+     Ejecuta la sentencia recibida como parametro. Si la sentencia no tiene variables de salida consideraria
+     que es un comando \em update, \em insert o \em delete, lo cual, implica la invocacion automatica a los
+     #commit o #rollback cuando termine la seccion critica de esta conexion.
+
+     \param statement Sentencia que vamos a ejecuta
+
+     \return La estructura con el resultado de la ejecucion de la sentencia.
+
+     \warning La invocacion a este metodo debera hacerse con una seccion critica activada sobre la
+     esta conexion, por ejemplo:
+     \code
+           Guard guard (connection);
+           connection.execute (someStatement);
+     \endcode
+  */
+  ResultCode execute(Statement* statement) throw(RuntimeException, DatabaseException);
+
+  /**
+     Devuelve una cadena con la informacion referente a esta instancia.
+     @return Una cadena con la informacion referente a esta instancia.
+  */
+  virtual std::string asString() const throw();
+
+  /**
+     Devuelve un documento XML con la informacion referente a esta instancia.
+     \param parent Nodo XML del que debe colgar la informacion.
+     @return un documento XML con la informacion referente a esta instancia.
+  */
+  virtual xml::Node* asXML(xml::Node* parent) const throw();
+
+protected:
+  /**
+    Instancia de la base de datos asociada a esta conexion.
+    Coincidiria con la indicada en el constructor.
+  */
+  Database& a_database;
+  std::string a_user; /**< Nombre del usuario */
+  std::string a_password; /**< Clave de acceso del usuario. */
+
+  /**
+     Contructor.
+
+     @param database Instancia de la base de datos asociada a esta conexion.
+     @param name Nombre logico de la conexion.
+     @param user Nombre del usuario con el que realizamos la conexion.
+     @param password Codigo de acceso del usuario.
+  */
+  Connection(Database& database, const std::string& name, const char* user, const char* password) :
+    comm::Resource(name),
+    a_database(database),
+    a_user(user),
+    a_password(password),
+    a_lockingCounter(0),
+    a_commitPending(0),
+    a_rollbackPending(false),
+    a_maxCommitPending(0) {}
+
+  /**
+     Metodo que fija los cambios realizados en la ejecucion de los comandos SQL.
+  */
+  void commit() throw(RuntimeException, DatabaseException);
+
+  /**
+     Metodo que debemos re-escribir para descartar los cambios realizados sobre las tablas mediante
+     esta conexion.
+  */
+  void rollback() throw();
+
+  /**
+     Metodo que debemos re-escribir para hacer efectiva esta conexion.
+  */
+  virtual void open() throw(DatabaseException) = 0;
+
+  /**
+     Metodo que debemos re-escribir para cerrar la conexion.
+  */
+  virtual void close() throw() = 0;
+
+private:
+  int a_commitPending; // Numero de sentencias a las que no se han fijado cambios.
+  bool a_rollbackPending;
+  int a_maxCommitPending;
+  int a_lockingCounter;
+
+  Connection(const Connection&);
+
+  void initialize() throw(RuntimeException, DatabaseException);
+  void lock() throw(RuntimeException);
+  void unlock() throw();
+
+  virtual bool do_beginTransaction() throw(RuntimeException, DatabaseException) { return false;}
+  virtual void do_commit() throw(RuntimeException, DatabaseException) = 0;
+  virtual void do_rollback() throw() = 0;
+
+  friend class Database;
+};
+
+}
+}
+
+#endif