First commit
[anna.git] / include / anna / dbms / Connection.hpp
1 // ANNA - Anna is Not 'N' Anymore
2 //
3 // (c) Copyright 2005-2014 Eduardo Ramos Testillano & Francisco Ruiz Rayo
4 //
5 // https://bitbucket.org/testillano/anna
6 //
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions
9 // are met:
10 //
11 //     * Redistributions of source code must retain the above copyright
12 // notice, this list of conditions and the following disclaimer.
13 //     * Redistributions in binary form must reproduce the above
14 // copyright notice, this list of conditions and the following disclaimer
15 // in the documentation and/or other materials provided with the
16 // distribution.
17 //     * Neither the name of Google Inc. nor the names of its
18 // contributors may be used to endorse or promote products derived from
19 // this software without specific prior written permission.
20 //
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 //
33 // Authors: eduardo.ramos.testillano@gmail.com
34 //          cisco.tierra@gmail.com
35
36
37 #ifndef anna_dbms_Connection_hpp
38 #define anna_dbms_Connection_hpp
39
40 #include <anna/comm/Resource.hpp>
41
42 #include <anna/dbms/DatabaseException.hpp>
43 #include <anna/dbms/ResultCode.hpp>
44
45 namespace anna {
46
47 namespace xml {
48 class Node;
49 }
50
51 namespace dbms {
52
53 class Database;
54 class Statement;
55
56 /**
57    Clase que modela la conexion con la base de datos.
58
59    Para crear una nueva conexion hay que invocar al Metodo Database::createConnection de la base de datos
60    contra la que deseamos establecer la conexion.
61
62    Para obtener una conexion a una determinada base de datos habria que instanciar dicha base de datos
63    e invocar al Metodo Database::createConnection. Independientemente del tipo de conexion particular que la base
64    de datos retorne, debemos asignarlo a un puntero de tipo anna::dbms::Connection.
65 */
66 class Connection : public comm::Resource {
67 public:
68   /**
69      Devuelve la instancia de la base de datos asociada a esta conexion.
70   */
71   Database& getDatabase() const throw() { return a_database; }
72
73   /**
74    * Devuelve el usuario con el que fué realizada esta conexión.
75    * \return el usuario con el que fué realizada esta conexión.
76    */
77   const std::string& getUser() const throw() { return a_user; }
78
79   /**
80    * Devuelve el password del usuario con el que fué realizada esta conexión.
81    * \return el password del usuario con el que fué realizada esta conexión.
82    */
83   const std::string& getPassword() const throw() { return a_password; }
84
85   /**
86    * Establece el password del usuario de esta conexión
87    * \param password Codigo de acceso del usuario.
88    */
89   void setPassword(const char* password) throw() { a_password = password; }
90
91   /**
92      Establece el periodo de grabacion de esta conexion. Damos la posibilidad de que la conexion confirme
93      cambios realizados hasta el momento sin que termine la seccion critica que debemos establecer antes
94      de usar la conexion.
95      \param maxCommitPending Numero de transacciones que pueden estar pedientes de confirmacion antes
96      de invocar a #commit. Un valor 0, desactiva el periodo.
97      \return El periodo de grabacion que habia antes de invocar a este metodo.
98      \warning La invocacion a este metodo debera hacerse con una seccion critica activada sobre la
99      esta conexion.
100   */
101   int setMaxCommitPending(const int maxCommitPending) throw() {
102     const int result = a_maxCommitPending;
103     a_maxCommitPending = maxCommitPending;
104     return result;
105   }
106
107   /**
108      Desactiva el indicador de que la conexion requiere una invocacion a #rollback.
109      \warning La invocacion a este metodo debera hacerse con una seccion critica activada sobre la
110      esta conexion.
111   */
112   void resetRollbackPending() throw() { a_rollbackPending =  false; }
113
114   /**
115      Activa de forma externa el indicador de que la conexion requiere una invocacion a #rollback.
116      \warning La invocacion a este metodo debera hacerse con una seccion critica activada sobre la
117      esta conexion.
118   */
119   void activateRollbackPending() throw() { a_rollbackPending = true; }
120
121   /**
122      Ejecuta la sentencia recibida como parametro. Si la sentencia no tiene variables de salida consideraria
123      que es un comando \em update, \em insert o \em delete, lo cual, implica la invocacion automatica a los
124      #commit o #rollback cuando termine la seccion critica de esta conexion.
125
126      \param statement Sentencia que vamos a ejecuta
127
128      \return La estructura con el resultado de la ejecucion de la sentencia.
129
130      \warning La invocacion a este metodo debera hacerse con una seccion critica activada sobre la
131      esta conexion, por ejemplo:
132      \code
133            Guard guard (connection);
134            connection.execute (someStatement);
135      \endcode
136   */
137   ResultCode execute(Statement* statement) throw(RuntimeException, DatabaseException);
138
139   /**
140      Devuelve una cadena con la informacion referente a esta instancia.
141      @return Una cadena con la informacion referente a esta instancia.
142   */
143   virtual std::string asString() const throw();
144
145   /**
146      Devuelve un documento XML con la informacion referente a esta instancia.
147      \param parent Nodo XML del que debe colgar la informacion.
148      @return un documento XML con la informacion referente a esta instancia.
149   */
150   virtual xml::Node* asXML(xml::Node* parent) const throw();
151
152 protected:
153   /**
154     Instancia de la base de datos asociada a esta conexion.
155     Coincidiria con la indicada en el constructor.
156   */
157   Database& a_database;
158   std::string a_user; /**< Nombre del usuario */
159   std::string a_password; /**< Clave de acceso del usuario. */
160
161   /**
162      Contructor.
163
164      @param database Instancia de la base de datos asociada a esta conexion.
165      @param name Nombre logico de la conexion.
166      @param user Nombre del usuario con el que realizamos la conexion.
167      @param password Codigo de acceso del usuario.
168   */
169   Connection(Database& database, const std::string& name, const char* user, const char* password) :
170     comm::Resource(name),
171     a_database(database),
172     a_user(user),
173     a_password(password),
174     a_lockingCounter(0),
175     a_commitPending(0),
176     a_rollbackPending(false),
177     a_maxCommitPending(0) {}
178
179   /**
180      Metodo que fija los cambios realizados en la ejecucion de los comandos SQL.
181   */
182   void commit() throw(RuntimeException, DatabaseException);
183
184   /**
185      Metodo que debemos re-escribir para descartar los cambios realizados sobre las tablas mediante
186      esta conexion.
187   */
188   void rollback() throw();
189
190   /**
191      Metodo que debemos re-escribir para hacer efectiva esta conexion.
192   */
193   virtual void open() throw(DatabaseException) = 0;
194
195   /**
196      Metodo que debemos re-escribir para cerrar la conexion.
197   */
198   virtual void close() throw() = 0;
199
200 private:
201   int a_commitPending; // Numero de sentencias a las que no se han fijado cambios.
202   bool a_rollbackPending;
203   int a_maxCommitPending;
204   int a_lockingCounter;
205
206   Connection(const Connection&);
207
208   void initialize() throw(RuntimeException, DatabaseException);
209   void lock() throw(RuntimeException);
210   void unlock() throw();
211
212   virtual bool do_beginTransaction() throw(RuntimeException, DatabaseException) { return false;}
213   virtual void do_commit() throw(RuntimeException, DatabaseException) = 0;
214   virtual void do_rollback() throw() = 0;
215
216   friend class Database;
217 };
218
219 }
220 }
221
222 #endif