f2180858db2ac17dbb1af0df889bc04ed863cfae
[anna.git] / Database.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_Database_hpp
10 #define anna_dbms_Database_hpp
11
12 #include <vector>
13
14 #include <anna/app/Component.hpp>
15
16 #include <anna/dbms/Connection.hpp>
17
18 namespace anna {
19
20 namespace comm {
21 class INetAddress;
22 class Delivery;
23 }
24
25 namespace dbms {
26
27 class Statement;
28 class InputBind;
29 class OutputBind;
30 class Data;
31 class FailRecoveryHandler;
32 class StatementTranslator;
33
34 /**
35    Clase que modela la interaccion entre la base y nuestra aplicacion.
36 */
37 class Database : public app::Component {
38 public:
39   /**
40      Numero maximo de conexiones que podemos crear.
41   */
42   static const int MaxConnection = 32;
43
44   /**
45      Formas de conexion a la base de datos.
46   */
47   struct Type {
48     enum _v { Local, Remote } value;
49     Type() : value(Local) {;}
50     Type(const _v v) : value(v) {;}
51     Type(const Type& v) : value(v.value) {;}
52     operator int () const { return value; }
53   };
54
55   typedef std::vector <Connection*>::const_iterator const_connection_iterator; /**<Iterador para acceder a las conexiones de esta base de datos */
56   typedef std::vector <Statement*>::const_iterator const_statement_iterator; /**<Iterador para acceder a las conexiones de esta base de datos */
57
58   /**
59      Destructor.
60   */
61   virtual ~Database();
62
63   /**
64      Devuelve el tipo de conexion de esta base de datos.
65      \return El tipo de conexion de esta base de datos.
66   */
67   const Type& getType() const { return a_type; }
68
69   /**
70      Devuelve el nombre de la base de datos indicado en el constructor.
71      \return El nombre de la base de datos indicado en el constructor.
72   */
73   const std::string& getName() const { return a_name; }
74
75   /**
76      Establece el manejador encargado de actuar cuando la recuperacion de la conexion falla.
77      El manejador por defecto no realiza ninguna activad.
78      \param failRecoveryHandler Manejador que seria invocado en caso de que no sea posible recuperar
79      una determina conexion.
80   */
81   void setFailRecoveryHandler(FailRecoveryHandler* failRecoveryHandler) { a_failRecoveryHandler = failRecoveryHandler; }
82
83   /**
84    * Establece el traductor de sentencias SQL usado ajustar las sentencias SQL al
85    * motor de base de datos usados en la aplicaciĆ³n.
86    */
87   void setStatementTranslator(StatementTranslator* statementTranslator) { a_statementTranslator = statementTranslator; }
88
89   /**
90      Crea y registra una nueva conexion con esta base de datos.
91      La clase usada para conectar con esta base de datos dependeria de la implementacion particular, que
92      seria definida por el metodo #allocateConnection.
93
94      \param name Nombre logico de la conexion a crear.
95      @param user Nombre del usuario con el que realizamos la conexion.
96      @param password Codigo de acceso del usuario.
97
98      @return La instancia de la nueva conexion a la base de datos.
99   */
100   Connection* createConnection(const char* name, const char* user, const char* password)
101   noexcept(false);
102
103   /**
104      Devuelve la conexion asociada al nombre logico recibido como parametro.
105      \param name Nombre logico de la conexion que queremos obtener.
106      \return La conexion asociada al nombre logico recibido como parametro.
107      \warning Si la conexion logica no existe no puede ser usada se lanzara una excepcion.
108   */
109   Connection& findConnection(const char* name) noexcept(false);
110
111   /**
112      Devuelve un iterator al comienzo de la lista de conexiones establecidas con esta base de datos.
113      \return Un iterator al comienzo de la lista de conexiones establecidas con esta base de datos.
114   */
115   const_connection_iterator connection_begin() const { return a_connections.begin(); }
116
117   /**
118      Devuelve un iterator al final de la lista de conexiones establecidas con esta base de datos.
119      \return Un iterator al final de la lista de conexiones establecidas con esta base de datos.
120   */
121   const_connection_iterator connection_end() const { return a_connections.end(); }
122
123   /**
124      Crea y registra una nueva sentencia SQL asociada a esta base de datos.
125      La clase usada para interpretar la sentencia SQL dependera de la implementacion particular definida
126      mediante el metodo #allocateStatement.
127
128      \param name Nombre logico de esta sentencia.
129      \param expression Expresion asociada a la sentencia.
130      \param isCritical Si vale \em true indica que si la ejecucion de esta sentencia falla al desbloquear
131      la conexion con la que ejecutamos esta sentencia se invocara a Connection::rollback, en otro caso
132      aunque falle se invocara a Connection::commit. Solo aplicara en sentencias que no sean de seleccion.
133
134      \return Una nueva instancia de una conexion a base de datos. No puede ser NULL.
135   */
136   Statement* createStatement(const char* name, const char* expression, const bool isCritical = true)
137   noexcept(false);
138
139   /**
140      Crea y registra una nueva sentencia SQL asociada a esta base de datos.
141      La clase usada para interpretar la sentencia SQL dependera de la implementacion particular definida
142      mediante el metodo #allocateStatement.
143
144      \param name Nombre logico de esta sentencia.
145      \param expression Expresion asociada a la sentencia.
146      \param isCritical Si vale \em true indica que si la ejecucion de esta sentencia falla al desbloquear
147      la conexion con la que ejecutamos esta sentencia se invocara a Connection::rollback, en otro caso
148      aunque falle se invocara a Connection::commit. Solo aplicara en sentencias que no sean de seleccion.
149
150      \return Una nueva instancia de una conexion a base de datos. No puede ser NULL.
151   */
152   Statement* createStatement(const char* name, const std::string& expression, const bool isCritical = true)
153   noexcept(false) {
154     return createStatement(name, expression.c_str(), isCritical);
155   }
156
157   /**
158      Devuelve la instancia de la sentencia SQL asociada al nombre recibido como parametro.
159
160      @return La instancia de la sentencia SQL  asociada al nombre recibido.
161      Puede ser NULL si el nombre no fue registrado previamente con #createStatement.
162   */
163   Statement* findStatement(const char* name) ;
164
165   /**
166      Libera los recursos de la sentencia SQL recibida como parametro.
167      \param statement Instancia de la sentencia SQL a liberar. deberia haber sido obtenida mediante
168      el metodo #createStatement.
169   */
170   void releaseStatement(Statement* statement) ;
171
172   /**
173      Devuelve un iterator al comienzo de la lista de sentencias SQL creadas en esta base de datos.
174      \return Un iterator al comienzo de la lista de sentencias SQL creadas en esta base de datos.
175   */
176   const_statement_iterator statement_begin() const { return a_statements.begin(); }
177
178   /**
179      Devuelve un iterator al final de la lista de sentencias SQL creadas en esta base de datos.
180      \return Un iterator al final de la lista de sentencias SQL creadas en esta base de datos.
181   */
182   const_statement_iterator statement_end() const { return a_statements.end(); }
183
184   /**
185      Devuelve el objeto sobre el que esta posicionado el iterator recibido como parametro.
186      \param ii Iterator que deberia estar comprendido entre #statement_begin y #statement_end.
187      \return El objeto sobre el que esta posicionado el iterator recibido como parametro.
188   */
189   static Statement* statement(const_statement_iterator& ii) { return *ii; }
190
191   /**
192      Devuelve una cadena con la informacion mas relevante de esta instancia.
193      \return Una cadena con la informacion mas relevante de esta instancia.
194   */
195   virtual std::string asString() const ;
196
197   /**
198      Devuelve un documento XML con la informacion mas relevante de esta instancia.
199      \param parent Nodo XML del que colgar la informacion referente a esta instancia.
200      \return Un documento XML con la informacion mas relevante de esta instancia.
201   */
202   virtual xml::Node* asXML(xml::Node* parent) const ;
203
204   /**
205      Devuelve el objeto sobre el que esta posicionado el iterator recibido como parametro.
206      \param ii Iterator que deberia estar comprendido entre #connection_begin y #connection_end.
207      \return El objeto sobre el que esta posicionado el iterator recibido como parametro.
208   */
209   static const Connection* connection(const_connection_iterator& ii) { return *ii; }
210
211 protected:
212   typedef std::vector <Connection*>::iterator connection_iterator; /**<Iterador para acceder a las conexiones de esta base de datos */
213
214   /**
215      Contructor.
216      \param rdbmsmsName Nombre del RDMS que gestiona esta base de datos.
217      \param dbmsName Nombre de la base de datos.
218   */
219   Database(const char* rdbmsmsName, const char* dbmsName);
220
221   /**
222      Recupera el estado de una conexion perdida.
223      \warning Este metodo se invoca automaticamente desde el nucleo de ANNA.dbms y nunca deberia
224      ser invocado por el programador.
225      \param connection Instancia de la conexion en la que hemos detectado el fallo.
226      \param tryCounter numero de intentos de recuperacion de la conexion.
227   */
228   void recover(Connection& connection, const int tryCounter) noexcept(false);
229
230   /**
231      Inicializa las conexiones definidas sobre esta base de datos. Este metodo se invocaria
232      automaticamente desde el nucleo de ANNA.
233      Slo seria necesario invocarlo cuando nuestro programa no tenga asociada ninguna aplicacion
234      que se encarga de inicializar los componentes.
235   */
236   virtual void do_initialize() noexcept(false);
237
238   /**
239      Elimina las conexiones definidas sobre esta base de datos. Este metodo se invocaria automaticamente
240      desde el nucleo de ANNA.
241   */
242   virtual void do_stop() ;
243
244   /**
245      Devuelve un iterator al comienzo de la lista de conexiones establecidas con esta base de datos.
246      \return Un iterator al comienzo de la lista de conexiones establecidas con esta base de datos.
247   */
248   connection_iterator connection_begin() { return a_connections.begin(); }
249
250   /**
251      Devuelve un iterator al final de la lista de conexiones establecidas con esta base de datos.
252      \return Un iterator al final de la lista de conexiones establecidas con esta base de datos.
253   */
254   connection_iterator connection_end() { return a_connections.end(); }
255
256   /**
257      Devuelve el objeto sobre el que esta posicionado el iterator recibido como parametro.
258      \param ii Iterator que deberia estar comprendido entre #connection_begin y #connection_end.
259      \return El objeto sobre el que esta posicionado el iterator recibido como parametro.
260   */
261   static Connection* connection(connection_iterator& ii) { return *ii; }
262
263 private:
264   const std::string a_name;
265   std::vector <Connection*> a_connections;
266   std::vector <Statement*> a_statements;
267   const Type a_type;
268   FailRecoveryHandler* a_failRecoveryHandler;
269   StatementTranslator* a_statementTranslator;
270
271   Database(const Database&);
272
273   void do_cloneChild() noexcept(false);
274
275   virtual Connection* allocateConnection(const std::string& name, const char* user, const char* password)
276   noexcept(false) = 0;
277
278   virtual Statement* allocateStatement(const char* name, const std::string& expression, const bool isCritical)
279   noexcept(false) = 0;
280
281   virtual InputBind* allocateInputBind(const char* name, Data& data)
282   noexcept(false) = 0;
283   virtual void deallocate(InputBind* inputBind)  = 0;
284
285   virtual OutputBind* allocateOutputBind(const char* name, Data& data)
286   noexcept(false) = 0;
287   virtual void deallocate(OutputBind* outputBind)  = 0;
288
289   friend class Statement;
290   friend ResultCode Connection::execute(Statement*) noexcept(false);
291 };
292
293 }
294 }
295
296 #endif