--- /dev/null
+// ANNA - Anna is Not Nothingness Anymore //
+// //
+// (c) Copyright 2005-2015 Eduardo Ramos Testillano & Francisco Ruiz Rayo //
+// //
+// See project site at http://redmine.teslayout.com/projects/anna-suite //
+// See accompanying file LICENSE or copy at http://www.teslayout.com/projects/public/anna.LICENSE //
+
+
+#ifndef anna_dbos_Set_hpp
+#define anna_dbos_Set_hpp
+
+#include <anna/core/mt/SafeRecycler.hpp>
+#include <anna/core/mt/Guard.hpp>
+#include <anna/core/Allocator.hpp>
+
+#include <anna/dbms/Statement.hpp>
+#include <anna/dbms/DatabaseException.hpp>
+
+#include <anna/dbos/Object.hpp>
+
+namespace anna {
+
+namespace dbos {
+
+/**
+ Template para acceder a los elementos de un conjunto de objetos inicializados a partir
+ de los datos contenidos en un medio fisico.
+
+ A continuacion presentamos un ejemplo de uso:
+
+ \code
+ Server::Set <Server>* servers (NULL); // Server hereda de esta clase.
+ ServerLoader serverLoader; // ServerLoader hereda de dbos::Loader.
+ Server* server;
+
+ try {
+ serverLoader.setKey (..........); // Establece los parametros de busqueda
+
+ servers = Server::instantiate (serverLoader);
+
+ if (servers->size () == 0) {
+ ....
+ .... Si fuera necesario Trataria la condicion de no encontrar ningun registro
+ ....
+ }
+
+ Server::iterator ii, maxii;
+
+ for (ii = servers->begin (), maxii = servers->end (); ii != maxii; ii ++) {
+ server = *ii;
+
+ .... Trataria cada uno de los Server encontrados ....
+ }
+
+ Server::release (servers);
+ }
+ catch (Exception& ex) {
+ Server::release (servers);
+
+ ...
+ ... Si fuera necesario Trataria la condicion de error.
+ }
+ \endcode
+ */
+template <typename T> class Set : public Object {
+public:
+ /**
+ Sinonimo usado para definir la clase contenedora de objetos del conjunto.
+ */
+ typedef typename anna::SafeRecycler <T, anna::Allocator<T> > Container;
+
+ /**
+ Sinonimo usado para acceder a los elementos del conjunto atraves de un iterador
+ de objetos no modificables.
+ */
+ typedef typename Container::const_iterator const_iterator;
+
+ /**
+ Sinonimo usado para acceder a los elementos del conjunto atraves de un iterador
+ de objetos modificables.
+ */
+ typedef typename Container::iterator iterator;
+
+ /**
+ Devuelve el inicio del vector de objetos contenidos en el conjunto.
+ \return El inicio del vector de objetos contenidos en el conjunto.
+ */
+ const_iterator begin() const throw() { return a_objects.begin(); }
+
+ /**
+ Devuelve el inicio del vector de objetos contenidos en el conjunto.
+ \return El inicio del vector de objetos contenidos en el conjunto.
+ */
+ iterator begin() throw() { return a_objects.begin(); }
+
+ /**
+ Devuelve el final del vector de objetos contenidos en el conjunto.
+ \return El final del vector de objetos contenidos en el conjunto.
+ */
+ const_iterator end() const throw() { return a_objects.end(); }
+
+ /**
+ Devuelve el final del vector de objetos contenidos en el conjunto.
+ \return El final del vector de objetos contenidos en el conjunto.
+ */
+ iterator end() throw() { return a_objects.end(); }
+
+ /**
+ Crea un nuevo puntero de la clase T dentro de este conjunto.
+ */
+ T* append() throw(RuntimeException) { return a_objects.create(); }
+
+ /**
+ Saca de este conjunto la instancia recibida como parametro y libera su memoria asociada.
+ La operacion se ignoraria si el puntero recibido como parametro es nulo o no pertenece al conjunto.
+ \param t Instancia que del objeto a eliminar.
+ */
+ void remove(T*& t) throw(RuntimeException) { a_objects.release(t); t = NULL; }
+
+ /**
+ Devuelve el nmero de elementos contenidos en el conjunto.
+ \return El nmero de elementos contenidos en el conjunto.
+ */
+ int size() const throw() { return a_objects.size(); }
+
+ /**
+ Devuelve el puntero sobre el que esta posicionado el iterador recibido como parametro.
+ \return El puntero sobre el que esta posicionado el iterador recibido como parametro.
+ */
+ static T* data(iterator& ii) throw() { return Container::data(ii); }
+
+ /**
+ Devuelve el puntero sobre el que esta posicionado el iterador recibido como parametro.
+ \return El puntero sobre el que esta posicionado el iterador recibido como parametro.
+ */
+ static const T* data(const_iterator& ii) throw() { return Container::data(ii); }
+
+private:
+ Container a_objects;
+
+ void initialize(Loader& loader)
+ throw(RuntimeException, dbms::DatabaseException) {
+ T* object;
+ dbms::Statement* statement = loader.getStatement();
+
+ try {
+ do {
+ a_objects.create()->initialize(loader);
+ } while(statement->fetch() == true);
+ } catch(RuntimeException&) {
+ destroy();
+ throw;
+ } catch(dbms::DatabaseException&) {
+ destroy();
+ throw;
+ }
+ }
+
+ void destroy()
+ throw() {
+ for(iterator ii = begin(), maxii = end(); ii != maxii; ii ++)
+ data(ii)->destroy();
+
+ a_objects.clear();
+ }
+};
+
+}
+}
+
+#endif
+
+