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