178e833917f5ccf38aa62d6c9f95683b434bb826
[anna.git] / Connection.hpp
1 // ANNA - Anna is Not Nothingness Anymore                                                         //
2 //                                                                                                //
3 // (c) Copyright 2005-2015 Eduardo Ramos Testillano & Francisco Ruiz Rayo                         //
4 //                                                                                                //
5 // See project site at http://redmine.teslayout.com/projects/anna-suite                           //
6 // See accompanying file LICENSE or copy at http://www.teslayout.com/projects/public/anna.LICENSE //
7
8
9 #ifndef anna_dbms_Connection_hpp
10 #define anna_dbms_Connection_hpp
11
12 #include <anna/comm/Resource.hpp>
13
14 #include <anna/dbms/DatabaseException.hpp>
15 #include <anna/dbms/ResultCode.hpp>
16
17 namespace anna {
18
19 namespace xml {
20 class Node;
21 }
22
23 namespace dbms {
24
25 class Database;
26 class Statement;
27
28 /**
29    Clase que modela la conexion con la base de datos.
30
31    Para crear una nueva conexion hay que invocar al Metodo Database::createConnection de la base de datos
32    contra la que deseamos establecer la conexion.
33
34    Para obtener una conexion a una determinada base de datos habria que instanciar dicha base de datos
35    e invocar al Metodo Database::createConnection. Independientemente del tipo de conexion particular que la base
36    de datos retorne, debemos asignarlo a un puntero de tipo anna::dbms::Connection.
37 */
38 class Connection : public comm::Resource {
39 public:
40   /**
41      Devuelve la instancia de la base de datos asociada a esta conexion.
42   */
43   Database& getDatabase() const { return a_database; }
44
45   /**
46    * Devuelve el usuario con el que fué realizada esta conexión.
47    * \return el usuario con el que fué realizada esta conexión.
48    */
49   const std::string& getUser() const { return a_user; }
50
51   /**
52    * Devuelve el password del usuario con el que fué realizada esta conexión.
53    * \return el password del usuario con el que fué realizada esta conexión.
54    */
55   const std::string& getPassword() const { return a_password; }
56
57   /**
58    * Establece el password del usuario de esta conexión
59    * \param password Codigo de acceso del usuario.
60    */
61   void setPassword(const char* password) { a_password = password; }
62
63   /**
64      Establece el periodo de grabacion de esta conexion. Damos la posibilidad de que la conexion confirme
65      cambios realizados hasta el momento sin que termine la seccion critica que debemos establecer antes
66      de usar la conexion.
67      \param maxCommitPending Numero de transacciones que pueden estar pedientes de confirmacion antes
68      de invocar a #commit. Un valor 0, desactiva el periodo.
69      \return El periodo de grabacion que habia antes de invocar a este metodo.
70      \warning La invocacion a este metodo debera hacerse con una seccion critica activada sobre la
71      esta conexion.
72   */
73   int setMaxCommitPending(const int maxCommitPending) {
74     const int result = a_maxCommitPending;
75     a_maxCommitPending = maxCommitPending;
76     return result;
77   }
78
79   /**
80      Desactiva el indicador de que la conexion requiere una invocacion a #rollback.
81      \warning La invocacion a este metodo debera hacerse con una seccion critica activada sobre la
82      esta conexion.
83   */
84   void resetRollbackPending() { a_rollbackPending =  false; }
85
86   /**
87      Activa de forma externa el indicador de que la conexion requiere una invocacion a #rollback.
88      \warning La invocacion a este metodo debera hacerse con una seccion critica activada sobre la
89      esta conexion.
90   */
91   void activateRollbackPending() { a_rollbackPending = true; }
92
93   /**
94      Ejecuta la sentencia recibida como parametro. Si la sentencia no tiene variables de salida consideraria
95      que es un comando \em update, \em insert o \em delete, lo cual, implica la invocacion automatica a los
96      #commit o #rollback cuando termine la seccion critica de esta conexion.
97
98      \param statement Sentencia que vamos a ejecuta
99
100      \return La estructura con el resultado de la ejecucion de la sentencia.
101
102      \warning La invocacion a este metodo debera hacerse con una seccion critica activada sobre la
103      esta conexion, por ejemplo:
104      \code
105            Guard guard (connection);
106            connection.execute (someStatement);
107      \endcode
108   */
109   ResultCode execute(Statement* statement) noexcept(false);
110
111   /**
112      Devuelve una cadena con la informacion referente a esta instancia.
113      @return Una cadena con la informacion referente a esta instancia.
114   */
115   virtual std::string asString() const ;
116
117   /**
118      Devuelve un documento XML con la informacion referente a esta instancia.
119      \param parent Nodo XML del que debe colgar la informacion.
120      @return un documento XML con la informacion referente a esta instancia.
121   */
122   virtual xml::Node* asXML(xml::Node* parent) const ;
123
124 protected:
125   /**
126     Instancia de la base de datos asociada a esta conexion.
127     Coincidiria con la indicada en el constructor.
128   */
129   Database& a_database;
130   std::string a_user; /**< Nombre del usuario */
131   std::string a_password; /**< Clave de acceso del usuario. */
132
133   /**
134      Contructor.
135
136      @param database Instancia de la base de datos asociada a esta conexion.
137      @param name Nombre logico de la conexion.
138      @param user Nombre del usuario con el que realizamos la conexion.
139      @param password Codigo de acceso del usuario.
140   */
141   Connection(Database& database, const std::string& name, const char* user, const char* password) :
142     comm::Resource(name),
143     a_database(database),
144     a_user(user),
145     a_password(password),
146     a_lockingCounter(0),
147     a_commitPending(0),
148     a_rollbackPending(false),
149     a_maxCommitPending(0) {}
150
151   /**
152      Metodo que fija los cambios realizados en la ejecucion de los comandos SQL.
153   */
154   void commit() noexcept(false);
155
156   /**
157      Metodo que debemos re-escribir para descartar los cambios realizados sobre las tablas mediante
158      esta conexion.
159   */
160   void rollback() ;
161
162   /**
163      Metodo que debemos re-escribir para hacer efectiva esta conexion.
164   */
165   virtual void open() noexcept(false) = 0;
166
167   /**
168      Metodo que debemos re-escribir para cerrar la conexion.
169   */
170   virtual void close()  = 0;
171
172 private:
173   int a_commitPending; // Numero de sentencias a las que no se han fijado cambios.
174   bool a_rollbackPending;
175   int a_maxCommitPending;
176   int a_lockingCounter;
177
178   Connection(const Connection&);
179
180   void initialize() noexcept(false);
181   void lock() noexcept(false);
182   void unlock() ;
183
184   virtual bool do_beginTransaction() noexcept(false) { return false;}
185   virtual void do_commit() noexcept(false) = 0;
186   virtual void do_rollback()  = 0;
187
188   friend class Database;
189 };
190
191 }
192 }
193
194 #endif