First commit
[anna.git] / include / anna / dbos / Set.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_dbos_Set_hpp
38 #define anna_dbos_Set_hpp
39
40 #include <anna/core/mt/SafeRecycler.hpp>
41 #include <anna/core/mt/Guard.hpp>
42 #include <anna/core/Allocator.hpp>
43
44 #include <anna/dbms/Statement.hpp>
45 #include <anna/dbms/DatabaseException.hpp>
46
47 #include <anna/dbos/Object.hpp>
48
49 namespace anna {
50
51 namespace dbos {
52
53 /**
54    Template para acceder a los elementos de un conjunto de objetos inicializados a partir
55    de los datos contenidos en un medio fisico.
56
57    A continuacion presentamos un ejemplo de uso:
58
59    \code
60    Server::Set <Server>* servers (NULL);   // Server hereda de esta clase.
61    ServerLoader serverLoader;        // ServerLoader hereda de dbos::Loader.
62    Server* server;
63
64    try {
65       serverLoader.setKey (..........); // Establece los parametros de busqueda
66
67       servers = Server::instantiate (serverLoader);
68
69       if (servers->size () == 0) {
70          ....
71          .... Si fuera necesario Trataria  la condicion de no encontrar ningun registro
72          ....
73       }
74
75       Server::iterator ii, maxii;
76
77       for (ii = servers->begin (), maxii = servers->end (); ii != maxii; ii ++) {
78          server = *ii;
79
80          .... Trataria  cada uno de los Server encontrados ....
81       }
82
83       Server::release (servers);
84    }
85    catch (Exception& ex) {
86       Server::release (servers);
87
88       ...
89       ... Si fuera necesario Trataria  la condicion de error.
90    }
91    \endcode
92  */
93 template <typename T> class Set : public Object {
94 public:
95   /**
96      Sinonimo usado para definir la clase contenedora de objetos del conjunto.
97   */
98   typedef typename anna::SafeRecycler <T, anna::Allocator<T> > Container;
99
100   /**
101      Sinonimo usado para acceder a los elementos del conjunto atraves de un iterador
102      de objetos no modificables.
103   */
104   typedef typename Container::const_iterator const_iterator;
105
106   /**
107      Sinonimo usado para acceder a los elementos del conjunto atraves de un iterador
108      de objetos modificables.
109   */
110   typedef typename Container::iterator iterator;
111
112   /**
113      Devuelve el inicio del vector de objetos contenidos en el conjunto.
114      \return El inicio del vector de objetos contenidos en el conjunto.
115   */
116   const_iterator begin() const throw() { return a_objects.begin(); }
117
118   /**
119      Devuelve el inicio del vector de objetos contenidos en el conjunto.
120      \return El inicio del vector de objetos contenidos en el conjunto.
121   */
122   iterator begin() throw() { return a_objects.begin(); }
123
124   /**
125      Devuelve el final del vector de objetos contenidos en el conjunto.
126      \return El final del vector de objetos contenidos en el conjunto.
127   */
128   const_iterator end() const throw() { return a_objects.end(); }
129
130   /**
131      Devuelve el final del vector de objetos contenidos en el conjunto.
132      \return El final del vector de objetos contenidos en el conjunto.
133   */
134   iterator end() throw() { return a_objects.end(); }
135
136   /**
137      Crea un nuevo puntero de la clase T dentro de este conjunto.
138   */
139   T* append() throw(RuntimeException) { return a_objects.create(); }
140
141   /**
142      Saca de este conjunto la instancia recibida como parametro y libera su memoria asociada.
143      La operacion se ignoraria si el puntero recibido como parametro es nulo o no pertenece al conjunto.
144      \param t Instancia que del objeto a eliminar.
145   */
146   void remove(T*& t) throw(RuntimeException) { a_objects.release(t); t = NULL; }
147
148   /**
149      Devuelve el nmero de elementos contenidos en el conjunto.
150      \return El nmero de elementos contenidos en el conjunto.
151   */
152   int size() const throw() { return a_objects.size(); }
153
154   /**
155      Devuelve el puntero sobre el que esta posicionado el iterador recibido como parametro.
156      \return El puntero sobre el que esta posicionado el iterador recibido como parametro.
157   */
158   static T* data(iterator& ii) throw() { return Container::data(ii); }
159
160   /**
161      Devuelve el puntero sobre el que esta posicionado el iterador recibido como parametro.
162      \return El puntero sobre el que esta posicionado el iterador recibido como parametro.
163   */
164   static const T* data(const_iterator& ii) throw() { return Container::data(ii); }
165
166 private:
167   Container a_objects;
168
169   void initialize(Loader& loader)
170   throw(RuntimeException, dbms::DatabaseException) {
171     T* object;
172     dbms::Statement* statement = loader.getStatement();
173
174     try {
175       do {
176         a_objects.create()->initialize(loader);
177       } while(statement->fetch() == true);
178     } catch(RuntimeException&) {
179       destroy();
180       throw;
181     } catch(dbms::DatabaseException&) {
182       destroy();
183       throw;
184     }
185   }
186
187   void destroy()
188   throw() {
189     for(iterator ii = begin(), maxii = end(); ii != maxii; ii ++)
190       data(ii)->destroy();
191
192     a_objects.clear();
193   }
194 };
195
196 }
197 }
198
199 #endif
200
201