Updated license
[anna.git] / include / anna / dbos / Accesor.hpp
1 // ANNA - Anna is Not Nothingness 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_dbos_Accesor_hpp
38 #define anna_dbos_Accesor_hpp
39
40 #include <anna/core/RuntimeException.hpp>
41 #include <anna/core/mt/Mutex.hpp>
42
43 #include <anna/dbms/DatabaseException.hpp>
44
45 #include <anna/dbos/defines.hpp>
46
47 namespace anna {
48
49 namespace dbms {
50 class Database;
51 class Connection;
52 class Statement;
53 }
54
55 namespace dbos {
56
57 class StorageArea;
58
59 /**
60    Interfaz que deben cumplir los objetos encargados de acceder al objeto del medio fisico,
61    que normalmente sera alguna base de datos.
62 */
63 class Accesor : public Mutex {
64 public:
65   typedef short Id; /**< Permite identificar el tipo de accesor. */
66
67   /**
68      Destructor.
69   */
70   virtual ~Accesor();
71
72   /**
73      Devuelve el identificador de este accesor.
74      \return El identificador de este accesor.
75   */
76   Id getId() const throw() { return a_id; }
77
78   /**
79      Devuelve la instancia de la sentencia \em statement asociada a este cargador.
80      \return La instancia de la sentencia \em statement asociada a este cargador. Puede ser NULL.
81   */
82   dbms::Statement* getStatement()
83   throw(RuntimeException) {
84     return (a_statement == NULL && a_database != NULL) ? (a_statement = initialize(*a_database)) : a_statement;
85   }
86
87   /**
88    * Devuelve \em true si el accesor fue inicializado con base de datos o \em false en otro caso.
89    * \return \em true si el accesor fue inicializado con base de datos o \em false en otro caso.
90    */
91   bool hasDataBase() const throw() { return a_database != NULL; }
92
93   /**
94      Devuelve la instancia de la base de datos asociada a este cargador.
95      \return La instancia de la base de datos asociada a este cargador.
96
97      \warning Si el accesor fue inicializado sin base de datos lo resultados no están definidos.
98   */
99   dbms::Database& getDatabase() throw() { return *a_database; }
100
101   /**
102      Devuelve la conexion que esta usando actualmente este cargador.
103      \return la conexion que esta usando actualmente este cargador.
104   */
105   dbms::Connection& getConnection() throw(RuntimeException) {
106     if(a_connection == NULL) {
107       std::string msg(asString());
108       msg += " | No available database connection";
109       throw RuntimeException(msg, ANNA_FILE_LOCATION);
110     }
111
112     return *a_connection;
113   }
114
115   /**
116      Devuelve la representacion en forma de cadena de la clave primaria establecida.
117      @return La representacion en forma de cadena de la clave primaria establecida.
118   */
119   virtual std::string asString() const throw() = 0;
120
121   /**
122      Metodo de debemos re-escribir para devolver el nombre completo del selector de recursos.
123      Para evitar ambigüedades este nombre deberia incluir la lista completa de \em namespaces
124      a la que pertenece la clase.
125      \return Una cadena con el nombre de este selector.
126   */
127   virtual const char* getClassName() const throw() = 0;
128
129 protected:
130   /**
131      Constructor.
132      \param database Base de datos asociada a este cargador y que deberia servir para
133      obtener los datos de un objeto. Debe tener la misma disponibilidad que este cargador.
134      \param id Identificador de este accesor.
135   */
136   Accesor(dbms::Database& database, const Id id) :
137     a_database(&database),
138     a_id(id),
139     a_statement(NULL),
140     a_connection(NULL),
141     a_emodeIsNull(true)
142   {;}
143
144   /**
145      Constructor.
146      \param database Base de datos asociada a este cargador y que deberia servir para
147      obtener los datos de un objeto. Debe tener la misma disponibilidad que este cargador.
148      \param id Identificador de este accesor.
149      \param emode Modo de actuar en caso de no encontrar el dato buscado.
150   */
151   Accesor(dbms::Database& database, const Id id, const Exception::Mode::_v emode) :
152     a_database(&database),
153     a_id(id),
154     a_statement(NULL),
155     a_connection(NULL),
156     a_emodeIsNull(false),
157     a_exceptionMode(emode)
158   {;}
159
160   /**
161      Constructor.
162      \param id Identificador de este accesor.
163   */
164   Accesor(const Id id) :
165     a_database(NULL),
166     a_id(id),
167     a_statement(NULL),
168     a_connection(NULL),
169     a_emodeIsNull(true)
170   {;}
171
172   /**
173      Metodo que deben implementar todos los accesores para definir la sentencia
174      SQL que los definira.
175      Se invocara automaticamente desde el nucleo de anna.dbos la primera vez que
176      se use este accesor, de forma que el programador solo debe preocuparse por
177      definir este metodo.
178      \param database Instancia de la base de datos indicada en el constructor.
179   */
180   virtual dbms::Statement* initialize(dbms::Database& database) throw(RuntimeException) = 0;
181
182 private:
183   dbms::Database* a_database;
184   const Id a_id;
185   dbms::Statement* a_statement;
186   dbms::Connection* a_connection;
187   bool a_emodeIsNull;
188   Exception::Mode::_v a_exceptionMode;
189
190   void setStatement(dbms::Statement* statement) throw() { a_statement = statement; }
191
192   virtual bool load(dbms::Connection*, const StorageArea*) throw(RuntimeException, dbms::DatabaseException);
193
194   friend class StorageArea;
195 };
196
197 }
198 }
199
200 #endif
201
202
203