1 // ANNA - Anna is Not 'N' Anymore
3 // (c) Copyright 2005-2014 Eduardo Ramos Testillano & Francisco Ruiz Rayo
5 // https://bitbucket.org/testillano/anna
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions
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
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.
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.
33 // Authors: eduardo.ramos.testillano@gmail.com
34 // cisco.tierra@gmail.com
37 #ifndef anna_dbms_Database_hpp
38 #define anna_dbms_Database_hpp
42 #include <anna/app/Component.hpp>
44 #include <anna/dbms/Connection.hpp>
59 class FailRecoveryHandler;
60 class StatementTranslator;
63 Clase que modela la interaccion entre la base y nuestra aplicacion.
65 class Database : public app::Component {
68 Numero maximo de conexiones que podemos crear.
70 static const int MaxConnection = 32;
73 Formas de conexion a la base de datos.
76 enum _v { Local, Remote } value;
77 Type() : value(Local) {;}
78 Type(const _v v) : value(v) {;}
79 Type(const Type& v) : value(v.value) {;}
80 operator int () const throw() { return value; }
83 typedef std::vector <Connection*>::const_iterator const_connection_iterator; /**<Iterador para acceder a las conexiones de esta base de datos */
84 typedef std::vector <Statement*>::const_iterator const_statement_iterator; /**<Iterador para acceder a las conexiones de esta base de datos */
92 Devuelve el tipo de conexion de esta base de datos.
93 \return El tipo de conexion de esta base de datos.
95 const Type& getType() const throw() { return a_type; }
98 Devuelve el nombre de la base de datos indicado en el constructor.
99 \return El nombre de la base de datos indicado en el constructor.
101 const std::string& getName() const throw() { return a_name; }
104 Establece el manejador encargado de actuar cuando la recuperacion de la conexion falla.
105 El manejador por defecto no realiza ninguna activad.
106 \param failRecoveryHandler Manejador que seria invocado en caso de que no sea posible recuperar
107 una determina conexion.
109 void setFailRecoveryHandler(FailRecoveryHandler* failRecoveryHandler) throw() { a_failRecoveryHandler = failRecoveryHandler; }
112 * Establece el traductor de sentencias SQL usado ajustar las sentencias SQL al
113 * motor de base de datos usados en la aplicaciĆ³n.
115 void setStatementTranslator(StatementTranslator* statementTranslator) throw() { a_statementTranslator = statementTranslator; }
118 Crea y registra una nueva conexion con esta base de datos.
119 La clase usada para conectar con esta base de datos dependeria de la implementacion particular, que
120 seria definida por el metodo #allocateConnection.
122 \param name Nombre logico de la conexion a crear.
123 @param user Nombre del usuario con el que realizamos la conexion.
124 @param password Codigo de acceso del usuario.
126 @return La instancia de la nueva conexion a la base de datos.
128 Connection* createConnection(const char* name, const char* user, const char* password)
129 throw(RuntimeException, DatabaseException);
132 Devuelve la conexion asociada al nombre logico recibido como parametro.
133 \param name Nombre logico de la conexion que queremos obtener.
134 \return La conexion asociada al nombre logico recibido como parametro.
135 \warning Si la conexion logica no existe no puede ser usada se lanzara una excepcion.
137 Connection& findConnection(const char* name) throw(RuntimeException);
140 Devuelve un iterator al comienzo de la lista de conexiones establecidas con esta base de datos.
141 \return Un iterator al comienzo de la lista de conexiones establecidas con esta base de datos.
143 const_connection_iterator connection_begin() const throw() { return a_connections.begin(); }
146 Devuelve un iterator al final de la lista de conexiones establecidas con esta base de datos.
147 \return Un iterator al final de la lista de conexiones establecidas con esta base de datos.
149 const_connection_iterator connection_end() const throw() { return a_connections.end(); }
152 Crea y registra una nueva sentencia SQL asociada a esta base de datos.
153 La clase usada para interpretar la sentencia SQL dependera de la implementacion particular definida
154 mediante el metodo #allocateStatement.
156 \param name Nombre logico de esta sentencia.
157 \param expression Expresion asociada a la sentencia.
158 \param isCritical Si vale \em true indica que si la ejecucion de esta sentencia falla al desbloquear
159 la conexion con la que ejecutamos esta sentencia se invocara a Connection::rollback, en otro caso
160 aunque falle se invocara a Connection::commit. Solo aplicara en sentencias que no sean de seleccion.
162 \return Una nueva instancia de una conexion a base de datos. No puede ser NULL.
164 Statement* createStatement(const char* name, const char* expression, const bool isCritical = true)
165 throw(RuntimeException);
168 Crea y registra una nueva sentencia SQL asociada a esta base de datos.
169 La clase usada para interpretar la sentencia SQL dependera de la implementacion particular definida
170 mediante el metodo #allocateStatement.
172 \param name Nombre logico de esta sentencia.
173 \param expression Expresion asociada a la sentencia.
174 \param isCritical Si vale \em true indica que si la ejecucion de esta sentencia falla al desbloquear
175 la conexion con la que ejecutamos esta sentencia se invocara a Connection::rollback, en otro caso
176 aunque falle se invocara a Connection::commit. Solo aplicara en sentencias que no sean de seleccion.
178 \return Una nueva instancia de una conexion a base de datos. No puede ser NULL.
180 Statement* createStatement(const char* name, const std::string& expression, const bool isCritical = true)
181 throw(RuntimeException) {
182 return createStatement(name, expression.c_str(), isCritical);
186 Devuelve la instancia de la sentencia SQL asociada al nombre recibido como parametro.
188 @return La instancia de la sentencia SQL asociada al nombre recibido.
189 Puede ser NULL si el nombre no fue registrado previamente con #createStatement.
191 Statement* findStatement(const char* name) throw();
194 Libera los recursos de la sentencia SQL recibida como parametro.
195 \param statement Instancia de la sentencia SQL a liberar. deberia haber sido obtenida mediante
196 el metodo #createStatement.
198 void releaseStatement(Statement* statement) throw();
201 Devuelve un iterator al comienzo de la lista de sentencias SQL creadas en esta base de datos.
202 \return Un iterator al comienzo de la lista de sentencias SQL creadas en esta base de datos.
204 const_statement_iterator statement_begin() const throw() { return a_statements.begin(); }
207 Devuelve un iterator al final de la lista de sentencias SQL creadas en esta base de datos.
208 \return Un iterator al final de la lista de sentencias SQL creadas en esta base de datos.
210 const_statement_iterator statement_end() const throw() { return a_statements.end(); }
213 Devuelve el objeto sobre el que esta posicionado el iterator recibido como parametro.
214 \param ii Iterator que deberia estar comprendido entre #statement_begin y #statement_end.
215 \return El objeto sobre el que esta posicionado el iterator recibido como parametro.
217 static Statement* statement(const_statement_iterator& ii) throw() { return *ii; }
220 Devuelve una cadena con la informacion mas relevante de esta instancia.
221 \return Una cadena con la informacion mas relevante de esta instancia.
223 virtual std::string asString() const throw();
226 Devuelve un documento XML con la informacion mas relevante de esta instancia.
227 \param parent Nodo XML del que colgar la informacion referente a esta instancia.
228 \return Un documento XML con la informacion mas relevante de esta instancia.
230 virtual xml::Node* asXML(xml::Node* parent) const throw();
233 Devuelve el objeto sobre el que esta posicionado el iterator recibido como parametro.
234 \param ii Iterator que deberia estar comprendido entre #connection_begin y #connection_end.
235 \return El objeto sobre el que esta posicionado el iterator recibido como parametro.
237 static const Connection* connection(const_connection_iterator& ii) throw() { return *ii; }
240 typedef std::vector <Connection*>::iterator connection_iterator; /**<Iterador para acceder a las conexiones de esta base de datos */
244 \param rdbmsmsName Nombre del RDMS que gestiona esta base de datos.
245 \param dbmsName Nombre de la base de datos.
247 Database(const char* rdbmsmsName, const char* dbmsName);
250 Recupera el estado de una conexion perdida.
251 \warning Este metodo se invoca automaticamente desde el nucleo de ANNA.dbms y nunca deberia
252 ser invocado por el programador.
253 \param connection Instancia de la conexion en la que hemos detectado el fallo.
254 \param tryCounter numero de intentos de recuperacion de la conexion.
256 void recover(Connection& connection, const int tryCounter) throw(RuntimeException);
259 Inicializa las conexiones definidas sobre esta base de datos. Este metodo se invocaria
260 automaticamente desde el nucleo de ANNA.
261 Slo seria necesario invocarlo cuando nuestro programa no tenga asociada ninguna aplicacion
262 que se encarga de inicializar los componentes.
264 virtual void do_initialize() throw(RuntimeException);
267 Elimina las conexiones definidas sobre esta base de datos. Este metodo se invocaria automaticamente
268 desde el nucleo de ANNA.
270 virtual void do_stop() throw();
273 Devuelve un iterator al comienzo de la lista de conexiones establecidas con esta base de datos.
274 \return Un iterator al comienzo de la lista de conexiones establecidas con esta base de datos.
276 connection_iterator connection_begin() throw() { return a_connections.begin(); }
279 Devuelve un iterator al final de la lista de conexiones establecidas con esta base de datos.
280 \return Un iterator al final de la lista de conexiones establecidas con esta base de datos.
282 connection_iterator connection_end() throw() { return a_connections.end(); }
285 Devuelve el objeto sobre el que esta posicionado el iterator recibido como parametro.
286 \param ii Iterator que deberia estar comprendido entre #connection_begin y #connection_end.
287 \return El objeto sobre el que esta posicionado el iterator recibido como parametro.
289 static Connection* connection(connection_iterator& ii) throw() { return *ii; }
292 const std::string a_name;
293 std::vector <Connection*> a_connections;
294 std::vector <Statement*> a_statements;
296 FailRecoveryHandler* a_failRecoveryHandler;
297 StatementTranslator* a_statementTranslator;
299 Database(const Database&);
301 void do_cloneChild() throw(RuntimeException);
303 virtual Connection* allocateConnection(const std::string& name, const char* user, const char* password)
304 throw(RuntimeException) = 0;
306 virtual Statement* allocateStatement(const char* name, const std::string& expression, const bool isCritical)
307 throw(RuntimeException) = 0;
309 virtual InputBind* allocateInputBind(const char* name, Data& data)
310 throw(RuntimeException) = 0;
311 virtual void deallocate(InputBind* inputBind) throw() = 0;
313 virtual OutputBind* allocateOutputBind(const char* name, Data& data)
314 throw(RuntimeException) = 0;
315 virtual void deallocate(OutputBind* outputBind) throw() = 0;
317 friend class Statement;
318 friend ResultCode Connection::execute(Statement*) throw(RuntimeException, DatabaseException);