+++ /dev/null
-mysqlclient
+++ /dev/null
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-
-#include <mysql/mysql.h>
-
-#define STRING_SIZE 50
-
-#define INSERT_SAMPLE "insert into anna_db_test (xx, yy, zz, tt) values (?,?,?,?)"
-
-
-#define MAXCOLUMN 4
-
-MYSQL* mysql;
-MYSQL_STMT *stmt;
-MYSQL_BIND bind[MAXCOLUMN];
-MYSQL_TIME ts;
-unsigned long length[MAXCOLUMN];
-int param_count, column_count, row_count;
-float float_data;
-int int_data;
-char str_data[STRING_SIZE];
-my_bool is_null[MAXCOLUMN];
-
-/*
- * From http://dev.mysql.com/doc/refman/4.1/en/mysql-stmt-fetch.html
- */
-int main (int argc, const char** argv)
-{
- if ((mysql = mysql_init (NULL)) == NULL)
- exit(-12);
-
- if (mysql_real_connect (mysql, NULL, "sdp", "sdp", "test", 0, NULL, 0L) == NULL) {
- fprintf(stderr, " mysql_stmt_prepare(), SELECT failed\n");
- fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
- exit(0);
- }
-
- /* Prepare a SELECT query to fetch data from test_table */
- stmt = mysql_stmt_init(mysql);
- if (!stmt)
- {
- fprintf(stderr, " mysql_stmt_init(), out of memory\n");
- exit(0);
- }
-
- if (mysql_stmt_prepare(stmt, INSERT_SAMPLE, strlen(INSERT_SAMPLE)))
- {
- fprintf(stderr, " mysql_stmt_prepare(), INSERT failed\n");
- fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
- exit(0);
- }
- fprintf(stdout, " prepare, INSERT successful\n");
-
- /* Get the parameter count from the statement */
- param_count= mysql_stmt_param_count(stmt);
- fprintf(stdout, " total parameters in INSERT: %d\n", param_count);
-
- if (param_count != MAXCOLUMN) /* validate parameter count */
- {
- fprintf(stderr, " invalid parameter count returned by MySQL\n");
- exit(0);
- }
-
- /* Bind the result buffers for all 3 columns before fetching them */
-
- memset(bind, 0, sizeof(bind));
-
- /* INTEGER COLUMN */
- bind[0].buffer_type= MYSQL_TYPE_LONG;
- bind[0].buffer= (char *)&int_data;
- bind[0].is_null= &is_null[0];
- bind[0].length= &length[0];
-
- /* STRING COLUMN */
- bind[1].buffer_type= MYSQL_TYPE_STRING;
- bind[1].buffer= (char *)str_data;
- bind[1].buffer_length= STRING_SIZE;
- bind[1].is_null= &is_null[1];
- bind[1].length= &length [1];
-
- /* FLOAT COLUMN */
- bind[2].buffer_type= MYSQL_TYPE_FLOAT;
- bind[2].buffer= (char *)&float_data;
- bind[2].is_null= &is_null[2];
- bind[2].length= &length[2];
-
- /* TIME COLUMN */
- bind[3].buffer_type= MYSQL_TYPE_DATETIME;
- bind[3].buffer= (char *)&ts;
- bind[3].is_null= &is_null[2];
- bind[3].length= &length[2];
-
- /* Bind the result buffers */
- if (mysql_stmt_bind_param (stmt, bind))
- {
- fprintf(stderr, " mysql_stmt_bind_param() failed\n");
- fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
- exit(0);
- }
-
- int_data = 99;
- strcpy (str_data, "insert: 99");
- length [1] = strlen (str_data);
- float_data = 0.99;
- ts.year = 1996; ts.month = 2; ts.day = 11;
- ts.hour = 19; ts.minute = 22; ts.second = 0;
-
- /* Execute the INSERT query */
- if (mysql_stmt_execute(stmt))
- {
- fprintf(stderr, " mysql_stmt_execute(), failed\n");
- fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
- exit(0);
- }
-
- is_null [0] = 1;
- strcpy (str_data, "insert: <null>");
- length [1] = strlen (str_data);
- float_data = 0.98;
- ts.year = 1999; ts.month = 8; ts.day = 7;
- ts.hour = 19; ts.minute = 18; ts.second = 17;
-
- /* Execute the INSERT query */
- if (mysql_stmt_execute(stmt))
- {
- fprintf(stderr, " mysql_stmt_execute(), failed\n");
- fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
- exit(0);
- }
-
- /* Close the statement */
- if (mysql_stmt_close(stmt))
- {
- fprintf(stderr, " failed while closing the statement\n");
- fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
- exit(0);
- }
-
- return 0;
-}
+++ /dev/null
-mysqlclient
+++ /dev/null
-#include <string.h>
-#include <stdio.h>
-
-#include <mysql/mysql.h>
-
-#define STRING_SIZE 50
-
-#define SELECT_SAMPLE "SELECT xx, yy, zz, tt FROM anna_db_test"
-
-#define MAXCOLUMN 4
-
-MYSQL* mysql;
-MYSQL_STMT *stmt;
-MYSQL_BIND bind[MAXCOLUMN];
-MYSQL_RES *prepare_meta_result;
-MYSQL_TIME ts;
-unsigned long length[MAXCOLUMN];
-int param_count, column_count, row_count;
-float float_data;
-int int_data;
-char str_data[STRING_SIZE];
-my_bool is_null[MAXCOLUMN];
-
-/*
- * From http://dev.mysql.com/doc/refman/4.1/en/mysql-stmt-fetch.html
- */
-int main (int argc, const char** argv)
-{
- if ((mysql = mysql_init (NULL)) == NULL)
- exit (-12);
-
- if (mysql_real_connect (mysql, NULL, "sdp", "sdp", "test", 0, NULL, 0L) == NULL) {
- fprintf(stderr, " mysql_stmt_prepare(), SELECT failed\n");
- fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
- exit(0);
- }
-
- /* Prepare a SELECT query to fetch data from test_table */
- stmt = mysql_stmt_init(mysql);
- if (!stmt)
- {
- fprintf(stderr, " mysql_stmt_init(), out of memory\n");
- exit(0);
- }
-
- if (mysql_stmt_prepare(stmt, SELECT_SAMPLE, strlen(SELECT_SAMPLE)))
- {
- fprintf(stderr, " mysql_stmt_prepare(), SELECT failed\n");
- fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
- exit(0);
- }
- fprintf(stdout, " prepare, SELECT successful\n");
-
- /* Get the parameter count from the statement */
- param_count= mysql_stmt_param_count(stmt);
- fprintf(stdout, " total parameters in SELECT: %d\n", param_count);
-
- if (param_count != 0) /* validate parameter count */
- {
- fprintf(stderr, " invalid parameter count returned by MySQL\n");
- exit(0);
- }
-
- /* Fetch result set meta information */
- prepare_meta_result = mysql_stmt_result_metadata(stmt);
- if (!prepare_meta_result)
- {
- fprintf(stderr," mysql_stmt_result_metadata(), returned no meta information\n");
- fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
- exit(0);
- }
-
- /* Get total columns in the query */
- column_count= mysql_num_fields(prepare_meta_result);
- fprintf(stdout, " total columns in SELECT statement: %d\n", column_count);
-
- if (column_count != MAXCOLUMN) /* validate column count */
- {
- fprintf(stderr, " invalid column count returned by MySQL\n");
- exit(0);
- }
-
- /* Execute the SELECT query */
- if (mysql_stmt_execute(stmt))
- {
- fprintf(stderr, " mysql_stmt_execute(), failed\n");
- fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
- exit(0);
- }
-
- /* Bind the result buffers for all 4 columns before fetching them */
-
- memset(bind, 0, sizeof(bind));
-
- /* INTEGER COLUMN */
- bind[0].buffer_type= MYSQL_TYPE_LONG;
- bind[0].buffer= (char *)&int_data;
- bind[0].is_null= &is_null[0];
- bind[0].length= &length[0];
-
- /* STRING COLUMN */
- bind[1].buffer_type= MYSQL_TYPE_STRING;
- bind[1].buffer= (char *)str_data;
- bind[1].buffer_length= STRING_SIZE;
- bind[1].is_null= &is_null[1];
- bind[1].length= &length[1];
-
- /* SMALLINT COLUMN */
- bind[2].buffer_type= MYSQL_TYPE_FLOAT;
- bind[2].buffer= (char *)&float_data;
- bind[2].is_null= &is_null[2];
- bind[2].length= &length[2];
-
- /* TIMESTAMP COLUMN */
- bind[3].buffer_type= MYSQL_TYPE_TIMESTAMP;
- bind[3].buffer= (char *)&ts;
- bind[3].is_null= &is_null[3];
- bind[3].length= &length[3];
-
- /* Bind the result buffers */
- if (mysql_stmt_bind_result(stmt, bind))
- {
- fprintf(stderr, " mysql_stmt_bind_result() failed\n");
- fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
- exit(0);
- }
-
- /* Now buffer all results to client (optional step) */
- if (mysql_stmt_store_result(stmt))
- {
- fprintf(stderr, " mysql_stmt_store_result() failed\n");
- fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
- exit(0);
- }
-
- /* Fetch all rows */
- row_count= 0;
- fprintf(stdout, "Fetching results ...\n");
- while (!mysql_stmt_fetch(stmt))
- {
- row_count++;
- fprintf(stdout, " row %d\n", row_count);
-
- /* column 1 */
- fprintf(stdout, " column1 (integer) : ");
- if (is_null[0])
- fprintf(stdout, " NULL\n");
- else
- fprintf(stdout, " %d(%ld)\n", int_data, length[0]);
-
- /* column 2 */
- fprintf(stdout, " column2 (string) : ");
- if (is_null[1])
- fprintf(stdout, " NULL\n");
- else
- fprintf(stdout, " %s(%ld)\n", str_data, length[1]);
-
- /* column 3 */
- fprintf(stdout, " column3 (float) : ");
- if (is_null[2])
- fprintf(stdout, " NULL\n");
- else
- fprintf(stdout, " %f(%ld)\n", float_data, length[2]);
-
- /* column 4 */
- fprintf(stdout, " column4 (timestamp): ");
- if (is_null[3])
- fprintf(stdout, " NULL\n");
- else
- fprintf(stdout, " %04d-%02d-%02d %02d:%02d:%02d (%ld)\n",
- ts.year, ts.month, ts.day,
- ts.hour, ts.minute, ts.second,
- length[3]);
- fprintf(stdout, "\n");
- }
-
- /* Free the prepared result metadata */
- mysql_free_result(prepare_meta_result);
-
- /* Close the statement */
- if (mysql_stmt_close(stmt))
- {
- fprintf(stderr, " failed while closing the statement\n");
- fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
- exit(0);
- }
-
-}
+++ /dev/null
-anna_dbms.mysql_static
-anna_dbms_static
-anna_comm_static
-anna_app_static
-anna_xml_static
-anna_io_static
-anna_core_static
-mysqlclient
-rt
-xml2
+++ /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 //
-
-
-#include <iostream>
-
-#include <anna/core/core.hpp>
-#include <anna/dbms/dbms.hpp>
-#include <anna/app/app.hpp>
-
-#include <anna/dbms.mysql/Database.hpp>
-#include <anna/dbms.mysql/OracleTranslator.hpp>
-
-class Insert : public Application {
-public:
- Insert ();
- ~Insert () { delete a_db; }
-
-private:
- anna::dbms::Database* a_db;
-
- void initialize () throw (RuntimeException);
- void run () throw (RuntimeException);
-};
-
-using namespace std;
-
-int main (int argc, const char** argv)
-{
- CommandLine& commandLine (CommandLine::instantiate ());
- Insert testNull;
-
- try {
- commandLine.initialize (argv, argc);
- commandLine.verify ();
-
- Logger::setLevel (Logger::Debug);
- Logger::initialize ("copy", new TraceWriter ("xinsert.trace", 1024 * 1024));
-
- testNull.start ();
- }
- catch (Exception& ex) {
- cout << ex.asString () << endl;
- }
-
- return 0;
-}
-
-Insert::Insert () :
- Application ("xinsert", "Copiador de la tabla ad_funcionalidades", "1.0"),
- a_db (NULL)
-{
- CommandLine& cl (CommandLine::instantiate ());
-
- cl.add ("user", CommandLine::Argument::Mandatory, "Nombre del usuario");
- cl.add ("password", CommandLine::Argument::Mandatory, "Clave del usuario");
- cl.add ("host", CommandLine::Argument::Optional, "Nombre de la maquina donde se ubica el MySQL");
- cl.add ("db", CommandLine::Argument::Optional, "Nombre de la base de datos");
-}
-
-/*
- * Las sentencias SQL usadas por este programana estaba originalmente escritas para Oracle,
- * pero no hay que cambiar cada sentencia manualmente, s�lo hay que activar el traductor
- * correspondiente y anna.dbms.mysql lo hace autom�ticamente.
- */
-void Insert::initialize ()
- throw (RuntimeException)
-{
- CommandLine& ccll = CommandLine::instantiate ();
- const char* host = ccll.exists ("host") ? ccll.getValue ("host"): NULL;
-
- a_db = new anna::dbms::mysql::Database (ccll.getValue ("db"), host);
- a_db->setStatementTranslator (dbms::mysql::OracleTranslator::instantiate ());
-}
-
-void Insert::run ()
- throw (RuntimeException)
-{
- LOGMETHOD (TraceMethod tm ("Insert", "run", ANNA_FILE_LOCATION));
-
- CommandLine& cl (CommandLine::instantiate ());
-
- Statement* create;
- Statement* insert;
-
- dbms::Integer n (true);
- dbms::String name (15, true);
- dbms::Float zz (true);
- dbms::TimeStamp time (true);
-
- dbms::ResultCode resultCode;
-
- try {
- Connection* connection = a_db->createConnection ("xinsert", cl.getValue ("user"), cl.getValue ("password"));
-
- {
- Guard guard (connection);
-
- try {
- create = a_db->createStatement (
- "create", "create table anna_db_test (xx integer, yy varchar (15), zz float, tt datetime)"
- );
-
- resultCode = connection->execute (create);
- }
- catch (Exception& ex) {
- ex.trace ();
- }
- cout << "Creando: " << resultCode.asString () << endl << endl;
- }
- Guard guard (connection);
-
- /*
- * Observar que la sentencia indica los parámetros tal y como se haría en Oracle.
- */
- insert = a_db->createStatement ("select", "insert into anna_db_test (xx, yy, zz, tt) values (:x,:y,:z, :t)");
- insert->bindInput ("XX", n);
- insert->bindInput ("YY", name);
- insert->bindInput ("zz", zz);
- insert->bindInput ("tt", time);
-
- n = 88;
- name = "El 88";
- zz = 0.88;
- time.setValue (anna::functions::second ());
- cout << endl << " --- Insertando 1 ---" << endl;
- resultCode = connection->execute (insert);
- cout << resultCode.asString () << endl << endl;
-
- n = 1010;
- name = "El 1010";
- zz = 0.1010;
- time.setNull (true);
- cout << endl << " --- Insertando 2 (date=null)---" << endl;
- resultCode = connection->execute (insert);
- cout << resultCode.asString () << endl << endl;
-
- n = 89;
- name.setNull (true);
- zz = 0.89;
- time.setValue ((Second)(anna::functions::second () + 100));
- cout << endl << " --- Insertando 2 (name=null)---" << endl;
- resultCode = connection->execute (insert);
- cout << resultCode.asString () << endl << endl;
- }
- catch (dbms::DatabaseException& edb) {
- throw RuntimeException (edb);
- }
-}
-
-
-
+++ /dev/null
-anna_dbms.mysql_static
-anna_dbms_static
-anna_comm_static
-anna_app_static
-anna_xml_static
-anna_io_static
-anna_core_static
-mysqlclient
-rt
-xml2
+++ /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 //
-
-
-#include <iostream>
-
-#include <anna/core/core.hpp>
-#include <anna/dbms/dbms.hpp>
-#include <anna/app/app.hpp>
-
-#include <anna/dbms.mysql/Database.hpp>
-#include <anna/dbms.mysql/OracleTranslator.hpp>
-
-class Select : public Application {
-public:
- Select ();
- ~Select () { delete a_db; }
-
-private:
- anna::dbms::Database* a_db;
-
- void initialize () throw (RuntimeException);
- void run () throw (RuntimeException);
-};
-
-using namespace std;
-
-int main (int argc, const char** argv)
-{
- CommandLine& commandLine (CommandLine::instantiate ());
- Select testNull;
-
- try {
- commandLine.initialize (argv, argc);
- commandLine.verify ();
-
- Logger::setLevel (Logger::Debug);
- Logger::initialize ("copy", new TraceWriter ("xselect.trace", 1024 * 1024));
-
- testNull.start ();
- }
- catch (Exception& ex) {
- cout << ex.asString () << endl;
- }
-
- return 0;
-}
-
-Select::Select () :
- Application ("xselect", "Copiador de la tabla ad_funcionalidades", "1.0"),
- a_db (NULL)
-{
- CommandLine& cl (CommandLine::instantiate ());
-
- cl.add ("user", CommandLine::Argument::Mandatory, "Nombre del usuario");
- cl.add ("password", CommandLine::Argument::Mandatory, "Clave del usuario");
- cl.add ("host", CommandLine::Argument::Optional, "Nombre de la maquina donde se ubica el MySQL");
- cl.add ("db", CommandLine::Argument::Optional, "Nombre de la base de datos");
-}
-
-/*
- * Las sentencias SQL usadas por este programana estaba originalmente escritas para Oracle,
- * pero no hay que cambiar cada sentencia manualmente, s�lo hay que activar el traductor
- * correspondiente y anna.dbms.mysql lo hace autom�ticamente.
- */
-void Select::initialize ()
- throw (RuntimeException)
-{
- CommandLine& ccll = CommandLine::instantiate ();
- const char* host = ccll.exists ("host") ? ccll.getValue ("host"): NULL;
-
- a_db = new anna::dbms::mysql::Database (ccll.getValue ("db"), host);
- a_db->setStatementTranslator (dbms::mysql::OracleTranslator::instantiate ());
-}
-
-void Select::run ()
- throw (RuntimeException)
-{
- LOGMETHOD (TraceMethod tm ("Select", "run", ANNA_FILE_LOCATION));
-
- CommandLine& cl (CommandLine::instantiate ());
-
- Statement* select;
-
- dbms::Integer n (true);
- dbms::String name (15, true);
- dbms::Float zz (true);
- dbms::TimeStamp tt (true);
-
- dbms::ResultCode resultCode;
-
- try {
- Connection* connection = a_db->createConnection ("xselect", cl.getValue ("user"), cl.getValue ("password"));
-
- Guard guard (connection);
-
- select = a_db->createStatement ("select", "select xx,yy,zz, tt from anna_db_test");
- select->bindOutput ("XX", n);
- select->bindOutput ("YY", name);
- select->bindOutput ("zz", zz);
- select->bindOutput ("tt", tt);
-
- cout << endl << " --- Leyendo ---" << endl;
- resultCode = connection->execute (select);
-
- if (resultCode.successful () == true) {
- while (select->fetch () == true) {
- if (n.isNull () == true)
- cout << "<null>";
- else
- cout << n;
-
- cout << " | YY: " << ((name.isNull () == true) ? "<null>": name);
-
- cout << " | ZZ: ";
- if (zz.isNull () == true)
- cout << "<null>";
- else
- cout << zz.getValue ();
-
- cout << " | TT: " << ((tt.isNull () == true) ? "<null>": tt.getCStringValue ());
-
- cout << endl;
- }
- }
- else
- cout << resultCode.asString () << endl << endl;
- }
- catch (dbms::DatabaseException& edb) {
- throw RuntimeException (edb);
- }
-}
-
-
-
+++ /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 //
-
-
-#include "Abstract.hpp"
-
-using namespace std;
-using namespace anna;
-using namespace workdir;
-
-filesystem::Abstract::Abstract (const Abstract::ClassType::_v classType, const std::string& name) :
- a_classType (classType),
- a_name (name), a_parent (NULL)
-{
- a_path = name;
-}
-
-filesystem::Abstract::Abstract (const Abstract::ClassType::_v classType, filesystem::Abstract* parent, const std::string& name) :
- a_classType (classType),
- a_name (name),
- a_parent (parent)
-{
- a_parent->a_children.push_back (this);
- a_path = calculePath (parent, name);
-}
-
-/*virtual*/
-filesystem::Abstract::~Abstract ()
-{
- for (child_iterator ii = child_begin (), maxii = child_end (); ii != maxii; ii ++)
- delete child (ii);
-
- a_children.clear ();
-}
-
-/* static */
-string filesystem::Abstract::calculePath (const filesystem::Abstract* parent, const std::string& shortPath)
- throw ()
-{
- string result;
-
- if (parent!= NULL) {
- result = parent->a_path;
- result += '/';
- }
-
- return result += shortPath;
-}
+++ /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 dbos_workdir_filesystem_Abstract_hpp
-#define dbos_workdir_filesystem_Abstract_hpp
-
-#include <vector>
-#include <string>
-
-#include <anna/core/util/ExclusiveHash.hpp>
-
-namespace workdir {
-
-namespace filesystem {
-
-using namespace anna;
-
-class Abstract {
-public:
- struct ClassType { enum _v { Directory, File }; };
-
- typedef std::vector <Abstract*> child_container;
- typedef child_container::iterator child_iterator;
- typedef child_container::const_iterator const_child_iterator;
-
- virtual ~Abstract ();
-
- Abstract* getParent () const throw () { return a_parent; }
- ClassType::_v getClassType () const throw () { return a_classType; }
- const std::string& getName () const throw () { return a_name; }
- const std::string& getPath () const throw () { return a_path; }
-
- int child_size () const throw () { return a_children.size (); }
-
- child_iterator child_begin () throw () { return a_children.begin (); }
- child_iterator child_end () throw () { return a_children.end (); }
- static Abstract* child (child_iterator ii) throw () { return *ii; }
-
- const_child_iterator child_begin () const throw () { return a_children.begin (); }
- const_child_iterator child_end () const throw () { return a_children.end (); }
- static const Abstract* child (const_child_iterator ii) throw () { return *ii; }
-
- static std::string calculePath (const Abstract* parent, const std::string& shortPath) throw ();
-
- virtual void print (const int level) const throw () = 0;
-
-protected:
- Abstract (const ClassType::_v, const std::string& name);
- Abstract (const ClassType::_v, Abstract* parent, const std::string& name);
-
-private:
- const ClassType::_v a_classType;
- Abstract* a_parent;
- const std::string a_name;
- std::string a_path;
- child_container a_children;
-
- Abstract (const Abstract&);
-};
-
-}
-}
-
-#endif
+++ /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 //
-
-
-#include <iostream>
-
-#include "Directory.hpp"
-#include "File.hpp"
-
-using namespace std;
-using namespace anna;
-using namespace workdir;
-
-void filesystem::Directory::print (const int level) const
- throw ()
-{
- filesystem::Directory::const_child_iterator ii;
- filesystem::Directory::const_child_iterator maxii = child_end ();
- const filesystem::Directory* auxd;
- const filesystem::File* auxf;
- int row = 0;
- bool hasDirectories = false;
-
- for (int space = 0; space < level; space ++)
- cout << " ";
-
- cout << getName () << "/ (" << child_size () << "): " << endl;
-
- /*
- * Recorre todas las dependencias y visualiza primero todos los ficheros
- */
- for (ii = child_begin (); ii != maxii; ii ++) {
- auxf = filesystem::File::down_cast (filesystem::Directory::child (ii));
-
- if (auxf == NULL) {
- hasDirectories = true;
- continue;
- }
-
- if (row == 0) {
- for (int space = 0; space < level + 1; space ++)
- cout << " ";
- }
-
- auxf->print (level + 1);
-
- if (++ row == 5) {
- cout << endl;
- row = 0;
- }
- }
-
- if (row > 0)
- cout << endl;
-
- /*
- * Trata los directorios recursivamente
- */
- for (ii = child_begin (); hasDirectories == true && ii != maxii; ii ++) {
- auxd = filesystem::Directory::down_cast (filesystem::Directory::child (ii));
-
- if (auxd != NULL)
- auxd->print (level + 1);
- }
-}
+++ /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 dbos_workdir_filesystem_Directory_hpp
-#define dbos_workdir_filesystem_Directory_hpp
-
-#include "Abstract.hpp"
-
-namespace workdir {
-
-namespace filesystem {
-
-using namespace anna;
-
-class Directory : public Abstract {
-public:
- Directory (const std::string& name) : Abstract (ClassType::Directory, name) {;}
- Directory (Directory* parent, const std::string& name) : Abstract (ClassType::Directory, parent, name) {;}
-
- void print (const int level = 0) const throw ();
-
- static Directory* down_cast (Abstract* abstract) throw () {
- return (abstract->getClassType () == ClassType::Directory) ? static_cast <Directory*> (abstract): NULL;
- }
- static const Directory* down_cast (const Abstract* abstract) throw () {
- return (abstract->getClassType () == ClassType::Directory) ? static_cast <const Directory*> (abstract): NULL;
- }
-};
-
-}
-}
-
-#endif
+++ /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 //
-
-
-#include <iostream>
-
-#include "File.hpp"
-
-using namespace std;
-using namespace anna;
-using namespace workdir;
-
-void filesystem::File::print (const int) const
- throw ()
-{
- cout << getName () << " " << flush;
-}
+++ /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 dbos_workdir_filesystem_File_hpp
-#define dbos_workdir_filesystem_File_hpp
-
-#include "Abstract.hpp"
-#include "Directory.hpp"
-
-namespace workdir {
-
-namespace filesystem {
-
-using namespace anna;
-
-class File : public Abstract {
-public:
- File (Directory* parent, const std::string& name) : Abstract (ClassType::File, parent, name) {;}
-
- void print (const int level) const throw ();
-
- static File* down_cast (Abstract* abstract) throw () {
- return (abstract->getClassType () == ClassType::File) ? static_cast <File*> (abstract): NULL;
- }
- static const File* down_cast (const Abstract* abstract) throw () {
- return (abstract->getClassType () == ClassType::File) ? static_cast <const File*> (abstract): NULL;
- }
-};
-
-}
-}
-
-#endif
+++ /dev/null
-anna_dbos_static
-anna_dbms_static
-anna_comm_static
-anna_app_static
-anna_xml_static
-anna_io_static
-anna_core_static
-rt
-xml2
+++ /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 //
-
-
-#include <iostream>
-
-#include <anna/core/core.hpp>
-#include <anna/app/app.hpp>
-
-#include <anna/io/Directory.hpp>
-#include <anna/io/functions.hpp>
-
-#include <anna/xml/Compiler.hpp>
-#include <anna/xml/Node.hpp>
-
-#include <anna/dbos/Repository.hpp>
-#include <anna/dbos/AutoObject.hpp>
-
-#include "filesystem/Directory.hpp"
-#include "filesystem/File.hpp"
-
-#include "storage/Directory.hpp"
-#include "storage/File.hpp"
-
-using namespace std;
-using namespace workdir;
-
-template <typename T> void message (const char* text, T* tt) throw () {
- if (Logger::isActive (Logger::Debug) == false)
- return;
-
- cout << " " << text << " (";
- cout << anna::functions::asHexString (anna_ptrnumber_cast (tt));
- cout << "): ";
-
- if (tt != NULL)
- cout << tt->asString ();
- else
- cout << "<null>";
-
- cout << endl;
-}
-
-class WorkDirectory : public Application {
-public:
- struct Flags { enum _v { None = 0, Clear = 1 }; };
-
- WorkDirectory ();
-
- xml::Node* asXML (xml::Node* parent) const throw ();
-
-private:
- typedef vector <storage::File*> file_container;
- typedef file_container::iterator file_iterator;
- typedef file_container::reverse_iterator file_reverse_iterator;
-
- dbos::Repository a_repository;
- filesystem::Directory* a_root;
- file_container a_files;
-
- void initialize () throw (RuntimeException);
- void run () throw (RuntimeException);
-
- void forward (filesystem::Directory*) throw (RuntimeException);
- void instantiateOne (filesystem::Directory*) throw (RuntimeException);
- void fullCache (filesystem::Directory*, file_container&, const int flags) throw (RuntimeException);
- void reuseHoles (filesystem::Directory*, file_container&) throw (RuntimeException);
- void destroyObjects (filesystem::Directory* dir, file_container&) throw (RuntimeException);
- void clear (file_container&) throw ();
-
- static void load (filesystem::Directory* parent, const int maxLevel, const int level = 0) throw (RuntimeException);
-};
-
-using namespace std;
-
-int main (int argc, const char** argv)
-{
- CommandLine& commandLine (CommandLine::instantiate ());
- WorkDirectory storageNull;
-
- try {
- commandLine.initialize (argv, argc);
- commandLine.verify ();
-
- Logger::setLevel (Logger::Local6);
- Logger::initialize ("workdir", new TraceWriter ("file.trace", 4 * 1024 * 1024));
-
- storageNull.start ();
- }
- catch (Exception& ex) {
- cout << ex.asString () << endl;
- }
-
- return 0;
-}
-
-WorkDirectory::WorkDirectory () :
- Application ("workdir", "Dbos workdir", "1.0.0"),
- a_repository ("workdir")
-{
- CommandLine& cl (CommandLine::instantiate ());
-
- cl.add ("dir", CommandLine::Argument::Mandatory, "Nombre del directorio a procesar");
- cl.add ("l", CommandLine::Argument::Optional, "Numero maximo de niveles de profundidad");
- cl.add ("trace", CommandLine::Argument::Optional, "Nivel de trazado");
- cl.add ("s", CommandLine::Argument::Mandatory, "Cache size");
-}
-
-void WorkDirectory::initialize ()
- throw (RuntimeException)
-{
-}
-
-void WorkDirectory::run ()
- throw (RuntimeException)
-{
- LOGMETHOD (TraceMethod tm ("WorkDirectory", "run", ANNA_FILE_LOCATION));
-
- CommandLine& cl (CommandLine::instantiate ());
-
- const std::string& dir = cl.getValue ("dir");
- const int maxLevel = cl.exists ("l") ? cl.getIntegerValue ("l"): -1;
-
- if (cl.exists ("trace") == true)
- Logger::setLevel (Logger::asLevel (cl.getValue ("trace")));
-
- const int cacheSize = cl.getIntegerValue ("s");
-
- storage::Directory::setup (a_repository, cacheSize);
- storage::File::setup (a_repository, cacheSize);
-
- a_root = new filesystem::Directory (dir);
-
- load (a_root, maxLevel);
-
- a_root->print ();
- cout << endl;
-
- forward (a_root);
-
- writeContext ("file.context");
-}
-
-xml::Node* WorkDirectory::asXML (xml::Node* parent) const
- throw ()
-{
- xml::Node* result = app::Application::asXML (parent);
- a_repository.asXML (result);
- return result;
-}
-
-void WorkDirectory::forward (filesystem::Directory* dir)
- throw (RuntimeException)
-{
- cout << "forward: " << dir->getPath () << endl;
-
- for (filesystem::Directory::child_iterator ii = dir->child_begin (), maxii = dir->child_end (); ii != maxii; ii ++) {
- dir = filesystem::Directory::down_cast (filesystem::Directory::child (ii));
-
- if (dir == NULL)
- continue;
-
- try {
- instantiateOne (dir);
- fullCache (dir, a_files, Flags::Clear);
- reuseHoles (dir, a_files);
- destroyObjects (dir, a_files);
- forward (dir);
- }
- catch (RuntimeException& ex) {
- ex.trace ();
- }
- }
-}
-
-/*
- * Crea una serie de instancia simultáneas sobre el mismo objeto para verificar que sólo lo carga
- * de verdad sea necesario.
- */
-void WorkDirectory::instantiateOne (filesystem::Directory* dir)
- throw (RuntimeException)
-{
- TraceMethod tm ("WorkDirectory", "instantiateOne", ANNA_FILE_LOCATION);
-
- cout << "WorkDirectory::instantiateOne: Instancia varias veces la misma instancia para verificar el reuso" << endl;
-
- storage::Directory* aux;
-
- {
- dbos::AutoObject <storage::Directory> root1;
- aux = root1 = storage::Directory::instantiate (dir);
- message ("Root1", aux);
-
- dbos::AutoObject <storage::Directory> root2;
- aux = root2 = storage::Directory::instantiate (dir);
- message ("Root2", aux);
- }
-
- dbos::AutoObject <storage::Directory> root3;
- aux = root3 = storage::Directory::instantiate (dir);
- message ("Root3", aux);
-
- message ("StorageArea", storage::File::getStorageArea ());
-
- cout << endl;
-}
-
-void WorkDirectory::fullCache (filesystem::Directory* dir, WorkDirectory::file_container& files, const int flags)
- throw (RuntimeException)
-{
- TraceMethod tm ("WorkDirectory", "fullCache", ANNA_FILE_LOCATION);
-
- cout << "WorkDirectory::fullCache: Llena la cache de objetos para verificar que crece tanto como sea necesario" << endl;
-
- filesystem::File* file;
-
- int maxSize = storage::File::getMaxSize ();
-
- maxSize += rand () % maxSize;
-
- for (filesystem::Directory::child_iterator ii = dir->child_begin (), maxii = dir->child_end (); ii != maxii; ii ++) {
- file = filesystem::File::down_cast (filesystem::Directory::child (ii));
-
- if (file != NULL) {
- storage::File* storageFile = storage::File::instantiate (file);
- message ("File", storageFile);
- files.push_back (storageFile);
-
-// if (files.size () >= maxSize)
-// break;
- }
- }
-
- message ("StorageArea (full)", storage::File::getStorageArea ());
-
- if (flags & Flags::Clear)
- clear (files);
-
- message ("StorageArea (empty)", storage::File::getStorageArea ());
-
- cout << endl;
-}
-
-void WorkDirectory::reuseHoles (filesystem::Directory* dir, WorkDirectory::file_container& files)
- throw (RuntimeException)
-{
- TraceMethod tm ("WorkDirectory", "reuseHoles", ANNA_FILE_LOCATION);
-
- cout << "WorkDirectory::reuseHoles: Invoca dos veces a fullCache para verificar que el tamano se mantiene la segunda vez" << endl;
- fullCache (dir, files, Flags::Clear);
- fullCache (dir, files, Flags::Clear);
- cout << endl;
-}
-
-void WorkDirectory::destroyObjects (filesystem::Directory* dir, WorkDirectory::file_container& files)
- throw (RuntimeException)
-{
- TraceMethod tm ("WorkDirectory", "destroyObjects", ANNA_FILE_LOCATION);
-
- cout << "WorkDirectory::destroyObjects: Carga un directorio distinto, para verificar que destruye los objetos segun se dejan de utilizar" << endl;
- filesystem::File* file;
- filesystem::Directory* other = NULL;
-
- for (filesystem::Directory::child_iterator ii = dir->child_begin (), maxii = dir->child_end (); ii != maxii && other == NULL; ii ++)
- other = filesystem::Directory::down_cast (filesystem::Directory::child (ii));
-
- if (other == NULL) {
- cout << dir->getPath () << ": No se puede realizar esta prueba" << endl << endl;
- return;
- }
-
- cout << "New Directory: " << other->getPath () << endl;
- dir = other;
-
- for (filesystem::Directory::child_iterator ii = dir->child_begin (), maxii = dir->child_end (); ii != maxii; ii ++) {
- file = filesystem::File::down_cast (filesystem::Directory::child (ii));
-
- if (file != NULL) {
- storage::File* storageFile = storage::File::instantiate (file);
- message ("File", storageFile);
- storage::File::release (storageFile);
- }
- }
-
- message ("StorageArea", storage::File::getStorageArea ());
-
- cout << endl;
-}
-
-
-void WorkDirectory::clear (WorkDirectory::file_container& files)
- throw ()
-{
- storage::File* file;
-
- /* Libera los objetos en distinto orden para empeorar el tratamiento huecos */
-
- if ((anna::functions::millisecond () % 2) == 0) {
- cout << "Clear directo" << endl;
- for (file_iterator ii = files.begin (), maxii = files.end (); ii != maxii; ii ++) {
- file = *ii;
- storage::File::release (file);
- }
- }
- else {
- cout << "Clear inverso" << endl;
- for (file_reverse_iterator ii = files.rbegin (), maxii = files.rend (); ii != maxii; ii ++) {
- file = *ii;
- storage::File::release (file);
- }
- }
-
- files.clear ();
-}
-
-/*static*/
-void WorkDirectory::load (filesystem::Directory* parent, const int maxLevel, const int level)
- throw (RuntimeException)
-{
- if (level == maxLevel)
- return;
-
- io::Directory directory;
- string fullPath;
-
- directory.read (parent->getPath (), io::Directory::Mode::ShortPath);
-
- for (io::Directory::const_iterator ii = directory.begin (), maxii = directory.end (); ii != maxii; ii ++) {
- const std::string& name = io::Directory::data (ii);
-
- fullPath = filesystem::Abstract::calculePath (parent, name);
-
- if (io::functions::isADirectory (fullPath)) {
- try {
- filesystem::Directory* dd = new filesystem::Directory (parent, name);
- load (dd, maxLevel, level + 1);
- }
- catch (RuntimeException& ex) {
- ex.trace ();
- }
- }
- else {
- //Auto association to the parent:
- new filesystem::File (parent, name);
- }
- }
-}
+++ /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 //
-
-
-#include <anna/core/functions.hpp>
-#include <anna/core/tracing/Logger.hpp>
-
-#include <anna/io/functions.hpp>
-
-#include <anna/dbms/Database.hpp>
-#include <anna/dbms/Statement.hpp>
-
-#include <anna/dbos/Repository.hpp>
-
-#include "../filesystem/Directory.hpp"
-
-#include "Directory.hpp"
-
-using namespace std;
-using namespace anna;
-using namespace workdir;
-
-/*static*/
-storage::Directory::Loader* storage::Directory::st_loader = NULL;
-
-/*static*/
-ExclusiveHash <std::string> storage::Directory::st_hash;
-
-/*static*/
-int storage::Directory::st_maxSize = 0;
-
-dbos_prepare_object (storage::Directory);
-
-void storage::Directory::setup (dbos::Repository& repository, const int maxSize)
- throw (RuntimeException)
-{
- st_loader = new Directory::Loader ();
- st_maxSize = maxSize;
-
- Directory::setStorageArea (
- repository.createStorageArea ( // (1)
- Directory::getStorageAreaId (), Directory::getStorageAreaName (), Directory::getMaxSize (),
- Directory::allocator, 2
- )
- );
-}
-
-storage::Directory* storage::Directory::instantiate (const filesystem::Directory* directory)
- throw (RuntimeException)
-{
- if (st_loader == NULL)
- throw RuntimeException ("storage::Directory::setup no ha sido invocado", ANNA_FILE_LOCATION);
-
- Directory* result = NULL;
-
- try {
- Guard guard (st_loader, "storage::Directory::Loader");
- result = dbos::ObjectFacade <Directory>::instance (st_loader->setKey (directory));
- }
- catch (dbms::DatabaseException& edb) {
- throw RuntimeException (edb);
- }
-
- return result;
-}
-
-void storage::Directory::initialize (dbos::Loader& loader)
- throw (RuntimeException, dbms::DatabaseException)
-{
- Directory::Loader& dbLoader = static_cast <Directory::Loader&> (loader);
-
- a_filesystemDirectory = dbLoader.getDirectory ();
- a_inode = dbLoader.getINode ();
-
- LOGINFORMATION (
- string msg ("storage::Directory::initialize | ");
- msg += asString ();
- Logger::information (msg, ANNA_FILE_LOCATION);
- );
-}
-
-void storage::Directory::destroy ()
- throw ()
-{
- LOGINFORMATION (
- string msg ("storage::Directory::destroy | ");
- msg += asString ();
- Logger::information (msg, ANNA_FILE_LOCATION);
- );
-}
-
-string storage::Directory::asString () const
- throw ()
-{
- std::string result ("storage::Directory { Name: ");
- result += a_filesystemDirectory->getPath ();
- result += functions::asHexText (" | I-Node: ", a_inode);
- return result += " }";
-}
-
-/*
- * Transfiere la información del medio físico al primer nivel de C++.
- * Posteriormente será interpretada en storage::Directory::initialize
- */
-bool storage::Directory::Loader::load (dbms::Connection*, const dbos::StorageArea* ssaa)
- throw (RuntimeException)
-{
- a_inode = io::functions::getINode (a_filesystemDirectory->getPath ());
- return true;
-}
-
-dbos::Index storage::Directory::Loader::getIndex () const
- throw ()
-{
- return st_hash.calcule (a_filesystemDirectory->getPath ());
-}
-
-string storage::Directory::Loader::asString () const
- throw ()
-{
- std::string result ("storage::Loader::Directory { Name: ");
- result += a_filesystemDirectory->getPath ();
- return result += " }";
-}
-
+++ /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 dbos_workdir_storage_Directory_hpp
-#define dbos_workdir_storage_Directory_hpp
-
-#include <anna/dbos/Object.hpp>
-#include <anna/dbos/ObjectFacade.hpp>
-#include <anna/dbos/Loader.hpp>
-
-namespace anna {
-namespace dbms {
-class Database;
-class Connection;
-}
-namespace dbos {
-class Repository;
-}
-}
-
-namespace workdir {
-
-namespace filesystem {
-class Directory;
-}
-
-namespace storage {
-
-using namespace anna;
-
-class Directory : public dbos::Object, public dbos::ObjectFacade <Directory> {
-public:
- const filesystem::Directory* getFilesystemDirectory() const throw() { return a_filesystemDirectory; }
- int getINode() const throw() { return a_inode; }
-
- std::string asString() const throw();
-
- static void setup(dbos::Repository&, const int maxSize) throw(RuntimeException);
- static Directory* instantiate(const filesystem::Directory*) throw(RuntimeException);
-
- static const char* getStorageAreaName() throw() { return "storage::Directory"; }
- static const dbos::Size getMaxSize() throw() { return st_maxSize; }
-
-private:
- class Loader : public dbos::Loader {
- public:
- Loader() : dbos::Loader() {;}
-
- Loader& setKey(const filesystem::Directory* directory) throw() {
- a_filesystemDirectory = directory;
- return *this;
- }
-
- const filesystem::Directory* getDirectory() const throw() { return a_filesystemDirectory; }
- int getINode() const throw() { return a_inode; }
-
- dbos::Index getIndex() const throw();
- std::string asString() const throw();
-
- private:
- const filesystem::Directory* a_filesystemDirectory;
- int a_inode;
-
- // dbms::Statement is not required
- dbms::Statement* initialize(dbms::Database&) throw(RuntimeException) { return NULL; }
- bool load(dbms::Connection*, const dbos::StorageArea*) throw(RuntimeException);
- };
-
- const filesystem::Directory* a_filesystemDirectory;
- int a_inode;
-
- static Loader* st_loader;
- static ExclusiveHash <std::string> st_hash;
- static int st_maxSize;
-
- Directory() { ; }
- Directory(const Directory&);
-
- void initialize(dbos::Loader& loader) throw(RuntimeException, dbms::DatabaseException);
- void destroy() throw();
-
- dbos_declare_object(Directory);
-};
-
-}
-}
-
-#endif
+++ /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 //
-
-
-#include <anna/core/functions.hpp>
-#include <anna/core/tracing/Logger.hpp>
-
-#include <anna/io/functions.hpp>
-
-#include <anna/dbms/Database.hpp>
-#include <anna/dbms/Statement.hpp>
-
-#include <anna/dbos/Repository.hpp>
-
-#include "../filesystem/File.hpp"
-#include "../filesystem/Directory.hpp"
-
-#include "File.hpp"
-#include "Directory.hpp"
-
-using namespace std;
-using namespace anna;
-using namespace workdir;
-
-/*static*/
-storage::File::Loader* storage::File::st_loader = NULL;
-
-/*static*/
-ExclusiveHash <std::string> storage::File::st_hash;
-
-/*static*/
-int storage::File::st_maxSize = 0;
-
-dbos_prepare_object (storage::File);
-
-void storage::File::setup (dbos::Repository& repository, const int maxSize)
- throw (RuntimeException)
-{
- st_loader = new File::Loader ();
- st_maxSize = maxSize;
-
- File::setStorageArea (
- repository.createStorageArea ( // (1)
- File::getStorageAreaId (), File::getStorageAreaName (), File::getMaxSize (),
- File::allocator, 2
- )
- );
-}
-
-storage::File* storage::File::instantiate (const filesystem::File* file)
- throw (RuntimeException)
-{
- if (st_loader == NULL)
- throw RuntimeException ("storage::File::setup no ha sido invocado", ANNA_FILE_LOCATION);
-
- File* result = NULL;
-
- try {
- Guard guard (st_loader, "storage::File::Loader");
- result = dbos::ObjectFacade <File>::instance (st_loader->setKey (file));
- }
- catch (dbms::DatabaseException& edb) {
- throw RuntimeException (edb);
- }
-
- return result;
-}
-
-void storage::File::initialize (dbos::Loader& loader)
- throw (RuntimeException, dbms::DatabaseException)
-{
- File::Loader& dbLoader = static_cast <File::Loader&> (loader);
-
- a_filesystemFile = dbLoader.getFile ();
- a_parent = Directory::instantiate (filesystem::Directory::down_cast (a_filesystemFile->getParent ()));
- a_inode = dbLoader.getINode ();
-
- LOGINFORMATION (
- string msg ("storage::File::initialize | ");
- msg += asString ();
- Logger::information (msg, ANNA_FILE_LOCATION);
- );
-}
-
-void storage::File::destroy ()
- throw ()
-{
- LOGINFORMATION (
- string msg ("storage::File::destroy | ");
- msg += asString ();
- Logger::information (msg, ANNA_FILE_LOCATION);
- );
- Directory::release (a_parent);
-}
-
-string storage::File::asString () const
- throw ()
-{
- std::string result ("storage::File { Name: ");
- result += a_filesystemFile->getPath ();
- result += functions::asHexText (" | I-Node: ", a_inode);
- return result += " }";
-}
-
-/*
- * Transfiere la información del medio físico al primer nivel de C++.
- * Posteriormente será interpretada en storage::File::initialize
- */
-bool storage::File::Loader::load (dbms::Connection*, const dbos::StorageArea* ssaa)
- throw (RuntimeException)
-{
- a_inode = io::functions::getINode (a_filesystemFile->getPath ());
- return true;
-}
-
-dbos::Index storage::File::Loader::getIndex () const
- throw ()
-{
- return st_hash.calcule (a_filesystemFile->getPath ());
-}
-
-string storage::File::Loader::asString () const
- throw ()
-{
- std::string result ("storage::Loader::File { Name: ");
- result += a_filesystemFile->getPath ();
- return result += " }";
-}
-
+++ /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 dbos_workdir_storage_File_hpp
-#define dbos_workdir_storage_File_hpp
-
-#include <anna/dbos/Object.hpp>
-#include <anna/dbos/ObjectFacade.hpp>
-#include <anna/dbos/Loader.hpp>
-
-namespace anna {
-namespace dbms {
-class Database;
-class Connection;
-}
-namespace dbos {
-class Repository;
-}
-}
-
-namespace workdir {
-
-namespace filesystem {
-class File;
-}
-
-namespace storage {
-
-class Directory;
-
-using namespace anna;
-
-class File : public dbos::Object, public dbos::ObjectFacade <File> {
-public:
- const Directory* getParent() const throw() { return a_parent; }
- const filesystem::File* getFilesystemFile() const throw() { return a_filesystemFile; }
- int getINode() const throw() { return a_inode; }
-
- std::string asString() const throw();
-
- static void setup(dbos::Repository&, const int maxSize) throw(RuntimeException);
- static File* instantiate(const filesystem::File*) throw(RuntimeException);
-
- static const char* getStorageAreaName() throw() { return "storage::File"; }
- static const dbos::Size getMaxSize() throw() { return st_maxSize; }
-
-private:
- class Loader : public dbos::Loader {
- public:
- Loader() : dbos::Loader() {;}
-
- Loader& setKey(const filesystem::File* file) throw() {
- a_filesystemFile = file;
- return *this;
- }
-
- const filesystem::File* getFile() const throw() { return a_filesystemFile; }
- int getINode() const throw() { return a_inode; }
-
- dbos::Index getIndex() const throw();
- std::string asString() const throw();
-
- private:
- const filesystem::File* a_filesystemFile;
- int a_inode;
-
- // dbms::Statement is not required
- dbms::Statement* initialize(dbms::Database&) throw(RuntimeException) { return NULL; }
- bool load(dbms::Connection*, const dbos::StorageArea*) throw(RuntimeException);
- };
-
- Directory* a_parent;
- const filesystem::File* a_filesystemFile;
- int a_inode;
-
- static Loader* st_loader;
- static ExclusiveHash <std::string> st_hash;
- static int st_maxSize;
-
- File() : a_parent(NULL) { ; }
- File(const File&);
-
- void initialize(dbos::Loader& loader) throw(RuntimeException, dbms::DatabaseException);
- void destroy() throw();
-
- dbos_declare_object(File);
-};
-
-}
-}
-
-#endif
+++ /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_dbms_mysql_BaseBind_hpp
-#define anna_dbms_mysql_BaseBind_hpp
-
-#include <anna/dbms/Data.hpp>
-
-#include <anna/dbms.mysql/forward.hpp>
-
-namespace anna {
-
-namespace dbms {
-
-namespace mysql {
-
-class BaseBind {
-public:
- virtual ~BaseBind();
-
-protected:
- /*
- * mysql.h:typedef char my_bool;
- */
- char a_nullIndicator;
-
- /**
- * mysql_time.h: typedef st_mysql_time MYSQL_TIME
- */
- st_mysql_time* a_time;
-
- unsigned long a_length;
-
- BaseBind(const dbms::Data& data) ;
- void setupBind(st_mysql_bind&, dbms::Data&) throw(RuntimeException);
-
-private:
- static const int MaxBlobSize = 2 << 16;
-
- const Data::Type::_v a_type;
-};
-
-}
-}
-}
-
-#endif
-
+++ /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_dbms_mysql_Connection_hpp
-#define anna_dbms_mysql_Connection_hpp
-
-
-#include <anna/dbms/Connection.hpp>
-#include <anna/dbms/DatabaseException.hpp>
-
-#include <anna/dbms.mysql/forward.hpp>
-
-namespace anna {
-
-namespace dbms {
-
-class Database;
-
-namespace mysql {
-
-class Database;
-
-/**
- Clase que modela la conexion con el RDBMS MySQL (tm).
-
- Esta clase no puede usarse directamente, ya que la capa ANNA.dbms obliga a que todas las peticiones
- se hagan atraves de una instancia anna::dbms::Connection.
-
- Para obtener una conexion a una determinada base de datos habra que instanciar dicha base de datos
- e invocar al metodo createConnection. Independientemente del tipo de conexion particular que la
- base de datos retorne, debemos asignarlo a un puntero de tipo anna::dbms::Connection.
-*/
-class Connection : public dbms::Connection {
-public:
- /**
- Devuelve una cadena con la informacion referente a esta instancia.
- @return Una cadena con la informacion referente a esta instancia.
- */
- std::string asString() const throw();
-
- /**
- Operador de conversion.
- \return El puntero al entorno asociado a esta base de datos.
- */
- operator st_mysql*() throw() { return a_mysql; }
-
-private:
- Database& a_mysqlDatabase;
- st_mysql* a_mysql;
-
- Connection(Database& database, const std::string& name, const char* user, const char* password);
-
- bool isAvailable() const throw(RuntimeException) { return a_mysql != NULL; }
-
- void do_commit() throw(RuntimeException, DatabaseException);
- void do_rollback() throw();
- void open() throw(DatabaseException);
- void close() throw();
-
- friend class anna::dbms::mysql::Database;
-};
-
-}
-}
-}
-
-#endif
+++ /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_dbms_mysql_Database_hpp
-#define anna_dbms_mysql_Database_hpp
-
-#include <anna/dbms/Database.hpp>
-#include <anna/dbms/DatabaseException.hpp>
-
-namespace anna {
-
-namespace dbms {
-
-namespace mysql {
-
-/**
- Clase que modela la interaccion entre la RDMS MySQL (tm) y nuestra aplicacion.
-*/
-class Database : public dbms::Database {
-public:
- /**
- Contructor.
- \param dbmsName Nombre de la base de datos.
- \param host Identificador de la máquina anfitriona, que se usará para hacer las conexiones. Puede ser NULL.
- \see http://dev.mysql.com/doc/refman/4.1/en/mysql-real-connect.html
- */
- Database(const char* dbmsName, const char* host);
-
- /**
- Contructor.
- \param componentName Nombre logico de la base de datos por que el podemos buscar este componente.
- \param dbmsName Nombre de la base de datos.
- \param host Identificador de la máquina anfitriona, que se usará para hacer las conexiones. Puede ser NULL.
- \see http://dev.mysql.com/doc/refman/4.1/en/mysql-real-connect.html
- */
- Database(const char* componentName, const char* dbmsName, const char* host);
-
- /**
- Destructor.
- */
- virtual ~Database();
-
- /**
- * Devuelve el nombre de la máquina anfitriona indicado en el constructor.
- * \return El nombre de la máquina anfitriona indicado en el constructor.
- */
- const char* getHost() const throw() { return a_host; }
-
- /**
- Devuelve la cadena por la que podemos buscar el componente.
- \return La cadena por la que podemos buscar el componente.
- \see Application::find
- */
- static const char* getClassName() { return "anna::dbms::mysql::Database"; }
-
-private:
- char* a_host;
-
- void do_initialize() throw(RuntimeException);
-
- dbms::Connection* allocateConnection(const std::string& name, const char* user, const char* password)
- throw(RuntimeException);
-
- dbms::Statement* allocateStatement(const char* name, const std::string& expression, const bool isCritical)
- throw(RuntimeException);
-
- dbms::InputBind* allocateInputBind(const char* name, Data&)
- throw(RuntimeException);
- void deallocate(dbms::InputBind* inputBind) throw();
-
- dbms::OutputBind* allocateOutputBind(const char* name, Data&)
- throw(RuntimeException);
- void deallocate(dbms::OutputBind* outputBind) throw();
-};
-
-#ifdef ANNA_RDBMS_TRACE
-#define anna_dbms_mysql_check(a,_mysql) \
- { \
- Logger::write (Logger::Debug, (#a), __FILE__, __LINE__); \
- const int status = (a); \
- if (status != 0) { \
- anna::dbms::mysql::ResultCode resultCode ((_mysql)); \
- throw DatabaseException (resultCode, __FILE__, __LINE__); \
- } \
- }
-#else
-#define anna_dbms_mysql_check(a,_mysql) \
- { \
- const int status = (a); \
- if (status != 0) { \
- anna::dbms::mysql::ResultCode resultCode ((_mysql)); \
- throw DatabaseException (resultCode, __FILE__, __LINE__); \
- } \
- }
-#endif
-}
-}
-}
-
-#endif
+++ /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_dbms_mysql_InputBind_hpp
-#define anna_dbms_mysql_InputBind_hpp
-
-#include <anna/dbms/InputBind.hpp>
-
-#include <anna/dbms.mysql/BaseBind.hpp>
-
-namespace anna {
-
-class DataBlock;
-
-namespace dbms {
-
-class Data;
-class Statement;
-
-namespace mysql {
-
-class Statement;
-
-class InputBind : public dbms::InputBind, public BaseBind {
-public:
- InputBind(const char* name, dbms::Data& data);
- virtual ~InputBind();
-
-private:
- void code() const throw(RuntimeException);
-
- void codeShortBlock(dbms::Data&) throw();
- void codeDate(dbms::Data&) throw();
-
- static char asCharacter(const char byte)
- throw() {
- return (byte >= 0 && byte <= 9) ? (byte + '0') : ((byte - 0xa) + 'A');
- }
-
- /* Funciones virtuales puras */
- void prepare(anna::dbms::Statement*, anna::dbms::Connection*, const int pos) throw(RuntimeException);
- void release(anna::dbms::Statement*) throw() {;}
-
- friend class mysql::Statement;
-};
-
-}
-}
-}
-
-#endif
-
+++ /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_dbms_mysql_OracleTranslator_hpp
-#define anna_dbms_mysql_OracleTranslator_hpp
-
-#include <anna/dbms/StatementTranslator.hpp>
-
-namespace anna {
-
-namespace dbms {
-
-namespace mysql {
-
-/**
- * Ésta clase permite que sentencias, escritas originalmente para ser ejecutadas sobre
- * Oracle (tm) puedan ser ejecutadas desde MySQL (tm) sin ningún tipo de problemas.
- *
- * Si este traductor se aplica sobre una sentencia SQL escrita originalmente para
- * funcionar sobre MySQL el resultado será la misma sentencia.
- *
- * \see anna::dbms::Database::setStatementTranslator
- */
-class OracleTranslator : public StatementTranslator {
-public:
- /**
- * Obtiene la instancia de este traductor de sentencias SQL.
- */
- static StatementTranslator* instantiate() throw() { return &st_this; }
-
-private:
- char* a_buffer;
- int a_size;
-
- static OracleTranslator st_this;
-
- OracleTranslator() : StatementTranslator("dbms::mysql::OracleTranslator"),
- a_buffer(NULL), a_size(-1)
- {;}
-
- const char* apply(const char* statement) throw(RuntimeException);
- void allocate(const char* statement) throw();
-};
-
-}
-}
-}
-
-#endif
+++ /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_dbms_mysql_OutputBind_hpp
-#define anna_dbms_mysql_OutputBind_hpp
-
-#include <anna/core/DataBlock.hpp>
-
-#include <anna/dbms/OutputBind.hpp>
-#include <anna/dbms/DatabaseException.hpp>
-
-#include <anna/dbms.mysql/BaseBind.hpp>
-
-namespace anna {
-
-class DataBlock;
-
-namespace dbms {
-
-class Statement;
-
-namespace mysql {
-
-class OutputBind : public dbms::OutputBind, public BaseBind {
-public:
- OutputBind(const char* name, dbms::Data& data);
- ~OutputBind();
-
-private:
- struct Blob {
- DataBlock buffer;
- st_mysql_stmt* stmt;
- st_mysql_bind* binds;
- int pos;
-
- Blob();
- };
-
- Blob* a_blob;
-
- void decodeLongBlob(dbms::Data&) const throw(RuntimeException, dbms::DatabaseException);
- void decodeDate(dbms::Data&) throw();
-
- static unsigned char asByte(const char hex)
- throw() {
- return (hex >= '0' && hex <= '9') ? (hex - '0') : ((hex - 'A') + 0x0a);
- }
-
- /* Funciones virtuales puras */
- void decode() const throw(RuntimeException);
- void prepare(anna::dbms::Statement*, anna::dbms::Connection*, const int pos) throw(RuntimeException);
- void release(anna::dbms::Statement*) throw() {;}
- void do_write(const dbms::LongBlock&) const throw(RuntimeException, dbms::DatabaseException);
-
- friend class Statement;
-};
-
-}
-}
-}
-
-#endif
-
+++ /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_dbms_mysql_ResultCode_hpp
-#define anna_dbms_mysql_ResultCode_hpp
-
-#include <anna/dbms/ResultCode.hpp>
-
-#include <anna/dbms.mysql/forward.hpp>
-
-namespace anna {
-
-namespace dbms {
-
-namespace mysql {
-
-/**
- Clase para acceder a la informacion devuelta por el gestor de base de datos
- referente al ultimo comando realizado.
- */
-class ResultCode : public dbms::ResultCode {
-public:
- /**
- Constructor.
- \param mysql Instancia de la base de datos sobre la que aplicamos la sentencia SQL.
- */
- explicit ResultCode(st_mysql* mysql);
-
- /**
- Constructor.
- \param stmt Instancia de la sentencia ejecutada.
- */
- explicit ResultCode(st_mysql_stmt* stmt);
-
-private:
- class ErrorDecoder : public dbms::ResultCode::ErrorDecoder {
- bool notFound(const int errorCode) const throw();
- bool successful(const int errorCode) const throw();
- bool locked(const int errorCode) const throw();
- bool lostConnection(const int errorCode) const throw();
- };
-
- static ErrorDecoder st_errorDecoder;
-};
-
-}
-}
-}
-
-#endif
-
+++ /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_dbms_mysql_Statement_hpp
-#define anna_dbms_mysql_Statement_hpp
-
-#include <anna/dbms/Statement.hpp>
-
-#include <anna/dbms.mysql/forward.hpp>
-
-namespace anna {
-
-namespace dbms {
-
-class Connection;
-
-namespace mysql {
-
-class Database;
-
-/**
- Clase que facilita la ejecucion de sentencias SQL a traves del RDBMS MySQL (tm).
-
- Esta clase no puede usarse directamente, ya que la capa ANNA.dbms obliga a que todas las peticiones
- se hagan atraves de una instancia anna::dbms::Statement.
-
- Para obtener la instancia de un comando para una determinada base de datos habra que instanciar
- dicha base de datos e invocar al metodo createStatement. Independientemente del tipo de comando
- particular que la base de datos retorne, debemos asignarlo a un puntero de tipo anna::dbms::Statement.
- */
-class Statement : public dbms::Statement {
-public:
- /**
- Destructor.
- */
- virtual ~Statement();
-
- /**
- Operador de conversion.
- \return El puntero MYSQL_STMT de esta sentencia.
- */
- operator st_mysql_stmt*() throw() { return a_mysqlStmt; }
-
- /**
- * Obtiene el array asociado a los valores de entrada.
- * \return El array asociado a los valores de entrada.
- * \warning Exclusivamente uso interno.
- */
- st_mysql_bind* getBindParams() throw() { return a_params; }
-
- /**
- * Obtiene el array asociado a los valores de salida.
- * \return El array asociado a los valores de salida.
- * \warning Exclusivamente uso interno.
- */
- st_mysql_bind* getBindResults() throw() { return a_results; }
-
-private:
- st_mysql_stmt* a_mysqlStmt;
-
- st_mysql_bind* a_params;
- st_mysql_bind* a_results;
-
- Statement(Database& database, const char* name, const char* expression, const bool isCritical) :
- dbms::Statement(database, name, expression, isCritical),
- a_mysqlStmt(NULL),
- a_params(NULL),
- a_results(NULL) {}
-
- Statement(Database& database, const char* name, const std::string& expression, const bool isCritical) :
- dbms::Statement(database, name, expression, isCritical),
- a_mysqlStmt(NULL),
- a_params(NULL),
- a_results(NULL) {}
-
- st_mysql_bind* create(const int size, const char* whatis) throw(RuntimeException);
-
- void prepare(dbms::Connection* connection) throw(RuntimeException, DatabaseException);
- dbms::ResultCode execute(dbms::Connection* connection) throw(RuntimeException, DatabaseException);
- bool fetch() throw(RuntimeException, DatabaseException);
-
- friend class Database;
-};
-
-}
-}
-}
-
-#endif
-
+++ /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_dbms_mysql_forward_hpp
-#define anna_dbms_mysql_forward_hpp
-
-/*
- * el MYSQL es un typedef definido sobre la estructura st_mysql
- */
-struct st_mysql;
-
-/* MYSQL_STMT */
-struct st_mysql_stmt;
-
-/* MYSQL_BIND */
-struct st_mysql_bind;
-
-/* MYSQL_TIME */
-struct st_mysql_time;
-
-#endif /*_anna_dbms_mysql_forward_h*/
+++ /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_dbms_mysql_internal_sccs_hpp
-#define anna_dbms_mysql_internal_sccs_hpp
-
-namespace anna {
-
-namespace dbms {
-
-namespace mysql {
-
-class sccs {
-public:
- static void activate() throw();
-};
-
-}
-}
-}
-
-#endif
-
+++ /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_dbms_mysql_mysql_hpp
-#define anna_dbms_mysql_mysql_hpp
-
-namespace anna {
-
-namespace dbms {
-/**
-Proporciona las clases necesarias para acceder a la ejecucion de sentencias SQL para
-MySQL (tm).
-
-El ejecutable debera enlazarse con las librerias:
- \li anna.core.a
- \li anna.xml.a
- \li anna.app.a
- \li anna.comm.a
- \li anna.dbms.a
- \li anna.dbms.mysql.a
-
-El <b>Packet Header</b> es anna.dbms.mysql.h
-*/
-namespace mysql {
-}
-}
-}
-
-#include <anna/dbms.mysql/Connection.hpp>
-#include <anna/dbms.mysql/Database.hpp>
-#include <anna/dbms.mysql/InputBind.hpp>
-#include <anna/dbms.mysql/OutputBind.hpp>
-#include <anna/dbms.mysql/ResultCode.hpp>
-#include <anna/dbms.mysql/Statement.hpp>
-
-using namespace anna::dbms::mysql;
-
-#endif
-
+++ /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_dbms_oracle_BaseBind_hpp
-#define anna_dbms_oracle_BaseBind_hpp
-
-struct OCIEnv;
-struct OCIError;
-struct OCIBind;
-struct OCILobLocator;
-struct OCISvcCtx;
-struct OCIDateTime;
-
-#include <anna/dbms.oracle/Descriptor.hpp>
-
-namespace anna {
-
-class DataBlock;
-
-namespace dbms {
-
-class Statement;
-class Data;
-
-namespace oracle {
-
-class Statement;
-class Database;
-class Connection;
-
-class BaseBind {
-public:
- virtual ~BaseBind();
-
-protected:
- /**
- * Número de bytes reservados para un Float cuando se trata como si fuera una cadena.
- */
- static const int FloatSize = 63;
- struct oci_param {
- int type;
- int maxLength;
- short unsigned int* length;
- void* buffer;
- };
- struct Blob : public Descriptor {
- OCILobLocator* handle;
- Blob() : Descriptor((dvoid**) &handle) {;}
- };
- struct DateTime : public Descriptor {
- OCIDateTime* handle;
- DateTime() : Descriptor((dvoid**) &handle) {;}
- };
-
- short a_nullIndicator;
- unsigned short a_length;
- anna::DataBlock* a_ofb; // Oracle Formatted Buffer.
- Blob a_blob;
- DateTime a_datetime;
-
- BaseBind(const dbms::Data& data) ;
-
- oci_param getOCIParam(Database&, Connection*, dbms::Data&) throw(RuntimeException);
-
-private:
- const Data::Type::_v a_type;
-};
-
-}
-}
-}
-
-#endif
-
+++ /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_dbms_oracle_Connection_hpp
-#define anna_dbms_oracle_Connection_hpp
-
-struct OCIServer;
-struct OCISession;
-struct OCISvcCtx;
-
-#include <anna/dbms/Connection.hpp>
-#include <anna/dbms/DatabaseException.hpp>
-
-namespace anna {
-
-namespace dbms {
-
-class Database;
-
-namespace oracle {
-
-class Database;
-
-/**
- Clase que modela la conexion con el RDBMS Oracle (tm).
-
- Esta clase no puede usarse directamente, ya que la capa ANNA.dbms obliga a que todas las peticiones
- se hagan atraves de una instancia anna::dbms::Connection.
-
- Para obtener una conexion a una determinada base de datos habra que instanciar dicha base de datos
- e invocar al metodo createConnection. Independientemente del tipo de conexion particular que la
- base de datos retorne, debemos asignarlo a un puntero de tipo anna::dbms::Connection.
-*/
-class Connection : public dbms::Connection {
-public:
- /**
- Devuelve una cadena con la informacion referente a esta instancia.
- @return Una cadena con la informacion referente a esta instancia.
- */
- std::string asString() const throw();
-
- /**
- Operador de conversion.
- \return El puntero al contexto asociado a este conexion.
- */
- operator OCISvcCtx*() throw() { return a_context; }
-
-private:
- Database& a_oracleDatabase;
- OCISvcCtx* a_context;
- OCISession* a_session;
- OCIServer* a_server;
-
- Connection(Database& database, const std::string& name, const char* user, const char* password);
- bool isAvailable() const throw(RuntimeException) { return a_context != NULL && a_session != NULL && a_server != NULL; }
- void do_commit() throw(RuntimeException, DatabaseException);
- void do_rollback() throw();
- void open() throw(DatabaseException);
- void close() throw();
-
- friend class anna::dbms::oracle::Database;
-};
-
-}
-}
-}
-
-#endif
+++ /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_dbms_oracle_Database_hpp
-#define anna_dbms_oracle_Database_hpp
-
-#include <anna/dbms/Database.hpp>
-#include <anna/dbms/DatabaseException.hpp>
-
-struct OCIEnv;
-struct OCIError;
-
-namespace anna {
-
-namespace dbms {
-
-namespace oracle {
-
-/**
- Clase que modela la interaccion entre la RDMS Oracle (tm) y nuestra aplicacion.
-
- \warning La definicion conexiones y clusters debe hacerse antes de invocar al metodo Application::start,
- o bien, en el metodo Application::initialize.
-*/
-class Database : public dbms::Database {
-public:
- /**
- Contructor.
- \param dbmsName Nombre de la base de datos.
- */
- Database(const char* dbmsName);
-
- /**
- Contructor.
- \param componentName Nombre logico de la base de datos por que el podemos buscar este compoenente.
- \param dbmsName Nombre de la base de datos.
- */
- Database(const char* componentName, const char* dbmsName);
-
- /**
- Destructor.
- */
- virtual ~Database();
-
- /**
- Devuelve el manejador de error asociado a esta base de datos.
- \return El manejador de error asociado a esta base de datos.
- */
- OCIError* getErrorHandler() throw() { return a_error; }
-
- /**
- Operador de conversion.
- \return El puntero al entorno asociado a esta base de datos.
- */
- operator OCIEnv*() throw() { return a_env; }
-
- /**
- Devuelve la cadena por la que podemos buscar el componente.
- \return La cadena por la que podemos buscar el componente.
- \see Application::find
- */
- static const char* getClassName() { return "anna::dbms::oracle::Database"; }
-
- /**
- * Devuelve el caracter usado como punto decimal, obtenido a partir de la configuración establecida
- * por la variables de entorno, LANG, LC_NUMERIC, etc, etc.
- *
- * \return El caracter usado como punto decimal.
- *
- * \warning Metodo exclusivamente de uso interno.
- */
- static char getDecimalPoint() throw() { return st_decimalPoint; }
-
-private:
- OCIEnv* a_env;
- OCIError* a_error;
-
- static char st_decimalPoint;
-
- void do_initialize() throw(RuntimeException);
-
- dbms::Connection* allocateConnection(const std::string& name, const char* user, const char* password)
- throw(RuntimeException);
-
- dbms::Statement* allocateStatement(const char* name, const std::string& expression, const bool isCritical)
- throw(RuntimeException);
-
- dbms::InputBind* allocateInputBind(const char* name, Data&)
- throw(RuntimeException);
- void deallocate(dbms::InputBind* inputBind) throw();
-
- dbms::OutputBind* allocateOutputBind(const char* name, Data&)
- throw(RuntimeException);
- void deallocate(dbms::OutputBind* outputBind) throw();
-
- static void initializeDecimalPoint() throw(RuntimeException);
-};
-
-#ifdef ANNA_RDBMS_TRACE
-#define anna_dbms_oracle_check(a,error) \
- { \
- Logger::write (Logger::Debug, (#a), __FILE__, __LINE__); \
- const sword status = (a); \
- if (status != OCI_SUCCESS) { \
- anna::dbms::oracle::ResultCode resultCode (status, (error)); \
- throw DatabaseException (resultCode, __FILE__, __LINE__); \
- } \
- }
-#else
-#define anna_dbms_oracle_check(a,error) \
- { \
- const sword status = (a); \
- if (status != OCI_SUCCESS) { \
- anna::dbms::oracle::ResultCode resultCode (status, (error)); \
- throw DatabaseException (resultCode, __FILE__, __LINE__); \
- } \
- }
-#endif
-}
-}
-}
-
-#endif
+++ /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_dbms_oracle_Descriptor_hpp
-#define anna_dbms_oracle_Descriptor_hpp
-
-#include <anna/core/RuntimeException.hpp>
-
-struct OCIEnv;
-struct OCIError;
-struct OCIBind;
-struct OCILobLocator;
-struct OCISvcCtx;
-
-namespace anna {
-
-namespace dbms {
-
-namespace oracle {
-
-class Database;
-class Connection;
-
-struct Descriptor {
- dvoid** reference;
- OCIEnv* env;
- OCIError* error;
- OCISvcCtx* context;
- int type;
-
- Descriptor(dvoid** _handle) : reference(_handle) {
- *reference = NULL; env = NULL; error = NULL; context = NULL; type = -1;
- }
- virtual ~Descriptor();
-
- void allocate(Database&, Connection*, const int type) throw(RuntimeException);
-};
-
-}
-}
-}
-
-#endif
-
+++ /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_dbms_oracle_InputBind_hpp
-#define anna_dbms_oracle_InputBind_hpp
-
-#include <anna/dbms/InputBind.hpp>
-
-#include <anna/dbms.oracle/BaseBind.hpp>
-
-struct OCIBind;
-
-namespace anna {
-
-class DataBlock;
-
-namespace dbms {
-
-class Data;
-class Statement;
-
-namespace oracle {
-
-class Statement;
-
-class InputBind : public dbms::InputBind, public BaseBind {
-public:
- InputBind(const char* name, dbms::Data& data);
- virtual ~InputBind();
-
-private:
- OCIBind* a_ociBind;
-
- void code() const throw(RuntimeException);
- void prepare(dbms::Statement*, dbms::Connection*, const int pos) throw(RuntimeException, DatabaseException);
- void release(dbms::Statement*) throw() { a_ociBind = NULL; }
-
- void codeFloat(dbms::Data&) const throw();
- void codeShortBlock(dbms::Data&) const throw();
- void codeDate(dbms::Data&) const throw(RuntimeException, DatabaseException);
-
- static char asCharacter(const char byte)
- throw() {
- return (byte >= 0 && byte <= 9) ? (byte + '0') : ((byte - 0xa) + 'A');
- }
-
- friend class oracle::Statement;
-};
-
-}
-}
-}
-
-#endif
-
+++ /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_dbms_oracle_OutputBind_hpp
-#define anna_dbms_oracle_OutputBind_hpp
-
-#include <anna/dbms/OutputBind.hpp>
-
-#include <anna/dbms.oracle/BaseBind.hpp>
-
-struct OCIDefine;
-
-namespace anna {
-
-namespace dbms {
-
-class Statement;
-
-namespace oracle {
-
-class OutputBind : public dbms::OutputBind, public BaseBind {
-public:
- OutputBind(const char* name, dbms::Data& data);
- ~OutputBind();
-
-private:
- OCIDefine* a_ociDefine;
-
- void decode() const throw(anna::RuntimeException);
- void prepare(dbms::Statement*, dbms::Connection*, const int pos) throw(DatabaseException);
- void release(dbms::Statement*) throw() { a_ociDefine = NULL; }
-
- void decodeFloat(dbms::Data&) const throw(RuntimeException);
- void decodeShortBlock(dbms::Data&) const throw(RuntimeException);
- void decodeLongBlock(dbms::Data&) const throw(RuntimeException);
- void decodeDate(dbms::Data&) const throw(RuntimeException, DatabaseException);
-
- void do_write(const dbms::LongBlock&) const throw(RuntimeException, dbms::DatabaseException);
-
- static unsigned char asByte(const char hex)
- throw() {
- return (hex >= '0' && hex <= '9') ? (hex - '0') : ((hex - 'A') + 0x0a);
- }
-
- friend class Statement;
-};
-
-}
-}
-}
-
-#endif
-
+++ /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_dbms_oracle_ResultCode_hpp
-#define anna_dbms_oracle_ResultCode_hpp
-
-#include <anna/dbms/ResultCode.hpp>
-
-struct OCIError;
-
-namespace anna {
-
-namespace dbms {
-
-namespace oracle {
-
-/**
- Clase para acceder a la informacion devuelta por el gestor de base de datos
- referente al ultimo comando realizado.
- */
-class ResultCode : public dbms::ResultCode {
-public:
- /**
- Constructor.
-
- \param status Codigo de resultado de la ultima operacion realizada.
- \param error Estructura de datos que contiene la informacion adicional sobre el error.
- */
- explicit ResultCode(const int status, OCIError* error);
-
-private:
- class ErrorDecoder : public dbms::ResultCode::ErrorDecoder {
- bool notFound(const int errorCode) const throw();
- bool successful(const int errorCode) const throw();
- bool locked(const int errorCode) const throw() { return errorCode == 54; }
- bool lostConnection(const int errorCode) const throw();
- };
-
- static ErrorDecoder st_errorDecoder;
-};
-
-}
-}
-}
-
-#endif
-
+++ /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_dbms_oracle_Statement_hpp
-#define anna_dbms_oracle_Statement_hpp
-
-#include <anna/dbms/Statement.hpp>
-
-struct OCIStmt;
-struct OCIError;
-
-namespace anna {
-
-namespace dbms {
-
-class Connection;
-
-namespace oracle {
-
-/**
- Clase que facilita la ejecucion de sentencias SQL a traves del RDBMS Oracle (tm).
-
- Esta clase no puede usarse directamente, ya que la capa ANNA.dbms obliga a que todas las peticiones
- se hagan atraves de una instancia anna::dbms::Statement.
-
- Para obtener la instancia de un comando para una determinada base de datos habra que instanciar
- dicha base de datos e invocar al metodo createStatement. Independientemente del tipo de comando
- particular que la base de datos retorne, debemos asignarlo a un puntero de tipo anna::dbms::Statement.
- */
-class Statement : public dbms::Statement {
-public:
- /**
- Destructor.
- */
- virtual ~Statement();
-
- /**
- Operador de conversion.
- \return El puntero OCI de esta sentencia.
- */
- operator OCIStmt*() throw() { return a_ociStmt; }
-
-private:
- OCIStmt* a_ociStmt;
- OCIError* a_ociError;
- bool a_firstFetch;
-
- Statement(Database& database, const char* name, const char* expression, const bool isCritical) :
- dbms::Statement(database, name, expression, isCritical),
- a_ociStmt(NULL),
- a_ociError(NULL) {}
-
- Statement(Database& database, const char* name, const std::string& expression, const bool isCritical) :
- dbms::Statement(database, name, expression, isCritical),
- a_ociStmt(NULL),
- a_ociError(NULL) {}
-
- void prepare(dbms::Connection* connection) throw(RuntimeException, DatabaseException);
- dbms::ResultCode execute(dbms::Connection* connection) throw(RuntimeException, DatabaseException);
- bool fetch() throw(RuntimeException, DatabaseException);
-
- friend class Database;
-};
-
-}
-}
-}
-
-#endif
-
+++ /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_dbms_oracle_internal_sccs_hpp
-#define anna_dbms_oracle_internal_sccs_hpp
-
-namespace anna {
-
-namespace dbms {
-
-namespace oracle {
-
-class sccs {
-public:
- static void activate() throw();
-};
-
-}
-}
-}
-
-#endif
-
+++ /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_dbms_oracle_oracle_hpp
-#define anna_dbms_oracle_oracle_hpp
-
-namespace anna {
-
-namespace dbms {
-/**
-Proporciona las clases necesarias para acceder a la ejecucion de sentencias SQL para
-Oracle (tm).
-
-El ejecutable debera enlazarse con las librerias:
- \li anna.core.a
- \li anna.xml.a
- \li anna.app.a
- \li anna.comm.a
- \li anna.dbms.a
- \li anna.dbms.oracle.a
-
-El <b>Packet Header</b> es anna.dbms.oracle.h
-*/
-namespace oracle {
-}
-}
-}
-
-#include <anna/dbms.oracle/Connection.hpp>
-#include <anna/dbms.oracle/Database.hpp>
-#include <anna/dbms.oracle/InputBind.hpp>
-#include <anna/dbms.oracle/OutputBind.hpp>
-#include <anna/dbms.oracle/ResultCode.hpp>
-#include <anna/dbms.oracle/Statement.hpp>
-
-using namespace anna::dbms::oracle;
-
-#endif
-
+++ /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_dbms_Bind_hpp
-#define anna_dbms_Bind_hpp
-
-#include <anna/core/functions.hpp>
-#include <anna/core/RuntimeException.hpp>
-
-#include <anna/dbms/DatabaseException.hpp>
-#include <anna/dbms/Data.hpp>
-
-namespace anna {
-
-namespace dbms {
-
-class Connection;
-class Statement;
-class Data;
-
-class Bind {
-public:
- dbms::Data& getData() throw() { return a_data; }
- const dbms::Data& getData() const throw() { return a_data; }
-
- virtual void prepare(Statement* statement, Connection* connection, const int pos)
- throw(RuntimeException, DatabaseException) = 0;
-
- virtual void release(Statement* statement) throw() = 0;
- virtual void code() const throw(RuntimeException) = 0;
- virtual void decode() const throw(RuntimeException) = 0;
- virtual std::string asString() const throw();
-
-protected:
- Bind(const char* name, dbms::Data& data) : a_name(name), a_data(data) {;}
-
-private:
- const std::string a_name;
- dbms::Data& a_data;
-
- friend class Statement;
-};
-
-}
-}
-
-#endif
-
+++ /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_dbms_Connection_hpp
-#define anna_dbms_Connection_hpp
-
-#include <anna/comm/Resource.hpp>
-
-#include <anna/dbms/DatabaseException.hpp>
-#include <anna/dbms/ResultCode.hpp>
-
-namespace anna {
-
-namespace xml {
-class Node;
-}
-
-namespace dbms {
-
-class Database;
-class Statement;
-
-/**
- Clase que modela la conexion con la base de datos.
-
- Para crear una nueva conexion hay que invocar al Metodo Database::createConnection de la base de datos
- contra la que deseamos establecer la conexion.
-
- Para obtener una conexion a una determinada base de datos habria que instanciar dicha base de datos
- e invocar al Metodo Database::createConnection. Independientemente del tipo de conexion particular que la base
- de datos retorne, debemos asignarlo a un puntero de tipo anna::dbms::Connection.
-*/
-class Connection : public comm::Resource {
-public:
- /**
- Devuelve la instancia de la base de datos asociada a esta conexion.
- */
- Database& getDatabase() const throw() { return a_database; }
-
- /**
- * Devuelve el usuario con el que fué realizada esta conexión.
- * \return el usuario con el que fué realizada esta conexión.
- */
- const std::string& getUser() const throw() { return a_user; }
-
- /**
- * Devuelve el password del usuario con el que fué realizada esta conexión.
- * \return el password del usuario con el que fué realizada esta conexión.
- */
- const std::string& getPassword() const throw() { return a_password; }
-
- /**
- * Establece el password del usuario de esta conexión
- * \param password Codigo de acceso del usuario.
- */
- void setPassword(const char* password) throw() { a_password = password; }
-
- /**
- Establece el periodo de grabacion de esta conexion. Damos la posibilidad de que la conexion confirme
- cambios realizados hasta el momento sin que termine la seccion critica que debemos establecer antes
- de usar la conexion.
- \param maxCommitPending Numero de transacciones que pueden estar pedientes de confirmacion antes
- de invocar a #commit. Un valor 0, desactiva el periodo.
- \return El periodo de grabacion que habia antes de invocar a este metodo.
- \warning La invocacion a este metodo debera hacerse con una seccion critica activada sobre la
- esta conexion.
- */
- int setMaxCommitPending(const int maxCommitPending) throw() {
- const int result = a_maxCommitPending;
- a_maxCommitPending = maxCommitPending;
- return result;
- }
-
- /**
- Desactiva el indicador de que la conexion requiere una invocacion a #rollback.
- \warning La invocacion a este metodo debera hacerse con una seccion critica activada sobre la
- esta conexion.
- */
- void resetRollbackPending() throw() { a_rollbackPending = false; }
-
- /**
- Activa de forma externa el indicador de que la conexion requiere una invocacion a #rollback.
- \warning La invocacion a este metodo debera hacerse con una seccion critica activada sobre la
- esta conexion.
- */
- void activateRollbackPending() throw() { a_rollbackPending = true; }
-
- /**
- Ejecuta la sentencia recibida como parametro. Si la sentencia no tiene variables de salida consideraria
- que es un comando \em update, \em insert o \em delete, lo cual, implica la invocacion automatica a los
- #commit o #rollback cuando termine la seccion critica de esta conexion.
-
- \param statement Sentencia que vamos a ejecuta
-
- \return La estructura con el resultado de la ejecucion de la sentencia.
-
- \warning La invocacion a este metodo debera hacerse con una seccion critica activada sobre la
- esta conexion, por ejemplo:
- \code
- Guard guard (connection);
- connection.execute (someStatement);
- \endcode
- */
- ResultCode execute(Statement* statement) throw(RuntimeException, DatabaseException);
-
- /**
- Devuelve una cadena con la informacion referente a esta instancia.
- @return Una cadena con la informacion referente a esta instancia.
- */
- virtual std::string asString() const throw();
-
- /**
- Devuelve un documento XML con la informacion referente a esta instancia.
- \param parent Nodo XML del que debe colgar la informacion.
- @return un documento XML con la informacion referente a esta instancia.
- */
- virtual xml::Node* asXML(xml::Node* parent) const throw();
-
-protected:
- /**
- Instancia de la base de datos asociada a esta conexion.
- Coincidiria con la indicada en el constructor.
- */
- Database& a_database;
- std::string a_user; /**< Nombre del usuario */
- std::string a_password; /**< Clave de acceso del usuario. */
-
- /**
- Contructor.
-
- @param database Instancia de la base de datos asociada a esta conexion.
- @param name Nombre logico de la conexion.
- @param user Nombre del usuario con el que realizamos la conexion.
- @param password Codigo de acceso del usuario.
- */
- Connection(Database& database, const std::string& name, const char* user, const char* password) :
- comm::Resource(name),
- a_database(database),
- a_user(user),
- a_password(password),
- a_lockingCounter(0),
- a_commitPending(0),
- a_rollbackPending(false),
- a_maxCommitPending(0) {}
-
- /**
- Metodo que fija los cambios realizados en la ejecucion de los comandos SQL.
- */
- void commit() throw(RuntimeException, DatabaseException);
-
- /**
- Metodo que debemos re-escribir para descartar los cambios realizados sobre las tablas mediante
- esta conexion.
- */
- void rollback() throw();
-
- /**
- Metodo que debemos re-escribir para hacer efectiva esta conexion.
- */
- virtual void open() throw(DatabaseException) = 0;
-
- /**
- Metodo que debemos re-escribir para cerrar la conexion.
- */
- virtual void close() throw() = 0;
-
-private:
- int a_commitPending; // Numero de sentencias a las que no se han fijado cambios.
- bool a_rollbackPending;
- int a_maxCommitPending;
- int a_lockingCounter;
-
- Connection(const Connection&);
-
- void initialize() throw(RuntimeException, DatabaseException);
- void lock() throw(RuntimeException);
- void unlock() throw();
-
- virtual bool do_beginTransaction() throw(RuntimeException, DatabaseException) { return false;}
- virtual void do_commit() throw(RuntimeException, DatabaseException) = 0;
- virtual void do_rollback() throw() = 0;
-
- friend class Database;
-};
-
-}
-}
-
-#endif
+++ /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_dbms_Data_hpp
-#define anna_dbms_Data_hpp
-
-#include <string>
-
-#include <anna/config/defines.hpp>
-#include <anna/core/functions.hpp>
-#include <anna/core/RuntimeException.hpp>
-
-namespace anna {
-
-namespace dbms {
-
-class Bind;
-
-/**
- Clase base para las variables de entrada/salida asociadas a las sentencias SQL.
-*/
-class Data {
-public:
- struct Type {
- enum _v {
- Integer, /**< Numeros enteros */
- String, /**< Cadenas de caracteres */
- Float, /**< Número en coma flotante */
- ShortBlock, /**< Tipos de dato RAW */
- LongBlock, /**< Tipo de datos CLOB */
- Date, /** Tipo de fecha (dependiendo del gestor de base de datos puede contener tambien la hora) */
- TimeStamp /** Tipo para contener simultáneamente la fecha y la hora */
- };
- };
-
- /**
- Devuelve el tamano maximo de este dato que coincidiria con el indicado en el constructor.
- \return El tamano maximo de este dato que coincidiria con el indicado en el constructor.
- */
- int getMaxSize() const throw() { return a_maxSize; }
-
- /**
- Devuelve el tipo de dato.
- \return El tipo de datos.
- */
- Type::_v getType() const throw() { return a_type; }
-
- /**
- Devuelve el area de memoria asociada a esta variable.
- */
- void* getBuffer() throw() { return a_buffer; }
-
- /**
- Devuelve el indicador de nulo de esta instancia.
- \return El indicador de nulo de esta instancia.
- */
- bool isNull() const throw() { return a_isNull; }
-
- /**
- Devuelve el valor que indica si este dato puede tomar valores nulos.
- \return El valor que indica si este dato puede tomar valores nulos.
- */
- bool isNulleable() const throw() { return a_isNulleable; }
-
- /**
- Establece el indicador de nulo de esta instancia.
- \param isNull Indicador de nulo de esta instancia.
- \warning Slo tendr�efecto en caso de haber indicado en el constructor que
- el dato puede tomar valores nulos.
- */
- void setNull(const bool isNull) throw() { if(a_isNulleable == true) a_isNull = isNull; }
-
- /**
- Incorpora el método clear para todos tipos de datos con lo que podemos obtener información
- del medio físico.
-
- Si el dato está definido como "nuleable" activará el indicador que indica que el dato está vacío,
- en otro caso se asignará un valor adecuado dependiendo del tipo del dato, cero para los números,
- "" para las cadenas, etc.
- */
- void clear() throw() {
- setNull(true);
- do_clear();
- }
-
- /**
- Devuelve una cadena con la informacion referente a esta instancia.
- @return Una cadena con la informacion referente a esta instancia.
- */
- virtual std::string asString() const throw();
-
-protected:
- /**
- Constructor.
- \param type Tipo de dato de esta instancia.
- \param maxSize Tamao maximo que puede tener este dato. Deberia coincidir con el indicado
- por la columna con la que vaya a corresponder en la sentencia.
- \param isNulleable Indica si el dato puede tomar valores nulos.
-
- \warning los tipos de datos complejos deberia reimplementar los metodos #code and #decode.
- */
- explicit Data(const Type::_v type, const int maxSize, const bool isNulleable) :
- a_type(type),
- a_maxSize(maxSize),
- a_isNulleable(isNulleable),
- a_isNull(isNulleable),
- a_buffer(NULL)
- {;}
-
- /**
- Constructor copia.
- \param other Instancia de la que copiar.
- */
- Data(const Data& other) :
- a_type(other.a_type),
- a_maxSize(other.a_maxSize),
- a_isNulleable(other.a_isNulleable),
- a_isNull(other.a_isNull),
- a_buffer(other.a_buffer)
- {;}
-
- /**
- Establece el area de memoria asociada a esta variable.
- \param buffer Direccion de memoria donde comienza el contenido esta variable.
- */
- void setBuffer(void* buffer) throw() { a_buffer = buffer; }
-
-private:
- const Type::_v a_type;
- const int a_maxSize;
- const bool a_isNulleable;
- void* a_buffer;
- bool a_isNull;
-
- virtual void do_clear() throw() = 0;
-};
-
-}
-}
-
-#endif
-
+++ /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_dbms_Database_hpp
-#define anna_dbms_Database_hpp
-
-#include <vector>
-
-#include <anna/app/Component.hpp>
-
-#include <anna/dbms/Connection.hpp>
-
-namespace anna {
-
-namespace comm {
-class INetAddress;
-class Delivery;
-}
-
-namespace dbms {
-
-class Statement;
-class InputBind;
-class OutputBind;
-class Data;
-class FailRecoveryHandler;
-class StatementTranslator;
-
-/**
- Clase que modela la interaccion entre la base y nuestra aplicacion.
-*/
-class Database : public app::Component {
-public:
- /**
- Numero maximo de conexiones que podemos crear.
- */
- static const int MaxConnection = 32;
-
- /**
- Formas de conexion a la base de datos.
- */
- struct Type {
- enum _v { Local, Remote } value;
- Type() : value(Local) {;}
- Type(const _v v) : value(v) {;}
- Type(const Type& v) : value(v.value) {;}
- operator int () const throw() { return value; }
- };
-
- typedef std::vector <Connection*>::const_iterator const_connection_iterator; /**<Iterador para acceder a las conexiones de esta base de datos */
- typedef std::vector <Statement*>::const_iterator const_statement_iterator; /**<Iterador para acceder a las conexiones de esta base de datos */
-
- /**
- Destructor.
- */
- virtual ~Database();
-
- /**
- Devuelve el tipo de conexion de esta base de datos.
- \return El tipo de conexion de esta base de datos.
- */
- const Type& getType() const throw() { return a_type; }
-
- /**
- Devuelve el nombre de la base de datos indicado en el constructor.
- \return El nombre de la base de datos indicado en el constructor.
- */
- const std::string& getName() const throw() { return a_name; }
-
- /**
- Establece el manejador encargado de actuar cuando la recuperacion de la conexion falla.
- El manejador por defecto no realiza ninguna activad.
- \param failRecoveryHandler Manejador que seria invocado en caso de que no sea posible recuperar
- una determina conexion.
- */
- void setFailRecoveryHandler(FailRecoveryHandler* failRecoveryHandler) throw() { a_failRecoveryHandler = failRecoveryHandler; }
-
- /**
- * Establece el traductor de sentencias SQL usado ajustar las sentencias SQL al
- * motor de base de datos usados en la aplicación.
- */
- void setStatementTranslator(StatementTranslator* statementTranslator) throw() { a_statementTranslator = statementTranslator; }
-
- /**
- Crea y registra una nueva conexion con esta base de datos.
- La clase usada para conectar con esta base de datos dependeria de la implementacion particular, que
- seria definida por el metodo #allocateConnection.
-
- \param name Nombre logico de la conexion a crear.
- @param user Nombre del usuario con el que realizamos la conexion.
- @param password Codigo de acceso del usuario.
-
- @return La instancia de la nueva conexion a la base de datos.
- */
- Connection* createConnection(const char* name, const char* user, const char* password)
- throw(RuntimeException, DatabaseException);
-
- /**
- Devuelve la conexion asociada al nombre logico recibido como parametro.
- \param name Nombre logico de la conexion que queremos obtener.
- \return La conexion asociada al nombre logico recibido como parametro.
- \warning Si la conexion logica no existe no puede ser usada se lanzara una excepcion.
- */
- Connection& findConnection(const char* name) throw(RuntimeException);
-
- /**
- Devuelve un iterator al comienzo de la lista de conexiones establecidas con esta base de datos.
- \return Un iterator al comienzo de la lista de conexiones establecidas con esta base de datos.
- */
- const_connection_iterator connection_begin() const throw() { return a_connections.begin(); }
-
- /**
- Devuelve un iterator al final de la lista de conexiones establecidas con esta base de datos.
- \return Un iterator al final de la lista de conexiones establecidas con esta base de datos.
- */
- const_connection_iterator connection_end() const throw() { return a_connections.end(); }
-
- /**
- Crea y registra una nueva sentencia SQL asociada a esta base de datos.
- La clase usada para interpretar la sentencia SQL dependera de la implementacion particular definida
- mediante el metodo #allocateStatement.
-
- \param name Nombre logico de esta sentencia.
- \param expression Expresion asociada a la sentencia.
- \param isCritical Si vale \em true indica que si la ejecucion de esta sentencia falla al desbloquear
- la conexion con la que ejecutamos esta sentencia se invocara a Connection::rollback, en otro caso
- aunque falle se invocara a Connection::commit. Solo aplicara en sentencias que no sean de seleccion.
-
- \return Una nueva instancia de una conexion a base de datos. No puede ser NULL.
- */
- Statement* createStatement(const char* name, const char* expression, const bool isCritical = true)
- throw(RuntimeException);
-
- /**
- Crea y registra una nueva sentencia SQL asociada a esta base de datos.
- La clase usada para interpretar la sentencia SQL dependera de la implementacion particular definida
- mediante el metodo #allocateStatement.
-
- \param name Nombre logico de esta sentencia.
- \param expression Expresion asociada a la sentencia.
- \param isCritical Si vale \em true indica que si la ejecucion de esta sentencia falla al desbloquear
- la conexion con la que ejecutamos esta sentencia se invocara a Connection::rollback, en otro caso
- aunque falle se invocara a Connection::commit. Solo aplicara en sentencias que no sean de seleccion.
-
- \return Una nueva instancia de una conexion a base de datos. No puede ser NULL.
- */
- Statement* createStatement(const char* name, const std::string& expression, const bool isCritical = true)
- throw(RuntimeException) {
- return createStatement(name, expression.c_str(), isCritical);
- }
-
- /**
- Devuelve la instancia de la sentencia SQL asociada al nombre recibido como parametro.
-
- @return La instancia de la sentencia SQL asociada al nombre recibido.
- Puede ser NULL si el nombre no fue registrado previamente con #createStatement.
- */
- Statement* findStatement(const char* name) throw();
-
- /**
- Libera los recursos de la sentencia SQL recibida como parametro.
- \param statement Instancia de la sentencia SQL a liberar. deberia haber sido obtenida mediante
- el metodo #createStatement.
- */
- void releaseStatement(Statement* statement) throw();
-
- /**
- Devuelve un iterator al comienzo de la lista de sentencias SQL creadas en esta base de datos.
- \return Un iterator al comienzo de la lista de sentencias SQL creadas en esta base de datos.
- */
- const_statement_iterator statement_begin() const throw() { return a_statements.begin(); }
-
- /**
- Devuelve un iterator al final de la lista de sentencias SQL creadas en esta base de datos.
- \return Un iterator al final de la lista de sentencias SQL creadas en esta base de datos.
- */
- const_statement_iterator statement_end() const throw() { return a_statements.end(); }
-
- /**
- Devuelve el objeto sobre el que esta posicionado el iterator recibido como parametro.
- \param ii Iterator que deberia estar comprendido entre #statement_begin y #statement_end.
- \return El objeto sobre el que esta posicionado el iterator recibido como parametro.
- */
- static Statement* statement(const_statement_iterator& ii) throw() { return *ii; }
-
- /**
- Devuelve una cadena con la informacion mas relevante de esta instancia.
- \return Una cadena con la informacion mas relevante de esta instancia.
- */
- virtual std::string asString() const throw();
-
- /**
- Devuelve un documento XML con la informacion mas relevante de esta instancia.
- \param parent Nodo XML del que colgar la informacion referente a esta instancia.
- \return Un documento XML con la informacion mas relevante de esta instancia.
- */
- virtual xml::Node* asXML(xml::Node* parent) const throw();
-
- /**
- Devuelve el objeto sobre el que esta posicionado el iterator recibido como parametro.
- \param ii Iterator que deberia estar comprendido entre #connection_begin y #connection_end.
- \return El objeto sobre el que esta posicionado el iterator recibido como parametro.
- */
- static const Connection* connection(const_connection_iterator& ii) throw() { return *ii; }
-
-protected:
- typedef std::vector <Connection*>::iterator connection_iterator; /**<Iterador para acceder a las conexiones de esta base de datos */
-
- /**
- Contructor.
- \param rdbmsmsName Nombre del RDMS que gestiona esta base de datos.
- \param dbmsName Nombre de la base de datos.
- */
- Database(const char* rdbmsmsName, const char* dbmsName);
-
- /**
- Recupera el estado de una conexion perdida.
- \warning Este metodo se invoca automaticamente desde el nucleo de ANNA.dbms y nunca deberia
- ser invocado por el programador.
- \param connection Instancia de la conexion en la que hemos detectado el fallo.
- \param tryCounter numero de intentos de recuperacion de la conexion.
- */
- void recover(Connection& connection, const int tryCounter) throw(RuntimeException);
-
- /**
- Inicializa las conexiones definidas sobre esta base de datos. Este metodo se invocaria
- automaticamente desde el nucleo de ANNA.
- Slo seria necesario invocarlo cuando nuestro programa no tenga asociada ninguna aplicacion
- que se encarga de inicializar los componentes.
- */
- virtual void do_initialize() throw(RuntimeException);
-
- /**
- Elimina las conexiones definidas sobre esta base de datos. Este metodo se invocaria automaticamente
- desde el nucleo de ANNA.
- */
- virtual void do_stop() throw();
-
- /**
- Devuelve un iterator al comienzo de la lista de conexiones establecidas con esta base de datos.
- \return Un iterator al comienzo de la lista de conexiones establecidas con esta base de datos.
- */
- connection_iterator connection_begin() throw() { return a_connections.begin(); }
-
- /**
- Devuelve un iterator al final de la lista de conexiones establecidas con esta base de datos.
- \return Un iterator al final de la lista de conexiones establecidas con esta base de datos.
- */
- connection_iterator connection_end() throw() { return a_connections.end(); }
-
- /**
- Devuelve el objeto sobre el que esta posicionado el iterator recibido como parametro.
- \param ii Iterator que deberia estar comprendido entre #connection_begin y #connection_end.
- \return El objeto sobre el que esta posicionado el iterator recibido como parametro.
- */
- static Connection* connection(connection_iterator& ii) throw() { return *ii; }
-
-private:
- const std::string a_name;
- std::vector <Connection*> a_connections;
- std::vector <Statement*> a_statements;
- const Type a_type;
- FailRecoveryHandler* a_failRecoveryHandler;
- StatementTranslator* a_statementTranslator;
-
- Database(const Database&);
-
- void do_cloneChild() throw(RuntimeException);
-
- virtual Connection* allocateConnection(const std::string& name, const char* user, const char* password)
- throw(RuntimeException) = 0;
-
- virtual Statement* allocateStatement(const char* name, const std::string& expression, const bool isCritical)
- throw(RuntimeException) = 0;
-
- virtual InputBind* allocateInputBind(const char* name, Data& data)
- throw(RuntimeException) = 0;
- virtual void deallocate(InputBind* inputBind) throw() = 0;
-
- virtual OutputBind* allocateOutputBind(const char* name, Data& data)
- throw(RuntimeException) = 0;
- virtual void deallocate(OutputBind* outputBind) throw() = 0;
-
- friend class Statement;
- friend ResultCode Connection::execute(Statement*) throw(RuntimeException, DatabaseException);
-};
-
-}
-}
-
-#endif
+++ /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_dbms_DatabaseException_hpp
-#define anna_dbms_DatabaseException_hpp
-
-#include <anna/core/Exception.hpp>
-
-#include <anna/dbms/ResultCode.hpp>
-
-namespace anna {
-
-namespace dbms {
-
-/**
- Exception ocurrida al acceder a algun servicio de la base de datos.
-*/
-class DatabaseException : public Exception {
-public:
- /**
- Constructor.
-
- @param resultCode Clase utilizada para transferir codigo de error entre el gestor de base de datos
- y nuestro programa. Entre otra informacion contiene el error ocurrido en la ultima operacion realizada.
- @param fromFile Fichero en el que se provoco la situacion de error.
- @param fromLine Linea del fichero en la que se provoco la situacion de error.
- */
- DatabaseException(const ResultCode& resultCode, const char* fromFile, const int fromLine) :
- Exception(resultCode.getErrorText(), "DatabaseException", fromFile, fromLine),
- a_resultCode(resultCode) {}
-
- /**
- Constructor.
-
- @param logicalName Nombre logico del elemento que genera la excepcion.
- @param resultCode Clase utilizada para transferir codigo de error entre el gestor de base de datos
- y nuestro programa. Entre otra informacion contiene el error ocurrido en la ultima operacion realizada.
- @param fromFile Fichero en el que se provoco la situacion de error.
- @param fromLine Linea del fichero en la que se provoco la situacion de error.
- */
- DatabaseException(const std::string& logicalName, const ResultCode& resultCode, const char* fromFile, const int fromLine) :
- Exception("", "DatabaseException", fromFile, fromLine),
- a_resultCode(resultCode) {
- std::string aux(logicalName);
- aux += ": ";
- aux += resultCode.getErrorText();
- setText(aux.c_str());
- }
-
- /**
- Destructor.
- */
- virtual ~DatabaseException() throw() {;}
-
- /**
- Devuelve el resultado de base de datos asociado a la excepcion
-
- @return El resultado de base de datos asociado a la excepcion
- */
- const ResultCode& getResultCode() const throw() { return a_resultCode; }
-
-private:
- const ResultCode a_resultCode;
-};
-
-}
-}
-
-
-#endif
-
+++ /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_dbms_Date_hpp
-#define anna_dbms_Date_hpp
-
-#include <time.h>
-
-#include <anna/config/defines.hpp>
-#include <anna/core/RuntimeException.hpp>
-
-#include <anna/dbms/Data.hpp>
-
-namespace anna {
-
-namespace dbms {
-
-/**
- Tipo de datos que permite trabajar con el tipo de dato 'Date' de un gestor de base de
- datos generico.
-
- Dependiendo el gestor de base de datos usado el tipo \em date puede contener informacion que incluya
- la hora del día, en Oracle (tm) la incluye, mientras que en mysql, por ejemplo, no la incluye.
-
- Internamente trabaja con una estructura de tipo 'tm' que habitualmente tendrá los campos:
- \code
- struct tm {
- int tm_sec; // Seconds. [0-60] (1 leap second)
- int tm_min; // Minutes. [0-59]
- int tm_hour; // Hours. [0-23]
- int tm_mday; // Day. [1-31]
- int tm_mon; // Month. [0-11]
- int tm_year; // Year - 1900.
- int tm_wday; // Day of week. [0-6]
- int tm_yday; // Days in year.[0-365]
- int tm_isdst; // DST. [-1/0/1]
- };
- \endcode
-*/
-class Date : public Data {
-public:
- /**
- * Espacio maximo reservado para representar lo datos de una fecha sobre una cadena.
- */
- static const int MaxDateSize = 48;
-
- /**
- Constructor.
- \param isNulleable Indica si el dato puede tomar valores nulos.
- \param format Formato usado para interpretar los datos de esta fecha, en los metodos Date::getCStringValue y
- Date::setValue (const char*) y Date::setValue (const std::string&). Sigue la especificacion:
-
- \code
- %a Replaced by the localeâs abbreviated weekday name. [ tm_wday]
-
- %A Replaced by the localeâs full weekday name. [ tm_wday]
-
- %b Replaced by the localeâs abbreviated month name. [ tm_mon]
-
- %B Replaced by the localeâs full month name. [ tm_mon]
-
- %c Replaced by the localeâs appropriate date and time representation. (See the Base Definitions volume of
- IEEE Std 1003.1-2001, <time.h>.)
-
- %C Replaced by the year divided by 100 and truncated to an integer, as a decimal number [00,99]. [ tm_year]
-
- %d Replaced by the day of the month as a decimal number [01,31]. [ tm_mday]
-
- %D Equivalent to %m / %d / %y . [ tm_mon, tm_mday, tm_year]
-
- %e Replaced by the day of the month as a decimal number [1,31]; a single digit is preceded by a space. [
- tm_mday]
-
- %F Equivalent to %Y - %m - %d (the ISO 8601:2000 standard date format). [ tm_year, tm_mon, tm_mday]
-
- %g Replaced by the last 2 digits of the week-based year (see below) as a decimal number [00,99]. [ tm_year,
- tm_wday, tm_yday]
-
- %G Replaced by the week-based year (see below) as a decimal number (for example, 1977). [ tm_year, tm_wday,
- tm_yday]
-
- %h Equivalent to %b . [ tm_mon]
-
- %H Replaced by the hour (24-hour clock) as a decimal number [00,23]. [ tm_hour]
-
- %I Replaced by the hour (12-hour clock) as a decimal number [01,12]. [ tm_hour]
-
- %j Replaced by the day of the year as a decimal number [001,366]. [ tm_yday]
-
- %m Replaced by the month as a decimal number [01,12]. [ tm_mon]
-
- %M Replaced by the minute as a decimal number [00,59]. [ tm_min]
-
- %n Replaced by a <newline>.
-
- %p Replaced by the localeâs equivalent of either a.m. or p.m. [ tm_hour]
-
- %r Replaced by the time in a.m. and p.m. notation; in the POSIX locale this shall be equivalent to %I : %M
- : %S %p . [ tm_hour, tm_min, tm_sec]
-
- %R Replaced by the time in 24-hour notation ( %H : %M ). [ tm_hour, tm_min]
-
- %S Replaced by the second as a decimal number [00,60]. [ tm_sec]
-
- %t Replaced by a <tab>.
-
- %T Replaced by the time ( %H : %M : %S ). [ tm_hour, tm_min, tm_sec]
-
- %u Replaced by the weekday as a decimal number [1,7], with 1 representing Monday. [ tm_wday]
-
- %U Replaced by the week number of the year as a decimal number [00,53]. The first Sunday of January is the
- first day of week 1; days in the new year before this are in week 0. [ tm_year, tm_wday, tm_yday]
-
- %V Replaced by the week number of the year (Monday as the first day of the week) as a decimal number [01,53].
- If the week containing 1 January has four or more days in the new year, then it is considered week 1. Oth-
- erwise, it is the last week of the previous year, and the next week is week 1. Both January 4th and the
- first Thursday of January are always in week 1. [ tm_year, tm_wday, tm_yday]
-
- %w Replaced by the weekday as a decimal number [0,6], with 0 representing Sunday. [ tm_wday]
-
- %W Replaced by the week number of the year as a decimal number [00,53]. The first Monday of January is the
- first day of week 1; days in the new year before this are in week 0. [ tm_year, tm_wday, tm_yday]
-
- %x Replaced by the localeâs appropriate date representation. (See the Base Definitions volume of
- IEEE Std 1003.1-2001, <time.h>.)
-
- %X Replaced by the localeâs appropriate time representation. (See the Base Definitions volume of
- IEEE Std 1003.1-2001, <time.h>.)
-
- %y Replaced by the last two digits of the year as a decimal number [00,99]. [ tm_year]
-
- %Y Replaced by the year as a decimal number (for example, 1997). [ tm_year]
-
- %z Replaced by the offset from UTC in the ISO 8601:2000 standard format ( +hhmm or -hhmm ), or by no charac-
- ters if no timezone is determinable. For example, "-0430" means 4 hours 30 minutes behind UTC (west of
- Greenwich). If tm_isdst is zero, the standard time offset is used. If tm_isdst is greater than zero, the
- daylight savings time offset is used. If tm_isdst is negative, no characters are returned. [ tm_isdst]
-
- %Z Replaced by the timezone name or abbreviation, or by no bytes if no timezone information exists. [
- tm_isdst]
-
- %% Replaced by % .
- \endcode
-
- Para obtener más informacion sobre la espeficacion de formato \em man \em strftime (p.e.).
- */
- explicit Date(const bool isNulleable = false, const char* format = NULL) ;
-
- /**
- Constructor copia.
- \param other Instancia de la que copiar.
- */
- Date(const Date& other);
-
- /**
- Destructor.
- */
- virtual ~Date();
-
- /**
- Devuelve el contenido de esta fecha.
- \return El contenido de esta fecha.
- \warning Si el metodo Data::isNull devolvio \em true el contenido de la estructura no esta definido.
- */
- const tm& getValue() const throw() { return a_value; }
-
- /**
- Devuelve el contenido de esta fecha.
- \return El contenido de esta fecha.
- \warning Si el metodo Data::isNull devolvio \em true el contenido de la estructura no esta definido.
- */
- tm& getValue() throw() { return a_value; }
-
- /**
- * Interpreta el contenido de la fecha y lo transfiere al buffer.
- * \return El buffer que contiene esta fecha interpretada con el formato indicado en el contructor.
- * \warning El resultado sera NULL en caso de no poder interpretar correctamente la fecha.
- */
- virtual const char* getCStringValue() const throw();
-
- /**
- * Interpreta el contenido de esta fecha como el numero de segundos transcurridos desde el 1 de Enero de 1970.
- * Si el contenido de la columna sociada es nulo este metodo devolvera 0. Si la conversion a segundos no puede
- * ser realizada devolvera -1.
- * \return Interpreta el contenido de esta fecha como el numero de segundos transcurridos desde el 1 de Enero de 1970.
- * Si el contenido de la columna sociada es nulo este metodo devolvera 0. Si la conversion a
- * segundos no puede ser realizada devolvera -1.
- */
- Second getSecondValue() const throw() { return Second((Data::isNull() == true) ? 0 : mktime(&const_cast <Date*>(this)->a_value)); }
-
- /**
- * Devuelve el formato indicado en el constructor de la clase.
- * \return El formato indicado en el constructor de la clase.
- */
- const char* getFormat() const throw() { return a_format; }
-
- /**
- * Devuelve el año contenido por esta fecha.
- * \return El año contenido por esta fecha.
- */
- int getYear() const throw() { return a_value.tm_year + 1900; }
-
- /**
- * Devuelve el mes contenido por esta fecha.
- * \return El mes contenido por esta fecha.
- */
- int getMonth() const throw() { return a_value.tm_mon + 1; }
-
- /**
- * Devuelve el dia del mes contenido por esta fecha.
- * \return El dia del mes contenido por esta fecha.
- */
- int getDay() const throw() { return a_value.tm_mday; }
-
- /**
- * Devuelve la hora del dia contenida en la fecha.
- * \return La hora del dia contenida en la fecha.
- * \warning Verifique que el tipo 'Date' de su RDBMS es capaz de contener horas, minutos y segundos.
- */
- int getHour() const throw() { return a_value.tm_hour; }
-
- /**
- * Devuelve el minuto de la hora contenida en la fecha.
- * \return El minuto de la hora contenida en la fecha.
- * \warning Verifique que el tipo 'Date' de su RDBMS es capaz de contener horas, minutos y segundos.
- */
- int getMinute() const throw() { return a_value.tm_min; }
-
- /**
- * Devuelve el segundo de la hora contenida en la fecha.
- * \return El segundo de la hora contenida en la fecha.
- * \warning Verifique que el tipo 'Date' de su RDBMS es capaz de contener horas, minutos y segundos.
- */
- int getSecond() const throw() { return a_value.tm_sec; }
-
- /**
- * Establece el año de esta fecha
- * \param year Año de la fecha. Debe ser mayor de 1900.
- */
- void setYear(const int year) throw(RuntimeException) { set("Year", a_value.tm_year, year - 1900, 0, -1); }
-
- /**
- * Establece mes de esta fecha.
- * \param month Mes de la fecha. Debe estar comprendido entre 1 y 12.
- */
- void setMonth(const int month) throw(RuntimeException) { set("Month", a_value.tm_mon, month - 1, 0, 11); }
-
- /**
- * Establece el dia del mes de esta fecha.
- * \param day Dia del mes. Debe estar comprendido entre 1 y 31.
- */
- void setDay(const int day) throw(RuntimeException) { set("Day", a_value.tm_mday, day, 1, 31); }
-
- /**
- * Establece la hora de esta fecha.
- * \param hour Hora del dia. Debe estar comprendida entre 0 y 23.
- * \warning Verifique que el tipo 'Date' de su RDBMS es capaz de contener horas, minutos y segundos.
- */
- void setHour(const int hour) throw(RuntimeException) { set("Hour", a_value.tm_hour, hour, 0, 23); }
-
- /**
- * Establece el minuto de esta fecha.
- * \param minute Minuto de la hora del dia. Debe estar comprendida entre 0 y 59.
- * \warning Verifique que el tipo 'Date' de su RDBMS es capaz de contener horas, minutos y segundos.
- */
- void setMinute(const int minute) throw(RuntimeException) { set("Minute", a_value.tm_min, minute, 0, 59); }
-
- /**
- * Establece el segundo de esta fecha.
- * \param second Segungo de la hora del dia. Debe estar comprendida entre 0 y 60.
- * \warning Verifique que el tipo 'Date' de su RDBMS es capaz de contener horas, minutos y segundos.
- */
- void setSecond(const int second) throw(RuntimeException) { set("Second", a_value.tm_sec, second, 0, 60); }
-
- /**
- Interpreta la cadena recibida segun el formato indicado en el constructor y la asigna a esta instancia, pero requiere que al
- invocar al constructor de esta fecha se indique el formato usado para traducir.
- \param str Cadena de la que copiar.
- */
- void setValue(const char* str) throw(RuntimeException);
-
- /**
- Interpreta la cadena recibida segun el formato indicado en el constructor y la asigna a esta instancia, pero requiere que al
- invocar al constructor de esta fecha se indique el formato usado para traducir.
- \param str Cadena de la que copiar.
- */
- void setValue(const std::string& str) throw(RuntimeException) { setValue(str.c_str()); }
-
- /**
- * Establece esta fecha con los segundos transcurridos desde el 1/1/1970.
- * \param second Numeros de segundos transcurridos desde el 1 de Enero de 1970.
- * \see anna::functions::second
- */
- void setValue(const Second &second) throw(RuntimeException);
-
- /**
- Operador de copia.
- \param date Fecha de la que copiar.
- \return La instancia de esta fecha.
- \warning Solo copia el contenido de la fecha recibida, no cambia el formato de interpretacion de la fecha origen.
- */
- Date& operator = (const Date& date) throw(RuntimeException);
-
- /**
- Devuelve una cadena con la informacion referente a esta instancia.
- \return Una cadena con la informacion referente a esta instancia.
- */
- virtual std::string asString() const throw();
-
-protected:
- char* a_format;
- tm a_value;
- char a_buffer [MaxDateSize + 1];
-
- /**
- * Constructor invocado desde el constructor de TimeStamp.
- \param type Sera Data::Type::TimeStamp.
- \param isNulleable Indica si el dato puede tomar valores nulos.
- \param format Formato usado para representar los datos de esta fecha.
- */
- explicit Date(const Type::_v type, const bool isNulleable, const char* format);
-
-private:
- void set(const char* what, int& variable, const int value, const int min, const int max) throw(RuntimeException);
- void do_clear() throw() { anna_memset(&a_value, 0, sizeof(a_value)); }
-};
-
-}
-}
-
-#endif
-
+++ /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_dbms_Delivery_hpp
-#define anna_dbms_Delivery_hpp
-
-#include <anna/comm/Delivery.hpp>
-
-namespace anna {
-
-namespace dbms {
-
-class Connection;
-
-/**
- Agrupacion logica de conexiones con la base de datos. Reparte la carga de las transacciones contra
- la base de datos entre las distintas conexiones que contenga esta instancia. Ademas en caso de estar
- en una ejecucion con soporte para multithread (ver anna::functions::supportMultithread) asegura
- que cada uno de los threads siempre utiliza la misma conexion lo cual asegura el mantinimiento de la
- integridad de cada una de las transacciones de los threads.
-*/
-class Delivery : comm::Delivery {
-public:
- /**
- Constructor.
- @param name Nombre logico de este grupo de conexiones.
- */
- Delivery(const char *name) : comm::Delivery(name) {;}
-
- /**
- Crea automaticamente las conexiones a la base de datos recibida como parametro con el usuario/password
- indicado.
- \param database Instancia de la base de datos contra la que realizamos la conexion.
- \param prefixName Prefijo del nombre logico de la conexiones que vamos a crear. El resto del nombre vendra
- dado por el numero secuencial de la conexion.
- \param user Nombre del usuario con el que realizamos la conexion.
- \param password Codigo de acceso del usuario.
- \param n Numero de conexion a crear.
- \warning Recordar que el numero maximo de conexiones a una base de datos esta limitado por Database::maxConnection.
- */
- void createConnections(Database& database, const char* prefixName, const char* user, const char* password, const int n)
- throw(RuntimeException, DatabaseException);
-
- /**
- Incorpora al conexion recibida como parametro a la agrupacion logica.
- \param connection Conexion que vamos a incorporar a la agrupacion logica.
- */
- void addConnection(Connection* connection) throw(RuntimeException) {
- this->add(connection);
- a_iiConnection = this->begin();
- }
-
- /**
- Devuelve la instancia de la conexion a base de datos con la que debemos trabajar.
- @return la instancia de la conexion a base de datos con la que debemos trabajar.
- \warning La conexion debe ser bloqueada por el Thread que la recibe (ver anna::Guard) para asegurar que
- cualquier otro thread que intente acceder a ella queda bloqueado a la espera de que terminemos de
- trabajar sobre ella.
- */
- Connection& getConnection() throw(RuntimeException);
-
-private:
- iterator a_iiConnection;
-
- void do_initialize() throw() { a_iiConnection = begin(); }
- comm::Resource* do_apply() throw(RuntimeException);
- static Connection* connection(iterator& ii) { return (Connection*) comm::Delivery::resource(ii); }
-
-};
-
-}
-}
-
-#endif
+++ /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_dbms_FailRecoveryHandler_hpp
-#define anna_dbms_FailRecoveryHandler_hpp
-
-namespace anna {
-
-namespace dbms {
-
-class Database;
-class Connection;
-
-/**
- Interfaz que deben cumplir los manejadores que reciben la notificacion de que no ha sido posible
- restaurar una determina conexion con la base de datos.
-*/
-class FailRecoveryHandler {
-protected:
- /**
- Este metodo debe ser reimplementado para describir las operaciones que vamos a realizar en caso
- de no poder recuperar la conexion recibida como parametro.
- \param connection Instancia de la conexion en la que hemos detectado el fallo.
- \param tryCounter Numero de intentos de recuperacion de la conexion.
-
- \warning Este metodo se invocara automaticamente desde anna::dbms::Database::recover.
- */
- virtual void apply(Connection& connection, const int tryCounter) throw(RuntimeException) = 0;
-
- friend class Database;
-};
-
-}
-}
-
-#endif
-
-
-
+++ /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_dbms_Float_hpp
-#define anna_dbms_Float_hpp
-
-#include <anna/core/RuntimeException.hpp>
-
-#include <anna/dbms/Data.hpp>
-
-namespace anna {
-
-namespace dbms {
-
-/**
- Numero en coma flotante usado como entrada y/o salida de las sentencias SQL.
-*/
-class Float : public Data {
-public:
- /**
- Constructor.
- \param isNulleable Indica si el dato puede tomar valores nulos.
- \para format Indica el indicador de formato para pasar de cadena a numero. Usa la misma nomenclatura
- que printf, scanf, etc. Su uso dependerá del gestor de base de datos usado.
- */
- explicit Float(const bool isNulleable = false, const char* format = "%f") :
- Data(Type::Float, sizeof(float), isNulleable),
- a_format(format),
- a_value(0.0) {
- Data::setBuffer(&a_value);
- }
-
- /**
- Constructor copia.
- \param other Instancia de la que copiar.
- */
- Float(const Float& other) : Data(other), a_value(other.a_value), a_format(other.a_format) {
- Data::setBuffer(&a_value);
- }
-
- /**
- * Metodo obsoleto, debería usar #getValue.
- Devuelve el contenido del campo de tipo Float.
- \return el contenido del campo de tipo Float.
- \warning Si el metodo Data::isNull devolvio \em true el resultado de este metodo no esta definido.
- */
- //float getFloatValue () const throw () { return getValue (); }
-
- /**
- * Devuelve el valor asociado a este campo.
- * \return Devuelve el valor asociado a este campo.
- */
- float getValue() const throw() { return a_value; }
-
- /**
- * Devuelve el formato que indica la forma en la que el número será representado sobre
- * una cadena, en caso de que fuera necesario.
- */
- const char* getFormat() const throw() { return a_format; }
-
- /**
- Operador de copia.
- \param other Float del que copiar.
- \return La instancia de esta cadena.
- */
- Float& operator = (const Float& other) throw(RuntimeException) {
- if(this != &other) {
- setNull(other.isNull());
- a_value = other.a_value;
- }
-
- return *this;
- }
-
- /**
- Operador de asignacion.
- \param value Float del que copiar.
- \return La instancia de esta cadena.
- */
- Float& operator = (const float value) throw(RuntimeException) {
- a_value = value;
- setNull(false);
- return *this;
- }
-
- /**
- Operador de conversion.
- \warning Si la columna asociada tiene un valor NULL, devolvera 0.0.
- \return El contenido de esta cadena.
- */
- operator float() const throw() { return getValue(); }
-
- /**
- Devuelve una cadena con la informacion referente a esta instancia.
- \return Una cadena con la informacion referente a esta instancia.
- */
- std::string asString() const throw();
-
-private:
- float a_value;
- const char* a_format;
-
- void do_clear() throw() { a_value = 0.0; }
-};
-
-}
-}
-
-#endif
-
+++ /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_dbms_InputBind_hpp
-#define anna_dbms_InputBind_hpp
-
-#include <anna/dbms/Bind.hpp>
-
-namespace anna {
-
-namespace dbms {
-
-class InputBind : public Bind {
-protected:
- InputBind(const char* name, dbms::Data& value) : Bind(name, value) {;}
-
-private:
- // Éste metodo no sera invocado nunca. A partir de un Input nunca hay que
- // convertir de C++ -> RDBMS
- void decode() const throw(RuntimeException) {;}
-};
-
-}
-}
-
-#endif
-
+++ /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_dbms_Integer_hpp
-#define anna_dbms_Integer_hpp
-
-#include <anna/dbms/Data.hpp>
-
-namespace anna {
-
-namespace dbms {
-
-/**
- Cadena usada como entrada y/o salida de las sentencias SQL.
-*/
-class Integer : public Data {
-public:
- /**
- Constructor.
- \param isNulleable Indica si el dato puede tomar valores nulos
- */
- explicit Integer(const bool isNulleable = false) :
- Data(Type::Integer, sizeof(int), isNulleable),
- a_value(0) {
- Data::setBuffer(&a_value);
- }
-
- /**
- Constructor copia.
- \param other Instancia de la que copiar.
- */
- Integer(const Integer& other) :
- Data(other),
- a_value(other.a_value) {
- Data::setBuffer(&a_value);
- }
-
- /**
- Devuelve el valor entero asociado a esta instancia.
- \return El valor entero asociado a esta instancia.
- */
- int getValue() const throw() { return a_value; }
-
- /**
- Operador de asignacin entero.
- \param i Valor entero a asignar.
- \return La referencia a esta instancia.
- */
- Integer& operator = (const int i)
- throw() {
- a_value = i;
- Data::setNull(false);
- return *this;
- }
-
- /**
- Operador copia.
- \param other Instancia de la que copiar.
- \return La referencia a esta instancia.
- */
- Integer& operator = (const Integer& other)
- throw() {
- if(this != &other) {
- setNull(other.isNull());
- a_value = other.a_value;
- }
-
- return *this;
- }
-
- /**
- Operador de conversion.
- \return El valor entero asociado a esta instancia.
- */
- operator int () const throw() { return a_value; }
-
- /**
- Devuelve una cadena con la informacion referente a esta instancia.
- @return Una cadena con la informacion referente a esta instancia.
- */
- std::string asString() const throw();
-
-private:
- int a_value;
-
- void do_clear() throw() { a_value = 0; }
-};
-
-}
-}
-
-#endif
-
+++ /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_dbms_LongBlock_hpp
-#define anna_dbms_LongBlock_hpp
-
-#include <string>
-
-#include <anna/core/RuntimeException.hpp>
-#include <anna/core/DataBlock.hpp>
-
-#include <anna/dbms/Data.hpp>
-
-namespace anna {
-
-namespace dbms {
-
-/**
- Bloque de datos usado como entrada y/o salida de las sentencias SQL.
-
- A diferencia del tipo de datos ShortBlock, en principio, no tiene ninguna limitacion
- en cuanto a la longitud del campo que vamos a tratar. Por contra, dependiendo del motor
- de base de datos que vayamos a usar puede tener un tratamiento especial a la hora de
- grabarlo en la base de datos.
-
- \see ShortBlock
-*/
-class LongBlock : public Data {
-public:
- /**
- Constructor.
- \param isNulleable Indica si el dato puede tomar valores nulos.
- */
- explicit LongBlock(const bool isNulleable = false) :
- Data(Type::LongBlock, 0, isNulleable),
- a_value(true) {
- Data::setBuffer((void*) NULL);
- }
-
- /**
- Constructor copia.
- \param other Instancia de la que copiar.
- */
- LongBlock(const LongBlock& other) :
- Data(other),
- a_value(true) {
- a_value = other.a_value;
- }
-
- /**
- Destructor.
- */
- virtual ~LongBlock() {;}
-
- /**
- Devuelve el tamao actual de este dato.
- \return El tamao actual de este dato.
- */
- int getSize() const throw() { return a_value.getSize(); }
-
- /**
- Devuelve el contenido de la este bloque de memoria.
- \return Devuelve el contenido de la este bloque de memoria.
- \warning Si el metodo Data::isNull devolvio \em true el resultado de este metodo no esta definido.
- */
- const anna::DataBlock& getValue() const throw() { return a_value; }
-
- /**
- Devuelve el contenido de la este bloque de memoria.
- \return Devuelve el contenido de la este bloque de memoria.
- \warning Si el metodo Data::isNull devolvio \em true el resultado de este metodo no esta definido.
- */
- anna::DataBlock& getValue() throw() { return a_value; }
-
- /**
- Operador de asignacin.
- \param other Bloque del que copiar.
- \return La instancia de este bloque de memoria.
- */
- LongBlock& operator = (const LongBlock& other) throw(RuntimeException);
-
- /**
- Operador de asignacin.
- \param value Valor que queremos a asignar.
- \return La instancia de esta cadena.
- */
- LongBlock& operator = (const anna::DataBlock& value) throw(RuntimeException);
-
- /**
- Operador de conversion.
- \return El anna::DataBlock asociado a esta instancia.
- */
- operator anna::DataBlock& () throw() { return a_value; }
-
- /**
- Operador de conversion.
- \return El anna::DataBlock asociado a esta instancia.
- */
- operator const anna::DataBlock& () const throw() { return a_value; }
-
- /**
- Devuelve una cadena con la informacion referente a esta instancia.
- \return Una cadena con la informacion referente a esta instancia.
- */
- std::string asString() const throw();
-
-protected:
- anna::DataBlock a_value;
-
- void do_clear() throw() { a_value.clear(); }
-};
-
-}
-}
-
-#endif
-
+++ /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_dbms_OutputBind_hpp
-#define anna_dbms_OutputBind_hpp
-
-#include <anna/dbms/Bind.hpp>
-
-namespace anna {
-
-namespace dbms {
-
-class LongBlock;
-
-/**
- Clase que facilita la interconexion entre las variables del ambito C++ y el ambito RDBMS.
-
- A continuacion presentamos un ejemplo de uso detallado.
- \include db_blob.p/main.cc
-*/
-class OutputBind : public Bind {
-public:
- /**
- Graba el valor de la variable anna::dbms::LongBlock asociada a esta OutputBind. Cualquier
- modificacion que necesitemos aplicar sobre la columnna de tipo se debera hacer mediante los
- metodos ofrecidos por la clase anna::dbms::LongBlock.
-
- \warning Este metodo solo puede ser usado para variables de tipo dbms::Data::Type::LongBlock y
- siempre y cuando hayamos abierto el BLOB con una sentencia SQL de seleccion.
- */
- void write() const throw(RuntimeException, dbms::DatabaseException);
-
-protected:
- OutputBind(const char* name, dbms::Data& value) : Bind(name, value) {;}
-
-private:
- // este metodo no sera invocado nunca. A partir de un Output nunca hay que
- // convertir de C++ -> RDBMS
- void code() const throw(RuntimeException) {;}
-
- virtual void do_write(const dbms::LongBlock&) const throw(RuntimeException, dbms::DatabaseException) = 0;
-};
-
-}
-}
-
-#endif
-
+++ /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_dbms_ResultCode_hpp
-#define anna_dbms_ResultCode_hpp
-
-#include <string>
-
-#include <string.h>
-
-#include <stdlib.h>
-
-#include <anna/config/defines.hpp>
-#include <anna/core/RuntimeException.hpp>
-
-namespace anna {
-
-namespace dbms {
-
-/**
- Clase para acceder a la informacion devuelta por el gestor de base de datos
- referente al ultimo comando realizado.
- */
-class ResultCode {
-public:
- /**
- Constructor vacio.
- \warning Antes de usarse debe asignarse a algun otro ResultCode obtenido mediante la invocacion
- a anna::dbms::Connection::execute.
- */
- ResultCode() : a_errorText(NULL), a_errorDecoder(NULL), a_errorCode(0) {;}
-
- /**
- Constructor copia.
- @param other Instancia de la que copiar los datos.
- */
- ResultCode(const ResultCode& other) :
- a_errorText(NULL),
- a_errorDecoder(other.a_errorDecoder) {
- set(other.a_errorCode, other.a_errorText);
- }
-
- /**
- Destructor.
- */
- virtual ~ResultCode() { if(a_errorText != NULL) free(a_errorText); }
-
- /**
- Devuelve el codigo de error del ultimo comando ejecutado contra la base de datos.
- @return El codigo de error del ultimo comando ejecutado contra la base de datos.
- */
- int getErrorCode() const throw() { return a_errorCode; }
-
- /**
- Devuelve el texto del error del ultimo comando ejecutado contra la base de datos.
- @return El texto del error del ultimo comando ejecutado contra la base de datos.
- */
- const char* getErrorText() const throw() { return (a_errorText != NULL) ? a_errorText : ""; }
-
- // Operadores
- /**
- Operador copia.
- @param resultCode Instancia a copiar.
- @return Una instancia de si mismo.
- */
- ResultCode& operator = (const ResultCode& resultCode)
- throw() {
- if(this != &resultCode) {
- a_errorDecoder = resultCode.a_errorDecoder;
- set(resultCode.a_errorCode, resultCode.a_errorText);
- }
-
- return *this;
- }
-
- /**
- Devuelve \em true si las condiciones de busqueda de la ultimo operacion
- no han sido satisfechas por ningun registro o \em false en otro caso.
- @return \em true si las condiciones de busqueda de la ultimo operacion
- no han sido satisfechas por ningun registro o \em false en otro caso.
- */
- bool notFound() const throw(anna::RuntimeException);
-
- /**
- Devuelve \em true si la ultima operacion solicitada fue realizada correctamente
- o \em false en otro caso.
- @return \em true si la ultima operacion solicitada fue realizada correctamente
- o \em false en otro caso.
- */
- bool successful() const throw(anna::RuntimeException);
-
- /**
- Devuelve \em true Si el registro obtenenido en una sentencia de seleccion con indicador
- de modo exclusivo ha sido bloqueada previamente por otro proceso y/o contexto de base de
- datos o \em false en otro caso.
- @return \em true Si el registro obtenenido en una sentencia de seleccion con indicador
- de modo exclusivo ha sido bloqueada previamente por otro proceso y/o contexto de base de
- datos o \em false en otro caso.
- */
- bool locked() const throw(anna::RuntimeException);
-
- /**
- Devuelve \em true si se perdio la conexion la base de datos o \em false en otro caso.
- @return \em true si se perdio la conexion la base de datos o \em false en otro caso.
- */
- bool lostConnection() const throw(anna::RuntimeException);
-
- /**
- Devuelve una cadena con la informacion sobre esta clase.
- \return Una cadena con la informacion sobre esta clase.
- */
- std::string asString() const throw();
-
-protected:
- static const int MaxErrorLen = 512;
-
- /**
- Decodificador del error devuelto por el RDBMS concreto que estemos usando.
- \warning Exclusivamente uso interno.
- */
- class ErrorDecoder {
- public:
- virtual bool notFound(const int errorCode) const throw() = 0;
- virtual bool successful(const int errorCode) const throw() = 0;
- virtual bool locked(const int errorCode) const throw() = 0;
- virtual bool lostConnection(const int errorCode) const throw() = 0;
- };
-
- /**
- Constructor.
-
- \param errorCode Codigo de error asociado a la ultima operacion realizada contra la base de datos.
- \param errorText Texto asociado al error de ultima operacion realizada contra la base de datos. Puede ser
- NULL si no hay ningun texto de error asociado al codigo recibido.
- \param errorDecoder Decofidicador de errores.
- */
- ResultCode(const int errorCode, const char* errorText, const ErrorDecoder* errorDecoder) :
- a_errorText(NULL),
- a_errorDecoder(errorDecoder) {
- set(errorCode, errorText);
- }
-
- /**
- Establece el contenido de esta clase.
-
- \param errorCode Codigo de error asociado a la ultima operacion realizada contra la base de datos.
- \param errorText Texto asociado al error de ultima operacion realizada contra la base de datos.
- */
- void set(const int errorCode, const char* errorText)
- throw() {
- a_errorCode = errorCode;
- copy(errorText);
- }
-
-private:
- int a_errorCode;
- char* a_errorText;
- const ErrorDecoder* a_errorDecoder;
-
- void copy(const char* text) throw();
-};
-
-}
-}
-
-#endif
-
+++ /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_dbms_Sentence_hpp
-#define anna_dbms_Sentence_hpp
-
-#include <anna/core/mt/Mutex.hpp>
-
-#include <anna/dbms/ResultCode.hpp>
-
-namespace anna {
-
-namespace xml {
-class Node;
-}
-
-namespace dbms {
-
-class Database;
-class Connection;
-class Statement;
-
-/**
- Clase que facilita la ejecucion de sentencias SQL compuestas y la comprobacion de errores ya que
- solo devuelve excepciones de tipo anna::RuntimeException.
-*/
-class Sentence : public Mutex {
-public:
- /**
- Modos de actuar cuando se detecta un error en la ejecucion de las sentencias SQL.
- \see Sentence
- */
- struct Mode { enum _v { ExceptionWhenNotFound, SilentWhenNotFound }; };
-
- /**
- Ejecuta la sentencia SQL asociada a este instancia. Antes de invocar a este metodo debemos
- activar una seccion critica sobre esta instancia.
- \param connection Conexion usada para ejecutar la sentencia. Debe tener activa una seccion critica.
- */
- virtual dbms::ResultCode execute(dbms::Connection& connection) throw(RuntimeException) {
- return execute(connection, a_dbStatement);
- }
-
- /**
- Devuelve el nombre de la sentencia SQL asociada a esta instancia.
- \return El nombre de la sentencia SQL asociada a esta instancia.
- \warning Si todavia no tiene nombre asociado devolvera una cadena vacia.
- */
- const std::string& getName() const throw();
-
- /**
- Inicializa el estado de esta instancia
- \param database Instancia de la base de datos usada para definir las sentencias SQL que componen esta
- instancia.
- */
- void initialize(dbms::Database& database) throw(RuntimeException);
-
- /**
- Transfiere un registro desde la base de datos a las variables del entorno C++.
- \return \em false si no hay mas registros o \em true en caso contrario.
- */
- bool fetch() throw(RuntimeException);
-
- /**
- Transfiere un registro desde la base de datos a las variables del entorno C++.
- \param resultCode Variable que contiene el resultado de invocar a anna::dbms::Sentence::execute
- \return \em false si no hay mas registros o \em true en caso contrario.
- */
- bool fetch(const ResultCode& resultCode) throw(RuntimeException) {
- return (resultCode.successful() == true) ? fetch() : false;
- }
-
- /**
- Devuelve una cadena con la informacion referente a esta instancia.
- \return una cadena con la informacion referente a esta instancia.
- */
- virtual std::string asString() const throw();
-
- /**
- Devuelve un documento XML con la informacion referente a esta instancia.
- \param parent Nodo XML del que dependerá la información referente a esta instancia.
- \return un documento XML con la informacion referente a esta instancia.
- */
- virtual xml::Node* asXML(xml::Node* parent) const throw();
-
-protected:
- /**
- Constructor.
- \param mode Modo de actuacion en caso de detectar errores.
- */
- Sentence(const Mode::_v mode = Mode::ExceptionWhenNotFound) :
- a_mode(mode), a_dbStatement(NULL)
- {;}
-
- /**
- Ejecuta la sentencia SQL asociada a este instancia.
- \param connection Conexion usada para ejecutar la sentencia. Debe tener activa una seccion critica.
- \param statement Sentencia a ejecutar.
- */
- dbms::ResultCode execute(dbms::Connection& connection, dbms::Statement* statement) throw(RuntimeException);
-
- /**
- Metodo que debe inicializar las sentencias asociadas a esta instancia (valores de entrada y salida).
- \return Retorna la instancia de la sentencia asociada a esta instancia debidamente inicializada.
- */
- virtual dbms::Statement* do_initialize(dbms::Database&) throw(RuntimeException) = 0;
-
-private:
- const Mode::_v a_mode;
- dbms::Statement* a_dbStatement;
-};
-
-}
-}
-
-#endif
-
+++ /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_dbms_ShortBlock_hpp
-#define anna_dbms_ShortBlock_hpp
-
-#include <string>
-
-#include <anna/core/RuntimeException.hpp>
-#include <anna/core/DataBlock.hpp>
-
-#include <anna/dbms/Data.hpp>
-
-namespace anna {
-
-namespace dbms {
-
-/**
- Bloque de datos usado como entrada y/o salida de las sentencias SQL.
-
- La longitud del dato a tratar estara en 2048 y 4096 bytes, dependiendo
- del RDBMS concreto con el que estemos trabajando.
-
- \see LongBlock
-*/
-class ShortBlock : public Data {
-public:
- /**
-
- Constructor.
- \param maxSize Tamao maximo que puede tener este bloque.
- \param isNulleable Indica si el dato puede tomar valores nulos.
- */
- explicit ShortBlock(const int maxSize, const bool isNulleable = false) :
- Data(Type::ShortBlock, maxSize, isNulleable),
- a_value(true) {
- a_value.allocate(maxSize);
- Data::setBuffer((void*) a_value.getData());
- }
-
- /**
- Constructor copia.
- \param other Instancia de la que copiar.
- */
- ShortBlock(const ShortBlock& other) :
- Data(other),
- a_value(true) {
- a_value = other.a_value;
- Data::setBuffer((void*) a_value.getData());
- }
-
- /**
- Destructor.
- */
- virtual ~ShortBlock() {;}
-
- /**
- Devuelve el tamao actual de este dato.
- \return El tamao actual de este dato.
- */
- int getSize() const throw() { return a_value.getSize(); }
-
- /**
- Devuelve el contenido de la este bloque de memoria.
- \return Devuelve el contenido de la este bloque de memoria.
- \warning Si el metodo Data::isNull devolvio \em true el resultado de este metodo no esta definido.
- */
- const anna::DataBlock& getValue() const throw() { return a_value; }
-
- /**
- Operador de asignacin.
- \param other Bloque del que copiar.
- \return La instancia de este bloque de memoria.
- */
- ShortBlock& operator = (const ShortBlock& other) throw(RuntimeException);
-
- /**
- Operador de asignacin.
- \param value Valor que queremos a asignar.
- \return La instancia de esta cadena.
- */
- ShortBlock& operator = (const anna::DataBlock& value) throw(RuntimeException);
-
- /**
- Operador de conversion.
- \return El anna::DataBlock asociado a esta instancia.
- */
- operator anna::DataBlock& () throw() { return a_value; }
-
- /**
- Operador de conversion.
- \return El anna::DataBlock asociado a esta instancia.
- */
- operator const anna::DataBlock& () const throw() { return a_value; }
-
- /**
- Devuelve una cadena con la informacion referente a esta instancia.
- \return Una cadena con la informacion referente a esta instancia.
- */
- std::string asString() const throw();
-
-protected:
- anna::DataBlock a_value;
-};
-
-}
-}
-
-#endif
-
+++ /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_dbms_Statement_hpp
-#define anna_dbms_Statement_hpp
-
-#include <vector>
-
-#include <anna/core/RuntimeException.hpp>
-#include <anna/core/mt/Mutex.hpp>
-#include <anna/core/util/Average.hpp>
-#include <anna/core/util/Microsecond.hpp>
-
-#include <anna/dbms/DatabaseException.hpp>
-#include <anna/dbms/ResultCode.hpp>
-
-namespace anna {
-
-namespace xml {
-class Node;
-}
-
-namespace dbms {
-
-class Database;
-class Connection;
-class InputBind;
-class OutputBind;
-class Data;
-
-/**
- Clase que facilita la ejecucion de sentencias SQL.
-
- Para obtener la instancia de un comando para una determinada base de datos habra que instanciar
- dicha base de datos e invocar al metodo Database::createStatement. Independientemente del tipo de comando
- particular que la base de datos retorne, debemos asignarlo a un puntero de tipo anna::dbms::Statement.
-*/
-class Statement : public Mutex {
-public:
- typedef std::vector <InputBind*>::iterator input_iterator;
- typedef std::vector <OutputBind*>::iterator output_iterator;
-
- /**
- Destructor.
- */
- virtual ~Statement();
-
- /**
- Devuelve el nombre logico de esta sentencia.
- \return El nombre logico de esta sentencia.
- */
- const std::string& getName() const throw() { return a_name; }
-
- /**
- Devuelve la expresion SQL recibida en el constructor.
- \return La expresion SQL recibida en el constructor.
- */
- const std::string& getExpression() const throw() { return a_expression; }
-
- /**
- Devuelve el indicador de criticidad, si vale \em true indica que si la ejecucion de esta sentencia
- falla al desbloquear la conexion con la que ejecutamos esta sentencia se invocara a
- Connection::rollback, en otro caso aunque falle se invocara a Connection::commit.
- Solo aplicara en sentencias que no sean de seleccion.
- \return El indicador de criticidad de esta sentencia.
- */
- bool isCritical() const throw() { return a_isCritical; }
-
- /**
- Devuelve la instancia de la base de datos asociada a esta sentencia.
- \return La instancia de la base de datos asociada a la sentencia.
- */
- Database& getDatabase() const throw() { return a_database; }
-
- /**
- Establece el parametro de entrada de la sentencia SQL.Cada una de las variables de entrada indicadas
- en esta sentencia SQL deberia tener un parametro de entrada asociado. La correspondencia entre esta
- variable y la sentencia SQL vendra dada por el orden de aparacion en la sentencia SQL y por el orden
- de definicion del parametro.
-
- Por ejemplo la sentencia:
-
- \code
- update tabla1 set xx = :unavariable where yy = :otravariable;
- \endcode
-
- Cada una de las variables \em unavariable y \em otravariable debera tener asociado una variable de entrada.
- Primero debemos indicaremos la correspondiente a \em unavariable y luego la correspondiente a \em otravariable.
-
- \param name Nombre logico de esta variable. No tiene porque tener ninguna correspondencia con el nombre
- de la columna.
- \param data Variable que deseamos asociar como variable de entrada. La correspondencia entre esta
- y la sentencia SQL vendra dada por el orden de declaracion.
- */
- void bindInput(const char* name, Data& data) throw();
-
- /**
- Establece el parametro de salida de la sentencia SQL.Cada una de las variables de salida indicadas
- en esta sentencia SQL deberia tener un parametro de salida asociado. La correspondencia entre esta
- variable y la sentencia SQL vendra dada por el orden de aparacion en la sentencia SQL y por el orden
- de definicion del parametro.
-
- Por ejemplo la sentencia:
-
- \code
- select xx, yy from tabla1 where zz = :unavariable;
- \endcode
-
- Cada una de las variables \em xx e \em yy debera tener asociado una variable de salida.
- Ademas la variable \em unavaraible debera tener asociada una variable de entrada.
-
- \param name Nombre logico de esta variable. No tiene porque tener ninguna correspondencia con el nombre
- de la columna.
- \param data Variable que deseamos asociar como variable de salida. La correspondencia entre esta
- y la sentencia SQL vendra dada por el orden de declaracion.
-
- \return La instancia del dbms::OutputBind asociado al dato. nos permite
- grabar el contenido de los tipos de datos BLOB.
-
- \warning Solo las sentencias SQL del tipo \em select usan las variables de salida.
- */
- const dbms::OutputBind* bindOutput(const char* name, Data& data) throw();
-
- /**
- Establece el valor del indicador que activa/desactiva la necesidad de invocar al
- \em commit y/o \em rollback despues de ejecutar esta sentencia.
- */
- void setRequiresCommit(const bool requiresCommit) throw() { a_requiresCommit = requiresCommit; }
-
- /**
- Devuelve \em true si la sentencia requiere la invocacion a \em commit o \em rollback
- tras su ejecucion. Puede devolver \em true por tratarse de una sentencia que no tiene variables
- de salida (insert, update o delete) o bien porque se haya activado el indicador correspondiente
- mediante la llamada #setRequiresCommit
- */
- bool requiresCommit() const throw() { return (a_requiresCommit == true) || (a_outputBinds.empty() == true); }
-
- /**
- Devuelve el iterador que apunta a la primera variable de entrada.
- \return el iterador que apunta a la primera variable de entrada.
- */
- input_iterator input_begin() throw() { return a_inputBinds.begin(); }
-
- /**
- Devuelve el iterador que apunta a la primera variable de entrada.
- \return el iterador que apunta a la primera variable de entrada.
- */
- input_iterator input_end() throw() { return a_inputBinds.end(); }
-
- /**
- Devuelve el numero de variables de entrada asociado a esta sentencia SQL.
- \return el numero de variables de entrada asociado a esta sentencia SQL.
- */
- int input_size() const throw() { return a_inputBinds.size(); }
-
- /**
- Devuelve el iterador que apunta a la primera variable de salida.
- \return el iterador que apunta a la primera variable de salida.
- */
- output_iterator output_begin() throw() { return a_outputBinds.begin(); }
-
- /**
- Devuelve el iterador que apunta a la primera variable de salida.
- \return el iterador que apunta a la primera variable de salida.
- */
- output_iterator output_end() throw() { return a_outputBinds.end(); }
-
- /**
- Devuelve el numero de variables de entrada asociado a esta sentencia SQL.
- \return el numero de variables de entrada asociado a esta sentencia SQL.
- */
- int output_size() const throw() { return a_outputBinds.size(); }
-
- /**
- Devuelve un documento XML con la informacion referente a esta instancia.
- \param parent Nodo XML del que debe colgar la informacion.
- @return un documento XML con la informacion referente a esta instancia.
- */
- virtual xml::Node* asXML(xml::Node* parent) const throw();
-
- /**
- Devuelve una cadena con la informacion referente a esta instancia.
- @return Una cadena con la informacion referente a esta instancia.
- */
- virtual std::string asString() const throw();
-
- /**
- Transfiere la informacion de una fila de la sentencia SQL de seleccion a las
- variables de salida asociadas a la sentencia.
-
- \return \em true si el registro ha sido transferido a las variables de salida o \em false si habiamos llegado
- al ultimo registro de la seleccion.
- */
- virtual bool fetch() throw(RuntimeException, DatabaseException) = 0;
-
- /**
- Devuelve la variable de entrada apuntada por el iterador recibido como parametro.
- \return la variable de entrada apuntada por el iterador recibido como parametro.
- */
- static Data& input(input_iterator& ii) throw();
-
- /**
- Devuelve la variable de salida apuntada por el iterador recibido como parametro.
- \return la variable de salida apuntada por el iterador recibido como parametro.
- */
- static Data& output(output_iterator& ii) throw();
-
-protected:
- /**
- Contructor.
-
- \param database Base de datos sobre la que se define la sentencia.
- \param name Nombre logico de la sentencia.
- \param expression Sentencia SQL asociada a esta clase.
- \param isCritical Si vale \em true indica que si la ejecucion de esta sentencia falla al desbloquear
- la conexion con la que ejecutamos esta sentencia se invocara a Connection::rollback, en otro caso
- aunque falle se invocara a Connection::commit. Solo aplicara en sentencias que no sean de seleccion.
- */
- Statement(Database& database, const char* name, const char* expression, const bool isCritical) :
- a_database(database),
- a_name(name),
- a_expression(expression),
- a_prepared(false),
- a_isCritical(isCritical),
- a_measureTiming("Timing", "us"),
- a_requiresCommit(false) {
- }
-
- /**
- Contructor.
-
- \param database Base de datos sobre la que se define la sentencia.
- \param name Nombre logico de la sentencia.
- \param expression Sentencia SQL asociada a esta clase.
- \param isCritical Si vale \em true indica que si la ejecucion de esta sentencia falla al desbloquear
- la conexion con la que ejecutamos esta sentencia se invocara a Connection::rollback, en otro caso
- aunque falle se invocara a Connection::commit. Solo aplicara en cuenta en sentencias que no
- sean de seleccion.
- */
- Statement(Database& database, const char* name, const std::string& expression, const bool isCritical) :
- a_database(database),
- a_name(name),
- a_expression(expression),
- a_prepared(false),
- a_isCritical(isCritical),
- a_measureTiming("Timing", "us"),
- a_requiresCommit(false) {
- }
-
- /**
- Devuelve la referencia de entrada apuntada por el iterador recibido como parametro.
- \return la referencia de entrada apuntada por el iterador recibido como parametro.
- */
- static InputBind* inputBind(input_iterator& ii) throw() { return *ii; }
-
- /**
- Devuelve la referencia de salida apuntada por el iterador recibido como parametro.
- \return la referencia de salida apuntada por el iterador recibido como parametro.
- */
- static OutputBind* outputBind(output_iterator& ii) throw() { return *ii; }
-
-private:
- Database& a_database;
- const std::string a_name;
- std::string a_expression;
- std::vector <InputBind*> a_inputBinds; /**< Lista de variables de entrada */
- std::vector <OutputBind*> a_outputBinds; /**< Lista de variables de salida */
- bool a_prepared;
- const bool a_isCritical;
- Average <Microsecond> a_measureTiming;
- bool a_requiresCommit;
-
- Statement(const Statement&);
- void measureTiming(const Microsecond & init, const Microsecond & end) throw() { a_measureTiming += (end - init); }
-
- virtual void prepare(Connection* connection) throw(RuntimeException, DatabaseException) = 0;
- virtual ResultCode execute(Connection* connection) throw(RuntimeException, DatabaseException) = 0;
-
- friend class Connection;
- friend class Database;
-};
-
-}
-}
-
-#endif
+++ /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_dbms_StatementTranslator_hpp
-#define anna_dbms_StatementTranslator_hpp
-
-#include <anna/core/RuntimeException.hpp>
-
-namespace anna {
-
-namespace dbms {
-
-class Database;
-
-/**
- * Clase que ajustar de forma transparente las diferencias de tratamiento que tiene las
- * sentencias SQL en los distintos motores de base de datos. De esta forma una aplicación
- * originariamente escrita para un determinado RDBMS no tendrá que hacer ningún cambio
- * en las sentencias SQL al cambiar a otro RDBMS.
- *
- * Por ejemplo para indicar los parámetros de entrada en Oracle se indica con un
- * literal precedido de ':' o '&'. Con lo que la sentencia podría quedar como:
- * \code
- * insert into foo (field1, field2) values (:f1, :f2)
- * \endcode
- *
- * En PosgreSQL (tambien sorpotado en Oracle) quedaría algo así:
- * \code
- * insert into foo (field1, field2) values (&f1, &f2)
- * \endcode
- *
- * Mientras que en MySQL la expresión debería ser como:
- * \code
- * insert into foo (field1, field2) values (?, ?);
- * \endcode
- *
- * \see anna::dbms::Database::setStatementTranslator
- */
-class StatementTranslator {
- /**
- * Devuelve el nombre lógico de este traductor.
- * \return el nombre lógico de este traductor.
- */
- const char* getName() const throw() { return a_name; }
-
-protected:
- /**
- * Constructor.
- * \param name Nombre lógico del traductor.
- */
- explicit StatementTranslator(const char* name) : a_name(name) {;}
-
- /**
- * Se invoca automáticamente desde anna::dbms::Database::createStatement si la
- * instancia de la base de datos tiene asociada alguna instancia heredada de esta clase.
- *
- * Ã\89ste metodo sólo se invoca una vez para cada una de las sentencias definidas sobre
- * la base de datos, por lo que la traducción de sentencias SQL tiene un consumo despreciable
- * con respecto al tiempo total del proceso.
- *
- * \param statement Sentencia SQL original.
- * \return La sentencia SQL correspondiente con la original, pero tratada para que
- * pueda ser interpretada correctamente por el motor de base de datos sobre el que
- * se va a ejecutar.
- */
- virtual const char* apply(const char* statement) throw(RuntimeException) = 0;
-
-private:
- const char* a_name;
-
- StatementTranslator(const StatementTranslator&);
-
- friend class Database;
-};
-
-}
-}
-
-#endif
-
-
+++ /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_dbms_String_hpp
-#define anna_dbms_String_hpp
-
-#include <anna/core/RuntimeException.hpp>
-
-#include <anna/dbms/Data.hpp>
-
-namespace anna {
-
-namespace dbms {
-
-/**
- Cadena usada como entrada y/o salida de las sentencias SQL.
-*/
-class String : public Data {
-public:
- /**
- Constructor.
- \param maxSize Tamao maximo que puede tener esta cadena. Deberia coincidir con el indicado
- por la columna con la que vaya a corresponder en la sentencia.
- \param isNulleable Indica si el dato puede tomar valores nulos.
- */
- explicit String(const int maxSize, const bool isNulleable = false) :
- Data(Type::String, maxSize, isNulleable) {
- Data::setBuffer(a_value = new char [maxSize + 1]);
- anna_memset(a_value, 0, maxSize + 1);
- }
-
- /**
- Constructor copia.
- \param other Instancia de la que copiar.
- */
- String(const String& other) :
- Data(other),
- a_value(other.a_value) {
- const int maxSize = getMaxSize();
- Data::setBuffer(a_value = new char [maxSize + 1]);
- anna_memset(a_value, 0, maxSize + 1);
- }
-
- /**
- Destructor.
- */
- virtual ~String() { delete [] a_value; }
-
- /**
- Devuelve el contenido de la cadena.
- \return El contenido de la cadena.
- \warning Si el metodo Data::isNull devolvio \em true el resultado de este metodo no esta definido.
- */
- const char* getValue() const throw() { return a_value; }
-
- /**
- Operador de copia.
- \param str Cadena de la que copiar. Si la longitud de la cadena sobrepasa el tamao maximo
- indicado en el constructor obtendremos una excepcin.
- \return La instancia de esta cadena.
- */
- String& operator = (const String& str) throw(RuntimeException);
-
- /**
- Operador de asignacin.
- \param str Cadena de la que copiar. Si la longitud de la cadena sobrepasa el tamao maximo
- indicado en el constructor obtendremos una excepcin.
- \return La instancia de esta cadena.
- */
- String& operator = (const char* str) throw(RuntimeException);
-
- /**
- Operador de asignacin.
- \param str Cadena de la que copiar. Si la longitud de la cadena sobrepasa el tamao maximo
- indicado en el constructor obtendremos una excepcin.
- \return La instancia de esta cadena.
- */
- String& operator = (const std::string& str) throw(RuntimeException) { return operator= (str.c_str()); }
-
- /**
- Operador de conversion. si el contenido de la columna sociada
- fue nulo este metodo devolvera NULL.
- \return El contenido de esta cadena.
- */
- operator const char*() const throw() { return (Data::isNull() == true) ? NULL : a_value; }
-
- /**
- Elimina los espacios a la derecha de la cadena recibida.
- \return La misma cadena recibida pero con los espacios eliminados.
- */
- static char* strip(char *str) throw();
-
- /**
- Devuelve una cadena con la informacion referente a esta instancia.
- \return Una cadena con la informacion referente a esta instancia.
- */
- virtual std::string asString() const throw();
-
-private:
- char* a_value;
-
- void do_clear() throw() { a_value [0] = 0; }
-};
-
-}
-}
-
-#endif
-
+++ /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_dbms_TimeStamp_hpp
-#define anna_dbms_TimeStamp_hpp
-
-#include <anna/dbms/Date.hpp>
-
-namespace anna {
-
-namespace dbms {
-
-/**
- Tipo de datos que permite trabajar con el tipo de dato 'TimeStamp' de un gestor de base de
- datos generico.
-
- El tipo de dato TimeStamp contiene la información suficiente para representar una fecha
- incluyendo la hora del día.
-*/
-class TimeStamp : public Date {
-public:
- /**
- Constructor.
- \param isNulleable Indica si el dato puede tomar valores nulos.
- \param format Formato usado para interpretar los datos de esta fecha, en los metodos Date::getCStringValue y
- Date::setValue (const char*) y Date::setValue (const std::string&). Sigue la especificacion:
-
- \code
- %a Replaced by the localeâs abbreviated weekday name. [ tm_wday]
-
- %A Replaced by the localeâs full weekday name. [ tm_wday]
-
- %b Replaced by the localeâs abbreviated month name. [ tm_mon]
-
- %B Replaced by the localeâs full month name. [ tm_mon]
-
- %c Replaced by the locale's appropriate date and time representation. (See the Base Definitions volume of
- IEEE Std 1003.1-2001, <time.h>.)
-
- %C Replaced by the year divided by 100 and truncated to an integer, as a decimal number [00,99]. [ tm_year]
-
- %d Replaced by the day of the month as a decimal number [01,31]. [ tm_mday]
-
- %D Equivalent to %m / %d / %y . [ tm_mon, tm_mday, tm_year]
-
- %e Replaced by the day of the month as a decimal number [1,31]; a single digit is preceded by a space. [
- tm_mday]
-
- %F Equivalent to %Y - %m - %d (the ISO 8601:2000 standard date format). [ tm_year, tm_mon, tm_mday]
-
- %g Replaced by the last 2 digits of the week-based year (see below) as a decimal number [00,99]. [ tm_year,
- tm_wday, tm_yday]
-
- %G Replaced by the week-based year (see below) as a decimal number (for example, 1977). [ tm_year, tm_wday,
- tm_yday]
-
- %h Equivalent to %b . [ tm_mon]
-
- %H Replaced by the hour (24-hour clock) as a decimal number [00,23]. [ tm_hour]
-
- %I Replaced by the hour (12-hour clock) as a decimal number [01,12]. [ tm_hour]
-
- %j Replaced by the day of the year as a decimal number [001,366]. [ tm_yday]
-
- %m Replaced by the month as a decimal number [01,12]. [ tm_mon]
-
- %M Replaced by the minute as a decimal number [00,59]. [ tm_min]
-
- %n Replaced by a <newline>.
-
- %p Replaced by the locale's equivalent of either a.m. or p.m. [ tm_hour]
-
- %r Replaced by the time in a.m. and p.m. notation; in the POSIX locale this shall be equivalent to %I : %M
- : %S %p . [ tm_hour, tm_min, tm_sec]
-
- %R Replaced by the time in 24-hour notation ( %H : %M ). [ tm_hour, tm_min]
-
- %S Replaced by the second as a decimal number [00,60]. [ tm_sec]
-
- %t Replaced by a <tab>.
-
- %T Replaced by the time ( %H : %M : %S ). [ tm_hour, tm_min, tm_sec]
-
- %u Replaced by the weekday as a decimal number [1,7], with 1 representing Monday. [ tm_wday]
-
- %U Replaced by the week number of the year as a decimal number [00,53]. The first Sunday of January is the
- first day of week 1; days in the new year before this are in week 0. [ tm_year, tm_wday, tm_yday]
-
- %V Replaced by the week number of the year (Monday as the first day of the week) as a decimal number [01,53].
- If the week containing 1 January has four or more days in the new year, then it is considered week 1. Oth-
- erwise, it is the last week of the previous year, and the next week is week 1. Both January 4th and the
- first Thursday of January are always in week 1. [ tm_year, tm_wday, tm_yday]
-
- %w Replaced by the weekday as a decimal number [0,6], with 0 representing Sunday. [ tm_wday]
-
- %W Replaced by the week number of the year as a decimal number [00,53]. The first Monday of January is the
- first day of week 1; days in the new year before this are in week 0. [ tm_year, tm_wday, tm_yday]
-
- %x Replaced by the locale's appropriate date representation. (See the Base Definitions volume of
- IEEE Std 1003.1-2001, <time.h>.)
-
- %X Replaced by the locale's appropriate time representation. (See the Base Definitions volume of
- IEEE Std 1003.1-2001, <time.h>.)
-
- %y Replaced by the last two digits of the year as a decimal number [00,99]. [ tm_year]
-
- %Y Replaced by the year as a decimal number (for example, 1997). [ tm_year]
-
- %z Replaced by the offset from UTC in the ISO 8601:2000 standard format ( +hhmm or -hhmm ), or by no charac-
- ters if no timezone is determinable. For example, "-0430" means 4 hours 30 minutes behind UTC (west of
- Greenwich). If tm_isdst is zero, the standard time offset is used. If tm_isdst is greater than zero, the
- daylight savings time offset is used. If tm_isdst is negative, no characters are returned. [ tm_isdst]
-
- %Z Replaced by the timezone name or abbreviation, or by no bytes if no timezone information exists. [
- tm_isdst]
-
- %% Replaced by % .
- \endcode
-
- Para obtener más informacion sobre la espeficacion de formato \em man \em strftime (p.e.).
-
- Para poder obtener la parte fraccionaria en la salida del metodo #getCStringValue hay que indicar el literal \em %%d. Por ejemplo:
-
- \code
- TimeStamp oneTime (false, "%T.%%d")
- \endcode
- */
- explicit TimeStamp(const bool isNulleable = false, const char* format = NULL) :
- Date(Data::Type::TimeStamp, isNulleable, format),
- a_fractionalSecond(0)
- {;}
-
- /**
- * Devuelve la parte fraccionaria de los segundos asociados a este objeto.
- * \return La parte fraccionaria de los segundos asociados a este objeto.
- */
- int getFractionalSecond() const throw() { return a_fractionalSecond; }
-
- /**
- * Establece la parte fraccionaria de los segundos de este objeto.
- * \param fsec Parte fraccionaria de los segundos.
- */
- void setFractionalSecond(const int fsec) throw() { a_fractionalSecond = fsec; }
-
- /**
- * Interpreta el contenido de la fecha y lo transfiere al buffer.
- * \return El buffer que contiene esta fecha interpretada con el formato indicado en el contructor.
- * \warning El resultado sera NULL en caso de no poder interpretar correctamente la fecha.
- */
- virtual const char* getCStringValue() const throw();
-
- /**
- Operador de copia.
- \param timeStamp Fecha de la que copiar.
- \return La instancia de esta fecha.
- \warning Solo copia el contenido de la fecha recibida, no cambia el formato de interpretacion de la fecha origen.
- */
- TimeStamp& operator = (const TimeStamp& timeStamp) throw(RuntimeException) {
- Date::operator= (timeStamp);
- a_fractionalSecond = timeStamp.a_fractionalSecond;
- return *this;
- }
-
- /**
- Operador de copia.
- \param date Fecha de la que copiar.
- \return La instancia de esta fecha.
- \warning Solo copia el contenido de la fecha recibida, no cambia el formato de interpretacion de la fecha origen.
- */
- TimeStamp& operator = (const Date& date) throw(RuntimeException) { Date::operator= (date); a_fractionalSecond = 0; return *this; }
-
-private:
- char a_anotherBuffer [MaxDateSize + 1];
- int a_fractionalSecond;
-
- void do_clear() throw() { a_fractionalSecond = 0; a_anotherBuffer [0] = 0; }
-};
-
-}
-}
-
-#endif
-
+++ /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_dbms_dbms_hpp
-#define anna_dbms_dbms_hpp
-
-namespace anna {
-/**
-Define de forma generica el protocolo de acceso a los datos guardados en un DBMS.
-
-El ejecutable debera enlazarse con las librerias:
- \li anna.core.a
- \li anna.xml.a
- \li anna.app.a
- \li anna.comm.a
- \li anna.dbms.a
-
-El <b>Packet Header</b> es anna.dbms.h
-*/
-namespace dbms {
-}
-}
-
-#include <anna/dbms/Connection.hpp>
-#include <anna/dbms/Data.hpp>
-#include <anna/dbms/Database.hpp>
-#include <anna/dbms/DatabaseException.hpp>
-#include <anna/dbms/Delivery.hpp>
-#include <anna/dbms/FailRecoveryHandler.hpp>
-#include <anna/dbms/Integer.hpp>
-#include <anna/dbms/LongBlock.hpp>
-#include <anna/dbms/OutputBind.hpp>
-#include <anna/dbms/ResultCode.hpp>
-#include <anna/dbms/ShortBlock.hpp>
-#include <anna/dbms/Statement.hpp>
-#include <anna/dbms/StatementTranslator.hpp>
-#include <anna/dbms/Sentence.hpp>
-#include <anna/dbms/String.hpp>
-#include <anna/dbms/Float.hpp>
-#include <anna/dbms/Date.hpp>
-#include <anna/dbms/TimeStamp.hpp>
-
-using namespace anna::dbms;
-
-#endif
-
+++ /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_dbms_functions_hpp
-#define anna_dbms_functions_hpp
-
-#include <anna/core/RuntimeException.hpp>
-
-namespace anna {
-namespace dbms {
-class Connection;
-}
-}
-
-namespace anna {
-namespace dbms {
-
-using namespace anna;
-
-
-/**
- Métodos usados habitualmente para trabajar contra la base de datos.
-*/
-struct functions {
-public:
- /**
- * Este metodo asegura la integridad entre el esquema de tablas instalado y el esperado por los procesos de un proyecto.
- * Para ello cada uno de los proyectos debe invocar a este método indicado los parámetro requeridos. Es imprescindible
- * que la versión esperada del esquema de base de datos esté definida en una única variable centralizada.
- *
- * La idea es que cada vez que hagamos un cambio en la estructura de tablas de una cierta entidad cambiemos la versión
- * del esquema, y ese cambio deberá reflejarse en la invocación a este nuevo método.
- *
- * Este método lanzará una excepción si el último parche instalado en el esquema de base de datos no coincide
- * con el valor de la variable \em requiredPatch.
- *
- * Cada proceso debe invocar la comprobación de esquema en cuanto la base de datos tenga una conexión disponible, de forma
- * que si el esquema de base de datos no coincide con el esperado el proceso mostrará un error indicado el esquema de base
- * de datos esperado y el esquema de base datos instalado.
- *
- * Para usar este método el esquema de base de nuestro proyecto debe disponer de una tabla que debe contener, al menos,
- * la siguiente estructura:
- *
- * \code
- * -- Ejemplo de creación para Oracle(tm)
- * create table axe_dataScheme (
- * id varchar(8) not null,
- * installation_date date default sysdate not null
- * );
- *
- * alter table axe_dataScheme add constraint axe_dataScheme_pk primary key (id);
- *
- * \endcode
- *
- * \code
- * -- Ejemplo de creación para PostgreSQL
- * create table data_scheme (
- * id varchar(8) not null,
- * installation_date timestamp default now (),
- * primary key (id)
- * );
- * \endcode
- *
- * El nombre de la tabla y los campos de las columnas podrían ser distintos ya que este método los recibe como parámetros.
- *
- * Un ejemplo de implementación podría ser:
- *
- * \code
- * //static
- * void axe::storage::functions::verifyDataScheme (dbms::Connection& connection)
- * throw (RuntimeException)
- * {
- * anna::dbms::functions::verifyDataScheme (connection, "axe_dataScheme", "v1.3");
- * }
- * \endcode
- *
- * \param connection Conexión usada para acceder a los datos.
- * \param tableName Nombre de la tabla que contiene las versiones instaladas.
- * \param requiredPatch Identificador de parche de base de base de datos requerido por los procesos de nuestro proyecto.
- * Este indicador debería estar definido en un único punto para todo nuestro proyecto.
- * \param columnID Nombre de la columna que contiene el identificador de cada uno de los parches instalados.
- * \param columnDate Nombre de la columna que contiene la fecha de instalación de cada parche.
- */
- static void verifyDataScheme(dbms::Connection& connection, const char* tableName, const char* requiredPatch, const char* columnID = "id", const char* columnDate = "installation_date")
- throw(RuntimeException);
-};
-
-}
-}
-
-#endif
+++ /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_dbms_internal_sccs_hpp
-#define anna_dbms_internal_sccs_hpp
-
-namespace anna {
-
-namespace dbms {
-
-class sccs {
-public:
- static void activate() throw();
-};
-
-}
-}
-
-#endif
-
+++ /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_Accesor_hpp
-#define anna_dbos_Accesor_hpp
-
-#include <anna/core/RuntimeException.hpp>
-#include <anna/core/mt/Mutex.hpp>
-
-#include <anna/dbms/DatabaseException.hpp>
-
-#include <anna/dbos/defines.hpp>
-
-namespace anna {
-
-namespace dbms {
-class Database;
-class Connection;
-class Statement;
-}
-
-namespace dbos {
-
-class StorageArea;
-
-/**
- Interfaz que deben cumplir los objetos encargados de acceder al objeto del medio fisico,
- que normalmente sera alguna base de datos.
-*/
-class Accesor : public Mutex {
-public:
- typedef short Id; /**< Permite identificar el tipo de accesor. */
-
- /**
- Destructor.
- */
- virtual ~Accesor();
-
- /**
- Devuelve el identificador de este accesor.
- \return El identificador de este accesor.
- */
- Id getId() const throw() { return a_id; }
-
- /**
- Devuelve la instancia de la sentencia \em statement asociada a este cargador.
- \return La instancia de la sentencia \em statement asociada a este cargador. Puede ser NULL.
- */
- dbms::Statement* getStatement()
- throw(RuntimeException) {
- return (a_statement == NULL && a_database != NULL) ? (a_statement = initialize(*a_database)) : a_statement;
- }
-
- /**
- * Devuelve \em true si el accesor fue inicializado con base de datos o \em false en otro caso.
- * \return \em true si el accesor fue inicializado con base de datos o \em false en otro caso.
- */
- bool hasDataBase() const throw() { return a_database != NULL; }
-
- /**
- Devuelve la instancia de la base de datos asociada a este cargador.
- \return La instancia de la base de datos asociada a este cargador.
-
- \warning Si el accesor fue inicializado sin base de datos lo resultados no están definidos.
- */
- dbms::Database& getDatabase() throw() { return *a_database; }
-
- /**
- Devuelve la conexion que esta usando actualmente este cargador.
- \return la conexion que esta usando actualmente este cargador.
- */
- dbms::Connection& getConnection() throw(RuntimeException) {
- if(a_connection == NULL) {
- std::string msg(asString());
- msg += " | No available database connection";
- throw RuntimeException(msg, ANNA_FILE_LOCATION);
- }
-
- return *a_connection;
- }
-
- /**
- Devuelve la representacion en forma de cadena de la clave primaria establecida.
- @return La representacion en forma de cadena de la clave primaria establecida.
- */
- virtual std::string asString() const throw() = 0;
-
- /**
- Metodo de debemos re-escribir para devolver el nombre completo del selector de recursos.
- Para evitar ambigüedades este nombre deberia incluir la lista completa de \em namespaces
- a la que pertenece la clase.
- \return Una cadena con el nombre de este selector.
- */
- virtual const char* getClassName() const throw() = 0;
-
-protected:
- /**
- Constructor.
- \param database Base de datos asociada a este cargador y que deberia servir para
- obtener los datos de un objeto. Debe tener la misma disponibilidad que este cargador.
- \param id Identificador de este accesor.
- */
- Accesor(dbms::Database& database, const Id id) :
- a_database(&database),
- a_id(id),
- a_statement(NULL),
- a_connection(NULL),
- a_emodeIsNull(true)
- {;}
-
- /**
- Constructor.
- \param database Base de datos asociada a este cargador y que deberia servir para
- obtener los datos de un objeto. Debe tener la misma disponibilidad que este cargador.
- \param id Identificador de este accesor.
- \param emode Modo de actuar en caso de no encontrar el dato buscado.
- */
- Accesor(dbms::Database& database, const Id id, const Exception::Mode::_v emode) :
- a_database(&database),
- a_id(id),
- a_statement(NULL),
- a_connection(NULL),
- a_emodeIsNull(false),
- a_exceptionMode(emode)
- {;}
-
- /**
- Constructor.
- \param id Identificador de este accesor.
- */
- Accesor(const Id id) :
- a_database(NULL),
- a_id(id),
- a_statement(NULL),
- a_connection(NULL),
- a_emodeIsNull(true)
- {;}
-
- /**
- Metodo que deben implementar todos los accesores para definir la sentencia
- SQL que los definira.
- Se invocara automaticamente desde el nucleo de anna.dbos la primera vez que
- se use este accesor, de forma que el programador solo debe preocuparse por
- definir este metodo.
- \param database Instancia de la base de datos indicada en el constructor.
- */
- virtual dbms::Statement* initialize(dbms::Database& database) throw(RuntimeException) = 0;
-
-private:
- dbms::Database* a_database;
- const Id a_id;
- dbms::Statement* a_statement;
- dbms::Connection* a_connection;
- bool a_emodeIsNull;
- Exception::Mode::_v a_exceptionMode;
-
- void setStatement(dbms::Statement* statement) throw() { a_statement = statement; }
-
- virtual bool load(dbms::Connection*, const StorageArea*) throw(RuntimeException, dbms::DatabaseException);
-
- friend class StorageArea;
-};
-
-}
-}
-
-#endif
-
-
-
+++ /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_AutoObject_hpp
-#define anna_dbos_AutoObject_hpp
-
-#include <anna/dbos/Object.hpp>
-
-namespace anna {
-
-namespace dbos {
-
-
-/**
- Facilita el uso de los punteros a objectos obtenidos a partir de los datos guardados en un medio fisico.
-
- La idea de esta clase es que el constructor y el destructor de esta clase cooperan para reservar y/o
- liberar correctamente la instancia de T asociada a esta instancia.
-
- \param T Clase que vamos a gestionar.
-
- En el siguiente ejemplo podemos ver la forma habitual de trabajar con un objeto persistente tiene
- el incoveniente de que tenemos que tener en cuenta cada una de las situaciones en las que la
- referencia obtenida mediante el metodo \em instantiate debe ser liberada.
-
- \code
- void Application::getServerSocketsData (vector <SocketData>& serverSocketsData) const
- throw (RuntimeException)
- {
- LOGMETHOD (TraceMethod ("anna::Application", "getServerSocketsData", ANNA_FILE_LOCATION));
-
- Facility* facility (NULL);
- FacilityLoader facilityLoader;
-
- try {
- facility = Facility::instantiate (facilityLoader.setKey (a_thisFacility)); // (1)
- LOGDEBUG (Logger::write (Logger::Debug, facility->asString (), ANNA_FILE_LOCATION));
-
- getSocketsData (getThisHostName (), facility->getName (), a_thisCell, a_thisInstance, serverSocketsData);
-
- Facility::release (facility);
- }
- catch (dbos::DatabaseException& edbos) {
- Facility::release (facility);
- throw RuntimeException (edbos.getText (), ANNA_FILE_LOCATION);
- }
- catch (RuntimeException&) { // Tenemos que capturar esta excepcion para liberar el recurso.
- Facility::release (facility);
- throw;
- }
- }
- \endcode
-
- Como podemos ver a continuacion el siguiente metodo es mucho mas sencillo y aporta la gran ventaja de que
- el sistema trabaja por nosotros para liberar correctamente los recursos.
-
- \code
- void Application::getServerSocketsData (vector <SocketData>& serverSocketsData) const
- throw (RuntimeException)
- {
- LOGMETHOD (TraceMethod ("anna::Application", "getServerSocketsData", ANNA_FILE_LOCATION));
-
- AutoObject <Facility> facility;
- FacilityLoader facilityLoader;
-
- try {
- facility = Facility::instantiate (facilityLoader.setKey (a_thisFacility)); // (1)
-
- LOGDEBUG (Logger::write (Logger::Debug, facility->asString (), ANNA_FILE_LOCATION));
-
- getSocketsData (getThisHostName (), facility->getName (), a_thisCell, a_thisInstance, serverSocketsData);
- }
- catch (dbos::DatabaseException& edbos) {
- throw RuntimeException (edbos.getText (), ANNA_FILE_LOCATION);
- }
- }
- \endcode
-*/
-template <typename T> class AutoObject {
-public:
- /**
- Constructor.
- \param t Instancia del objeto asociado a esta instancia.
- \warning La instancia deberia haber sido obtenida mediate la invocacion a \em T::instantiate de la
- clase persistente.
- */
- explicit AutoObject(T* t) : a_t(t) {;}
-
- /**
- Constructor.
- */
- AutoObject() : a_t(NULL) {;}
-
- /**
- Destructor. Invoca al metodo \em T::release
- */
- ~AutoObject() { if(a_t != NULL) T::release(a_t); }
-
- /**
- Operador ->
- Permite invocar a metodos de la clase T.
- \return La instancia de la clase T asociada a esta instancia.
- */
- T* operator -> () const throw() { return a_t; }
-
- /**
- Operador copia.
- \param t Referencia al objeto que vamos a tratar.
- \return La instancia de la clase T asociada a esta instancia.
- */
- T* operator = (T* t) throw() {
- if(a_t != t) {
- T::release(a_t);
- a_t = t;
- }
-
- return a_t;
- }
-
- /**
- Operador copia.
- \param other Referencia al objeto que vamos a tratar.
- \return La instancia de la clase T asociada a esta instancia.
- */
- T* operator = (const AutoObject <T>& other) throw(RuntimeException) {
- return (this != &other) ? (*this = T::duplicate(other.a_t)) : a_t;
- }
-
- /**
- Operador de conversion.
- \return La instancia de la clase T asociada a esta instancia.
- */
- operator T*() const throw() { return a_t; }
-
-private:
- T* a_t;
-};
-
-
-}
-}
-
-
-
-#endif
-
-
+++ /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_AutoSet_hpp
-#define anna_dbos_AutoSet_hpp
-
-#include <anna/dbos/Set.hpp>
-
-namespace anna {
-
-namespace dbos {
-
-
-/**
- Facilita el uso de los punteros a objectos obtenidos a partir de los datos guardados en un medio fisico.
-
- La idea de esta clase es que el constructor y el destructor de esta clase cooperan para reservar y/o
- liberar correctamente la instancia de T asociada a esta instancia.
-
- \param T Clase que vamos a gestionar.
-
- En el siguiente ejemplo podemos ver la forma habitual de trabajar con un objeto persistente tiene
- el incoveniente de que tenemos que tener en cuenta cada una de las situaciones en las que la
- referencia obtenida mediante el metodo \em instantiate debe ser liberada.
-
- \code
- Server::Set <Server>* servers (NULL);
- ServerLoader serverLoader; // ServerLoader hereda de anna::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 condificion de error.
- }
- \endcode
-
- Como podemos ver a continuacion el siguiente metodo es mucho mas sencillo y aporta la gran ventaja de que
- el sistema trabaja por nosotros para liberar correctamente los recursos.
-
- \code
- AutoSet <Server> servers;
- ServerLoader serverLoader; // ServerLoader hereda de anna::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 ....
- }
- }
- catch (Exception& ex) {
- ...
- ... Si fuera necesario trataria la condificion de error.
- }
- \endcode
-*/
-template <typename T> class AutoSet {
-public:
- /**
- Constructor.
- \param t Instancia del objeto asociado a esta instancia.
- \warning La instancia deberia haber sido obtenida mediate la invocacion a \em T::instantiate de la
- clase persistente.
- */
- explicit AutoSet(Set <T>* t) : a_t(t) {;}
-
- /**
- Constructor.
- */
- AutoSet() : a_t(NULL) {;}
-
- /**
- Destructor. Invoca al metodo \em T::release
- */
- ~AutoSet() { if(a_t != NULL) T::release(a_t); }
-
- /**
- Operador ->
- Permite invocar a metodos de la clase T.
- \return La instancia de la clase T asociada a esta instancia.
- */
- Set <T>* operator -> () const throw() { return a_t; }
-
- /**
- Operador copia.
- \return La instancia de la clase T asociada a esta instancia.
- */
- Set <T>* operator = (Set<T>* t)
- throw() {
- if(a_t == t)
- return t;
-
- if(a_t != NULL)
- T::release(a_t);
-
- return a_t = t;
- }
-
- /**
- Operador de conversion.
- \return La instancia de la clase T asociada a esta instancia.
- */
- operator Set <T>*() const throw() { return a_t; }
-
-private:
- Set <T>* a_t;
-};
-
-
-}
-}
-
-
-
-#endif
-
-
+++ /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_Creator_hpp
-#define anna_dbos_Creator_hpp
-
-#include <anna/dbos/Accesor.hpp>
-
-namespace anna {
-
-namespace dbos {
-
-/**
- Interfaz que deben cumplir los objetos encargados de crear un nuevo objeto que sera ubicado
- en el area de almacenamiento asociado a un medio fisico.
-*/
-class Creator : public Accesor {
-public:
- /**
- Metodo de debemos re-escribir para devolver el nombre completo del selector de recursos.
- Para evitar ambigüedades este nombre deberia incluir la lista completa de \em namespaces
- a la que pertenece la clase.
- \return Una cadena con el nombre de este selector.
- */
- virtual const char* getClassName() const throw() { return "anna::dbos::Creator"; }
-
-protected:
- /**
- Constructor.
- \param database Base de datos asociada a este cargador y que deberia servir para
- obtener los datos de un objeto. Debe tener la misma disponibilidad que este cargador.
- \param id Identificador de este accesor.
- */
- Creator(dbms::Database& database, const Id id = 0) : Accesor(database, id) {;}
-
- /**
- Constructor.
- \param id Identificador de este accesor.
- */
- Creator(const Id id = 0) : Accesor(id) {;}
-
- /**
- Devuelve el indice usado para ubicar en memoria el objeto que vamos a cargar.
- @return El indice usado para ubicar en memoria el objeto que vamos a cargar.
- */
- virtual Index getIndex() const throw(RuntimeException) = 0;
-
-private:
- dbms::Statement* initialize(dbms::Database&) throw(RuntimeException) { return NULL;}
-
- friend class StorageArea;
-};
-
-}
-}
-
-#endif
-
-
-
+++ /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_CrossedLoader_hpp
-#define anna_dbos_CrossedLoader_hpp
-
-#include <anna/dbos/Accesor.hpp>
-
-namespace anna {
-
-namespace dbms {
-class Database;
-}
-
-namespace dbos {
-
-class Loader;
-
-/**
- * Interfaz que deben cumplir los cargadores cruzados. Un cargador cruzado facilita que una
- * misma clase pueda ser cargada usando varios criterios de búsqueda.
- *
- * El criterio de búsqueda más usado y que debería ser más óptimo será desarrollado
- * mediante la definición del anna::dbos::Loader específico. El resto de criterios de búsqueda,
- * los cargadores cruzados, deberían ser capaces obtener los datos usados como clave en el criterio
- * principal, para a partir de ahí poder aplicar el criterio de búsqueda principal.
- *
- * Cada cargador cruzado podría tener una lista de pares (clave_alternativa, clave_principal) que permitirá
- * acelerar las búsquedas de la clave principal, en base a la clave alternativa usada en este cargador.
- *
- * Para obtener los datos de la clave principal en base a los datos de la clave alternativa habrá que
- * acceder al medio físico.
- *
- * Para optimizar el acceso a los pares (Clave alternativa, Clave Principal) se podría usar una
- * instancia del tipo anna::LRUMap.
-*/
-class CrossedLoader : public Accesor {
-public:
- /**
- Metodo de debemos re-escribir para devolver el nombre completo del selector de recursos.
- Para evitar ambigüedades este nombre deberia incluir la lista completa de \em namespaces
- a la que pertenece la clase.
- \return Una cadena con el nombre de este selector.
- */
- virtual const char* getClassName() const throw() { return "anna::dbos::CrossedLoader"; }
-
-protected:
- /**
- Constructor.
- \param database Base de datos asociada a este cargador y que deberia servir para
- obtener los datos de un objeto. Debe tener la misma disponibilidad que este cargador.
- \param id Identificador de este accesor.
- */
- CrossedLoader(dbms::Database& database, const Id id = 0) : Accesor(database, id) {;}
-
- /**
- Constructor.
- \param database Base de datos asociada a este cargador y que deberia servir para
- obtener los datos de un objeto. Debe tener la misma disponibilidad que este cargador.
- \param id Identificador de este accesor.
- \param emode Modo de actuar en caso de no encontrar el dato buscado.
- */
- CrossedLoader(dbms::Database& database, const Id id, const Exception::Mode::_v emode) : Accesor(database, id, emode) {;}
-
- /**
- Este método debe ser reescrito para que permita localizar la información del objeto, que posiblemente
- esté ubicado en la lista de objetos de este cargador cruzado.
-
- @return \em true si se ha localizado la información la clave primaria del objeto en su lista de pares
- o \em false en otro caso.
- */
- virtual bool seek() const throw() { return false; }
-
- /**
- * Este método debe ser reescrito para que se pueda actualizar la lista de pares (clave_alternativa, clave_principal)
- * que permitirá acelear las posteriores búsquedas.
- *
- * \param loader Instancia del cargador principal que habrá compuesto la clave principal con los suministrados por
- * esta instancia.
- */
- virtual void download(Loader& loader) throw() {;}
-
- friend class StorageArea;
-};
-
-}
-}
-
-#endif
-
-
-
+++ /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_Eraser_hpp
-#define anna_dbos_Eraser_hpp
-
-#include <anna/dbos/Accesor.hpp>
-
-namespace anna {
-
-namespace dbos {
-
-class Object;
-
-/**
- Interfaz que deben cumplir los objetos encargados de borrar el objeto del medio fisico,
- que normalmente sera alguna base de datos.
-*/
-class Eraser : public Accesor {
-public:
- /**
- Devuelve la instancia establecida por #setObject.
- \return La instancia establecida por #setObject. Puede ser NULL.
- */
- Object* getObject() throw() { return a_object; }
-
- /**
- Establece la instancia del objeto sobre el que vamos a actuar.
- \param object Instancia del objeto sobre el que vamos a actuar.
- */
- void setObject(Object* object) throw() { a_object = object; }
-
- /**
- Metodo de debemos re-escribir para devolver el nombre completo del selector de recursos.
- Para evitar ambigüedades este nombre deberia incluir la lista completa de \em namespaces
- a la que pertenece la clase.
- \return Una cadena con el nombre de este selector.
- */
- virtual const char* getClassName() const throw() { return "anna::dbos::Eraser"; }
-
-protected:
- /**
- Constructor.
- \param database Base de datos asociada a este cargador y que deberia servir para
- obtener los datos de un objeto. Debe tener la misma disponibilidad que este cargador.
- \param id Identificador de este accesor.
- */
- Eraser(dbms::Database& database, const Id id = 0) :
- Accesor(database, id),
- a_object(NULL)
- {;}
-
-private:
- Object* a_object;
-
- Index getIndex() const throw() { return 0; } // No se usa
-};
-
-}
-}
-
-#endif
-
-
-
+++ /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_Loader_hpp
-#define anna_dbos_Loader_hpp
-
-#include <anna/dbos/Accesor.hpp>
-
-namespace anna {
-
-namespace dbms {
-class Database;
-}
-
-namespace dbos {
-
-class CrossedLoader;
-
-/**
- Interfaz que deben cumplir los objetos encargados de cargar el objeto desde el medio fisico,
- que normalmente sera alguna base de datos, y pasarlo un ambito de objetos en C++.
-*/
-class Loader : public Accesor {
-public:
- /**
- Metodo de debemos re-escribir para devolver el nombre completo del selector de recursos.
- Para evitar ambigüedades este nombre deberia incluir la lista completa de \em namespaces
- a la que pertenece la clase.
- \return Una cadena con el nombre de este selector.
- */
- virtual const char* getClassName() const throw() { return "anna::dbos::Loader"; }
-
-protected:
- /**
- Constructor.
- \param database Base de datos asociada a este cargador y que deberia servir para
- obtener los datos de un objeto. Debe tener la misma disponibilidad que este cargador.
- \param id Identificador de este accesor.
- */
- Loader(dbms::Database& database, const Id id = 0) : Accesor(database, id) {;}
-
- /**
- Constructor.
- \param id Identificador de este accesor.
- */
- Loader(const Id id = 0) : Accesor(id) {;}
-
- /**
- Devuelve el indice usado para ubicar en memoria el objeto que vamos a cargar.
- @return El indice usado para ubicar en memoria el objeto que vamos a cargar.
- */
- virtual Index getIndex() const throw(RuntimeException) = 0;
-
- /**
- * Este método debe ser reescrito para poder obtener los datos de la clave principal usada para localizar
- * los objetos en un área del almacenamiento.
- *
- * \param crossedLoader Instancia del cargador alternativo que habrá calculado la clave principal en
- * a lo clave alternativa contenida en él.
- */
- virtual void upload(CrossedLoader& crossedLoader) throw(RuntimeException) {;}
-
- friend class StorageArea;
-};
-
-}
-}
-
-#endif
-
-
-
+++ /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_Object_hpp
-#define anna_dbos_Object_hpp
-
-#include <anna/core/RuntimeException.hpp>
-
-#include <anna/dbms/DatabaseException.hpp>
-
-#include <anna/dbos/Loader.hpp>
-
-namespace anna {
-
-namespace dbos {
-
-class Creator;
-
-/**
- Interfaz que deben cumplir los objetos persistentes.
-
- Ejemplo de definicion de una clase usando esta interfaz:
-
- \include dbos_demo.p/oodb.d/hdrs/dbos_demo.oodb.Table01.h
-
- Ejemplo de implementacion de la clase correspondiente a la definicion:
-
- \include dbos_demo.p/oodb.d/oodb.Table01.cc
-*/
-class Object {
-public:
- /**
- Devuelve el indice asociado a este objeto
- \return el indice asociado a este objeto
- */
- Index getIndex() const throw() { return a_index; }
-
- /**
- * Devuelve \em true si este objeto ya existe en el medio físico (fué cargado desde allí o fue creado y grabado posteriormente) o
- * \em false si este objeto sólo existe en la memoria intermedia.
- * \return \em true si este objeto ya existe en el medio físico (fué cargado desde allí o fue creado y grabado posteriormente) o
- * \em false si este objeto sólo existe en la memoria intermedia.
- */
- bool isStored() const throw() { return a_isStored; }
-
-protected:
- /**
- Constructor.
- */
- Object() : a_index(0), a_isStored(false) {;}
-
- /**
- Inicializa este objeto con la informacion obtenida desde el medio fisico donde
- esta grabado el objeto. Normalmente este medio fisico correspondera con una base de datos.
-
- \param loader Cargador que contiene la informacion con la que debemos inicializar este objeto.
-
- */
- virtual void initialize(Loader& loader) throw(RuntimeException, dbms::DatabaseException) = 0;
-
- /**
- Actualiza la informacion de este objeto con la nueva informacion obtenida del medio
- fisico.
- \param creator Creador que contiene la informacion con la que debemos inicializar este objeto.
- */
- virtual void create(Creator& creator) throw(RuntimeException, dbms::DatabaseException) {;}
-
- /**
- Libera los recursos reservados por este objeto. Este metodo solo se invocara cuando el objeto
- vaya a ser sacado definitivamente del area de almacenamiento.
- */
- virtual void destroy() throw() {;}
-
- /**
- Devuelve \em true si el registro del medio fisico ha cambiado respecto al registro
- cargado en memoria o \em false en otro caso.
-
- \param loader Cargador que contiene la informacion con la que deberiamos re-inicializar
- este objeto.
-
- \return \em true si el registro del medio fisico ha cambiado respecto al registro
- cargado en memoria o \em false en otro caso.
- */
- virtual bool hasChanges(Loader& loader) throw(RuntimeException, dbms::DatabaseException) {
- return true;
- }
-
- /**
- Devuelve \em true si el objeto requiere comenzar el proceso de comprobacion de recarga
- de datos \em false en otro caso.
- */
- virtual bool enableUpdate() const throw() { return true; }
-
-private:
- Index a_index;
- bool a_isStored;
-
- void setIndex(const Index index) throw() { a_index = index; }
-
- friend class StorageArea;
-};
-
-
-}
-}
-
-#endif
+++ /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_ObjectAllocator_hpp
-#define anna_dbos_ObjectAllocator_hpp
-
-namespace anna {
-
-namespace dbos {
-
-class Object;
-
-typedef Object*(*ObjectAllocator)();
-
-}
-
-}
-
-#endif
-
+++ /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_ObjectFacade_hpp
-#define anna_dbos_ObjectFacade_hpp
-
-#include <anna/core/RuntimeException.hpp>
-
-#include <anna/dbms/DatabaseException.hpp>
-
-#include <anna/dbos/StorageArea.hpp>
-#include <anna/dbos/Creator.hpp>
-#include <anna/dbos/Loader.hpp>
-#include <anna/dbos/Recorder.hpp>
-#include <anna/dbos/Eraser.hpp>
-
-namespace anna {
-
-namespace dbms {
-class Connection;
-}
-
-namespace dbos {
-
-class Object;
-
-/**
- Clase que facilita el acceso y uso de las clases encargadas de la instanciacion de objetos a partir de los datos
- contenidos en un medio fisico, que normalmente seria la tabla de una base de datos.
-
- \param T clase debe ser heredada de anna::dbos::Object.
-
- Ejemplo de definicion de una clase usando esta interfaz:
-
- \include dbos_demo.p/oodb.d/hdrs/dbos_demo.oodb.Table01.h
-
- Ejemplo de implementacion de la clase correspondiente a la definicion:
-
- \include dbos_demo.p/oodb.d/oodb.Table01.cc
-
- \see dbos_declare_object
- \see dbos_prepare_object
-*/
-template <typename T> class ObjectFacade {
-public:
- /**
- Devuelve un numerico que puede ser usado en la definicion del area de almacenamiento.
-
- \return Un numerico que puede ser usado en la definicion del area de almacenamiento.
- \see Database::createStorageArea
- */
- static StorageId getStorageAreaId() throw() { return (StorageId) anna_ptrnumber_cast(&st_storageArea); }
-
- /**
- Devuelve el area de almacenamiento asociado a esta clase.
- \return Devuelve el area de almacenamiento asociado a esta clase.
- */
- static StorageArea* getStorageArea() throw() { return st_storageArea; }
-
- /**
- Establece el area de almacenamiento asociado a esta clase, que deberiaser creado mediante la invocacin al metodo
- Database::createStorageArea.
-
- \param storageArea area de almacenamiento asociada esta clase.
-
- \warning El area de almacenamiento debe establecerse antes de invocar a cualquier otro metodo de esta clase.
- */
- static void setStorageArea(StorageArea* storageArea) throw() {
- (st_storageArea = storageArea)->setSizeof(sizeof(T));
- }
-
- /**
- Carga la informacion de un objeto contenida en un medio fisico y la interpreta para adecuarla a
- una clase C++.
-
- Este cargador deberia tener todos los datos necesarios para localizar la informacion del objeto que
- debe cargar. Por ejemplo, en caso de tener que obtener el objeto a partir de los datos contenidos
- en una tabla de una base de datos deberia conocer la clave primaria del objeto a cargar, o alguna
- otra combinacion de columnas que lo identifiquen univocamente.
-
- \param connection Conexion usada si fuera necesario extraer los datos del medio fisico.
- \param loader Cargador de clase encargado de localizar y obtener la informacion referente al objeto
- que deseamos cargar en memoria.
-
- \return Una instancia que cumple el patron establecido por el cargador. Puede ser NULL en caso de
- que al inicializar el area de almacenamiento asociado a esta clase se halla indicado un \em errorCode
- igual a -1 en otro caso si no encuentra el objeto que cumpla el patron devolveria una
- excepcion.
-
- \warning Cada llamada a este metodo deberia tener su correspondiente liberacion invocando a #release
- cuando dejemos de usar la instancia.
- */
- static T* instance(dbms::Connection& connection, Loader& loader)
- throw(RuntimeException, dbms::DatabaseException) {
- if(st_storageArea == NULL) {
- std::string msg(loader.asString());
- msg += " | ObjectFacade uninitialized ";
- throw RuntimeException(msg, ANNA_FILE_LOCATION);
- }
-
- return static_cast <T*>(st_storageArea->instance(connection, loader));
- }
-
- /**
- Carga la informacion de un objeto contenida en un medio fisico y la interpreta para adecuarla a
- una clase C++.
-
- Este cargador deberia tener todos los datos necesarios para localizar la informacion del objeto que
- debe cargar.
-
- \param loader Cargador de clase encargado de localizar y obtener la informacion referente al objeto
- que deseamos cargar en memoria.
-
- \return Una instancia que cumple el patron establecido por el cargador. Puede ser NULL en caso de
- que al inicializar el area de almacenamiento asociado a esta clase se halla indicado un \em errorCode
- igual a -1 en otro caso si no encuentra el objeto que cumpla el patron devolveria una
- excepcion.
-
- \warning Cada llamada a este metodo deberia tener su correspondiente liberacion invocando a #release
- cuando dejemos de usar la instancia.
- */
- static T* instance(Loader& loader)
- throw(RuntimeException, dbms::DatabaseException) {
- if(st_storageArea == NULL) {
- std::string msg(loader.asString());
- msg += " | ObjectFacade uninitialized ";
- throw RuntimeException(msg, ANNA_FILE_LOCATION);
- }
-
- return static_cast <T*>(st_storageArea->instance(loader));
- }
-
- /**
- Carga la informacion de un objeto contenida en un medio fisico y la interpreta para adecuarla a
- una clase C++.
-
- Este cargador deberia tener todos los datos necesarios para localizar la informacion del objeto que
- debe cargar. Por ejemplo, en caso de tener que obtener el objeto a partir de los datos contenidos
- en una tabla de una base de datos deberia conocer la clave primaria del objeto a cargar, o alguna
- otra combinacion de columnas que lo identifiquen univocamente.
-
- \param connection Conexion usada si fuera necesario extraer los datos del medio fisico.
- \param crossedLoader Cargador encargado de encontrar la clave principal a aplicar con el #Loader
- recibido como parámetro en base a una clave alternativa contenida en el mismo.
- \param loader Cargador de clase encargado de localizar y obtener la informacion referente al objeto
- que deseamos cargar en memoria.
-
- \return Una instancia que cumple el patron establecido por el cargador. Puede ser NULL en caso de
- que al inicializar esta clase \em errorCode se halla indicado un #NoExceptionWhenNotFound en otro
- caso si no encuentra el objeto que cumpla el patron devolveria una excepcion de ejecucion.
-
- \warning Cada llamada a este método deberia tener su correspondiente liberacion invocando a #release
- cuando dejemos de usar la instancia.
- */
- static T* instance(dbms::Connection& connection, CrossedLoader& crossedLoader, Loader& loader)
- throw(RuntimeException, dbms::DatabaseException) {
- if(st_storageArea == NULL) {
- std::string msg(loader.asString());
- msg += " | ObjectFacade uninitialized ";
- throw RuntimeException(msg, ANNA_FILE_LOCATION);
- }
-
- return static_cast <T*>(st_storageArea->instance(connection, crossedLoader, loader));
- }
-
- /**
- Crea un objeto en el area de almacenamiento un y lo prepara para ser transferido al medio fisico
- si fuera necesario.
-
- Este cargador deberia tener todos los datos necesarios para localizar la informacion del objeto que
- debe cargar. Por ejemplo, en caso de tener que obtener el objeto a partir de los datos contenidos
- en una tabla de una base de datos deberia conocer la clave primaria del objeto a cargar, o alguna
- otra combinacion de columnas que lo identifiquen univocamente.
-
- \param connection Conexion usada si fuera necesario acceder al medio fisico.
- \param creator Creador encargado de generar el objeto de forma que sea facil de localizar posteriormente
- en el area de almacenamiento.
-
- \return La nueva instancia que cumple el patron establecido por el creador.
-
- \warning Cada llamada a este metodo deberia tener su correspondiente liberacion invocando a #release
- cuando dejemos de usar la instancia.
- */
- static T* create(dbms::Connection& connection, Creator& creator)
- throw(RuntimeException, dbms::DatabaseException) {
- if(st_storageArea == NULL) {
- std::string msg(creator.asString());
- msg += " | ObjectFacade uninitialized ";
- throw RuntimeException(msg, ANNA_FILE_LOCATION);
- }
-
- return static_cast <T*>(st_storageArea->create(connection, creator));
- }
-
- /**
- Devuelve la informacion de un objeto cargado desde el medio fisico.
-
- Este cargador deberia tener todos los datos necesarios para localizar la informacion del objeto que
- debe buscar. Por ejemplo, en caso de tener que obtener el objeto a partir de los datos contenidos
- en una tabla de una base de datos deberia conocer la clave primaria del objeto a cargar, o alguna
- otra combinacion de columnas que lo identifiquen univocamente.
-
- \param loader Cargador de clase encargado de localizar la informacion referente al objeto buscado.
-
- \return Una instancia que cumple el patron establecido por el cargador. Puede ser NULL si el
- objeto no fue cargado en el area de almacenamiento.
-
- \warning Cada llamada a este metodo deberia tener su correspondiente liberacion invocando a #release
- cuando dejemos de usar la instancia.
- */
- static T* find(Loader& loader)
- throw(RuntimeException) {
- if(st_storageArea == NULL) {
- std::string msg(loader.asString());
- msg += " | ObjectFacade uninitialized ";
- throw RuntimeException(msg, ANNA_FILE_LOCATION);
- }
-
- return static_cast <T*>(st_storageArea->find(loader));
- }
-
- /**
- Habilita la reutilizacion del espacio de memoria ocupado por un objeto alojado en el area de almacenamiento.
-
- Este metodo no saca al objeto de la memoria de almacenamiento, sino que marca su espacio de memoria
- como subceptible de ser reutilizado. De esta forma, si el numero de objetos cargados en memoria se
- acerca al tamao maximo indicado en la inicializacion, se intentara reusar espacios libres en vez
- de continuar ampliando la memoria reservada.
-
- \param t Instancia del tipo T que vamos a liberar.
-
- \warning Si el objeto recibido como parametro no fue reservado mediate alguno de los metodos de reserva de
- objetos ofrecidos por esta clase no tendra ningun efecto.
- */
- static void release(T*& t)
- throw() {
- if(st_storageArea == NULL)
- return;
-
- try {
- st_storageArea->release(reinterpret_cast <Object**>(&t));
- } catch(RuntimeException& ex) {
- ex.trace();
- }
- }
-
- /**
- Descarga todos los objetos contenidos en el area de almacenamiento.
- */
- static void clear()
- throw(RuntimeException) {
- if(st_storageArea == NULL)
- throw RuntimeException("ObjectFacade uninitialized ", ANNA_FILE_LOCATION);
-
- st_storageArea->clear();
- }
-
- /**
- Devuelve de una copia del objeto recibido como parametro e incrementa la cuenta de utilizacion
- asociada a la instancia.
-
- \param t Instancia del tipo T obtenida mediate el metodo #instance.
-
- \return Una copia del objeto recibido como parametro. Si el parametro recibido es NULL devolveria NULL.
-
- \warning Cada llamada a este metodo deberia tener su correspondiente liberacion invocando a #release
- cuando dejemos de usar la instancia.
- */
- static T* duplicate(const T* t)
- throw(RuntimeException) {
- if(st_storageArea == NULL)
- throw RuntimeException("ObjectFacade uninitialized ", ANNA_FILE_LOCATION);
-
- return static_cast <T*>(st_storageArea->duplicate(t));
- }
-
- /**
- Permite conocer si un determinado objeto esta alojado en el area de almacenamiento.
-
- \param loader Cargador de clase encargado de localizar la informacion referente al objeto buscado.
-
- \return \em true Si el objeto identificado por el Loader esta en el area de almacenamiento o
- \em false en otro caso.
- */
- static bool isLoaded(const Loader& loader)
- throw(RuntimeException) {
- if(st_storageArea == NULL)
- throw RuntimeException("ObjectFacade uninitialized ", ANNA_FILE_LOCATION);
-
- return st_storageArea->isLoaded(loader);
- }
-
- /**
- Transfiere la informacion del objeto recibido como parametro al medio fisico usando el Recorder
- recibido como parametro.
-
- \param connection Conexion usada si fuera necesario extraer los datos del medio fisico.
- \param recorder Grabador usado para transferir los datos al medio fisico.
- */
- static void apply(dbms::Connection& connection, Recorder& recorder)
- throw(RuntimeException, dbms::DatabaseException) {
- if(st_storageArea == NULL) {
- std::string msg(recorder.asString());
- msg += " | ObjectFacade uninitialized";
- throw RuntimeException(msg, ANNA_FILE_LOCATION);
- }
-
- st_storageArea->apply(connection, recorder);
- }
-
- /**
- Elimina la informacion del objeto recibido como parametro del medio fisico usando el Eraser
- recibido como parametro.
-
- \param connection Conexion usada si fuera necesario extraer los datos del medio fisico.
- \param eraser Objecto usado para eliminar los datos al medio fisico.
-
- \warning Si la cuanta de utilizacion de T es 1 se liberaria en otro caso se devolveria una excepcion.
- */
- static void apply(dbms::Connection& connection, Eraser& eraser)
- throw(RuntimeException, dbms::DatabaseException) {
- if(st_storageArea == NULL) {
- std::string msg(eraser.asString());
- msg += " | ObjectFacade uninitialized";
- throw RuntimeException(msg, ANNA_FILE_LOCATION);
- }
-
- st_storageArea->apply(connection, eraser);
- }
-
- /**
- Elimina toda la informacion referente al objeto recibido como parametro, siempre y cuando
- solo tenga un unica referencia activa. Descarga el objeto de la memoria de almacenamiento,
-
- \param t Instancia del tipo T que vamos a descargar de la memoria de almacenamiento.
-
- \warning \li Si el objeto recibido como parametro no fue reservado mediate #instance no tiene
- ningun efecto. \li La instancia a liberar solo puede tener 1 en su cuenta de utilizacion.
- \li La memoria asignada a la instancia recibida es liberada, por lo que podemos evitar la invocacion
- al metodo #release para esta instancia.
- */
- static void erase(T*& t)
- throw(RuntimeException) {
- if(st_storageArea == NULL)
- return;
-
- st_storageArea->erase(reinterpret_cast <Object**>(&t));
- }
-
- /**
- Devuelve el puntero sobre el que estaria posicionado el iterador recibido como parametro.
- \return El puntero sobre el que estaria posicionado el iterador recibido como parametro.
- */
- static T* data(StorageArea::iterator& ii) throw() { return static_cast <T*>(StorageArea::data(ii)); }
-
- /**
- Devuelve el puntero sobre el que estaria posicionado el iterador recibido como parametro.
- \return El puntero sobre el que estaria posicionado el iterador recibido como parametro.
- */
- static const T* data(StorageArea::const_iterator& ii) throw() { return static_cast <const T*>(StorageArea::data(ii)); }
-
- /**
- Metodo creador de nuevas instancias de la clase T.
- \return Una nueva instancia del tipo de objeto T.
- \warning Solo deberia ser llamado desde anna::comm::StorageArea cuando sea preciso crear
- nuevas instancias de objetos.
- */
- static Object* allocator() throw() { return new T; }
-
-protected:
- static StorageArea* st_storageArea;
-
- /**
- Constructor.
- */
- ObjectFacade() {}
-};
-
-}
-}
-
-/**
- Definicion a la que hay que invocar en la implementacion de la clase que hereda
- de anna::dbos::ObjectFacade.
-
- \param T Nombre de la clase que vamos a tratar en el ambito de C++.
-*/
-#define dbos_prepare_object(T) \
- template <> anna::dbos::StorageArea* anna::dbos::ObjectFacade< T >::st_storageArea = NULL
-
-/**
- Definicion a la que hay que invocar dentro de la definicion de la clase que hereda
- de anna::dbos::ObjectFacade.
-
- \param T Nombre de la clase que vamos a tratar en el ambito de C++.
-*/
-#define dbos_declare_object(T) \
- friend class anna::dbos::ObjectFacade <T>
-
-
-#endif
+++ /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_Recorder_hpp
-#define anna_dbos_Recorder_hpp
-
-#include <anna/dbos/Accesor.hpp>
-
-namespace anna {
-
-namespace dbos {
-
-/**
- Interfaz que deben cumplir los objetos encargados de grabar el objeto en el medio fisico,
- que normalmente sera alguna base de datos.
-*/
-class Recorder : public Accesor {
-public:
- /**
- Metodo de debemos re-escribir para devolver el nombre completo del selector de recursos.
- Para evitar ambigüedades este nombre deberia incluir la lista completa de \em namespaces
- a la que pertenece la clase.
- \return Una cadena con el nombre de este selector.
- */
- virtual const char* getClassName() const throw() { return "anna::dbos::Recorder"; }
-
-protected:
- /**
- Constructor.
- \param database Base de datos asociada a este cargador y que deberia servir para
- obtener los datos de un objeto. Debe tener la misma disponibilidad que este cargador.
- \param id Identificador de este accesor.
- */
- Recorder(dbms::Database& database, const Id id = 0) : Accesor(database, id) {;}
-
-private:
- Index getIndex() const throw() { return 0; } // No se usa
-};
-
-}
-}
-
-#endif
-
-
-
+++ /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_Repository_hpp
-#define anna_dbos_Repository_hpp
-
-#include <vector>
-
-#include <anna/core/mt/Mutex.hpp>
-
-#include <anna/dbos/StorageArea.hpp>
-#include <anna/dbos/defines.hpp>
-
-namespace anna {
-
-namespace xml {
-class Node;
-}
-
-namespace comm {
-class INetAddress;
-class Delivery;
-}
-
-namespace dbms {
-class Connection;
-}
-
-namespace dbos {
-
-/**
- Clase que modela la interaccion entre la base y nuestra aplicacion.
-*/
-class Repository : public Mutex {
-public:
- typedef std::map <StorageId, StorageArea*> container;
- typedef container::const_iterator const_storage_iterator; /**<Iterador para acceder a las areas de almacenamiento de esta base de datos */
- typedef container::iterator storage_iterator; /**<Iterador para acceder a las areas de almacenamiento de esta base de datos */
-
- /**
- Constructor.
- \param name Nombre logico del repositorio de areas de almacenamiento.
- */
- explicit Repository(const char* name);
-
- /**
- Constructor.
- \param name Nombre logico del repositorio de areas de almacenamiento.
- */
- explicit Repository(const std::string& name);
-
- /**
- Crea una nueva area de almacenamiento para objetos cargados a partir de un medio fisico, normalmente
- la base de datos.
-
- El tipo de dato de esta nueva area vendria definida implicitamente por el tipo de factoria empleadas
- para instanciar y/o liberar los objetos y sus respectivos registros.
-
- \param index Clave que seria usada para localizar el area de almacenamiento.
- \param name Nombre logico de la nueva area de almacenamiento.
- \param maxSize Limita el numero maximo de objetos que pueden estar cargados simultanemante en memoria.
- Si se alcanza este limite pero no hay ningun objeto susceptible de ser sacado de la memoria de almacenamiento
- se ampliaria automaticamente la reserva de memoria necesaria para cargar nuevos objetos, en tanto en cuanto
- no se libere alguno de los objetos cargados. Ver StorageArea::StandardSize.
- \param objectAllocator actoria de objetos usada para crear las nuevas instancias en este area de
- almacenamiento.
- \param errorCode Cdigo de error asociado a la excepcin lanzada por el metodo StorageArea::instantiate
- en caso de que no se encuentre el objeto buscado. Si vale StorageArea::NoExceptionWhenNotFound en
- caso de no encontrar el objeto no se devolveriaexcepcin y el valor retornado seria NULL.
- \param aamm Modo de acceso de este area de almacenamiento.
-
- \warning Las dos actorias deben estar disponibles desde el momento de invocar a este metodo hasta la
- finalizacin de esta instancia de base de datos.
- */
- StorageArea* createStorageArea(const StorageId index, const char* name, const Size maxSize, ObjectAllocator objectAllocator, const int errorCode, const StorageArea::AccessMode::_v aamm = StorageArea::AccessMode::ReadOnly)
- throw(RuntimeException);
-
- /**
- Devuelve la instancia del area de almacenamiento asociada al indice recibido.
-
- \param index Indice del area de almacenamiento.
-
- \return La instancia del area de almacenamiento asociada al indice recibido. Puede ser NULL si el
- indice no fue usado para crear un area mediate #createStorageArea.
- */
- StorageArea* findStorageArea(const StorageId index) throw();
-
- /**
- Elimina todos los objetos cargados en las areas de almacenamiento definidas.
- */
- void clear() throw(RuntimeException);
-
- /**
- Devuelve un iterator al comienzo de la lista de areas de almacenamiento de esta base de datos.
- \return Un iterator al comienzo de la lista de areas de almacenamiento de esta base de datos.
- */
- const_storage_iterator storage_begin() const throw() { return a_storageAreas.begin(); }
-
- /**
- Devuelve un iterator al final de la lista de areas de almacenamiento de esta base de datos.
- \return Un iterator al final de la lista de areas de almacenamiento de esta base de datos.
- */
- const_storage_iterator storage_end() const throw() { return a_storageAreas.end(); }
-
- /**
- Devuelve el objeto sobre el que esta posicionado el iterator recibido como parametro.
- \param ii Iterator que deberia estar comprendido entre #const_storage_begin y #const_storage_end.
- \return El objeto sobre el que esta posicionado el iterator recibido como parametro.
- */
- static const StorageArea* storageArea(const_storage_iterator& ii) throw() { return ii->second; }
-
- /**
- Devuelve un documento XML con la informacion referente a esta instancia.
- \param parent Nodo XML del que dependende la informacion.
- @return un documento XML con la informacion referente a esta instancia.
- */
- xml::Node* asXML(xml::Node* parent) const throw();
-
-protected:
- /**
- Devuelve un iterator al comienzo de la lista de areas de almacenamiento de esta base de datos.
- \return Un iterator al comienzo de la lista de areas de almacenamiento de esta base de datos.
- */
- storage_iterator storage_begin() throw() { return a_storageAreas.begin(); }
-
- /**
- Devuelve un iterator al final de la lista de areas de almacenamiento de esta base de datos.
- \return Un iterator al final de la lista de areas de almacenamiento de esta base de datos.
- */
- storage_iterator storage_end() throw() { return a_storageAreas.end(); }
-
- /**
- Devuelve el objeto sobre el que esta posicionado el iterator recibido como parametro.
- \param ii Iterator que deberia estar comprendido entre #const_storage_begin y #const_storage_end.
- \return El objeto sobre el que esta posicionado el iterator recibido como parametro.
- */
- static StorageArea* storageArea(storage_iterator& ii) throw() { return ii->second; }
-
-private:
- std::string a_name;
- container a_storageAreas;
-
- Repository(const Repository&);
-};
-
-}
-}
-
-#endif
+++ /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
-
-
+++ /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_SetFacade_hpp
-#define anna_dbos_SetFacade_hpp
-
-#include <vector>
-
-#include <anna/dbos/Set.hpp>
-#include <anna/dbos/ObjectFacade.hpp>
-
-namespace anna {
-
-namespace dbos {
-
-/**
- Clase que facilita el acceso y uso de las clases encargadas de la instanciacion de multiples objetos a partir de los
- datos contenidos en un medio fisico, que normalmente seria la tabla de una base de datos.
-
- Esta nos facilita el manejo de instancias multiples, es decir, para una condicion de carga dada hay varios registros
- o elementos del medio fisico que la cumplen.
-
- La clase \em T debe tener definidos los siquientes metodos:
- \li anna::dbos::Object::instantiate: Interpreta la informacin la del medio fisico para adecuarla a
- la clase C++.
- \li void destroy () throw (): Libera los recursos reservados por este objeto
-
- \see dbos_declare_set
- \see dbos_prepare_set
-*/
-template <typename T> class SetFacade : public ObjectFacade < Set <T> > {
-public:
- typedef typename Set<T>::iterator iterator;
- typedef typename Set<T>::const_iterator const_iterator;
-
- /**
- Devuelve el numero de elementos contenidos en el conjunto recibido como parametro.
- Se puede usar sin tener que preocuparse por
- el valor de la instancia del conjunto, ya que si este es NULL devolveria 0.
- \param t Instancia del conjunto.
- \return El numero de elementos que contiene el conjunto.
- */
- static int size(Set<T>* t) throw() { return (t == NULL) ? 0 : t->size(); }
-
- /**
- Iterator al primer elemento del conjunto. Se puede usar sin tener que preocuparse por
- el valor de la instancia del conjunto, ya que si este es NULL devolveria 0.
- \return Un iterador del primer elemento del conjunto.
- */
- static iterator begin(Set<T>* t) throw() {
- return (t == NULL) ? iterator(0) : t->begin();
- }
-
- /**
- Iterator al ultimo elemento del conjunto. Se puede usar sin tener que preocuparse por
- el valor de la instancia del conjunto, ya que si este es NULL devolveria 0.
- \return Un iterador del primer elemento del conjunto.
- */
- static iterator end(Set<T>* t) throw() {
- return (t == NULL) ? iterator(0) : t->end();
- }
-
- /**
- Iterator al primer elemento del conjunto. Se puede usar sin tener que preocuparse por
- el valor de la instancia del conjunto, ya que si este es NULL devolveria 0.
- \return Un iterador del primer elemento del conjunto.
- */
- static const_iterator begin(const Set<T>* t) throw() {
- return (t == NULL) ? const_iterator(0) : t->begin();
- }
-
- /**
- Iterator al ultimo elemento del conjunto. Se puede usar sin tener que preocuparse por
- el valor de la instancia del conjunto, ya que si este es NULL devolveria 0.
- \return Un iterador del primer elemento del conjunto.
- */
- static const_iterator end(const Set<T>* t) throw() {
- return (t == NULL) ? const_iterator(0) : t->end();
- }
- /**
- Devuelve el objeto referenciado por el iterator recibido como parametro.
- \return El objeto referenciado por el iterator recibido como parametro.
- */
- static T* data(iterator ii) throw() { return Set<T>::data(ii); }
-
- /**
- Devuelve el objeto referenciado por el iterator recibido como parametro.
- \return El objeto referenciado por el iterator recibido como parametro.
- */
- static const T* data(const_iterator ii) throw() { return Set<T>::data(ii); }
-
-protected:
- /**
- Contructor.
- */
- SetFacade() {}
-};
-
-/**
- Definicion a la que hay que invocar en la implementacion de la clase que hereda
- de anna::dbos::SetFacade.
-
- \param T Nombre de la clase que vamos a tratar en el ambito de C++.
-*/
-#define dbos_prepare_set(T) \
- template <> anna::dbos::StorageArea* anna::dbos::ObjectFacade < anna::dbos::Set <T> >::st_storageArea = NULL
-
-/**
- Definicion a la que hay que invocar dentro de la definicion de la clase que hereda
- de anna::dbos::SetFacade.
-
- \param T Nombre de la clase que vamos a tratar en el ambito de C++.
-*/
-#define dbos_declare_set(T) \
- friend class anna::Allocator<T>; \
- friend class anna::dbos::Set <T>
-
-}
-}
-
-#endif
+++ /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_StorageArea_hpp
-#define anna_dbos_StorageArea_hpp
-
-#include <vector>
-#include <map>
-#include <list>
-#include <deque>
-
-#include <algorithm>
-
-#include <anna/core/mt/Mutex.hpp>
-#include <anna/config/defines.hpp>
-#include <anna/core/util/SortedVector.hpp>
-
-#include <anna/dbms/DatabaseException.hpp>
-
-#include <anna/dbos/defines.hpp>
-#include <anna/dbos/ObjectAllocator.hpp>
-
-namespace anna {
-
-namespace xml {
-class Node;
-}
-
-namespace dbms {
-class Connection;
-}
-
-namespace dbos {
-
-class Accesor;
-class Object;
-class Creator;
-class Loader;
-class Recorder;
-class Eraser;
-class Repository;
-class CrossedLoader;
-
-/**
- Area de almacenamiento de los objetos obtenidos a partir de los datos guardados en un medio
- fisico, que normalmente seria una base de datos.
-
- La creacion de cualquier área de almacenamiento debe hacerse mediante el método
- anna::dbos::Repository::createStorageArea.
-
- \warning Exclusivamente para uso interno de anna.dbos
-*/
-class StorageArea : public Mutex {
- struct Instance;
- class Block;
- class Holes;
-
-public:
- /**
- Modo de acceso al área de almacenamiento.
- */
- struct AccessMode {
- enum _v {
- /**
- Carga el objeto una vez y no lo vuelve a comprobar mientras tena un estado valido.
- No permite la creacion de nuevos objetos.
- */
- ReadOnly,
- /**
- Carga el objeto una vez e intenta recargarlo cada vez que su cuenta de utilizacion
- sea cero. Se invocara al método dbos::Object::needUpdate () que se ejecuta antes de
- realizar ninguna operacion sobre el medio fisico, si devuelve 'true' cargaria la
- informacion mediante el dbos::Loader correspondiente y se invocaria al
- método dbos::Object::hasChange (dbos::Loader&).
- */
- ReadWrite,
- /**
- Comprueba la recarga del objeto cada vez que se accede a el. Se invocara al método dbos::Object::needUpdate () que se ejecuta antes de
- realizar ninguna operacion sobre el medio fisico, si devuelve 'true' cargaria la
- informacion mediante el dbos::Loader correspondiente y se invocaria al
- método dbos::Object::hasChange (dbos::Loader&).
- */
- ReadEver
- };
-
- /*
- Devuelve el literal correspondiente al codigo recibido.
- \param v Codigo a traducir a literal.
- \return el literal correspondiente al codigo recibido.
- */
- static const char* asString(const _v v) throw();
- };
-
- /**
- Flags usados para marcar los registros cargados en memoria.
- \warning Exclusivamente uso interno.
- */
- struct Flag {
- enum _v {
- None = 0, Dirty = 1, Incoherent = 2, Empty = 4, HasHole = 8, Ready = 16, InProgress = 32,
- NoDirty = ~Dirty, NoIncoherent = ~Incoherent, NoEmpty = ~Empty, NoHasHole = ~HasHole, NoReady = ~Ready, Done = ~InProgress
- };
- };
-
- /**
- Tamaños normalizados del área de almacenamiento.
-
- @see StorageArea
- */
- struct StandardSize {
- enum Value {
- Tiny = 16, /**< Intenta que el número de registros cargados no supere los 16 registros. */
- Little = 64, /**< Intenta que el número de registros cargados no supere los 64 registros. */
- Small = 256, /**<Intenta que el número de registros cargados no supere los 256 registros.*/
- Medium = 2048, /**<Intenta que el número de registros cargados no supere los 2048 registros.*/
- Large = 8192, /**<Intenta que el número de registros cargados no supere los 8192 registros.*/
- Huge = 32768, /**<Intenta que el número de registros cargados no supere los 32768 registros.*/
- LargeHuge = 65536, /**<Intenta que el número de registros cargados no supere los 65536 registros.*/
- Biggest = 131072 /**<Intenta que el número de registros cargados no supere los 131072 registros.*/
- };
- };
-
- /**
- Valor que hay que indicar al crear el área de almacenamiento (ver anna::dbos::Repository::createStorageArea)
- para que el método #instance no devuelva excepcion de ejecucion en caso de no encontrar el
- registro buscado.
- */
- static const int NoExceptionWhenNotFound = -1;
-
- typedef std::vector <Block*> Blocks; /**< Estructura para mantener los bloques de objetos */
- typedef std::map <Index, Instance*>::iterator iterator; /**< Definicion para recorrer los objetos del área de almacenamiento */
- typedef std::map <Index, Instance*>::const_iterator const_iterator; /**< Definicion para recorrer los objetos del área de almacenamiento */
-
- /**
- Destructor.
- */
- virtual ~StorageArea();
-
- /**
- * Devuelve el código de error asociado a la excepción cuando no se encuentra un registro buscado.
- * \return el código de error asociado a la excepción cuando no se encuentra un registro buscado.
- */
- int getErrorCode() const throw() { return a_errorCode; }
-
- /*
- * Devuelve el nombre de la este área de almacenamiento.
- * \return el nombre de la este área de almacenamiento.
- */
- const std::string& getName() const throw() { return a_name; }
-
- /**
- Carga la informacion de un objeto contenida en un medio fisico y la interpreta para adecuarla a
- una clase C++.
-
- Este cargador deberia tener todos los datos necesarios para localizar la informacion del objeto que
- debe cargar. Por ejemplo, en caso de tener que obtener el objeto a partir de los datos contenidos
- en una tabla de una base de datos deberia conocer la clave primaria del objeto a cargar, o alguna
- otra combinacion de columnas que lo identifiquen univocamente.
-
- \param connection Conexion usada si fuera necesario extraer los datos del medio fisico.
- \param loader Cargador de clase encargado de localizar y obtener la informacion referente al objeto
- que deseamos cargar en memoria.
-
- \return Una instancia que cumple el patron establecido por el cargador. Puede ser NULL en caso de
- que al inicializar esta clase \em errorCode se halla indicado un #NoExceptionWhenNotFound en otro
- caso si no encuentra el objeto que cumpla el patron devolveria una excepcion de ejecucion.
-
- \warning Cada llamada a este método deberia tener su correspondiente liberacion invocando a #release
- cuando dejemos de usar la instancia.
- */
- Object* instance(dbms::Connection& connection, Loader& loader) throw(RuntimeException, dbms::DatabaseException) {
- return instance(&connection, loader);
- }
-
- /**
- Carga la informacion de un objeto contenida en un medio fisico y la interpreta para adecuarla a
- una clase C++.
-
- Este cargador deberia tener todos los datos necesarios para localizar la informacion del objeto que
- debe cargar. Por ejemplo, en caso de tener que obtener el objeto a partir de los datos contenidos
- en una tabla de una base de datos deberia conocer la clave primaria del objeto a cargar, o alguna
- otra combinacion de columnas que lo identifiquen univocamente.
-
- \param connection Conexion usada si fuera necesario extraer los datos del medio fisico.
- \param loader Cargador de clase encargado de localizar y obtener la informacion referente al objeto
- que deseamos cargar en memoria.
-
- \return Una instancia que cumple el patron establecido por el cargador. Puede ser NULL en caso de
- que al inicializar esta clase \em errorCode se halla indicado un #NoExceptionWhenNotFound en otro
- caso si no encuentra el objeto que cumpla el patron devolveria una excepcion de ejecucion.
-
- \warning Cada llamada a este método deberia tener su correspondiente liberacion invocando a #release
- cuando dejemos de usar la instancia.
- */
- Object* instance(dbms::Connection* connection, Loader& loader) throw(RuntimeException, dbms::DatabaseException);
-
- /**
- Carga la informacion de un objeto contenida en un medio fisico y la interpreta para adecuarla a
- una clase C++.
-
- Este cargador deberia tener todos los datos necesarios para localizar la informacion del objeto que
- debe cargar. Por ejemplo, en caso de tener que obtener el objeto a partir de los datos contenidos
- en una tabla de una base de datos deberia conocer la clave primaria del objeto a cargar, o alguna
- otra combinacion de columnas que lo identifiquen univocamente.
-
- \param connection Conexion usada si fuera necesario extraer los datos del medio fisico.
- \param crossedLoader Cargador encargado de encontrar la clave principal a aplicar con el #Loader
- recibido como parámetro en base a una clave alternativa contenida en el mismo.
- \param loader Cargador de clase encargado de localizar y obtener la informacion referente al objeto
- que deseamos cargar en memoria.
-
- \return Una instancia que cumple el patron establecido por el cargador. Puede ser NULL en caso de
- que al inicializar esta clase \em errorCode se halla indicado un #NoExceptionWhenNotFound en otro
- caso si no encuentra el objeto que cumpla el patron devolveria una excepcion de ejecucion.
-
- \warning Cada llamada a este método deberia tener su correspondiente liberacion invocando a #release
- cuando dejemos de usar la instancia.
- */
- Object* instance(dbms::Connection& connection, CrossedLoader& crossedLoader, Loader& loader)
- throw(RuntimeException, dbms::DatabaseException) {
- return instance(&connection, crossedLoader, loader);
- }
-
- /**
- Carga la informacion de un objeto contenida en un medio fisico y la interpreta para adecuarla a
- una clase C++.
-
- Este cargador deberia tener todos los datos necesarios para localizar la informacion del objeto que
- debe cargar. Por ejemplo, en caso de tener que obtener el objeto a partir de los datos contenidos
- en una tabla de una base de datos deberia conocer la clave primaria del objeto a cargar, o alguna
- otra combinacion de columnas que lo identifiquen univocamente.
-
- \param connection Conexion usada si fuera necesario extraer los datos del medio fisico.
- \param crossedLoader Cargador encargado de encontrar la clave principal a aplicar con el #Loader
- recibido como parámetro en base a una clave alternativa contenida en el mismo.
- \param loader Cargador de clase encargado de localizar y obtener la informacion referente al objeto
- que deseamos cargar en memoria.
-
- \return Una instancia que cumple el patron establecido por el cargador. Puede ser NULL en caso de
- que al inicializar esta clase \em errorCode se halla indicado un #NoExceptionWhenNotFound en otro
- caso si no encuentra el objeto que cumpla el patron devolveria una excepcion de ejecucion.
-
- \warning Cada llamada a este método deberia tener su correspondiente liberacion invocando a #release
- cuando dejemos de usar la instancia.
- */
- Object* instance(dbms::Connection* connection, CrossedLoader& crossedLoader, Loader& loader)
- throw(RuntimeException, dbms::DatabaseException);
-
- /**
- Carga la informacion de un objeto contenida en un medio fisico y la interpreta para adecuarla a
- una clase C++.
-
- Este cargador deberia tener todos los datos necesarios para localizar la informacion del objeto que
- debe cargar.
-
- \param loader Cargador de clase encargado de localizar y obtener la informacion referente al objeto
- que deseamos cargar en memoria.
-
- \return Una instancia que cumple el patron establecido por el cargador. Puede ser NULL en caso de
- que al inicializar esta clase \em errorCode se halla indicado un #NoExceptionWhenNotFound en otro
- caso si no encuentra el objeto que cumpla el patron devolveria una excepcion de ejecucion.
-
- \warning Cada llamada a este método deberia tener su correspondiente liberacion invocando a #release
- cuando dejemos de usar la instancia.
- \warning Para usar este método se requiere haber re-escrito el método virtual Loader::load para que no intente
- obtener los datos desde la base de datos.
- */
- Object* instance(Loader& loader) throw(RuntimeException, dbms::DatabaseException) {
- return instance(NULL, loader);
- }
-
- /**
- Crea un objeto en el área de almacenamiento un y lo prepara para ser transferido al medio fisico
- si fuera necesario.
-
- Este cargador deberia tener todos los datos necesarios para localizar la informacion del objeto que
- debe cargar. Por ejemplo, en caso de tener que obtener el objeto a partir de los datos contenidos
- en una tabla de una base de datos deberia conocer la clave primaria del objeto a cargar, o alguna
- otra combinacion de columnas que lo identifiquen univocamente.
-
- \param connection Conexion usada si fuera necesario acceder al medio fisico.
- \param creator Creador encargado de generar el objeto en el área de almacenamiento.
-
- \return La nueva instancia que cumple el patron establecido por el creador.
-
- \warning \li Cada llamada a este método deberia tener su correspondiente liberacion invocando a #release
- cuando dejemos de usar la instancia.
- \li No puede usarse en las áreas de almacenamiento definidas como AccessMode::ReadOnly.
- */
- Object* create(dbms::Connection& connection, Creator& creator) throw(RuntimeException, dbms::DatabaseException) {
- return create(&connection, creator);
- }
-
- /**
- Crea un objeto en el área de almacenamiento un y lo prepara para ser transferido al medio fisico
- si fuera necesario.
-
- Este cargador deberia tener todos los datos necesarios para localizar la informacion del objeto que
- debe cargar. Por ejemplo, en caso de tener que obtener el objeto a partir de los datos contenidos
- en una tabla de una base de datos deberia conocer la clave primaria del objeto a cargar, o alguna
- otra combinacion de columnas que lo identifiquen univocamente.
-
- \param connection Conexion usada si fuera necesario acceder al medio fisico.
- \param creator Creador encargado de generar el objeto en el área de almacenamiento.
-
- \return La nueva instancia que cumple el patron establecido por el creador.
-
- \warning \li Cada llamada a este método deberia tener su correspondiente liberacion invocando a #release
- cuando dejemos de usar la instancia.
- \li No puede usarse en las áreas de almacenamiento definidas como AccessMode::ReadOnly.
- */
- Object* create(dbms::Connection* connection, Creator& creator) throw(RuntimeException, dbms::DatabaseException);
-
- /**
- Crea un objeto en el área de almacenamiento y lo prepara para ser transferido al medio fisico
- si fuera necesario.
-
- Este cargador deberia tener todos los datos necesarios para localizar la informacion del objeto que
- debe cargar.
-
- \param creator Creador encargado de generar el objeto en el área de almacenamiento.
-
- \return La nueva instancia que cumple el patron establecido por el creador.
-
- \warning \li Cada llamada a este método deberia tener su correspondiente liberacion invocando a #release
- cuando dejemos de usar la instancia.
- \li No puede usarse en las áreas de almacenamiento definidas como AccessMode::ReadOnly.
- */
- Object* create(Creator& creator) throw(RuntimeException, dbms::DatabaseException) { return create(NULL, creator); }
-
- /**
- Devuelve la informacion de un objeto cargado desde el medio fisico.
-
- Este cargador deberia tener todos los datos necesarios para localizar la informacion del objeto que
- debe buscar. Por ejemplo, en caso de tener que obtener el objeto a partir de los datos contenidos
- en una tabla de una base de datos deberia conocer la clave primaria del objeto a cargar, o alguna
- otra combinacion de columnas que lo identifiquen univocamente.
-
- \param loader Cargador de clase encargado de localizar la informacion referente al objeto buscado.
-
- \return Una instancia que cumple el patron establecido por el cargador. Puede ser NULL si el
- objeto no fue cargado en el área de almacenamiento.
-
- \warning Cada llamada a este método deberia tener su correspondiente liberacion invocando a #release
- cuando dejemos de usar la instancia.
- */
- Object* find(Loader& loader) throw(RuntimeException);
-
- /**
- Devuelve de una copia del objeto recibido como parámetro e incrementa la cuenta de utilizacion
- asociada a la instancia.
-
- \param object Instancia obtenida mediate el método #instance.
-
- \return Una copia del objeto recibido como parámetro. Si el parámetro recibido es NULL devolveria NULL.
-
- \warning Cada llamada a este método deberia tener su correspondiente liberacion invocando a #release
- cuando dejemos de usar la instancia.
- */
- Object* duplicate(const Object* object) throw(RuntimeException);
-
- /**
- Permite conocer si un determinado objeto esta alojado en el área de almacenamiento. No
- cambia la cuenta de utilizacion de los objetos ni provoca cambios en las estadisticas
- de aciertos.
-
- \param loader Cargador de clase encargado de localizar la informacion referente al objeto buscado.
-
- \return \em true Si el objeto identificado por el Loader esta en el área de almacenamiento o
- \em false en otro caso.
- */
- bool isLoaded(const Loader& loader) throw(RuntimeException);
-
- /**
- Transfiere la informacion del objeto recibido como parámetro al medio fisico usando el Recorder
- recibido como parámetro.
-
- \param connection Conexion usada si fuera necesario acceder al medio fisico.
- \param recorder Grabador usado para transferir los datos al medio fisico.
- */
- void apply(dbms::Connection& connection, Recorder& recorder) throw(RuntimeException, dbms::DatabaseException);
-
- /**
- Elimina la informacion del objeto recibido como parámetro del medio fisico usando el Eraser
- recibido como parámetro.
-
- \param connection Conexion usada si fuera necesario acceder al medio fisico.
- \param eraser Objecto usado para eliminar los datos al medio fisico.
-
- \warning Si la cuenta de utilizacion del objeto es 1 se liberaría en otro caso se devolvería una excepción.
- */
- void apply(dbms::Connection& connection, Eraser& eraser) throw(RuntimeException, dbms::DatabaseException);
-
- /**
- Habilita la reutilizacion del espacio de memoria ocupado por un objeto instanciado mediate #instance.
-
- Este método no saca al objeto de la memoria de almacenamiento, sino que marca su espacio de memoria
- como subceptible de ser reutilizado. De esta forma, si el número de objetos cargados en memoria se
- acerca al tamaño maximo indicado en la inicializacin, cuando halla que cargar un nuevo registro se
- reusaria el espacio libre en vez de seguir aumentando el tamaño de la memoria de almacenamiento.
-
- \param object Instancia del objeto que vamos a liberar.
-
- \warning Si el objeto recibido como parámetro no fue reservado mediate #instance no tiene
- ningun efecto.
- */
- void release(Object** object) throw(RuntimeException);
-
- /**
- Elimina toda la informacion referente al objeto recibido como parámetro, siempre y cuando
- solo tenga un unica referencia activa. Descarga el objeto de la memoria de almacenamiento,
-
- \param object Instancia que vamos a descargar de la memoria de almacenamiento.
-
- \warning \li Si el objeto recibido como parámetro no fue reservado mediate #instance no tiene
- ningun efecto.
- \li La instancia a liberar solo puede tener 1 en su cuenta de utilizacion.
- */
- void erase(Object** object) throw(RuntimeException);
-
- /**
- Marca el objeto recibido como pendiente de recarga de datos.
-
- \param object Instancia que vamos a marcar como pendiente de recarga.
-
- \warning \li Si el objeto recibido como parámetro no fue reservado mediate #instance no tiene
- ningun efecto.
- \li La instancia a marcar solo deberia tener una unica instancia en uso.
- */
- void dirty(Object* object) throw(RuntimeException);
-
- /**
- Establece el tamanho de las instancias de los objetos contenidos en este área de almacenamiento.
- \param _sizeof Numero de bytes ocupado por cada una de las instancias.
- */
- void setSizeof(const Size _sizeof) throw() { a_sizeof = _sizeof + sizeof(Instance); }
-
- /**
- Devuelve el numero maximo de bytes teorico que puede llegar a reservar este área de almacenamiento.
- \return el numero maximo de bytes teorico que puede llegar a reservar este área de almacenamiento.
- */
- Size getMaxSizeOf() const throw() { return a_maxSize * a_sizeof; }
-
- /**
- Devuelve el numero de bytes teorico que puede llegar a reservar este área de almacenamiento.
- \return el numero de bytes teorico que puede llegar a reservar este área de almacenamiento.
- */
- Size getSizeOf() const throw() { return a_directory.size() * a_sizeof; }
-
- /**
- Devuelve un iterator al primero de los objetos contenido en el área del almacenamiento.
- \return Un iterator al primero de los objetos contenido en el área del almacenamiento.
- */
- iterator begin() throw() { return a_directory.begin(); }
-
- /**
- Devuelve un iterator al primero de los objetos contenido en el área del almacenamiento.
- \return Un iterator al primero de los objetos contenido en el área del almacenamiento.
- */
- const_iterator begin() const throw() { return a_directory.begin(); }
-
- /**
- Devuelve un iterator al fin de los objetos contenidos en el área del almacenamiento.
- \return Un iterator al fin de los objetos contenidos en el área del almacenamiento.
- */
- iterator end() throw() { return a_directory.end(); }
-
- /**
- Devuelve un iterator al fin de los objetos contenidos en el área del almacenamiento.
- \return Un iterator al fin de los objetos contenidos en el área del almacenamiento.
- */
- const_iterator end() const throw() { return a_directory.end(); }
-
- /**
- Devuelve el puntero sobre el que esta posicionado el iterador recibido como parámetro.
- \return El puntero sobre el que esta posicionado el iterador recibido como parámetro.
- */
- static Object* data(iterator ii) throw() { return ii->second->object; }
-
- /**
- Devuelve el puntero sobre el que esta posicionado el iterador recibido como parámetro.
- \return El puntero sobre el que esta posicionado el iterador recibido como parámetro.
- */
- static const Object* data(const_iterator ii) throw() { return ii->second->object; }
-
- /**
- Devuelve una cadena con la informacion referente a este área de almacenamiento.
- \return Una cadena con la informacion referente a este área de almacenamiento.
- */
- std::string asString() const throw();
-
- /**
- Devuelve un documento XML con la informacion referente a esta instancia.
- \param parent Nodo XML del que dependende la informacion.
- @return un documento XML con la informacion referente a esta instancia.
- */
- xml::Node* asXML(xml::Node* parent) const throw();
-
-protected:
- /**
- Descarga del área de almacenamiento todos los objetos que estuviera cargados.
- Este método se invoca desde anna::dbos::Repository::clear
- */
- void clear() throw(RuntimeException);
-
- /**
- Devuelve un literal con el entero recibido tratado como una cantidad en bytes.
- \return un literal con el entero recibido tratado como un cantidad en bytes
- */
- static std::string asMemorySize(const Size size) throw();
-
-private:
- typedef std::map <Index, Instance*>::value_type value_type;
-
- friend class Holes;
-
- class Holes {
- public:
- struct Mode { enum _v { ReadyToReuse, TimeWait }; };
-
- typedef std::list <Instance*> hole_container;
- typedef hole_container::iterator hole_iterator;
-
- Holes() : a_size(0) {;}
-
- bool insert(Instance* instance, const Mode::_v mode) throw();
- void erase(Instance* instance) throw();
- Instance* front() throw() { return a_holes.front(); }
- int size() const throw() { return a_size; }
- int empty() const throw() { return a_holes.empty(); }
- void pop_front() throw() { a_holes.pop_front(); a_size --; }
- void clear() throw() { a_holes.clear(); a_size = 0; }
-
- private:
- hole_container a_holes;
- int a_size;
- };
-
- //------------------------------------------------------------------------
- // - object: Puntero a la instancia con el objeto cacheado.
- // - msHoleTime: Millisecond en el que entra en la lista de huecos.
- // - copyCounter: Numero de copias del objeto.
- // - flags: Flags (Dirty, Incoherent, Empty).
- //------------------------------------------------------------------------
- friend struct Instance;
-
- struct Instance {
- Object* object;
- Counter copyCounter;
- int flags;
- Holes::hole_iterator holeIterator;
-
- Instance() : copyCounter(0), object(NULL), flags(Flag::None) {;}
- };
-
- friend class Block;
-
- class Block {
- public:
- Block(ObjectAllocator objectAllocator, const Size maxSize);
- Instance* getInstance() throw() { return (a_size < a_maxSize) ? &a_instances [a_size ++] : NULL; }
- void reset() throw() { a_size = 0; }
-
- private:
- Instance* a_instances;
- Size a_maxSize;
- Size a_size;
- };
-
- const std::string a_name;
- const Size a_maxSize;
- ObjectAllocator a_objectAllocator;
- const AccessMode::_v a_accessMode;
- int a_errorCode;
- Size a_sizeof;
-
- Blocks a_blocks;
- std::map <Index, Instance*> a_directory;
- Holes a_holes;
- Block* a_currentBlock;
- int a_indexBlock;
- Counter a_hit;
- Counter a_fault;
- Counter a_doneReuse;
-
- /*
- typedef std::deque <std::pair <DBIndex> inprogress_container;
- typedef inprogress_container::iterator inprogress_iterator;
- inprogress_container a_inprogress;
-
- inprogress_iterator inprogress_begin () const throw () { return a_inprogress.begin (); }
- inprogress_iterator inprogress_end () const throw () { return a_inprogress.end (); }
- static DBIndex index (inprogress_iterator ii) throw () { return *ii; }
- bool isInProgress (const DBIndex index) const throw ();
- */
-
- /*
- * Constructor.
- * \warning Este método sólo debería usarse desde el método dbos::Repository::allocateStorageArea.
- */
- StorageArea(const char* name, const Size maxSize, ObjectAllocator, const AccessMode::_v, const int errorCode);
- StorageArea(const StorageArea&);
-
- Object* reload(dbms::Connection*, Loader&, Instance*) throw(RuntimeException, dbms::DatabaseException);
- void checkIncoherence(Instance*) throw();
- bool quickReusing(Instance*) throw();
- void verifyStatus(StorageArea::Instance*, const bool ignoreDirty = false) throw(RuntimeException);
- Instance* allocate() throw();
- Instance* reuse() throw();
-
- static Instance* instance(iterator& ii) throw() { return ii->second; }
- static std::string asString(const Instance*) throw();
-
- friend class Repository;
-};
-
-}
-}
-
-#endif
+++ /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_dbos_hpp
-#define anna_dbos_dbos_hpp
-
-namespace anna {
-/**
-Define las clases y templates necesarias para convertir datos guardados en un medio fisico en
-clases totalmente funcionalines en C++.
-
-El ejecutable debera enlazarse con las librerias:
- \li anna.core.a
- \li anna.xml.a
- \li anna.app.a
- \li anna.comm.a
- \li anna.dbms.a
- \li anna.dbos.a
-
-El <b>Packet Header</b> es anna.dbos.h
-*/
-namespace dbos {
-}
-}
-
-#include <anna/dbos/Accesor.hpp>
-#include <anna/dbos/AutoObject.hpp>
-#include <anna/dbos/AutoSet.hpp>
-#include <anna/dbos/Creator.hpp>
-#include <anna/dbos/Eraser.hpp>
-#include <anna/dbos/Loader.hpp>
-#include <anna/dbos/Repository.hpp>
-#include <anna/dbos/Object.hpp>
-#include <anna/dbos/ObjectAllocator.hpp>
-#include <anna/dbos/ObjectFacade.hpp>
-#include <anna/dbos/Recorder.hpp>
-#include <anna/dbos/Set.hpp>
-#include <anna/dbos/SetFacade.hpp>
-#include <anna/dbos/StorageArea.hpp>
-#include <anna/dbos/CrossedLoader.hpp>
-
-using namespace anna::dbos;
-
-#endif
-
+++ /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_defines_hpp
-#define anna_dbos_defines_hpp
-
-#include <anna/config/defines.hpp>
-
-namespace anna {
-
-namespace dbos {
-typedef unsigned int Size;
-typedef U64 Index;
-typedef ptrnumber StorageId;
-typedef unsigned int Counter;
-}
-
-}
-
-#endif
-
+++ /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_internal_sccs_hpp
-#define anna_dbos_internal_sccs_hpp
-
-namespace anna {
-
-namespace dbos {
-
-class sccs {
-public:
- static void activate() throw();
-};
-
-}
-}
-
-#endif
-
+++ /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 //
-
-
-#include <mysql/mysql.h>
-
-#include <anna/core/DataBlock.hpp>
-
-#include <anna/dbms/Data.hpp>
-#include <anna/dbms/LongBlock.hpp>
-
-#include <anna/dbms.mysql/BaseBind.hpp>
-
-using namespace std;
-using namespace anna;
-
-//----------------------------------------------------------------------------
-// (1) Reserva 2 Kbytes para trabajar con el LOB.
-//----------------------------------------------------------------------------
-dbms::mysql::BaseBind::BaseBind(const dbms::Data& data) :
- a_type(data.getType()),
- a_time(NULL) {
- switch(a_type) {
- case Data::Type::ShortBlock:
- case Data::Type::LongBlock:
- break;
- case Data::Type::Date: // (1)
- case Data::Type::TimeStamp:
- a_time = new MYSQL_TIME;
- break;
- default: break;
- }
-}
-
-dbms::mysql::BaseBind::~BaseBind() {
- delete a_time;
-}
-
-/**
- * Según http://dev.mysql.com/doc/refman/4.1/en/c-api-prepared-statement-datatypes.html
- * y el truco para recoger BLOB's http://dev.mysql.com/doc/refman/4.1/en/mysql-stmt-fetch.html.
- */
-void dbms::mysql::BaseBind::setupBind(st_mysql_bind& bind, dbms::Data& data)
-throw(RuntimeException) {
- anna_memset(&bind, 0, sizeof(bind));
- bind.is_null = &a_nullIndicator;
- a_length = 0;
-
- switch(a_type) {
- case Data::Type::Integer:
- bind.buffer_type = MYSQL_TYPE_LONG;
- bind.buffer_length = data.getMaxSize();
- bind.length = &a_length;
- bind.buffer = const_cast <dbms::Data&>(data).getBuffer();
- bind.is_unsigned = false;
- break;
- case Data::Type::String:
- bind.buffer_type = MYSQL_TYPE_STRING;
- bind.buffer_length = data.getMaxSize();
- bind.length = &a_length;
- bind.buffer = const_cast <dbms::Data&>(data).getBuffer();
- break;
- case Data::Type::Float:
- bind.buffer_type = MYSQL_TYPE_FLOAT;
- bind.buffer_length = data.getMaxSize();
- bind.length = &a_length;
- bind.buffer = const_cast <dbms::Data&>(data).getBuffer();
- break;
- case Data::Type::Date: // (1)
- bind.buffer_type = MYSQL_TYPE_DATE;
- bind.buffer_length = sizeof(MYSQL_TIME);
- bind.length = &a_length;
- bind.buffer = (char*) a_time;
- break;
- case Data::Type::TimeStamp:
- bind.buffer_type = MYSQL_TYPE_DATETIME;
- bind.buffer_length = sizeof(MYSQL_TIME);
- bind.length = &a_length;
- bind.buffer = (char*) a_time;
- break;
- case Data::Type::ShortBlock:
-
- if((bind.buffer_length = data.getMaxSize()) < MaxBlobSize) {
- bind.buffer_type = MYSQL_TYPE_BLOB;
- bind.length = &a_length;
- bind.buffer = const_cast <dbms::Data&>(data).getBuffer();
- } else {
- string msg(data.asString());
- msg += functions::asString(" | Over maximum size: %d/%d", data.getMaxSize(), MaxBlobSize);
- throw RuntimeException(msg, ANNA_FILE_LOCATION);
- }
-
- break;
- case Data::Type::LongBlock:
- /**
- * El tratamiento particular se realiza en las clases InputBind y OutputBind.
- */
- break;
- default:
- throw RuntimeException(functions::asString("Unsupported data type %d", (int) a_type), ANNA_FILE_LOCATION);
- }
-}
-
+++ /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 //
-
-
-#include <mysql/mysql.h>
-
-#include <anna/core/tracing/Logger.hpp>
-#include <anna/core/tracing/TraceMethod.hpp>
-#include <anna/core/functions.hpp>
-
-#include <anna/dbms.mysql/Database.hpp>
-#include <anna/dbms.mysql/Connection.hpp>
-#include <anna/dbms.mysql/ResultCode.hpp>
-
-using namespace std;
-using namespace anna;
-using namespace anna::dbms;
-
-mysql::Connection::Connection(Database& database, const std::string& name, const char* user, const char* password) :
- dbms::Connection(database, name, user, password),
- a_mysqlDatabase(database),
- a_mysql(NULL) {
-}
-
-void mysql::Connection::open()
-throw(dbms::DatabaseException) {
- if(a_mysql != NULL) {
- LOGWARNING(
- string msg = asString();
- msg += " | Has already been established";
- Logger::warning(msg, ANNA_FILE_LOCATION);
- );
- return;
- }
-
- if((a_mysql = mysql_init(NULL)) == NULL)
- RuntimeException("Cannot initiate MySQL", ANNA_FILE_LOCATION);
-
- const char* dbmsName = (a_mysqlDatabase.getType() == Database::Type::Remote) ? a_mysqlDatabase.getName().c_str() : NULL;
-
- try {
- if(mysql_real_connect(a_mysql, a_mysqlDatabase.getHost(), a_user.c_str(), a_password.c_str(), dbmsName, 0, NULL, 0L) == NULL) {
- ResultCode resultCode(a_mysql);
- throw DatabaseException(resultCode, ANNA_FILE_LOCATION);
- }
-
- LOGINFORMATION(
- string msg("anna::dbms::mysql::Connection::open | ");
- msg += asString();
- Logger::information(msg, ANNA_FILE_LOCATION);
- );
- } catch(DatabaseException& edbms) {
- close();
- throw;
- }
-}
-
-void mysql::Connection::close()
-throw() {
- LOGINFORMATION(
- string msg("anna::dbms::mysql::Connection::close | ");
- msg += asString();
- Logger::information(msg, ANNA_FILE_LOCATION);
- );
-
- if(a_mysql != NULL) {
- mysql_close(a_mysql);
- a_mysql = NULL;
- LOGINFORMATION(
- string msg("anna::dbms::mysql::Connection::close | ");
- msg += asString();
- Logger::information(msg, ANNA_FILE_LOCATION);
- );
- }
-}
-
-void mysql::Connection::do_commit()
-throw(RuntimeException, dbms::DatabaseException) {
- anna_dbms_mysql_check(mysql_commit(a_mysql), a_mysql);
-}
-
-void mysql::Connection::do_rollback()
-throw() {
- try {
- anna_dbms_mysql_check(mysql_rollback(a_mysql), a_mysql);
- } catch(Exception& ex) {
- ex.trace();
- }
-}
-
-string mysql::Connection::asString() const
-throw() {
- string result("dbms::mysql::Connection { ");
- result += dbms::Connection::asString();
- result += " | Context: ";
- result += (a_mysql == NULL) ? "(null)" : functions::asHexString(anna_ptrnumber_cast(a_mysql));
- return result += " }";
-}
-
+++ /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 //
-
-
-#include <string.h>
-
-#include <anna/core/tracing/Logger.hpp>
-#include <anna/core/tracing/TraceMethod.hpp>
-
-#include <anna/dbms.mysql/mysql.hpp>
-#include <anna/dbms.mysql/internal/sccs.hpp>
-
-using namespace std;
-using namespace anna;
-using namespace anna::dbms;
-
-mysql::Database::Database(const char* dbmsName, const char* host) :
- dbms::Database(getClassName(), dbmsName) {
- a_host = (host == NULL) ? NULL : strdup(host);
- mysql::sccs::activate();
-}
-
-mysql::Database::Database(const char* componentName, const char* dbmsName, const char* host) :
- dbms::Database(componentName, dbmsName) {
- a_host = (host == NULL) ? NULL : strdup(host);
- mysql::sccs::activate();
-}
-
-void mysql::Database::do_initialize()
-throw(RuntimeException) {
- LOGMETHOD(TraceMethod tm("anna::dbms::mysql::Database", "do_initialize", ANNA_FILE_LOCATION));
- dbms::Database::do_initialize();
-}
-
-//----------------------------------------------------------------------------------
-// Libera todos los manejadores asociados a este entorno.
-//----------------------------------------------------------------------------------
-mysql::Database::~Database() {
- LOGMETHOD(TraceMethod tm("anna::dbms::mysql::Database", "~Database", ANNA_FILE_LOCATION));
-
- if(a_host != NULL)
- free(a_host);
-}
-
-dbms::Connection* mysql::Database::allocateConnection(const std::string& name, const char* user, const char* password)
-throw(RuntimeException) {
- return new Connection(*this, name, user, password);
-}
-
-dbms::Statement* mysql::Database::allocateStatement(const char* name, const std::string& expression, const bool isCritical)
-throw(RuntimeException) {
- return new Statement(*this, name, expression, isCritical);
-}
-
-dbms::InputBind* mysql::Database::allocateInputBind(const char* name, Data& data)
-throw(RuntimeException) {
- return new InputBind(name, data);
-}
-
-void mysql::Database::deallocate(dbms::InputBind* inputBind)
-throw() {
- delete(InputBind*) inputBind;
-}
-
-dbms::OutputBind* mysql::Database::allocateOutputBind(const char* name, Data& data)
-throw(RuntimeException) {
- return new OutputBind(name, data);
-}
-
-void mysql::Database::deallocate(dbms::OutputBind* outputBind)
-throw() {
- delete(OutputBind*) outputBind;
-}
+++ /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 //
-
-
-#include <time.h>
-
-#include <mysql/mysql.h>
-
-#include <anna/config/defines.hpp>
-#include <anna/core/functions.hpp>
-#include <anna/core/DataBlock.hpp>
-#include <anna/core/tracing/Logger.hpp>
-
-#include <anna/dbms/String.hpp>
-#include <anna/dbms/ShortBlock.hpp>
-#include <anna/dbms/Date.hpp>
-#include <anna/dbms/TimeStamp.hpp>
-#include <anna/dbms/LongBlock.hpp>
-
-#include <anna/dbms.mysql/mysql.hpp>
-
-using namespace std;
-using namespace anna;
-
-InputBind::InputBind(const char* name, dbms::Data& data) :
- dbms::InputBind(name, data),
- BaseBind(data) {
-}
-
-InputBind::~InputBind() {
-}
-
-/*
- * Completa la informacion establececida por el setupBind.
- */
-void InputBind::prepare(anna::dbms::Statement* dbmsStmt, anna::dbms::Connection*, const int pos)
-throw(RuntimeException) {
- st_mysql_bind* bind = static_cast <dbms::mysql::Statement*>(dbmsStmt)->getBindParams() + pos;
- Data& data = anna::dbms::Bind::getData();
- BaseBind::setupBind(*bind, data);
-
- if(data.getType() == Data::Type::LongBlock) {
- DataBlock& dataBlock = static_cast <dbms::LongBlock&>(data).getValue();
- bind->buffer_type = MYSQL_TYPE_BLOB;
- bind->buffer_length = dataBlock.getSize();
- bind->buffer = (char*) dataBlock.getData();
- bind->length = &a_length;
- }
-}
-
-/*
- * Se invoca desde anna::dbms::mysql::Statement::execute.
- * Codificar� la informaci�n C++ de forma que encaje en las estructuras requeridas por el API de MySQL.
- */
-void InputBind::code() const
-throw(RuntimeException) {
- InputBind* _this = const_cast <InputBind*>(this);
- Data& data = _this->getData();
-
- if((_this->a_nullIndicator = data.isNull() ? true : false) == true)
- return;
-
- switch(data.getType()) {
- case Data::Type::String:
- _this->a_length = anna_strlen((char*)(static_cast <dbms::String&>(data).getBuffer()));
- break;
- case Data::Type::Date:
- case Data::Type::TimeStamp:
- _this->codeDate(data);
- break;
- case Data::Type::Integer:
- throw RuntimeException("anna::dbms::mysql::InputBind::code not implemented for Data::Type::Integer", ANNA_FILE_LOCATION);
- break;
- case Data::Type::Float:
- throw RuntimeException("anna::dbms::mysql::InputBind::code not implemented for Data::Type::Float", ANNA_FILE_LOCATION);
- break;
- case Data::Type::ShortBlock:
- throw RuntimeException("anna::dbms::mysql::InputBind::code not implemented for Data::Type::ShortBlock", ANNA_FILE_LOCATION);
- break;
- case Data::Type::LongBlock:
- throw RuntimeException("anna::dbms::mysql::InputBind::code not implemented for Data::Type::LongBlock", ANNA_FILE_LOCATION);
- break;
-
- }
-}
-
-/**
- * El bind.buffer ha sido asociado a una estructura de tipo MYSQL_TIME (a_time), cuyos valores vamos
- * a establecer en �ste m�todo.
- */
-void InputBind::codeDate(dbms::Data& data)
-throw() {
- dbms::Date& date = static_cast <dbms::Date&>(data);
-
- if(data.getType() == Data::Type::TimeStamp) {
- a_time->second_part = static_cast <dbms::TimeStamp&>(data).getFractionalSecond();
- }
-
- a_time->year = date.getYear();
- a_time->month = date.getMonth();
- a_time->day = date.getDay();
- a_time->hour = date.getHour();
- a_time->minute = date.getMinute();
- a_time->second = date.getSecond();
-}
-
+++ /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 //
-
-
-#include <ctype.h>
-
-#include <anna/config/defines.hpp>
-
-#include <anna/dbms.mysql/OracleTranslator.hpp>
-
-using namespace std;
-using namespace anna;
-using namespace anna::dbms;
-
-mysql::OracleTranslator mysql::OracleTranslator::st_this;
-
-/*
- * Pone las sentencias SQL escritas para Oracle en el formato que necesita el
- * MySQL.
- *
- * La sentencia Oracle podría ser algo así como:
- * insert into foo (a, b, c) values (:x, :y, :zzzz)
- * update goo set xx=&value where yy=:zzz
- *
- * Y Debería quedar algo así:
- * insert into foo (a, b, c) values (?,?,?)
- * update goo set xx=? where yy=?
- */
-const char* mysql::OracleTranslator::apply(const char* statement)
-throw(RuntimeException) {
- bool makeit = false;
-
- if(anna_strchr(statement, ':') != NULL)
- makeit = true;
- else if(anna_strchr(statement, '&') != NULL)
- makeit = true;
-
- if(makeit == false)
- return statement;
-
- allocate(statement);
- enum { Copying, Filtering };
- int mode(Copying);
- char* w = a_buffer;
- char character;
-
- while((character = *statement) != 0) {
- switch(mode) {
- case Copying:
-
- if(character == ':' || character == '&') {
- *w ++ = '?';
- mode = Filtering;
- } else
- *w ++ = character;
-
- break;
- case Filtering:
-
- if(character == ',' || character == ')' || isspace(character) || iscntrl(character)) {
- *w ++ = character;
- mode = Copying;
- }
-
- break;
- }
-
- statement ++;
- }
-
- *w = 0;
- return a_buffer;
-}
-
-void mysql::OracleTranslator::allocate(const char* statement)
-throw() {
- const int size = anna_strlen(statement);
-
- if(size > a_size) {
- if(a_size > 0) {
- delete a_buffer;
- a_buffer = NULL;
- }
-
- a_buffer = new char [a_size = size + 1];
- }
-
- a_buffer [0] = 0;
-}
-
+++ /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 //
-
-
-#include <mysql/mysql.h>
-
-#include <anna/config/defines.hpp>
-#include <anna/core/tracing/Logger.hpp>
-#include <anna/core/DataBlock.hpp>
-
-#include <anna/dbms/Float.hpp>
-#include <anna/dbms/ShortBlock.hpp>
-#include <anna/dbms/LongBlock.hpp>
-#include <anna/dbms/String.hpp>
-#include <anna/dbms/Date.hpp>
-#include <anna/dbms/TimeStamp.hpp>
-
-#include <anna/dbms.mysql/mysql.hpp>
-
-using namespace anna;
-using namespace std;
-
-OutputBind::OutputBind(const char* name, dbms::Data& data) :
- dbms::OutputBind(name, data),
- BaseBind(data) {
- a_blob = (data.getType() == Data::Type::LongBlock) ? new Blob : NULL;
-}
-
-OutputBind::~OutputBind() {
- delete a_blob;
-}
-
-/*
- * El dato de LONG BLOB se recoge según cuenta:
- * http://dev.mysql.com/doc/refman/4.1/en/mysql-stmt-fetch.html.
- */
-void OutputBind::prepare(anna::dbms::Statement* dbmsStmt, anna::dbms::Connection*, const int pos)
-throw(RuntimeException) {
- st_mysql_bind* bind = static_cast <dbms::mysql::Statement*>(dbmsStmt)->getBindResults() + pos;
- Data& data = anna::dbms::Bind::getData();
- BaseBind::setupBind(*bind, data);
-
- if(data.getType() == Data::Type::LongBlock) {
- dbms::mysql::Statement* myStmt = static_cast <dbms::mysql::Statement*>(dbmsStmt);
- a_blob->stmt = *myStmt;
- a_blob->binds = myStmt->getBindResults();
- a_blob->pos = pos;
- bind->buffer_type = MYSQL_TYPE_BLOB;
- bind->buffer = NULL;
- bind->buffer_length = 0;
- bind->length = &a_length;
- }
-}
-
-/*
- * Transfiere la información del los MYSQL_BIND del API C de MySQL a las
- * estructuras dbms::Data de nuestro programa C++.
- */
-void OutputBind::decode() const
-throw(RuntimeException) {
- OutputBind* _this = const_cast <OutputBind*>(this);
- char* str;
- Data& data = _this->getData();
- data.setNull(a_nullIndicator == true);
-
- switch(data.getType()) {
- case Data::Type::String:
- str = (char*) data.getBuffer();
-
- if(data.isNull() == true)
- *str = 0;
- else
- dbms::String::strip(str);
-
- break;
- case Data::Type::Float:
-
- if(data.isNull() == true)
- static_cast <dbms::Float&>(data) = 0.0;
-
- break;
- case Data::Type::Date:
- case Data::Type::TimeStamp:
- _this->decodeDate(data);
- break;
- case Data::Type::Integer:
- throw RuntimeException("anna::dbms::mysql::OutputBind::decode not implemented for Data::Type::Integer", ANNA_FILE_LOCATION);
- break;
- case Data::Type::ShortBlock:
- throw RuntimeException("anna::dbms::mysql::OutputBind::decode not implemented for Data::Type::ShortBlock", ANNA_FILE_LOCATION);
- break;
- case Data::Type::LongBlock:
-
- try {
- _this->decodeLongBlob(data);
- } catch(dbms::DatabaseException& edb) {
- throw RuntimeException(edb);
- }
-
- break;
- }
-}
-
-void OutputBind::do_write(const dbms::LongBlock&) const
-throw(RuntimeException, dbms::DatabaseException) {
-}
-
-/*
- * El m�todo BaseBind::setupBind asocia� el contenido de la variable
- * a_time al buffer de salida de la sentencia SQL, as� que el contenido
- * de la columna est� contenido ah�. S�lo tendremos que copiar dichos
- * contenidos en la variable C++ de nuestro entorno.
- */
-void OutputBind::decodeDate(dbms::Data& data)
-throw() {
- if(data.isNull() == true)
- return;
-
- Date& date = static_cast <Date&>(data);
- date.setYear(a_time->year);
- date.setMonth(a_time->month);
- date.setDay(a_time->day);
- date.setHour(a_time->hour);
- date.setMinute(a_time->minute);
- date.setSecond(a_time->second);
-
- if(data.getType() == Data::Type::TimeStamp)
- static_cast <dbms::TimeStamp&>(data).setFractionalSecond(a_time->second_part);
-}
-
-/*
- * Según http://dev.mysql.com/doc/refman/4.1/en/mysql-stmt-fetch.html
- *
- * Recoge el contenido total de BLOB en partes que va componiendo sobre el
- * DataBlock final asociado al anna::dbms::LongBlock sobre el que trabaja el
- * programador final.
- */
-void OutputBind::decodeLongBlob(dbms::Data& data) const
-throw(RuntimeException, dbms::DatabaseException) {
- const int bufferSize = a_blob->buffer.getMaxSize();
- st_mysql_bind& bind = a_blob->binds [a_blob->pos];
- DataBlock& target = static_cast <dbms::LongBlock&>(data).getValue();
- const int maxloop = *bind.length / bufferSize;
- const int remainder = *bind.length % bufferSize;
- int offset = 0;
- target.clear();
- bind.buffer = (void*) a_blob->buffer.getData();
-
- for(int iloop = 0; iloop < maxloop; iloop ++) {
- bind.buffer_length = bufferSize;
- anna_dbms_mysql_check(
- mysql_stmt_fetch_column(a_blob->stmt, a_blob->binds, a_blob->pos, offset), a_blob->stmt
- );
- target += DataBlock((const char*) bind.buffer, bind.buffer_length, false);
- offset += bufferSize;
- }
-
- if(remainder) {
- bind.buffer_length = remainder;
- anna_dbms_mysql_check(
- mysql_stmt_fetch_column(a_blob->stmt, a_blob->binds, a_blob->pos, offset), a_blob->stmt
- );
- target += DataBlock((const char*) bind.buffer, remainder, false);
- }
-}
-
-OutputBind::Blob::Blob() :
- buffer(true) {
- buffer.allocate(64 * 1024);
-}
+++ /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 //
-
-
-#include <mysql/mysql.h>
-#include <mysql/mysqld_error.h>
-#include <mysql/errmsg.h>
-
-#include <anna/config/defines.hpp>
-#include <anna/core/tracing/Logger.hpp>
-
-#include <anna/dbms.mysql/ResultCode.hpp>
-
-using namespace anna;
-using namespace anna::dbms;
-
-mysql::ResultCode::ErrorDecoder mysql::ResultCode::st_errorDecoder;
-
-mysql::ResultCode::ResultCode(st_mysql* _mysql) :
- dbms::ResultCode(0, NULL, &st_errorDecoder) {
- int errorCode = mysql_errno(_mysql);
-
- if(errorCode != 0)
- dbms::ResultCode::set(errorCode, mysql_error(_mysql));
-}
-
-mysql::ResultCode::ResultCode(st_mysql_stmt* stmt) :
- dbms::ResultCode(0, NULL, &st_errorDecoder) {
- int errorCode = mysql_stmt_errno(stmt);
-
- if(errorCode != 0)
- dbms::ResultCode::set(errorCode, mysql_stmt_error(stmt));
-}
-
-/*
- * Códigos de error obtenidos de:
- * http://dev.mysql.com/doc/refman/4.1/en/error-messages-client.html
- */
-
-bool mysql::ResultCode::ErrorDecoder::notFound(const int errorCode) const
-throw() {
- return errorCode == CR_NO_DATA;
-}
-
-bool mysql::ResultCode::ErrorDecoder::successful(const int errorCode) const
-throw() {
- return errorCode == 0;
-}
-
-bool mysql::ResultCode::ErrorDecoder::locked(const int errorCode) const
-throw() {
- return false; // No parece que haya un código de error en MySQL para identificar esta situación ¿?¿?
-}
-
-bool mysql::ResultCode::ErrorDecoder::lostConnection(const int errorCode) const
-throw() {
- return errorCode == CR_INVALID_CONN_HANDLE || errorCode == CR_SHARED_MEMORY_CONNECT_REQUEST_ERROR || errorCode == CR_SHARED_MEMORY_CONNECT_ANSWER_ERROR ||
- errorCode == CR_SHARED_MEMORY_CONNECT_MAP_ERROR || errorCode == CR_SHARED_MEMORY_CONNECT_SET_ERROR;
-}
+++ /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 //
-
-
-#include <mysql/mysql.h>
-
-#include <anna/config/defines.hpp>
-#include <anna/core/tracing/TraceMethod.hpp>
-
-#include <anna/dbms.mysql/mysql.hpp>
-
-using namespace std;
-using namespace anna;
-
-dbms::mysql::Statement::~Statement() {
- if(a_mysqlStmt) {
- try {
- anna_dbms_mysql_check(mysql_stmt_close(a_mysqlStmt), a_mysqlStmt);
- } catch(DatabaseException& edb) {
- edb.trace();
- }
- }
-
- delete [] a_params;
- delete [] a_results;
-}
-
-/**
- * Según el ejemplo de: http://dev.mysql.com/doc/refman/4.1/en/mysql-stmt-fetch.html
- *
- */
-void dbms::mysql::Statement::prepare(dbms::Connection* dbmsConnection)
-throw(RuntimeException, dbms::DatabaseException) {
- LOGMETHOD(TraceMethod tm("anna::dbms::mysql::Statement", "prepare", ANNA_FILE_LOCATION));
- Connection* connection(static_cast <Connection*>(dbmsConnection));
- //Database& dbms(static_cast <Database&>(connection->getDatabase()));
- LOGDEBUG(
- string msg("anna::dbms::mysql::Statement::prepare | ");
- msg += asString();
- Logger::debug(msg, ANNA_FILE_LOCATION);
- );
-
- /*
- * Libera la información establecida anteriormente. Las sentencias se pueden reusar.
- */
- if(a_mysqlStmt != NULL) {
- anna_dbms_mysql_check(mysql_stmt_reset(a_mysqlStmt), a_mysqlStmt);
- delete [] a_params;
- delete [] a_results;
- a_params = a_results = NULL;
- } else if((a_mysqlStmt = mysql_stmt_init(*connection)) == NULL) {
- string msg(asString());
- msg += " | Insufficient memory";
- throw RuntimeException(msg, ANNA_FILE_LOCATION);
- }
-
- const char* expression = dbms::Statement::getExpression().c_str();
-
- anna_dbms_mysql_check(mysql_stmt_prepare(a_mysqlStmt, expression, anna_strlen(expression)), a_mysqlStmt);
-
- const int paramCount = mysql_stmt_param_count(a_mysqlStmt);
-
- const int inputSize = dbms::Statement::input_size();
-
- const int outputSize = dbms::Statement::output_size();
-
- /*
- * Verifica que el número de parámetros de entrada de la sentencia coincida con el número de parámetros
- * indicados por el programador.
- */
- if(paramCount != inputSize) {
- string msg(asString());
- msg += " | Wrong input parameters";
- throw RuntimeException(msg, ANNA_FILE_LOCATION);
- }
-
- /*
- * Verifica que el número de parámetros de salida de la sentencia coincida con el número de parámetros
- * indicados por el programador. Si no tiene parámetros de salida (INSERT) => no debe tener parámetros
- * indicados por el programador.
- */
- MYSQL_RES* metaResult = mysql_stmt_result_metadata(a_mysqlStmt);
-
- try {
- if(metaResult == NULL) {
- if(outputSize != 0) {
- string msg(asString());
- msg += " | Wrong output parameters";
- throw RuntimeException(msg, ANNA_FILE_LOCATION);
- }
- } else if(mysql_num_fields(metaResult) != outputSize) {
- string msg(asString());
- msg += " | Wrong output parameters";
- throw RuntimeException(msg, ANNA_FILE_LOCATION);
- }
- } catch(RuntimeException&) {
- mysql_free_result(metaResult);
- throw;
- }
-
- /*
- * Define las estructuras requeridas para asociar las columasn MySQL con las áreas de memoria C++
- */
- int pos;
-
- if((a_params = create(inputSize, "input")) != NULL) {
- pos = 0;
-
- for(input_iterator ii = input_begin(), maxii = input_end(); ii != maxii; ii ++)
- inputBind(ii)->prepare(this, dbmsConnection, pos ++);
-
- anna_dbms_mysql_check(mysql_stmt_bind_param(a_mysqlStmt, a_params), a_mysqlStmt);
- }
-
- if((a_results = create(outputSize, "output")) != NULL) {
- pos = 0;
-
- for(output_iterator oo = output_begin(), maxoo = output_end(); oo != maxoo; oo ++)
- outputBind(oo)->prepare(this, dbmsConnection, pos ++);
-
- anna_dbms_mysql_check(mysql_stmt_bind_result(a_mysqlStmt, a_results), a_mysqlStmt);
- }
-}
-
-dbms::ResultCode dbms::mysql::Statement::execute(dbms::Connection* dbmsConnection)
-throw(RuntimeException, dbms::DatabaseException) {
- //Connection* connection(static_cast <Connection*>(dbmsConnection));
-
- for(input_iterator ii = input_begin(), maxii = input_end(); ii != maxii; ii ++) {
- inputBind(ii)->code();
- LOGDEBUG(
- string msg("anna::dbms::mysql::Statement::InputBind: ");
- msg += inputBind(ii)->asString();
- Logger::debug(msg, ANNA_FILE_LOCATION);
- );
- }
-
- anna_dbms_mysql_check(mysql_stmt_execute(a_mysqlStmt), a_mysqlStmt)
- ResultCode result(a_mysqlStmt);
- return result;
-}
-
-/*
- * Según la información de http://dev.mysql.com/doc/refman/4.1/en/mysql-stmt-fetch.html
- */
-bool dbms::mysql::Statement::fetch()
-throw(RuntimeException, dbms::DatabaseException) {
- bool result = false;
-
- switch(mysql_stmt_fetch(a_mysqlStmt)) {
- case 0:
- result = true;
-
- for(output_iterator oo = output_begin(), maxoo = output_end(); oo != maxoo; oo ++) {
- outputBind(oo)->decode();
- LOGDEBUG(Logger::write(Logger::Debug, outputBind(oo)->asString(), ANNA_FILE_LOCATION));
- }
-
- break;
- case 1:
- throw DatabaseException(ResultCode(a_mysqlStmt), ANNA_FILE_LOCATION);
- default:
- result = false;
- break;
- }
-
- LOGDEBUG(
- string msg("anna::dbms::mysql::Statement::fetch | Result: ");
- msg += functions::asString(result);
- Logger::debug(msg, ANNA_FILE_LOCATION);
- );
- return result;
-}
-
-st_mysql_bind* dbms::mysql::Statement::create(const int size, const char* whatis)
-throw(RuntimeException) {
- st_mysql_bind* result = NULL;
-
- if(size > 0) {
- if((result = new st_mysql_bind [size]) == NULL) {
- string msg(asString());
- msg += anna::functions::asString("Insufficient memory to create %d parameters of %s", size, whatis);
- throw RuntimeException(msg, ANNA_FILE_LOCATION);
- }
- }
-
- return result;
-}
+++ /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 //
-
-
-#include <anna/core/internal/sccs.hpp>
-#include <anna/dbms/internal/sccs.hpp>
-#include <anna/dbms.mysql/internal/sccs.hpp>
-
-#include <anna/core/internal/ModuleManager.hpp>
-
-anna_define_sccs_tag_ex(dbms_mysql, dbms.mysql, 0);
-
-void anna::dbms::mysql::sccs::activate()
-throw() {
- dbms::sccs::activate();
- ModuleManager::instantiate().insert(anna_use_sccs_tag(dbms_mysql), "00");
-}
-
+++ /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 //
-
-
-#include <oci.h>
-
-#include <anna/core/DataBlock.hpp>
-
-#include <anna/dbms/Data.hpp>
-#include <anna/dbms/LongBlock.hpp>
-
-#include <anna/dbms.oracle/BaseBind.hpp>
-#include <anna/dbms.oracle/Database.hpp>
-#include <anna/dbms.oracle/Connection.hpp>
-#include <anna/dbms.oracle/ResultCode.hpp>
-
-using namespace anna;
-
-//----------------------------------------------------------------------------
-// (1) Reserva 2 Kbytes para trabajar con el LOB.
-//----------------------------------------------------------------------------
-dbms::oracle::BaseBind::BaseBind(const dbms::Data& data) :
- a_type(data.getType()),
- a_ofb(NULL) {
- switch(a_type) {
- case Data::Type::Float:
- a_ofb = new anna::DataBlock(true);
- a_ofb->allocate(FloatSize + 1);
- break;
- case Data::Type::ShortBlock:
- a_ofb = new anna::DataBlock(true);
- a_ofb->allocate(data.getMaxSize() * 2 + 1);
- break;
- case Data::Type::LongBlock:
- a_ofb = new anna::DataBlock(true);
- a_ofb->allocate(2048); // (1)
- break;
- default: break;
- }
-}
-
-dbms::oracle::BaseBind::~BaseBind() {
- delete a_ofb;
-}
-
-//
-// (1) Aunque sea un objeto de tipo Date lo define/trata como un tipo TimeStamp, porque de otro modo no se grabaria la
-// informacion referente a la hora.
-// (2) El Float hasta ahora se trataba como un tipo especial de cadena, pero no es un tratamiento indicado
-// para todos los gestores de base de datos, as� que vamos a resumir en estas clases todos los detalles de
-// tratamiento.
-//
-dbms::oracle::BaseBind::oci_param dbms::oracle::BaseBind::getOCIParam(dbms::oracle::Database& database, dbms::oracle::Connection* connection, dbms::Data& data)
-throw(RuntimeException) {
- oci_param ociparam;
-
- switch(a_type) {
- case Data::Type::Integer:
- ociparam.type = SQLT_INT;
- ociparam.maxLength = data.getMaxSize();
- ociparam.length = NULL;
- ociparam.buffer = const_cast <dbms::Data&>(data).getBuffer();
- break;
- case Data::Type::String:
- ociparam.type = SQLT_STR;
- ociparam.maxLength = data.getMaxSize() + 1;
- ociparam.length = NULL;
- ociparam.buffer = const_cast <dbms::Data&>(data).getBuffer();
- break;
- case Data::Type::Float: // (2)
- ociparam.type = SQLT_STR;
- ociparam.maxLength = FloatSize + 1;
- ociparam.length = NULL;
- ociparam.buffer = const_cast <char*>(a_ofb->getData());
- break;
- case Data::Type::ShortBlock:
- ociparam.type = SQLT_STR;
- ociparam.maxLength = data.getMaxSize() * 2 + 1;
- ociparam.length = &a_length;
- ociparam.buffer = const_cast <char*>(a_ofb->getData());
- break;
- case Data::Type::LongBlock:
- a_blob.allocate(database, connection, OCI_DTYPE_LOB);
- ociparam.type = SQLT_BLOB;
- ociparam.buffer = &a_blob.handle;
- ociparam.length = NULL;
- ociparam.maxLength = 0;
- break;
- case Data::Type::Date: // (1)
- case Data::Type::TimeStamp:
- a_datetime.allocate(database, connection, OCI_DTYPE_TIMESTAMP);
- ociparam.type = SQLT_TIMESTAMP;
- ociparam.buffer = &a_datetime.handle;
- ociparam.length = NULL;
- ociparam.maxLength = 0;
- break;
- default:
- throw RuntimeException(functions::asString("Unsupported data type %d", (int) a_type), ANNA_FILE_LOCATION);
- }
-
- return ociparam;
-}
-
+++ /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 //
-
-
-#include <oci.h>
-
-#include <anna/core/tracing/Logger.hpp>
-#include <anna/core/tracing/TraceMethod.hpp>
-#include <anna/core/functions.hpp>
-
-#include <anna/dbms.oracle/Database.hpp>
-#include <anna/dbms.oracle/Connection.hpp>
-#include <anna/dbms.oracle/ResultCode.hpp>
-
-using namespace std;
-using namespace anna;
-using namespace anna::dbms;
-
-oracle::Connection::Connection(Database& database, const std::string& name, const char* user, const char* password) :
- dbms::Connection(database, name, user, password),
- a_context(NULL),
- a_session(NULL),
- a_server(NULL),
- a_oracleDatabase(database) {
-}
-
-void oracle::Connection::open()
-throw(dbms::DatabaseException) {
- OCIError* error = a_oracleDatabase.getErrorHandler();
-
- if(a_context != NULL) {
- LOGWARNING(
- string msg = asString();
- msg += " | Already established";
- Logger::warning(msg, ANNA_FILE_LOCATION);
- );
- return;
- }
-
- try {
- anna_dbms_oracle_check(OCIHandleAlloc(a_oracleDatabase, (void**) &a_context, OCI_HTYPE_SVCCTX, 0, 0), error);
- anna_dbms_oracle_check(OCIHandleAlloc(a_oracleDatabase, (void**) &a_session, OCI_HTYPE_SESSION, 0, 0), error);
- anna_dbms_oracle_check(OCIHandleAlloc(a_oracleDatabase, (void**) &a_server, OCI_HTYPE_SERVER, 0, 0), error);
- const char* dbmsName = NULL;
- int lenDBName = 0;
-
- if(a_oracleDatabase.getType() == Database::Type::Remote) {
- dbmsName = a_oracleDatabase.getName().c_str();
- lenDBName = anna_strlen(dbmsName);
- }
-
- anna_dbms_oracle_check(
- OCIServerAttach(a_server, error, (unsigned char*) dbmsName, lenDBName, OCI_DEFAULT),
- error
- );
- anna_dbms_oracle_check(OCIAttrSet(a_context, OCI_HTYPE_SVCCTX, a_server, 0, OCI_ATTR_SERVER, error), error);
- anna_dbms_oracle_check(
- OCIAttrSet(a_session, OCI_HTYPE_SESSION, (void*) a_user.c_str(), a_user.size(), OCI_ATTR_USERNAME, error),
- error
- );
- anna_dbms_oracle_check(
- OCIAttrSet(a_session, OCI_HTYPE_SESSION, (void*) a_password.c_str(), a_password.size(), OCI_ATTR_PASSWORD, error),
- error
- );
- anna_dbms_oracle_check(OCISessionBegin(a_context, error, a_session, OCI_CRED_RDBMS, OCI_DEFAULT), error);
- anna_dbms_oracle_check(OCIAttrSet(a_context, OCI_HTYPE_SVCCTX, a_session, 0, OCI_ATTR_SESSION, error), error);
- LOGINFORMATION(
- string msg("anna::dbms::oracle::Connection::open | ");
- msg += asString();
- Logger::information(msg, ANNA_FILE_LOCATION);
- );
- } catch(DatabaseException& edbms) {
- close();
- throw;
- }
-}
-
-void oracle::Connection::close()
-throw() {
- OCIError* error = a_oracleDatabase.getErrorHandler();
-
- try {
- LOGINFORMATION(
- string msg("anna::dbms::oracle::Connection::close | ");
- msg += asString();
- Logger::information(msg, ANNA_FILE_LOCATION);
- );
-
- if(a_session != NULL && a_context != NULL) {
- OCISessionEnd(a_context, error, a_session, OCI_DEFAULT);
- a_session = NULL;
- }
-
- if(a_server != NULL) {
- OCIServerDetach(a_server, error, OCI_DEFAULT);
- OCIHandleFree(a_server, OCI_HTYPE_SERVER);
- a_server = NULL;
- }
-
- if(a_context != NULL) {
- OCIHandleFree(a_context, OCI_HTYPE_SVCCTX);
- a_context = NULL;
- }
-
- LOGINFORMATION(
- string msg("anna::dbms::oracle::Connection::close | ");
- msg += asString();
- Logger::information(msg, ANNA_FILE_LOCATION);
- );
- } catch(DatabaseException& ex) {
- ex.trace();
- }
-}
-
-void oracle::Connection::do_commit()
-throw(RuntimeException, dbms::DatabaseException) {
- OCIError* error = a_oracleDatabase.getErrorHandler();
- anna_dbms_oracle_check(OCITransCommit(a_context, error, 0), error);
-}
-
-void oracle::Connection::do_rollback()
-throw() {
- try {
- OCIError* error = a_oracleDatabase.getErrorHandler();
- anna_dbms_oracle_check(OCITransRollback(a_context, error, 0), error);
- } catch(Exception& ex) {
- ex.trace();
- }
-}
-
-string oracle::Connection::asString() const
-throw() {
- string result("dbms::oracle::Connection { ");
- result += dbms::Connection::asString();
- result += " | Context: ";
- result += (a_context == NULL) ? "(null)" : functions::asHexString(anna_ptrnumber_cast(a_context));
- result += " | Session: ";
- result += (a_session == NULL) ? "(null)" : functions::asHexString(anna_ptrnumber_cast(a_session));
- result += " | Server: ";
- result += (a_server == NULL) ? "(null)" : functions::asHexString(anna_ptrnumber_cast(a_server));
- return result += " }";
-}
-
+++ /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 //
-
-
-#include <locale.h>
-
-#include <oci.h>
-
-#include <anna/core/tracing/Logger.hpp>
-#include <anna/core/tracing/TraceMethod.hpp>
-
-#include <anna/dbms.oracle/oracle.hpp>
-#include <anna/dbms.oracle/internal/sccs.hpp>
-
-using namespace std;
-using namespace anna;
-using namespace anna::dbms;
-
-char oracle::Database::st_decimalPoint = 0;
-
-oracle::Database::Database(const char* dbmsName) :
- dbms::Database(getClassName(), dbmsName),
- a_env(NULL),
- a_error(NULL) {
- oracle::sccs::activate();
-}
-
-oracle::Database::Database(const char* componentName, const char* dbmsName) :
- dbms::Database(componentName, dbmsName),
- a_env(NULL),
- a_error(NULL) {
- oracle::sccs::activate();
-}
-
-void oracle::Database::do_initialize()
-throw(RuntimeException) {
- LOGMETHOD(TraceMethod tm("anna::dbms::oracle::Database", "do_initialize", ANNA_FILE_LOCATION));
-
- if(a_env != NULL) {
- Logger::write(Logger::Warning, asString(), "Already initialized", ANNA_FILE_LOCATION);
- return;
- }
-
- if(OCIInitialize(OCI_DEFAULT, 0, 0, 0, 0) != OCI_SUCCESS) {
- string msg(asString());
- msg += " | Cannot initialize Oracle access system";
- throw RuntimeException(msg, ANNA_FILE_LOCATION);
- }
-
- if(OCIEnvInit(&a_env, OCI_DEFAULT, 0, 0) != OCI_SUCCESS) {
- string msg(asString());
- msg += " | Cannot create database environment";
- throw RuntimeException(msg, ANNA_FILE_LOCATION);
- }
-
- if(OCIHandleAlloc(a_env, (void**) &a_error, OCI_HTYPE_ERROR, 0, 0) != OCI_SUCCESS) {
- string msg(asString());
- msg += " | Cannot create database error handler";
- throw RuntimeException(msg, ANNA_FILE_LOCATION);
- }
-
- WHEN_MULTITHREAD(
- OCIThreadProcessInit();
- anna_dbms_oracle_check(OCIThreadInit(a_env, a_error), a_error);
- );
- initializeDecimalPoint();
- dbms::Database::do_initialize();
-}
-
-//----------------------------------------------------------------------------------
-// Libera todos los manejadores asociados a �te entorno.
-//----------------------------------------------------------------------------------
-oracle::Database::~Database() {
- LOGMETHOD(TraceMethod tm("anna::dbms::oracle::Database", "~Database", ANNA_FILE_LOCATION));
-
- if(a_error) {
- OCIHandleFree(a_env, OCI_HTYPE_ERROR);
- a_env = NULL;
- }
-
- if(a_env) {
- OCIHandleFree(a_env, OCI_HTYPE_ENV);
- a_env = NULL;
- }
-}
-
-dbms::Connection* oracle::Database::allocateConnection(const std::string& name, const char* user, const char* password)
-throw(RuntimeException) {
- return new Connection(*this, name, user, password);
-}
-
-dbms::Statement* oracle::Database::allocateStatement(const char* name, const std::string& expression, const bool isCritical)
-throw(RuntimeException) {
- return new Statement(*this, name, expression, isCritical);
-}
-
-dbms::InputBind* oracle::Database::allocateInputBind(const char* name, Data& data)
-throw(RuntimeException) {
- return new InputBind(name, data);
-}
-
-void oracle::Database::deallocate(dbms::InputBind* inputBind)
-throw() {
- delete(InputBind*) inputBind;
-}
-
-dbms::OutputBind* oracle::Database::allocateOutputBind(const char* name, Data& data)
-throw(RuntimeException) {
- return new OutputBind(name, data);
-}
-
-void oracle::Database::deallocate(dbms::OutputBind* outputBind)
-throw() {
- delete(OutputBind*) outputBind;
-}
-
-/**
- * Ojo no se activa el uso de forma definitiva porque afectaría a todo el programa, cualquier
- * conversion texto -> float/double que se hiciera se vería afectado por este cambio, que sólo debería
- * aplicar a temas relaciones con la base de datos.
- *
- * Carga el valor del LC_NUMERIC de la correspondiente variable del entorno y luego repone el
- * usado por defecto en las librerias del core de C.
- */
-/*static*/
-void oracle::Database::initializeDecimalPoint()
-throw(RuntimeException) {
- setlocale(LC_NUMERIC, "");
- struct lconv *locale = localeconv();
-
- if(*locale->decimal_point != '.')
- st_decimalPoint = *locale->decimal_point;
-
- setlocale(LC_NUMERIC, "C");
-}
+++ /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 //
-
-
-#include <oci.h>
-
-#include <anna/dbms.oracle/Descriptor.hpp>
-#include <anna/dbms.oracle/Database.hpp>
-#include <anna/dbms.oracle/Connection.hpp>
-#include <anna/dbms.oracle/ResultCode.hpp>
-
-using namespace anna;
-
-dbms::oracle::Descriptor::~Descriptor() {
- if(*reference != NULL) {
- OCIDescriptorFree(*reference, type);
- *reference = NULL;
- }
-}
-
-void dbms::oracle::Descriptor::allocate(dbms::oracle::Database& database, dbms::oracle::Connection* connection, const int _type)
-throw(RuntimeException) {
- if(*reference != NULL)
- return;
-
- env = database;
- error = database.getErrorHandler();
- context = *connection; // Invoca al operador de conversion
-
- try {
- anna_dbms_oracle_check(OCIDescriptorAlloc(env, reference, type = _type, 0, 0), error);
- } catch(DatabaseException& edb) {
- throw RuntimeException(edb);
- }
-}
+++ /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 //
-
-
-#include <oci.h>
-
-#include <time.h>
-
-#include <anna/config/defines.hpp>
-#include <anna/core/functions.hpp>
-#include <anna/core/DataBlock.hpp>
-#include <anna/core/tracing/Logger.hpp>
-
-#include <anna/dbms/Float.hpp>
-#include <anna/dbms/ShortBlock.hpp>
-#include <anna/dbms/Date.hpp>
-#include <anna/dbms/TimeStamp.hpp>
-#include <anna/dbms/Database.hpp>
-
-#include <anna/dbms.oracle/oracle.hpp>
-
-using namespace std;
-using namespace anna;
-
-InputBind::InputBind(const char* name, dbms::Data& data) :
- dbms::InputBind(name, data),
- BaseBind(data),
- a_ociBind(NULL) {
-}
-
-InputBind::~InputBind() {
-}
-
-// Slo se invoca una vez. Establece las variables atrav� de las que nos vamos a poder
-// comunicar con Oracle, para indicar la longitud de una variable, o su estado de nulo o
-// no nulo.
-void InputBind::prepare(dbms::Statement* dbmsStatement, dbms::Connection* connection, const int pos)
-throw(RuntimeException, dbms::DatabaseException) {
- if(a_ociBind != NULL)
- return;
-
- Data& data = anna::dbms::Bind::getData();
-
- if(data.getType() == Data::Type::LongBlock) {
- string msg("anna::dbms::oracle::InputBind::prepare | ");
- msg += data.asString();
- msg += " | This RDBMS doesn't support BLOB type as BindInput (see anna::dbms::OutputBind::write)";
- throw RuntimeException(msg, ANNA_FILE_LOCATION);
- }
-
- Database& database = static_cast <Database&>(dbmsStatement->getDatabase());
- OCIError* error = database.getErrorHandler();
- Statement* statement(static_cast <Statement*>(dbmsStatement));
- oci_param ociparam = getOCIParam(database, static_cast <oracle::Connection*>(connection), data);
-
- if(data.isNulleable() == false) {
- anna_dbms_oracle_check(
- OCIBindByPos(
- *statement, &a_ociBind, error, pos, ociparam.buffer, ociparam.maxLength, ociparam.type,
- 0, ociparam.length, 0, 0, 0, OCI_DEFAULT
- ),
- error
- );
- } else {
- anna_dbms_oracle_check(
- OCIBindByPos(
- *statement, &a_ociBind, error, pos, ociparam.buffer, ociparam.maxLength, ociparam.type,
- &a_nullIndicator, ociparam.length, 0, 0, 0, OCI_DEFAULT
- ),
- error
- );
- }
-
- LOGDEBUG(
- std::string msg("anna::dbms::oracle::InputBind::prepare | ");
- msg += asString();
- msg += " | Sentence: ";
- msg += statement->getName();
- msg += " | Position: ";
- msg += functions::asString(pos);
- Logger::debug(msg, ANNA_FILE_LOCATION)
- );
-}
-
-//-------------------------------------------------------------------------------
-// Establece la informacin mediante la que conectamos con Oracle. Todos los
-// par�etros que modificamos en �te m�odo tienen efecto en la llamada a Oracle
-// debido cmo hemos invocamo al m�odo OCIBindByPos.
-//
-// Todo esto se podr� haber hecho en la anna::dbms::DataBlock pero exigir�
-// definir una clase distinta para cada RDBMS. Creo que los Binds particulares de
-// cada base de datos se ocupen toda la complejidad de convertir los datos.
-//-------------------------------------------------------------------------------
-void InputBind::code() const
-throw(RuntimeException) {
- InputBind* _this = const_cast <InputBind*>(this);
- Data& data = _this->getData();
-
- if((_this->a_nullIndicator = data.isNull() ? -1 : 0) == -1)
- return;
-
- switch(data.getType()) {
- case Data::Type::String:
- throw RuntimeException("anna::dbms::oracle::InputBind::code not implemented for Data::Type::String", ANNA_FILE_LOCATION);
- break;
- case Data::Type::Integer:
- throw RuntimeException("anna::dbms::oracle::InputBind::code not implemented for Data::Type::Integer", ANNA_FILE_LOCATION);
- break;
- case Data::Type::Float:
- codeFloat(data);
- break;
- case Data::Type::ShortBlock:
- codeShortBlock(data);
- break;
- case Data::Type::LongBlock:
- throw RuntimeException("anna::dbms::oracle::InputBind::code not implemented for Data::Type::LongBlock", ANNA_FILE_LOCATION);
- break;
- case Data::Type::Date:
- case Data::Type::TimeStamp:
-
- try {
- codeDate(data);
- } catch(DatabaseException& edb) {
- throw RuntimeException(edb);
- }
-
- break;
- }
-}
-
-/**
- * Transfiere el valor numerico del float, al buffer reservado para
- * ubiucarlo como una cadena. Ã\89ste buffer es el que está "conectado" con
- * Oracle (tm).
- */
-void InputBind::codeFloat(dbms::Data& data) const
-throw() {
- dbms::Float& _float = static_cast <dbms::Float&>(data);
- InputBind* _this = const_cast <InputBind*>(this);
- char* buffer = (char*) _this->a_ofb->getData();
- snprintf(buffer, FloatSize, _float.getFormat(), _float.getValue());
- const char decimalPoint = oracle::Database::getDecimalPoint();
-
- if(decimalPoint != 0) {
- char* point = anna_strchr(buffer, '.');
-
- if(point != NULL)
- *point = decimalPoint;
- }
-}
-
-void InputBind::codeShortBlock(dbms::Data& data) const
-throw() {
- const int length = static_cast <dbms::ShortBlock&>(data).getSize();
- InputBind* _this = const_cast <InputBind*>(this);
-
- if(length == 0) {
- _this->a_ofb->clear();
- _this->a_length = 0;
- return;
- }
-
- const char* src = (const char*) data.getBuffer();
-
- char* dest = const_cast <char*>(a_ofb->getData());
-
- int j = 0;
-
- for(int i = 0; i < length; i ++) {
- dest [j ++] = asCharacter((src [i] & 0xf0) >> 4);
- dest [j ++] = asCharacter(src [i] & 0x0f);
- }
-
- dest [j ++] = 0;
- _this->a_length = j;
-}
-
-void InputBind::codeDate(dbms::Data& data) const
-throw(RuntimeException, dbms::DatabaseException) {
- dbms::Date& date = static_cast <dbms::Date&>(data);
- ub4 fsec(0);
-
- if(data.getType() == Data::Type::TimeStamp)
- fsec = static_cast <dbms::TimeStamp&>(data).getFractionalSecond() * 1000;
-
- anna_dbms_oracle_check(
- OCIDateTimeConstruct(
- a_datetime.env, a_datetime.error, a_datetime.handle,
- date.getYear(), date.getMonth(), date.getDay(), date.getHour(), date.getMinute(), date.getSecond(), fsec, NULL, 0
- ),
- a_datetime.error
- );
- ub4 errorMask(0);
- anna_dbms_oracle_check(
- OCIDateTimeCheck(a_datetime.env, a_datetime.error, a_datetime.handle, &errorMask),
- a_datetime.error
- );
-
- if(errorMask != 0) {
- string msg(data.asString());
- msg += anna::functions::asHexText(" | Invalid date | ErrorCode: ", (int) errorMask);
- throw RuntimeException(msg, ANNA_FILE_LOCATION);
- }
-}
+++ /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 //
-
-
-#include <oci.h>
-#include <orl.h>
-
-#include <anna/config/defines.hpp>
-#include <anna/core/tracing/Logger.hpp>
-#include <anna/core/DataBlock.hpp>
-
-#include <anna/dbms/Float.hpp>
-#include <anna/dbms/ShortBlock.hpp>
-#include <anna/dbms/LongBlock.hpp>
-#include <anna/dbms/String.hpp>
-#include <anna/dbms/Date.hpp>
-#include <anna/dbms/TimeStamp.hpp>
-
-#include <anna/dbms.oracle/oracle.hpp>
-
-using namespace anna;
-using namespace std;
-
-OutputBind::OutputBind(const char* name, dbms::Data& data) :
- dbms::OutputBind(name, data),
- BaseBind(data),
- a_ociDefine(NULL) {
-}
-
-OutputBind::~OutputBind() {
-}
-
-void OutputBind::prepare(dbms::Statement* dbmsStatement, dbms::Connection* connection, const int pos)
-throw(dbms::DatabaseException) {
- if(a_ociDefine != NULL)
- return;
-
- Database& database(static_cast <Database&>(dbmsStatement->getDatabase()));
- OCIError* error = database.getErrorHandler();
- Statement* statement(static_cast <Statement*>(dbmsStatement));
- dbms::Data& data = anna::dbms::Bind::getData();
- oci_param ociparam = getOCIParam(database, static_cast <oracle::Connection*>(connection), data);
-
- if(data.isNulleable() == false) {
- anna_dbms_oracle_check(
- OCIDefineByPos(
- *statement, &a_ociDefine, error, pos, ociparam.buffer, ociparam.maxLength, ociparam.type,
- 0, ociparam.length, 0, OCI_DEFAULT
- ),
- error
- );
- } else {
- anna_dbms_oracle_check(
- OCIDefineByPos(
- *statement, &a_ociDefine, error, pos, ociparam.buffer, ociparam.maxLength, ociparam.type,
- &a_nullIndicator, ociparam.length, 0, OCI_DEFAULT
- ),
- error
- );
- }
-
- LOGDEBUG(
- std::string msg("anna::dbms::oracle::OutputBind::prepare | ");
- msg += asString();
- msg += " | Sentence: ";
- msg += statement->getName();
- msg += " | Position: ";
- msg += functions::asString(pos);
- Logger::debug(msg, ANNA_FILE_LOCATION)
- );
-}
-
-//-------------------------------------------------------------------------------
-// Transfiere la informacin obtenida desde Oracle. Todos los comprobados en �te
-// m�odo son parametros que modificados al ejecuta la sentencia Oracle debido cmo
-// hemos invocamo al m�odo OCIDefineByPos
-//
-// Todo esto se podr� haber hecho en la anna::dbms::DataBlock pero exigir�
-// definir una clase distinta para cada RDBMS. Creo que los Binds particulares de
-// cada base de datos se ocupen toda la complejidad de convertir los datos.
-//
-// (1) Truco para fijar el contenido y la longitud actual.
-//-------------------------------------------------------------------------------
-void OutputBind::decode() const
-throw(RuntimeException) {
- OutputBind* _this = const_cast <OutputBind*>(this);
- char* str;
- Data& data = _this->getData();
- data.setNull(a_nullIndicator < 0);
-
- switch(data.getType()) {
- case Data::Type::String:
- str = (char*) data.getBuffer();
-
- if(data.isNull() == true)
- *str = 0;
- else
- dbms::String::strip(str);
-
- break;
- case Data::Type::Integer:
- throw RuntimeException("anna::dbms::oracle::OutputBind::decode not implemented for Data::Type::Integer", ANNA_FILE_LOCATION);
- break;
- case Data::Type::Float:
- decodeFloat(data);
- break;
- case Data::Type::ShortBlock:
- decodeShortBlock(data);
- break;
- case Data::Type::LongBlock:
- decodeLongBlock(data);
- break;
- case Data::Type::Date:
- case Data::Type::TimeStamp:
-
- try {
- decodeDate(data);
- } catch(DatabaseException& edb) {
- throw RuntimeException(edb);
- }
-
- break;
- }
-}
-
-void OutputBind::decodeFloat(dbms::Data& data) const
-throw(RuntimeException) {
- dbms::Float& _float = static_cast <dbms::Float&>(data);
-
- if(data.isNull() == true) {
- _float = 0.0;
- return;
- }
-
- char* _data = (char*) a_ofb->getData();
- const char decimalPoint = oracle::Database::getDecimalPoint();
-
- if(decimalPoint != 0) {
- char* point = anna_strchr(_data, decimalPoint);
-
- if(point != NULL)
- *point = '.';
- }
-
- sscanf(_data, _float.getFormat(), (float*) _float.getBuffer());
-}
-
-void OutputBind::decodeShortBlock(dbms::Data& data) const
-throw(RuntimeException) {
- const anna::DataBlock& constdbms(static_cast <dbms::ShortBlock&>(data).getValue());
- anna::DataBlock& dataBlock(const_cast <anna::DataBlock&>(constdbms));
-
- if(data.isNull() == true) {
- dataBlock.clear();
- return;
- }
-
- const char* src = a_ofb->getData();
-
- char* dest = (char*) dataBlock.getData();
-
- unsigned char hex;
-
- int j = 0;
-
- for(int i = 1; i < a_length; i += 2, j ++) {
- hex = asByte(src [i - 1]) << 4;
- hex |= asByte(src [i]);
- dest [j] = hex;
- }
-
- dataBlock.clear();
- dataBlock.allocate(j); // (1)
-}
-
-//--------------------------------------------------------------------------------------------
-// (1) Offset = 1 => primer caracter.
-//--------------------------------------------------------------------------------------------
-void OutputBind::decodeLongBlock(dbms::Data& data) const
-throw(RuntimeException) {
- const anna::DataBlock& constdbms(static_cast <dbms::LongBlock&>(data).getValue());
- anna::DataBlock& dataBlock(const_cast <anna::DataBlock&>(constdbms));
- dataBlock.clear();
-
- if(data.isNull() == true)
- return;
-
- ub1* buffer;
- ub4 maxLength;
- ub4 length;
- sword ret;
- bool stop = false;
- ub4 offset = 1; // (1)
-
- try {
- buffer = (ub1*) a_ofb->getData();
- maxLength = a_ofb->getSize();
- length = 0;
-
- do {
- ret = OCILobRead(a_blob.context, a_blob.error, a_blob.handle, &length, offset, buffer, maxLength, 0, 0, 0, SQLCS_IMPLICIT);
-
- switch(ret) {
- case OCI_SUCCESS:
- dataBlock += anna::DataBlock((const char*) buffer, length, false);
- stop = true;
- break;
- case OCI_NEED_DATA:
- dataBlock += anna::DataBlock((const char*) buffer, length, false);
- offset += length;
- break;
- default:
- throw dbms::DatabaseException(oracle::ResultCode(ret, a_blob.error), ANNA_FILE_LOCATION);
- }
- } while(stop == false);
- } catch(dbms::DatabaseException& edbms) {
- throw RuntimeException(edbms);
- }
-}
-
-void OutputBind::do_write(const dbms::LongBlock& data) const
-throw(RuntimeException, dbms::DatabaseException) {
- const anna::DataBlock& dataBlock = data.getValue();
-
- if(a_blob.handle == NULL) {
- string msg("anna::dbms::oracle::OutputBind::do_write | ");
- msg += data.asString();
- msg += " | BLOB must be loaded before modification";
- throw RuntimeException(msg, ANNA_FILE_LOCATION);
- }
-
- ub1* buffer = (ub1*) dataBlock.getData();
- ub4 length = dataBlock.getSize();
- anna_dbms_oracle_check(
- OCILobWrite(a_blob.context, a_blob.error, a_blob.handle, &length, (ub4) 1, buffer, length, OCI_ONE_PIECE, 0, 0, 0, SQLCS_IMPLICIT),
- a_blob.error
- );
-}
-
-void OutputBind::decodeDate(dbms::Data& data) const
-throw(RuntimeException, dbms::DatabaseException) {
- if(data.isNull() == true)
- return;
-
- Date& date = static_cast <Date&>(data);
- sb2 year;
- ub1 month, day;
- anna_dbms_oracle_check(
- OCIDateTimeGetDate(a_datetime.env, a_datetime.error, a_datetime.handle, &year, &month, &day),
- a_datetime.error
- );
- date.setYear(year);
- date.setMonth(month);
- date.setDay(day);
- ub1 hour, min, sec;
- ub4 fsec;
- sword status = OCIDateTimeGetTime(a_datetime.env, a_datetime.error, a_datetime.handle, &hour, &min, &sec, &fsec);
-
- if(status == OCI_SUCCESS) {
- date.setHour(hour);
- date.setMinute(min);
- date.setSecond(sec);
-
- if(data.getType() == Data::Type::TimeStamp)
- static_cast <dbms::TimeStamp&>(data).setFractionalSecond(fsec / 1000);
- } else {
- date.setHour(0);
- date.setMinute(0);
- date.setSecond(0);
-
- if(data.getType() == Data::Type::TimeStamp)
- static_cast <dbms::TimeStamp&>(data).setFractionalSecond(0);
- }
-}
+++ /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 //
-
-
-#include <stdlib.h>
-#include <stdio.h>
-
-#include <oci.h>
-
-#include <anna/config/defines.hpp>
-#include <anna/core/tracing/Logger.hpp>
-
-#include <anna/dbms.oracle/ResultCode.hpp>
-
-using namespace anna;
-using namespace anna::dbms;
-
-oracle::ResultCode::ErrorDecoder oracle::ResultCode::st_errorDecoder;
-
-oracle::ResultCode::ResultCode(const int status, OCIError* error) :
- dbms::ResultCode(0, NULL, &st_errorDecoder) {
- char errorText [dbms::ResultCode::MaxErrorLen];
- int errorCode = status;
-
- if(status == OCI_SUCCESS) {
- dbms::ResultCode::set(OCI_SUCCESS, NULL);
- return;
- } else if(status == OCI_SUCCESS_WITH_INFO) {
- OCIErrorGet(error, (ub4) 1, (text*) 0, &errorCode, (unsigned char*) errorText, (ub4) sizeof(errorText), OCI_HTYPE_ERROR);
- dbms::ResultCode::set(OCI_SUCCESS, errorText);
- LOGINFORMATION(Logger::information(asString(), ANNA_FILE_LOCATION));
- return;
- }
-
- switch(status) {
- case OCI_ERROR:
- OCIErrorGet(error, (ub4) 1, (text*) 0, &errorCode, (unsigned char*) errorText, (ub4) sizeof(errorText), OCI_HTYPE_ERROR);
- break;
- case OCI_NEED_DATA: anna_strcpy(errorText, "OCI | Need data"); break;
- case OCI_NO_DATA: anna_strcpy(errorText, "OCI | Data not found"); break;
- case OCI_INVALID_HANDLE: anna_strcpy(errorText, "OCI | Invalid handle"); break;
- default: sprintf(errorText, "OCI | Error code: %d", status); break;
- }
-
- dbms::ResultCode::set(errorCode, errorText);
-}
-
-bool oracle::ResultCode::ErrorDecoder::notFound(const int errorCode) const
-throw() {
- return errorCode == OCI_NO_DATA;
-}
-
-bool oracle::ResultCode::ErrorDecoder::successful(const int errorCode) const
-throw() {
- return errorCode == OCI_SUCCESS;
-}
-
-bool oracle::ResultCode::ErrorDecoder::lostConnection(const int errorCode) const
-throw() {
- return errorCode == 28 || errorCode == 3113 || errorCode == 3114 || errorCode == 1012 || errorCode == 12570 || errorCode == 12571;
-}
+++ /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 //
-
-
-#include <oci.h>
-
-#include <anna/config/defines.hpp>
-#include <anna/core/tracing/TraceMethod.hpp>
-
-#include <anna/dbms.oracle/oracle.hpp>
-
-using namespace std;
-using namespace anna;
-
-dbms::oracle::Statement::~Statement() {
- if(a_ociStmt)
- OCIHandleFree(a_ociStmt, OCI_HTYPE_STMT);
-}
-
-void dbms::oracle::Statement::prepare(dbms::Connection* dbmsConnection)
-throw(RuntimeException, dbms::DatabaseException) {
- LOGMETHOD(TraceMethod tm("anna::dbms::oracle::Statement", "prepare", ANNA_FILE_LOCATION));
- Connection* connection(static_cast <Connection*>(dbmsConnection));
- Database& dbms(static_cast <Database&>(connection->getDatabase()));
- a_ociError = dbms.getErrorHandler();
-
- if(a_ociStmt != NULL) {
- anna_dbms_oracle_check(OCIHandleFree(a_ociStmt, OCI_HTYPE_STMT), a_ociError);
- a_ociStmt = NULL;
- }
-
- const char* expression = dbms::oracle::Statement::getExpression().c_str();
-
- anna_dbms_oracle_check(OCIHandleAlloc(dbms, (void**) &a_ociStmt, OCI_HTYPE_STMT, 0, 0), a_ociError);
-
- anna_dbms_oracle_check(
- OCIStmtPrepare(a_ociStmt, a_ociError, (text*) expression, anna_strlen(expression), OCI_NTV_SYNTAX, OCI_DEFAULT),
- a_ociError
- );
-
- int pos = 1;
-
- for(input_iterator ii = input_begin(), maxii = input_end(); ii != maxii; ii ++)
- inputBind(ii)->prepare(this, dbmsConnection, pos ++);
-
- pos = 1;
-
- for(output_iterator oo = output_begin(), maxoo = output_end(); oo != maxoo; oo ++)
- outputBind(oo)->prepare(this, dbmsConnection, pos ++);
-}
-
-dbms::ResultCode dbms::oracle::Statement::execute(dbms::Connection* dbmsConnection)
-throw(RuntimeException, dbms::DatabaseException) {
- Connection* connection(static_cast <Connection*>(dbmsConnection));
-
- for(input_iterator ii = input_begin(), maxii = input_end(); ii != maxii; ii ++) {
- inputBind(ii)->code();
- LOGDEBUG(
- string msg("anna::dbms::oracle::Statement::InputBind: ");
- msg += inputBind(ii)->asString();
- Logger::debug(msg, ANNA_FILE_LOCATION);
- );
- }
-
- const sword status = OCIStmtExecute(*connection, a_ociStmt, a_ociError, 1, 0, NULL, NULL, OCI_DEFAULT);
-
- a_firstFetch = false;
-
- ResultCode result(status, a_ociError);
-
- if(result.successful() == true && result.notFound() == false) {
- for(output_iterator oo = output_begin(), maxoo = output_end(); oo != maxoo; oo ++) {
- outputBind(oo)->decode();
- LOGDEBUG(
- string msg("anna::dbms::oracle::Statement::OutputBind: ");
- msg += outputBind(oo)->asString();
- Logger::debug(msg, ANNA_FILE_LOCATION);
- );
- }
-
- a_firstFetch = true;
- }
-
- return result;
-}
-
-//-------------------------------------------------------------------------------------------------
-// (1) Si es una consulta de seleccin, entonces, nada m� ejecutar la sentencia el primer registro
-// encontrado ya est�cargado en las variables de salida, para obtener los siguientes hay que invocar
-// a fetch. Vamos a hacer este esquema m� gen�ico de forma que siempre habr�que invocar a
-// 'fetch' para obtener los datos, pero en Oracle, la primera llamada no har�nada.
-//-------------------------------------------------------------------------------------------------
-bool dbms::oracle::Statement::fetch()
-throw(RuntimeException, dbms::DatabaseException) {
- bool result;
-
- if(a_firstFetch == true) { // (1)
- a_firstFetch = false;
- result = true;
- } else {
- ResultCode resultCode(OCIStmtFetch(a_ociStmt, a_ociError, 1, OCI_FETCH_NEXT, OCI_DEFAULT), a_ociError);
- result = resultCode.successful();
-
- if(result == false && resultCode.notFound() == false)
- Logger::write(Logger::Error, asString(), resultCode.asString(), ANNA_FILE_LOCATION);
-
- if(result == true) {
- for(output_iterator oo = output_begin(), maxoo = output_end(); oo != maxoo; oo ++) {
- outputBind(oo)->decode();
- LOGDEBUG(Logger::write(Logger::Debug, outputBind(oo)->asString(), ANNA_FILE_LOCATION));
- }
- }
- }
-
- LOGDEBUG(
- string msg("anna::dbms::oracle::Statement::fetch | Result: ");
- msg += functions::asString(result);
- Logger::debug(msg, ANNA_FILE_LOCATION);
- );
- return result;
-}
-
-
-
+++ /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 //
-
-
-#include <anna/core/internal/sccs.hpp>
-#include <anna/dbms/internal/sccs.hpp>
-#include <anna/dbms.oracle/internal/sccs.hpp>
-
-#include <anna/core/internal/ModuleManager.hpp>
-
-anna_define_sccs_tag_ex(dbms_oracle, dbms.oracle, 1);
-
-void anna::dbms::oracle::sccs::activate()
-throw() {
- dbms::sccs::activate();
- ModuleManager::instantiate().insert(anna_use_sccs_tag(dbms_oracle), "00");
-}
-
+++ /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 //
-
-
-#include <anna/dbms/Bind.hpp>
-#include <anna/dbms/Data.hpp>
-
-using namespace anna;
-
-std::string dbms::Bind::asString() const
-throw() {
- std::string result("dbms::Bind { Name: ");
- result += a_name;
- result += " | ";
- result += a_data.asString();
- return result += " }";
-}
-
-
+++ /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 //
-
-
-#include <anna/config/defines.hpp>
-#include <anna/core/tracing/TraceMethod.hpp>
-
-#include <anna/xml/Node.hpp>
-#include <anna/xml/Attribute.hpp>
-
-#include <anna/dbms/Connection.hpp>
-#include <anna/dbms/Database.hpp>
-#include <anna/dbms/Statement.hpp>
-#include <anna/dbms/Statement.hpp>
-
-using namespace std;
-using namespace anna;
-
-//-----------------------------------------------------------------------------------------------------------
-// (1) Si no tiene variables de salida => consideramos que es un update, insert o delete.
-//-----------------------------------------------------------------------------------------------------------
-dbms::ResultCode dbms::Connection::execute(Statement* statement)
-throw(RuntimeException, dbms::DatabaseException) {
- if(statement == NULL) {
- string msg(asString());
- msg += " | Cannot execute a NULL sentence";
- throw RuntimeException(msg, ANNA_FILE_LOCATION);
- }
-
- LOGMETHOD(TraceMethod ttmm("dbms::Connection", "execute", ANNA_FILE_LOCATION));
- LOGDEBUG(
- string msg("Using Connection | ");
- msg += asString();
- Logger::debug(msg, ANNA_FILE_LOCATION)
- );
- Guard guard(statement, "Statement from dbms::Connection::execute");
- const Microsecond init = functions::hardwareClock();
-
- if(statement->a_prepared == false) {
- statement->prepare(this);
- statement->a_prepared = true;
- }
-
- LOGDEBUG(
- string msg("dbms::Connection::execute | ");
- msg += statement->asString();
- Logger::debug(msg, ANNA_FILE_LOCATION);
- );
-
- if(statement->requiresCommit() == true && a_rollbackPending == true) { // (1)
- string msg("dbms::Connection::execute | ");
- msg += asString();
- msg += " | Connection has pending ROLLBACKS for execution";
- throw RuntimeException(msg, ANNA_FILE_LOCATION);
- }
-
- ResultCode result;
- int tryCounter = 0;
-
- while(true) {
- result = statement->execute(this);
-
- if(result.lostConnection() == false)
- break;
-
- string msg = asString();
- msg += " | ";
- msg += statement->asString();
- msg += " | ";
- msg += result.asString();
- Logger::alert(msg, ANNA_FILE_LOCATION);
- a_database.recover(*this, ++ tryCounter);
- }
-
- statement->measureTiming(init, functions::hardwareClock());
-
- if(result.successful() == false && result.notFound() == false) {
- string msg(asString());
- msg += " | Sentence: ";
- msg += statement->getName();
- Logger::write(Logger::Error, msg, result.asString(), ANNA_FILE_LOCATION);
- }
-
- if(statement->requiresCommit() == true) { // (1)
- if(result.successful() == false) {
- if(statement->isCritical() == true) {
- a_rollbackPending = true;
- throw DatabaseException(statement->getName(), result, ANNA_FILE_LOCATION);
- }
- } else {
- a_commitPending ++;
-
- if(a_maxCommitPending > 0 && a_commitPending > a_maxCommitPending) {
- commit();
- a_commitPending = 0;
- a_rollbackPending = false;
- }
- }
- }
-
- return result;
-}
-
-//------------------------------------------------------------------------------------------------
-// (1) Esto no es estrictamente necesario, pero lo hacemos para que no nos despisten las trazas
-// y los volcados de contexto.
-//------------------------------------------------------------------------------------------------
-void dbms::Connection::commit()
-throw(RuntimeException, dbms::DatabaseException) {
- LOGINFORMATION(
- string msg("dbms::Connection::commit | ");
- msg += asString();
- Logger::information(msg, ANNA_FILE_LOCATION);
- );
-
- if(isAvailable() == false) {
- string msg(asString());
- msg += " | Unavailable connection";
- throw RuntimeException(msg, ANNA_FILE_LOCATION);
- }
-
- do_commit();
- a_commitPending = 0; // (1)
- a_rollbackPending = false;
-}
-
-//------------------------------------------------------------------------------------------------
-// (1) Esto no es estrictamente necesario, pero lo hacemos para que no nos despisten las trazas
-// y los volcados de contexto.
-//------------------------------------------------------------------------------------------------
-void dbms::Connection::rollback()
-throw() {
- LOGWARNING(
- string msg("dbms::Connection::rollback | ");
- msg += asString();
- Logger::warning(msg, ANNA_FILE_LOCATION);
- );
-
- if(isAvailable() == false) {
- string msg(asString());
- msg += " | Unavailable connection";
- throw RuntimeException(msg, ANNA_FILE_LOCATION);
- }
-
- do_rollback();
- a_commitPending = 0;
- a_rollbackPending = false; // (1)
-}
-
-void dbms::Connection::lock()
-throw(RuntimeException) {
- if(isAvailable() == false) {
- string msg(asString());
- msg += " | Unavailable connection";
- throw RuntimeException(msg, ANNA_FILE_LOCATION);
- }
-
- comm::Resource::lock();
-
- if(a_lockingCounter ++ == 0) {
- a_commitPending = 0;
- a_rollbackPending = false;
-
- try {
- if(do_beginTransaction() == true)
- a_commitPending = 1;
- } catch(dbms::DatabaseException& edb) {
- throw RuntimeException(edb);
- }
- }
-
- LOGDEBUG(
- string msg("dbms::Connection::lock | ");
- msg += asString();
- Logger::debug(msg, ANNA_FILE_LOCATION)
- );
-}
-
-void dbms::Connection::unlock()
-throw() {
- LOGDEBUG(
- string msg("dbms::Connection::unlock | ");
- msg += asString();
- Logger::debug(msg, ANNA_FILE_LOCATION)
- );
-
- if(-- a_lockingCounter <= 0) {
- a_lockingCounter = 0;
-
- try {
- if(a_rollbackPending == true)
- rollback();
- else if(a_commitPending > 0)
- commit();
- } catch(Exception& ex) {
- Logger::emergency(ex.getText(), ex.getFromFile(), ex.getFromLine());
- }
- }
-
- comm::Resource::unlock();
-}
-
-string dbms::Connection::asString() const
-throw() {
- string result("dbms::Connection { ");
- result += comm::Resource::asString();
- result += " | ";
- result += a_database.asString();
- result += " | user: ";
- result += a_user;
- result += functions::asText(" | LockingCounter: ", a_lockingCounter);
- result += functions::asText(" | password: ******* | CommitPending: ", a_commitPending);
- result += functions::asText(" | RollbackPending: ", a_rollbackPending);
- return result += " }";
-}
-
-xml::Node* dbms::Connection::asXML(xml::Node* parent) const
-throw() {
- xml::Node* result = comm::Resource::asXML(parent);
- result->createAttribute("User", a_user);
- result->createAttribute("LockingCounter", a_lockingCounter);
- result->createAttribute("CommitPending", a_commitPending);
- result->createAttribute("RollbackPending", functions::asString(a_rollbackPending));
- return result;
-}
-
+++ /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 //
-
-
-#include <anna/core/functions.hpp>
-
-#include <anna/dbms/Data.hpp>
-
-using namespace anna;
-
-std::string dbms::Data::asString() const
-throw() {
- static const char* typeName [] = { "Integer", "String", "Float", "ShortBlock", "LongBlock", "Date", "TimeStamp" };
- std::string result("dbms::Data { Type: ");
- result += typeName [a_type];
- result += " | Buffer: ";
- result += functions::asHexString(anna_ptrnumber_cast(a_buffer));
- result += " | MaxSize: ";
- result += functions::asString(a_maxSize);
- result += " | Null: ";
- result += functions::asString(a_isNull);
- return result += " }";
-}
-
+++ /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 //
-
-
-#include <stdlib.h>
-#include <locale.h>
-
-#include <string>
-#include <algorithm>
-
-#include <anna/core/tracing/TraceMethod.hpp>
-
-#include <anna/xml/Node.hpp>
-#include <anna/xml/Attribute.hpp>
-
-#include <anna/comm/INetAddress.hpp>
-
-#include <anna/dbms/Database.hpp>
-#include <anna/dbms/Statement.hpp>
-#include <anna/dbms/FailRecoveryHandler.hpp>
-#include <anna/dbms/internal/sccs.hpp>
-#include <anna/dbms/Float.hpp>
-#include <anna/dbms/StatementTranslator.hpp>
-
-using namespace std;
-using namespace anna;
-using namespace anna::dbms;
-
-Database::Database(const char* className, const char* dbmsName) :
- Component(className),
- a_name((dbmsName == NULL) ? "local" : dbmsName),
- a_type((dbmsName == NULL) ? Type::Local : Type::Remote),
- a_failRecoveryHandler(NULL),
- a_statementTranslator(NULL) {
- dbms::sccs::activate();
-}
-
-Database::~Database() {
- stop();
-}
-
-void Database::do_initialize()
-throw(RuntimeException) {
- LOGMETHOD(TraceMethod tm("dbms::Database", "do_initialize", ANNA_FILE_LOCATION));
- int counter(0);
- bool error = false;
-
- for(connection_iterator iic = connection_begin(), maxiic = connection_end(); iic != maxiic; iic ++) {
- try {
- connection(iic)->open();
- counter ++;
- } catch(Exception& ex) {
- ex.trace();
- error = true;
- }
- }
-
- if(counter == 0 && error == true) {
- string msg(asString());
- msg += " | No available connections";
- throw RuntimeException(msg, ANNA_FILE_LOCATION);
- }
-
- LOGINFORMATION(
- Logger::information(asString(), ANNA_FILE_LOCATION);
- );
-}
-
-void Database::do_stop()
-throw() {
- LOGMETHOD(TraceMethod tm("dbms::Database", "do_stop", ANNA_FILE_LOCATION));
-
- try {
- Connection* _connection;
-
- for(connection_iterator iic = connection_begin(), maxiic = connection_end(); iic != maxiic; iic ++) {
- _connection = connection(iic);
- _connection->close();
- delete _connection;
- }
-
- a_connections.clear();
- } catch(Exception& ex) {
- ex.trace();
- a_connections.clear();
- }
-}
-
-/**
- * Para evitar que todos los clones usen la misma conexion a la base de datos, se realiza en
- * cada uno de ellos una re-conexion, es decir, se cierra la original (abierta por el proceso
- * padre) y se abre una nueva conexion con los mismos parametros y contra la misma base de datos.
- */
-void Database::do_cloneChild()
-throw(RuntimeException) {
- LOGMETHOD(TraceMethod tm("dbms::Database", "do_cloneChild", ANNA_FILE_LOCATION));
-
- for(connection_iterator ii = connection_begin(), maxii = connection_end(); ii != maxii; ii ++) {
- dbms::Connection* conn = connection(ii);
- LOGDEBUG(
- string msg("dbms::Database::do_cloneChild | ");
- msg += conn->asString();
- Logger::debug(msg, ANNA_FILE_LOCATION);
- );
- recover(*conn, 0);
- }
-}
-
-Connection* Database::createConnection(const char* name, const char* user, const char* password)
-throw(RuntimeException, DatabaseException) {
- Guard guard(this, "dbms::Database (createConnection)");
-
- if(a_connections.size() >= MaxConnection) {
- string msg("Database::createConnection | ");
- msg += asString();
- msg += functions::asText(" | Cannot create more than %d connections per database", MaxConnection);
- throw RuntimeException(msg, ANNA_FILE_LOCATION);
- }
-
- for(connection_iterator ii = connection_begin(), maxii = connection_end(); ii != maxii; ii ++) {
- if(connection(ii)->getName() == name) {
- string msg("Database::createConnection | ");
- msg += asString();
- msg += " | Connection: ";
- msg += name;
- msg += " | Previously registered";
- throw RuntimeException(msg, ANNA_FILE_LOCATION);
- }
- }
-
- string strname(name);
- Connection* result = allocateConnection(strname, user, password);
-
- if(result == NULL) {
- string msg(asString());
- msg += " | ";
- msg += strname;
- msg += " | Unable to instance connection";
- throw RuntimeException(msg, ANNA_FILE_LOCATION);
- }
-
- LOGDEBUG(
- string msg("dbms::Database::createConnection | ");
- msg += result->asString();
- Logger::write(Logger::Debug, msg, ANNA_FILE_LOCATION);
- );
-
- if(getState() == Component::State::Running) {
- try {
- result->open();
- a_connections.push_back(result);
- } catch(RuntimeException& ex) {
- ex.trace();
- delete result;
- throw;
- } catch(DatabaseException& edbms) {
- edbms.trace();
- delete result;
- throw;
- }
- } else
- a_connections.push_back(result);
-
- return result;
-}
-
-Connection& Database::findConnection(const char* name)
-throw(RuntimeException) {
- Guard guard(this, "dbms::Database (findConnection)");
- Connection* result = NULL;
-
- for(connection_iterator ii = connection_begin(), maxii = connection_end(); ii != maxii; ii ++) {
- if(anna_strcmp(connection(ii)->getName().c_str(), name) == 0) {
- result = connection(ii);
- break;
- }
- }
-
- if(result == NULL) {
- string msg("Database::findConnection | ");
- msg += asString();
- msg += " | Conexion: ";
- msg += name;
- msg += " | Unregistered";
- throw RuntimeException(msg, ANNA_FILE_LOCATION);
- }
-
- if(result->isAvailable() == false || result->isEnabled() == false) {
- string msg("Database::findConnection | ");
- msg += asString();
- msg += " | Connection: ";
- msg += name;
- msg += " | Unavailable";
- throw RuntimeException(msg, ANNA_FILE_LOCATION);
- }
-
- LOGDEBUG(
- string msg("Database::findConnection | ");
- msg += result->asString();
- Logger::debug(msg, ANNA_FILE_LOCATION);
- );
- return *result;
-}
-
-Statement* Database::createStatement(const char* name, const char* expression, const bool isCritical)
-throw(RuntimeException) {
- if(findStatement(name) != NULL)
- throw RuntimeException(functions::asString("Sentence: %s | Name already in use", name), ANNA_FILE_LOCATION);
-
- Guard guard(this, "dbms::Database::createStatement");
-
- if(a_statementTranslator != NULL)
- expression = a_statementTranslator->apply(expression);
-
- Statement* result = allocateStatement(name, expression, isCritical);
- LOGDEBUG(
- string msg("dbms::Database::createStatement | ");
- msg += result->asString();
-
- if(a_statementTranslator != NULL) {
- msg += " | Translator: ";
- msg += a_statementTranslator->getName();
- }
- Logger::debug(msg, ANNA_FILE_LOCATION);
- );
- a_statements.push_back(result);
- return result;
-}
-
-Statement* Database::findStatement(const char* name)
-throw() {
- Guard guard(this, "dbms::Database::findStatement");
- vector <Statement*>::iterator ii, maxii;
- Statement* result(NULL);
-
- for(ii = a_statements.begin(), maxii = a_statements.end(); ii != maxii; ii ++) {
- if(anna_strcmp((*ii)->getName().c_str(), name) == 0) {
- result = *ii;
- break;
- }
- }
-
- return result;
-}
-
-void Database::releaseStatement(Statement* statement)
-throw() {
- if(statement == NULL) {
- Logger::write(Logger::Warning, asString(), "Cannot release a NULL SQL sentence", ANNA_FILE_LOCATION);
- return;
- }
-
- LOGDEBUG(
- string msg("dbms::Database::releaseStatement | ");
- msg += statement->asString();
- Logger::debug(msg, ANNA_FILE_LOCATION);
- );
- Guard guard(this, "dbms::Database::releaseStatement");
- vector <Statement*>::iterator end = a_statements.end();
- vector <Statement*>::iterator ii = find(a_statements.begin(), end, statement);
-
- if(ii != end) {
- a_statements.erase(ii);
- delete statement;
- }
-}
-
-void Database::recover(Connection& connection, const int tryCounter)
-throw(RuntimeException) {
- try {
- connection.close();
- connection.open();
- } catch(DatabaseException& edbms) {
- edbms.trace();
-
- if(a_failRecoveryHandler != NULL)
- a_failRecoveryHandler->apply(connection, tryCounter);
- }
-}
-
-string Database::asString() const
-throw() {
- string result("dbms::Database { ");
- result += Component::asString();
-
- if(a_type == Type::Local)
- result += " | Type: Local";
- else {
- result += " | Type: Remote | Name: ";
- result += a_name;
- }
-
- return result += " }";
-}
-
-xml::Node* Database::asXML(xml::Node* parent) const
-throw() {
- parent = Component::asXML(parent);
- xml::Node* result = parent->createChild("dbms.Database");
- xml::Node* node;
- result->createAttribute("Type", (a_type == Type::Local) ? "Local" : "Remote");
-
- if(a_type != Type::Local)
- result->createAttribute("Name", a_name);
-
- if(a_statementTranslator != NULL)
- result->createAttribute("Translator", a_statementTranslator->getName());
-
- node = result-> createChild("Connections");
-
- for(const_connection_iterator ii = connection_begin(), maxii = connection_end(); ii != maxii; ii ++)
- connection(ii)->asXML(node);
-
- node = result-> createChild("Statements");
-
- for(const_statement_iterator ii = statement_begin(), maxii = statement_end(); ii != maxii; ii ++)
- statement(ii)->asXML(node);
-
- return result;
-}
-
+++ /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 //
-
-
-#include <string.h>
-
-#include <anna/config/defines.hpp>
-#include <anna/core/functions.hpp>
-
-#include <anna/dbms/Date.hpp>
-
-using namespace std;
-using namespace anna;
-using namespace anna::dbms;
-
-Date::Date(const bool isNulleable, const char* format) :
- Data(Type::Date, MaxDateSize, isNulleable) {
- Data::setBuffer(a_buffer);
- a_buffer [0] = 0;
- a_format = (format == NULL) ? NULL : strdup(format);
- anna_memset(&a_value, 0, sizeof(a_value));
-}
-
-Date::Date(const Data::Type::_v type, const bool isNulleable, const char* format) :
- Data(type, MaxDateSize, isNulleable) {
- Data::setBuffer(a_buffer);
- a_buffer [0] = 0;
- a_format = (format == NULL) ? NULL : strdup(format);
- anna_memset(&a_value, 0, sizeof(a_value));
-}
-
-Date::Date(const Date& other) :
- Data(other) {
- Data::setBuffer(a_buffer);
- a_buffer [0] = 0;
- a_format = (other.a_format == NULL) ? NULL : strdup(other.a_format);
- anna_memcpy(&a_value, &other.a_value, sizeof(a_value));
-}
-
-Date::~Date() {
- if(a_format != NULL)
- free(a_format);
-}
-
-const char* dbms::Date::getCStringValue() const
-throw() {
- const char* format;
-
- if((format = a_format) == NULL)
- format = "%d/%m/%Y %H:%M:%S";
-
- return (strftime(const_cast <Date*>(this)->a_buffer, MaxDateSize, format, &a_value) == 0) ? NULL : a_buffer;
-}
-
-Date& Date::operator = (const Date & other)
-throw(RuntimeException) {
- if(this != &other) {
- if(other.isNull() == true) {
- setNull(true);
- anna_memset(&a_value, 0, sizeof(a_value));
- } else {
- setNull(false);
- anna_memcpy(&a_value, &other.a_value, sizeof(a_value));
- }
- }
-
- return *this;
-}
-
-void Date::setValue(const char* str)
-throw(RuntimeException) {
- if(a_format == NULL) {
- string msg(asString());
- msg += " | anna::dbms::Data::setValue (const char*) requires format especification";
- throw RuntimeException(msg, ANNA_FILE_LOCATION);
- }
-
- tm aux;
- char* r = strptime(str, a_format, &aux);
-
- if(r == NULL) {
- string msg(asString());
- msg += " | String: ";
- msg += str;
- msg += " | Can't be interpreted as valid date";
- throw RuntimeException(msg, ANNA_FILE_LOCATION);
- }
-
- Data::setNull(false);
- anna_memcpy(&a_value, &aux, sizeof(a_value));
-}
-
-void Date::setValue(const Second &second)
-throw(RuntimeException) {
- tm* aux = localtime((time_t*) & second);
-
- if(aux == NULL) {
- string msg(asString());
- msg += functions::asText(" | Second: ", (int) second);
- msg += " | Can't be interpreted as valid date";
- throw RuntimeException(msg, ANNA_FILE_LOCATION);
- }
-
- Data::setNull(false);
- anna_memcpy(&a_value, aux, sizeof(a_value));
-}
-
-void dbms::Date::set(const char* what, int& variable, const int value, const int min, const int max)
-throw(RuntimeException) {
- if(value < min) {
- string msg(what);
- msg += functions::asText(" must be greater than or equal to ", min);
- throw RuntimeException(msg, ANNA_FILE_LOCATION);
- }
-
- if(value > max && max != -1) {
- string msg(what);
- msg += functions::asText(" must be less than or equal to ", max);
- throw RuntimeException(msg, ANNA_FILE_LOCATION);
- }
-
- Data::setNull(false);
- variable = value;
-}
-
-string dbms::Date::asString() const
-throw() {
- const char* cstring;
- string result("dbms::Date { ");
- result += dbms::Data::asString();
- result += " | Format: ";
- result += (a_format == NULL) ? "<null>" : a_format;
- result += " | Value: ";
-
- if(Data::isNull() == false) {
- if((cstring = getCStringValue()) == NULL)
- result += "<not valid>";
- else
- result += cstring;
- } else
- result += "<null>";
-
- return result += " }";
-}
-
+++ /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 //
-
-
-#include <anna/core/tracing/TraceMethod.hpp>
-#include <anna/core/functions.hpp>
-
-#include <anna/dbms/Database.hpp>
-#include <anna/dbms/Delivery.hpp>
-#include <anna/dbms/Connection.hpp>
-
-using namespace std;
-using namespace anna;
-
-void dbms::Delivery::createConnections(dbms::Database& database, const char* prefixName, const char* user, const char* password, const int n)
-throw(RuntimeException, dbms::DatabaseException) {
- string name;
-
- for(int i = 0; i < n; i ++) {
- name = prefixName;
- name += functions::asString("%04d", i);
- this->add(database.createConnection(name.c_str(), user, password));
- }
-
- a_iiConnection = this->begin();
-}
-
-dbms::Connection& dbms::Delivery::getConnection()
-throw(RuntimeException) {
- return *(static_cast <dbms::Connection*>(comm::Delivery::apply()));
-}
-
-//--------------------------------------------------------------------------------------------------
-// Se invoca desde la seccion critica establecida en comm::Delivery::apply.
-//
-// (0) Si no hay registrada ninguna conexion
-//--------------------------------------------------------------------------------------------------
-comm::Resource* dbms::Delivery::do_apply()
-throw(RuntimeException) {
- iterator maxii = end();
-
- if(a_iiConnection == maxii) // (0)
- return NULL;
-
- iterator init = a_iiConnection;
- Connection* result = NULL;
- Connection* w;
-
- do {
- w = connection(a_iiConnection);
-
- if(a_iiConnection == maxii)
- a_iiConnection = begin();
-
- if(w->isAvailable() == true && w->isEnabled() == true) {
- result = w;
- break;
- }
- } while(a_iiConnection != init);
-
- return result;
-}
+++ /dev/null
-#include <stdio.h>
-
-#include <anna/core/tracing/Logger.hpp>
-
-#include <anna/dbms/Float.hpp>
-
-using namespace anna;
-using namespace anna::dbms;
-
-std::string dbms::Float::asString () const
- throw ()
-{
- std::string result ("dbms::Float { ");
- result += dbms::Data::asString ();
- result += " | Value: ";
- result += functions::asString (a_format, a_value);
- return result += " }";
-}
-
+++ /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 //
-
-
-#include <stdio.h>
-
-#include <anna/core/tracing/Logger.hpp>
-
-#include <anna/dbms/Float.hpp>
-
-using namespace anna;
-using namespace anna::dbms;
-
-std::string dbms::Float::asString() const
-throw() {
- std::string result("dbms::Float { ");
- result += dbms::Data::asString();
- result += " | Value: ";
- result += functions::asString(a_format, a_value);
- return result += " }";
-}
-
+++ /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 //
-
-
-#include <anna/core/functions.hpp>
-
-#include <anna/dbms/Integer.hpp>
-
-using namespace anna;
-
-std::string dbms::Integer::asString() const
-throw() {
- std::string result("dbms::Integer { ");
- result += dbms::Data::asString();
- result += " | Valor: ";
- result += functions::asString(a_value);
- return result += " }";
-}
-
+++ /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 //
-
-
-#include <anna/core/functions.hpp>
-
-#include <anna/dbms/LongBlock.hpp>
-
-using namespace anna;
-
-dbms::LongBlock& dbms::LongBlock::operator = (const dbms::LongBlock & other)
-throw(RuntimeException) {
- if(this == &other)
- return *this;
-
- if(other.isNull() == true) {
- setNull(true);
- return *this;
- }
-
- return operator= (other.a_value);
-}
-
-dbms::LongBlock& dbms::LongBlock::operator = (const anna::DataBlock & value)
-throw(RuntimeException) {
- a_value = value;
- setNull(a_value.isEmpty());
- return *this;
-}
-
-std::string dbms::LongBlock::asString() const
-throw() {
- std::string result("dbms::LongBlock { ");
- result += dbms::Data::asString();
- result += " | Size: ";
-
- if(isNull())
- result += "(null)";
- else
- result += functions::asString(a_value.getSize());
-
- return result += " }";
-}
-
+++ /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 //
-
-
-#include <anna/core/functions.hpp>
-#include <anna/core/tracing/Logger.hpp>
-
-#include <anna/dbms/LongBlock.hpp>
-#include <anna/dbms/OutputBind.hpp>
-
-using namespace anna;
-using namespace std;
-
-void dbms::OutputBind::write() const
-throw(RuntimeException, dbms::DatabaseException) {
- const dbms::Data& data = Bind::getData();
-
- if(data.getType() != Data::Type::LongBlock) {
- string msg("anna::dbms::OutputBind::write | ");
- msg += data.asString();
- msg += " | This method only can be called for anna::dbms::LongBlock types";
- throw RuntimeException(msg, ANNA_FILE_LOCATION);
- }
-
- LOGDEBUG(
- string msg("anna::dbms::OutputBind::write | ");
- msg += data.asString();
- Logger::debug(msg, ANNA_FILE_LOCATION);
- );
- do_write(reinterpret_cast <const dbms::LongBlock&>(data));
-}
-
-
+++ /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 //
-
-
-#include <anna/core/functions.hpp>
-
-#include <anna/dbms/ResultCode.hpp>
-
-using namespace std;
-using namespace anna::dbms;
-
-bool ResultCode::notFound() const
-throw(anna::RuntimeException) {
- if(a_errorDecoder == NULL) {
- string msg(asString());
- msg += " | Has no decoder for associated error";
- throw anna::RuntimeException(msg, ANNA_FILE_LOCATION);
- }
-
- return a_errorDecoder->notFound(a_errorCode);
-}
-
-bool ResultCode::successful() const
-throw(anna::RuntimeException) {
- if(a_errorDecoder == NULL) {
- string msg(asString());
- msg += " | Has no decoder for associated error";
- throw anna::RuntimeException(msg, ANNA_FILE_LOCATION);
- }
-
- return a_errorDecoder->successful(a_errorCode);
-}
-
-bool ResultCode::locked() const
-throw(anna::RuntimeException) {
- if(a_errorDecoder == NULL) {
- string msg(asString());
- msg += " | Has no decoder for associated error";
- throw anna::RuntimeException(msg, ANNA_FILE_LOCATION);
- }
-
- return a_errorDecoder->locked(a_errorCode);
-}
-
-bool ResultCode::lostConnection() const
-throw(anna::RuntimeException) {
- if(a_errorDecoder == NULL) {
- string msg(asString());
- msg += " | Has no decoder for associated error";
- throw anna::RuntimeException(msg, ANNA_FILE_LOCATION);
- }
-
- return a_errorDecoder->lostConnection(a_errorCode);
-}
-
-//
-// No usamos la std::string porque la gran mayoría de las veces la ejecución de las sentencias SQL será
-// correcta => no hará falta reservar ninguna memoria.
-//
-void ResultCode::copy(const char* text)
-throw() {
- if(text == NULL) {
- if(a_errorText != NULL) {
- free(a_errorText);
- a_errorText = NULL;
- }
- } else {
- char* aux;
-
- if((aux = anna_strchr((char*) text, '\n')) != NULL)
- * aux = 0;
-
- const int textLen = anna_strlen(text);
-
- if(a_errorText == NULL)
- a_errorText = strdup(text);
- else if(anna_strlen(a_errorText) >= textLen)
- anna_strcpy(a_errorText, text);
- else {
- free(a_errorText);
- a_errorText = strdup(text);
- }
- }
-}
-
-std::string ResultCode::asString() const
-throw() {
- std::string result("dbms::ResultCode { Error: ");
- result += functions::asString(a_errorCode);
- result += " | Error: ";
- result += (a_errorText == NULL) ? "(null)" : a_errorText;
- result += " | Correct: ";
-
- if(a_errorDecoder != NULL)
- result += functions::asString(successful());
- else
- result += "<No ErrorDecoder>";
-
- return result += " }";
-}
+++ /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 //
-
-
-#include <anna/xml/Node.hpp>
-#include <anna/xml/Attribute.hpp>
-
-#include <anna/dbms/Database.hpp>
-#include <anna/dbms/Connection.hpp>
-#include <anna/dbms/Sentence.hpp>
-#include <anna/dbms/Statement.hpp>
-
-using namespace std;
-using namespace anna;
-
-const string& dbms::Sentence::getName() const
-throw() {
- static string empty;
- return (a_dbStatement == NULL) ? empty : a_dbStatement->getName();
-}
-
-void dbms::Sentence::initialize(dbms::Database& database)
-throw(RuntimeException) {
- Guard guard(this, "anna::dbms::Sentence (initialize)");
- a_dbStatement = do_initialize(database);
-}
-
-//-------------------------------------------------------------------------------------
-// Ojo!! No activamos la seccion critica en este metodo porque debera estar
-// activa externamente ... para recoger datos multiples, etc, etc.
-//-------------------------------------------------------------------------------------
-dbms::ResultCode dbms::Sentence::execute(dbms::Connection& connection, dbms::Statement* statement)
-throw(RuntimeException) {
- using namespace anna::dbms;
- ResultCode result;
-
- try {
- result = connection.execute(statement);
-
- if(result.successful() == false) {
- if(a_mode == Mode::SilentWhenNotFound && result.notFound() == true)
- return result;
-
- throw DatabaseException(result, ANNA_FILE_LOCATION);
- }
- } catch(DatabaseException& edb) {
- string msg("Sentence: ");
- msg += getName();
- msg += " | ";
- msg += edb.getText();
- throw RuntimeException(msg, ANNA_FILE_LOCATION);
- }
-
- return result;
-}
-
-bool dbms::Sentence::fetch()
-throw(RuntimeException) {
- bool result = false;
-
- try {
- result = a_dbStatement->fetch();
- } catch(dbms::DatabaseException& edb) {
- throw RuntimeException(edb);
- }
-
- return result;
-}
-
-string dbms::Sentence::asString() const
-/*virtual*/
-throw() {
- string result("dbms::Sentence { Mode: ");
- result += (a_mode == Mode::SilentWhenNotFound) ? "SilentWhenNotFound" : "ExceptionWhenNotFound";
- result += " | ";
-
- if(a_dbStatement != NULL)
- result += a_dbStatement->asString();
- else
- result += "dbms::Statement: <null>";
-
- return result += " }";
-}
-
-/*virtual*/
-xml::Node* dbms::Sentence::asXML(xml::Node* parent) const
-throw() {
- xml::Node* result = parent->createChild("dbms.Sentence");
- result->createAttribute("Mode", (a_mode == Mode::SilentWhenNotFound) ? "SilentWhenNotFound" : "ExceptionWhenNotFound");
-
- if(a_dbStatement)
- a_dbStatement->asXML(result);
-
- return result;
-}
+++ /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 //
-
-
-#include <anna/core/functions.hpp>
-
-#include <anna/dbms/ShortBlock.hpp>
-
-using namespace anna;
-
-dbms::ShortBlock& dbms::ShortBlock::operator = (const dbms::ShortBlock & other)
-throw(RuntimeException) {
- if(this == &other)
- return *this;
-
- if(other.isNull() == true) {
- setNull(true);
- return *this;
- }
-
- return operator= (other.a_value);
-}
-
-dbms::ShortBlock& dbms::ShortBlock::operator = (const anna::DataBlock & value)
-throw(RuntimeException) {
- if(value.getSize() > Data::getMaxSize()) {
- throw RuntimeException(
- functions::asString(
- "Block out of range | Max: %d | Current: %d ", Data::getMaxSize(), value.getSize()
- ),
- ANNA_FILE_LOCATION
- );
- }
-
- a_value = value;
- setNull(a_value.isEmpty());
- return *this;
-}
-
-std::string dbms::ShortBlock::asString() const
-throw() {
- std::string result("dbms::ShortBlock { ");
- result += dbms::Data::asString();
- result += " | Value: ";
- result += isNull() ? "(null)" : functions::asString(a_value).c_str();
- return result += " }";
-}
-
+++ /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 //
-
-
-#include <anna/core/tracing/TraceMethod.hpp>
-
-#include <anna/xml/Node.hpp>
-#include <anna/xml/Attribute.hpp>
-
-#include <anna/dbms/Statement.hpp>
-#include <anna/dbms/InputBind.hpp>
-#include <anna/dbms/OutputBind.hpp>
-#include <anna/dbms/Database.hpp>
-
-using namespace std;
-using namespace anna;
-using namespace anna::dbms;
-
-Statement::~Statement() {
- InputBind* ibind;
- OutputBind* obind;
-
- for(input_iterator ii = input_begin(), maxii = input_end(); ii != maxii; ii ++) {
- ibind = inputBind(ii);
- ibind->release(this);
- a_database.deallocate(ibind);
- }
-
- for(output_iterator ii = output_begin(), maxii = output_end(); ii != maxii; ii ++) {
- obind = outputBind(ii);
- obind->release(this);
- a_database.deallocate(obind);
- }
-}
-
-string Statement::asString() const
-throw() {
- string result("dbms::Statement { Nombre: ");
- result += a_name;
- result += functions::asText(" | Var.Entrada: ", input_size());
- result += functions::asText(" | Var.Salida: ", output_size());
- result += " | ";
- result += a_measureTiming.asString();
- result += " | Expresion: ";
- result += a_expression;
- return result += " }";
-}
-
-xml::Node* dbms::Statement::asXML(xml::Node* parent) const
-throw() {
- xml::Node* result = parent->createChild("dbms.Statement");
- result->createAttribute("Name", a_name);
- xml::Node* node = result->createChild("Timing");
- node->createAttribute("N", a_measureTiming.size());
- node->createAttribute("Accumulator", a_measureTiming.getAccumulator());
- node->createAttribute("Timing", a_measureTiming.asString());
- result->createChild("Expression")->createText(a_expression);
- return result;
-}
-
-void Statement::bindInput(const char* name, Data& data)
-throw() {
- a_inputBinds.push_back(a_database.allocateInputBind(name, data));
-}
-
-const OutputBind* Statement::bindOutput(const char* name, Data& i)
-throw() {
- OutputBind* result = a_database.allocateOutputBind(name, i);
- a_outputBinds.push_back(result);
- return result;
-}
-
-Data& Statement::input(input_iterator& ii)
-throw() {
- return (*ii)->getData();
-}
-
-Data& Statement::output(output_iterator& ii)
-throw() {
- return (*ii)->getData();
-}
-
+++ /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 //
-
-
-#include <anna/dbms/String.hpp>
-
-using namespace anna;
-using namespace anna::dbms;
-
-String& String::operator = (const String & other)
-throw(RuntimeException) {
- if(this == &other)
- return *this;
-
- if(other.isNull() == true) {
- setNull(true);
- a_value [0] = 0;
- return *this;
- }
-
- return operator= (other.a_value);
-}
-
-String& String::operator = (const char * str)
-throw(RuntimeException) {
- if(a_value != str) {
- if(anna_strlen(str) > Data::getMaxSize())
- throw RuntimeException(
- functions::asString("'%s' out of range | MaxLen: %d | Len: %d ", str, Data::getMaxSize(), anna_strlen(str)),
- ANNA_FILE_LOCATION
- );
-
- anna_strcpy(a_value, str);
- }
-
- Data::setNull(false);
- return *this;
-}
-
-char* String::strip(char *str)
-throw() {
- int len;
-
- if(str == NULL || (len = anna_strlen(str)) == 0)
- return str;
-
- int end = len - 1;
-
- while(end >= 0 && str [end] == ' ') end --;
-
- if(end >= 0)
- str [++ end] = 0;
-
- return str;
-}
-
-std::string dbms::String::asString() const
-throw() {
- std::string result("dbms::String { ");
- result += dbms::Data::asString();
- result += " | Value: ";
- result += a_value;
- return result += " }";
-}
-
+++ /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 //
-
-
-#include <stdio.h>
-
-#include <anna/dbms/TimeStamp.hpp>
-
-#include <anna/config/defines.hpp>
-#include <anna/core/functions.hpp>
-
-using namespace std;
-using namespace anna;
-using namespace anna::dbms;
-
-const char* dbms::TimeStamp::getCStringValue() const
-throw() {
- const char* format;
-
- if((format = a_format) == NULL)
- format = "%d/%m/%Y %H:%M:%S.%%d";
-
- TimeStamp* _this = const_cast <TimeStamp*>(this);
- char* result = _this->a_buffer;
-
- if(strftime(result, MaxDateSize, format, &a_value) == 0)
- return NULL;
-
- if(anna_strstr(result, "%d")) {
- anna_strcpy(_this->a_anotherBuffer, result);
- sprintf(result, _this->a_anotherBuffer, a_fractionalSecond);
- }
-
- return result;
-}
+++ /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 //
-
-
-#include <anna/core/functions.hpp>
-
-#include <anna/dbms/Connection.hpp>
-#include <anna/dbms/Database.hpp>
-#include <anna/dbms/functions.hpp>
-#include <anna/dbms/String.hpp>
-#include <anna/dbms/Statement.hpp>
-
-using namespace std;
-using namespace anna;
-
-/*static*/
-void dbms::functions::verifyDataScheme(dbms::Connection& connection, const char* tableName, const char* requiredPatch, const char* columnID, const char* columnDate)
-throw(RuntimeException) {
- dbms::Database& database = connection.getDatabase();
- dbms::Statement* statement = NULL;
- dbms::String id(8);
- string sql = anna::functions::asString(
- "select max(%s) from %s where %s in (select max(%s) from %s)",
- columnID, tableName, columnDate,
- columnDate, tableName
- );
-
- try {
- statement = database.createStatement("dbms::functions::VerifyDataScheme", sql);
- statement->bindOutput("max_id", id);
- dbms::ResultCode resultCode = connection.execute(statement);
-
- if(resultCode.successful() == false)
- throw dbms::DatabaseException(resultCode, ANNA_FILE_LOCATION);
-
- statement->fetch();
- const string _id(id.getValue());
- const string _required(requiredPatch);
-
- if(_required != _id) {
- std::string msg("DataScheme is out of date | Current patch: ");
- msg += id;
- msg += " | Required patch: ";
- msg += requiredPatch;
- throw RuntimeException(msg, ANNA_FILE_LOCATION);
- }
-
- database.releaseStatement(statement);
- } catch(dbms::DatabaseException& edb) {
- database.releaseStatement(statement);
- throw RuntimeException(edb);
- } catch(RuntimeException&) {
- database.releaseStatement(statement);
- throw;
- }
-}
+++ /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 //
-
-
-#include <anna/core/internal/sccs.hpp>
-#include <anna/app/internal/sccs.hpp>
-#include <anna/xml/internal/sccs.hpp>
-#include <anna/comm/internal/sccs.hpp>
-
-#include <anna/dbms/internal/sccs.hpp>
-
-#include <anna/core/internal/ModuleManager.hpp>
-
-anna_define_sccs_tag(dbms, 2);
-
-void anna::dbms::sccs::activate()
-throw() {
- anna::sccs::activate();
- xml::sccs::activate();
- app::sccs::activate();
- comm::sccs::activate();
- ModuleManager::instantiate().insert(anna_use_sccs_tag(dbms), "00");
-}
-
+++ /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 //
-
-
-#include <anna/core/tracing/Logger.hpp>
-
-#include <anna/dbms/Database.hpp>
-#include <anna/dbms/Connection.hpp>
-#include <anna/dbms/Statement.hpp>
-#include <anna/dbms/ResultCode.hpp>
-
-#include <anna/dbos/Accesor.hpp>
-#include <anna/dbos/StorageArea.hpp>
-
-using namespace std;
-using namespace anna;
-
-/*virtual*/
-dbos::Accesor::~Accesor() {
- if(a_statement != NULL && a_database != NULL)
- a_database->releaseStatement(a_statement);
-}
-
-//------------------------------------------------------------------------------------------
-// Transfiere la informacion del medio fisico al 'Loader' concreto.
-//
-// (1) Ojo!! Ejecuta la sentencia SQL y carga el primer registro en el area de intercambio
-// Slo habr�que invocar al 'fetch' para coger los siguientes registros'
-//------------------------------------------------------------------------------------------
-bool dbos::Accesor::load(dbms::Connection* connection, const dbos::StorageArea* ssaa)
-throw(RuntimeException, dbms::DatabaseException) {
-
- if(connection == NULL) {
- std::string msg(ssaa->asString());
- msg += " | ";
- msg += asString();
- msg += " | Cannot execute this method with dbms::Connection == NULL";
- throw RuntimeException(msg, ANNA_FILE_LOCATION);
- }
-
- dbms::Statement* statement(getStatement());
-
- if(statement == NULL) {
- std::string msg(ssaa->asString());
- msg += " | ";
- msg += asString();
- msg += " | Has no SQL sentence associated";
- throw RuntimeException(msg, ANNA_FILE_LOCATION);
- }
-
- LOGDEBUG(
- string msg("dbos::Accesor::load | ");
- msg += ssaa->asString();
- msg += " | ";
- msg += asString();
- Logger::debug(msg, ANNA_FILE_LOCATION);
- );
- dbms::ResultCode resultCode = connection->execute(statement); // (1)
-
- if(resultCode.notFound() == true) {
- if(a_emodeIsNull == true) {
- if(ssaa->getErrorCode() != StorageArea::NoExceptionWhenNotFound) {
- std::string msg(ssaa->asString());
- msg += " | ";
- msg += asString();
- msg += " | Register not found";
- RuntimeException ex(msg, ANNA_FILE_LOCATION);
- ex.setErrorCode(ssaa->getErrorCode());
- throw ex;
- } else
- return false;
- } else {
- std::string msg(ssaa->asString());
- msg += " | ";
- msg += asString();
- msg += " | Register not found";
-
- if(a_exceptionMode == Exception::Mode::Ignore) {
- Logger::debug(msg, ANNA_FILE_LOCATION);
- return false;
- }
-
- if(a_exceptionMode == Exception::Mode::Throw) {
- RuntimeException ex(msg, ANNA_FILE_LOCATION);
- ex.setErrorCode(ssaa->getErrorCode());
- throw ex;
- } else if(Logger::isActive(Logger::Warning)) {
- Logger::warning(msg, ANNA_FILE_LOCATION);
- }
- }
- }
-
- if(resultCode.successful() == false) {
- string msg(ssaa->getName());
- msg += " | ";
- msg += asString();
- throw dbms::DatabaseException(msg, resultCode, ANNA_FILE_LOCATION);
- }
-
- return statement->fetch();
-}
+++ /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 //
-
-
-#include <stdlib.h>
-
-#include <anna/core/tracing/Logger.hpp>
-
-#include <anna/xml/Node.hpp>
-#include <anna/xml/Attribute.hpp>
-
-#include <anna/dbos/Repository.hpp>
-#include <anna/dbos/StorageArea.hpp>
-#include <anna/dbos/internal/sccs.hpp>
-
-using namespace std;
-using namespace anna;
-
-dbos::Repository::Repository(const char* name) :
- a_name(name) {
- sccs::activate();
-}
-
-dbos::Repository::Repository(const std::string& name) :
- a_name(name) {
- sccs::activate();
-}
-
-dbos::StorageArea* dbos::Repository::createStorageArea(const dbos::StorageId index, const char* name, const dbos::Size maxSize, dbos::ObjectAllocator objectAllocator, const int errorCode, const StorageArea::AccessMode::_v accessMode)
-throw(RuntimeException) {
- Guard guard(this, "dbos::Repository from createStorageArea");
- storage_iterator ii = a_storageAreas.find(index) ;
-
- if(ii != a_storageAreas.end()) {
- string msg(ii->second->asString());
- msg += " | Already in use";
- throw RuntimeException(msg, ANNA_FILE_LOCATION);
- }
-
- StorageArea* result = new StorageArea(name, maxSize, objectAllocator, accessMode, errorCode);
- a_storageAreas.insert(container::value_type(index, result));
- LOGDEBUG(
- string msg("dbos::Repository::createStorageArea | Name: ");
- msg += a_name;
- msg += " | ";
- msg += result->asString();
- Logger::debug(msg, ANNA_FILE_LOCATION);
- );
- return result;
-}
-
-dbos::StorageArea* dbos::Repository::findStorageArea(const dbos::StorageId index)
-throw() {
- Guard guard(this, "dbos::Repository from findStorageArea");
- storage_iterator ii = a_storageAreas.find(index);
- return (ii != a_storageAreas.end()) ? storageArea(ii) : NULL;
-}
-
-void dbos::Repository::clear()
-throw(RuntimeException) {
- Guard guard(this, "dbos::Repository from clear");
- LOGWARNING(
- string msg("dbos::Repository::clear | Name: ");
- msg += a_name;
- Logger::warning(msg, ANNA_FILE_LOCATION);
- );
-
- for(storage_iterator ii = storage_begin(), maxii = storage_end(); ii != maxii; ii ++)
- storageArea(ii)->clear();
-}
-
-xml::Node* dbos::Repository::asXML(xml::Node* parent) const
-throw() {
- xml::Node* result = parent->createChild("dbos.Repository");
- dbos::Size maxSize(0);
- dbos::Size size(0);
- const StorageArea* ssaa;
- result->createAttribute("Name", a_name);
-
- for(const_storage_iterator ii = storage_begin(), maxii = storage_end(); ii != maxii; ii ++) {
- ssaa = storageArea(ii);
- maxSize += ssaa->getMaxSizeOf();
- size += ssaa->getSizeOf();
- ssaa->asXML(result);
- }
-
- result->createAttribute("SizeOf", StorageArea::asMemorySize(size));
- result->createAttribute("MaxSizeOf", StorageArea::asMemorySize(maxSize));
- return result;
-}
-
+++ /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 //
-
-
-#include <typeinfo>
-
-#include <algorithm>
-
-#include <anna/core/tracing/Logger.hpp>
-#include <anna/core/functions.hpp>
-
-#include <anna/dbms/dbms.hpp>
-#include <anna/dbos/dbos.hpp>
-
-#include <anna/xml/Node.hpp>
-#include <anna/xml/Attribute.hpp>
-
-using namespace std;
-using namespace anna;
-
-StorageArea::StorageArea(const char* name, const Size maxSize, ObjectAllocator objectAllocator, const StorageArea::AccessMode::_v accessMode, const int errorCode) :
- a_name(name),
- a_maxSize(maxSize),
- a_objectAllocator(objectAllocator),
- a_accessMode(accessMode),
- a_errorCode(errorCode),
- a_indexBlock(0),
- a_sizeof(0),
- a_doneReuse(0) {
- a_blocks.push_back(a_currentBlock = new Block(objectAllocator, maxSize));
- a_hit = a_fault = 0;
-}
-
-StorageArea::~StorageArea() {
-}
-
-//------------------------------------------------------------------------------------------------
-// Carga los datos del objeto y los guarda en el area de almacemiento.
-//
-// (1) Si no esta en memoria => se carga.
-// (1.1) Si el registro no existe => se progresa la posible excepcion.
-//
-// (2) Cambia la politica de refresco de las areas de almacenamiento ReadWrite/Dirty. La carga solo se
-// realizara cuando la copia de utilizacion sea 0. Ademas de la mejora de rendimiento aseguramos que
-// la estabilidad de una instancia se mantiene durante toda la vida de esta. Por ejmplo evitamos que
-// una instancia A este trabajando con una copia de una instancia que estamos liberando y volviendo
-// a cargar con datos totalmente distintos ... imaginad que estamos recorriendo un vector asociado
-// o algo asi.
-//
-// (3) Si no ha podido ser recargada (seguramente tiene mas de una referencia) debe evitar el
-// uso en caso de que este marcada como Dirty.
-// (4) Si el contador de uso es cero => que ya esta marcado como memoria libre, pero recordar que
-// tambien puede estar en la memoria activa (pendiente de liberar y/o volver a usar). En este
-// caso se ha reusado.
-//------------------------------------------------------------------------------------------------
-Object* StorageArea::instance(Connection* connection, Loader& loader)
-throw(RuntimeException, DatabaseException) {
- const Index index = loader.getIndex();
- Object* result(NULL);
- Instance* instance(NULL);
- LOGDEBUG(
- string msg("Instantiate (init) | ");
- msg += asString();
- msg += " | ";
- msg += loader.asString();
- msg += " | Index: ";
- msg += functions::asHexString(index);
- Logger::write(Logger::Debug, msg, ANNA_FILE_LOCATION)
- );
- loader.a_connection = connection;
- std::string name("dbos::StorageArea::instance with ");
- name += typeid(loader).name();
- Guard guard(this, name.c_str());
- iterator ii = a_directory.find(index);
-
- if(ii == a_directory.end()) { // (1)
- a_fault ++;
-
- if(loader.load(connection, this) == true) { // (1.1)
- pair <iterator, bool> rr;
- bool wasInserted = false;
- instance = allocate();
-
- try {
- instance->object->setIndex(index);
- /* Al añadir la instancia antes de invocar al método Object::initialize
- * nos aseguramos de que se permitan implementar relaciones circulares
- */
- rr = a_directory.insert(value_type(index, instance));
- wasInserted = true;
- result = instance->object;
- instance->flags |= Flag::InProgress;
- instance->object->initialize(loader);
- instance->object->a_isStored = true;
- instance->flags &= Flag::Done;
- } catch(DatabaseException&) {
- instance->flags &= Flag::Done;
-
- if(wasInserted)
- a_directory.erase(rr.first);
-
- a_holes.insert(instance, Holes::Mode::ReadyToReuse);
- throw;
- } catch(RuntimeException&) {
- instance->flags &= Flag::Done;
-
- if(wasInserted)
- a_directory.erase(rr.first);
-
- a_holes.insert(instance, Holes::Mode::ReadyToReuse);
- throw;
- }
- }
- } else {
- static const bool IgnoreDirty = true;
- verifyStatus(instance = StorageArea::instance(ii), IgnoreDirty);
-
- switch(a_accessMode) {
- case AccessMode::ReadOnly:
- result = ((instance->flags & Flag::Dirty) == 0) ? instance->object : reload(connection, loader, instance);
- break;
- case AccessMode::ReadWrite:
- result = (instance->copyCounter > 0) ? instance->object : reload(connection, loader, instance);
- break;
- case AccessMode::ReadEver:
- result = reload(connection, loader, instance);
- break;
- }
-
- if(instance->flags & Flag::Dirty) { // (3)
- string msg(asString());
- msg += " | ";
- msg += asString(instance);
- msg += " | Instance selected as unusable";
- throw RuntimeException(msg, ANNA_FILE_LOCATION);
- }
-
- if(result != NULL) {
- a_holes.erase(instance); // (4)
- instance->copyCounter ++;
- a_hit ++;
- }
- }
-
- LOGINFORMATION(
- string msg("Instantiate (final) | ");
- msg += asString();
- msg += " | ";
- msg += asString(instance);
- Logger::information(msg, ANNA_FILE_LOCATION)
- );
- return result;
-}
-
-Object* StorageArea::instance(Connection* connection, CrossedLoader& crossedLoader, Loader& loader)
-throw(RuntimeException, DatabaseException) {
- Object* result = NULL;
- crossedLoader.a_connection = connection;
- // Si el seek devuelve 'true' es que ya tiene cargada la correspondencia entre la clave alternativa y la
- // clave principal usada en el Loader recibido como parámetro.
- bool loaded = (crossedLoader.seek() == false) ? crossedLoader.load(connection, this) : true;
-
- if(loaded == true) {
- /*
- * Transfiere la clave principal conseguida por el cargador cruzado.
- */
- loader.upload(crossedLoader);
- result = instance(connection, loader);
- /*
- * Da la posibilidad de que el cargador cruzado mantenga la correspondencia entre sus claves y las claves primarias
- */
- crossedLoader.download(loader);
- }
-
- return result;
-}
-
-//-------------------------------------------------------------------------
-// Crea un nuevo objeto en el area de almacenamiento.
-//-------------------------------------------------------------------------
-Object* StorageArea::create(Connection* connection, Creator& creator)
-throw(RuntimeException, DatabaseException) {
- const Index index = creator.getIndex();
- Instance* instance = NULL;
- Object* result = NULL;
-
- if(a_accessMode == AccessMode::ReadOnly) {
- string msg(asString());
- msg += " | Cannot create object with AccessMode::ReadOnly";
- throw RuntimeException(msg, ANNA_FILE_LOCATION);
- }
-
- LOGDEBUG(
- string msg(asString());
- msg += " | ";
- msg += creator.asString();
- msg += " | Index: ";
- msg += functions::asHexString(index);
- Logger::write(Logger::Debug, msg, ANNA_FILE_LOCATION)
- );
- creator.a_connection = connection;
- std::string name("dbos::StorageArea::create with ");
- name += typeid(creator).name();
- Guard guard(this, name.c_str());
- iterator ii = a_directory.find(index);
-
- if(ii == a_directory.end()) {
- pair <iterator, bool> rr;
- bool wasInserted = false;
- a_fault ++;
- instance = allocate();
-
- try {
- instance->object->setIndex(index);
- instance->copyCounter = 1;
- result = instance->object;
- rr = a_directory.insert(value_type(index, instance));
- wasInserted = true;
- instance->flags |= Flag::InProgress;
- instance->object->create(creator);
- instance->flags &= Flag::Done;
- instance->object->a_isStored = false;
- } catch(DatabaseException&) {
- instance->flags &= Flag::Done;
-
- if(wasInserted)
- a_directory.erase(rr.first);
-
- a_holes.insert(instance, Holes::Mode::ReadyToReuse);
- throw;
- } catch(RuntimeException&) {
- instance->flags &= Flag::Done;
-
- if(wasInserted)
- a_directory.erase(rr.first);
-
- a_holes.insert(instance, Holes::Mode::ReadyToReuse);
- throw;
- }
- } else {
- verifyStatus(instance = StorageArea::instance(ii));
- a_hit ++;
- a_holes.erase(instance);
- instance->copyCounter ++;
- result = instance->object;
- }
-
- LOGINFORMATION(
- string msg("Create | ");
- msg += asString();
- msg += " | ";
- msg += asString(instance);
- Logger::information(msg, ANNA_FILE_LOCATION)
- );
- return result;
-}
-
-//-------------------------------------------------------------------------
-// Carga los datos del objeto y los guarda en el area de almacemiento.
-//
-// (1) Si tiene cuenta 0 => estaba en la lista de objetos liberados =>
-// lo sacamos de ah�
-//-------------------------------------------------------------------------
-Object* StorageArea::find(Loader& loader)
-throw(RuntimeException) {
- const Index index = loader.getIndex();
- Instance* instance = NULL;
- Object* result = NULL;
- LOGDEBUG(
- string msg(asString());
- msg += " | ";
- msg += loader.asString();
- msg += " | Index: ";
- msg += functions::asHexString(index);
- Logger::write(Logger::Debug, msg, ANNA_FILE_LOCATION)
- );
- std::string name("dbos::StorageArea::find with ");
- name += typeid(loader).name();
- Guard guard(this, name.c_str());
- iterator ii = a_directory.find(index);
-
- if(ii != a_directory.end()) {
- verifyStatus(instance = StorageArea::instance(ii));
- a_hit ++;
- a_holes.erase(instance);
- instance->copyCounter ++;
- result = instance->object;
- } else
- a_fault ++;
-
- LOGDEBUG(
- string msg("Find | ");
- msg += asString();
- msg += " | ";
- msg += asString(instance);
- Logger::write(Logger::Debug, msg, ANNA_FILE_LOCATION)
- );
- return result;
-}
-
-Object* StorageArea::duplicate(const Object* object)
-throw(RuntimeException) {
- if(object == NULL) return NULL;
-
- std::string name("dbos::StorageArea::duplicate with ");
- name += typeid(*object).name();
- Guard guard(this, name.c_str());
- iterator ii = a_directory.find(object->getIndex());
-
- if(ii == a_directory.end()) {
- a_fault ++;
- string msg(asString());
- msg += " | Index: ";
- msg += functions::asHexString(object->getIndex());
- msg += " | Invalid instance";
- throw RuntimeException(msg, ANNA_FILE_LOCATION);
- }
-
- Instance* instance = NULL;
- verifyStatus(instance = StorageArea::instance(ii));
- a_holes.erase(instance);
- instance->copyCounter ++;
- a_hit ++;
- LOGINFORMATION(
- string msg("Duplicate | ");
- msg += asString();
- msg += " | ";
- msg += asString(instance);
- Logger::information(msg, ANNA_FILE_LOCATION)
- );
- return instance->object;
-}
-
-bool StorageArea::isLoaded(const Loader& loader)
-throw(RuntimeException) {
- const Index index = loader.getIndex();
- std::string name("dbos::StorageArea::isLoaded with ");
- name += typeid(loader).name();
- Guard guard(this, name.c_str());
- iterator ii = a_directory.find(index);
- const bool result = (ii != a_directory.end());
- LOGDEBUG(
- string msg(asString());
- msg += " | ";
- msg += loader.asString();
- msg += " | Index: ";
- msg += functions::asHexString((int) index);
- msg += functions::asText(" | isLoaded: ", result);
- Logger::debug(msg, ANNA_FILE_LOCATION);
- );
- return result;
-}
-
-void StorageArea::apply(Connection& connection, Recorder& recorder)
-throw(RuntimeException, DatabaseException) {
- ResultCode resultCode = connection.execute(recorder.getStatement());
-
- if(resultCode.successful() == false)
- throw DatabaseException(resultCode, ANNA_FILE_LOCATION);
-}
-
-//------------------------------------------------------------------------------------------------
-// Borra un objeto del medio fisico => lo borra tambien de la cache
-//
-// (1) Como copyCounter = 0 => Lo metera en lista de huecos, le quitara del directorio y
-// si fuera necesario invocara al 'destroy'.
-// (2) No la puede sacar de la memoria porque tiene referencias activas, pero por lo menos la
-// marca como no usable para intentar provocar los avisos de uso incorrecto y expulsar la
-// instancia en cuanto pueda.
-//------------------------------------------------------------------------------------------------
-void StorageArea::apply(Connection& connection, Eraser& eraser)
-throw(RuntimeException, DatabaseException) {
- if(a_accessMode == AccessMode::ReadOnly) {
- string msg(asString());
- msg += " | Cannot erase object with AccessMode::ReadOnly";
- throw RuntimeException(msg, ANNA_FILE_LOCATION);
- }
-
- Object* object = eraser.getObject();
- eraser.a_connection = &connection;
- std::string name("dbos::StorageArea::apply with ");
- name += typeid(eraser).name();
- Guard guard(this, name.c_str());
- Instance* instance = NULL;
-
- if(object != NULL) {
- iterator ii = a_directory.find(object->getIndex());
-
- if(ii != a_directory.end()) {
- instance = StorageArea::instance(ii);
-
- if(instance->copyCounter > 1) {
- instance->flags |= Flag::Incoherent; // (2)
- string msg(eraser.asString());
- msg += " | Instances: ";
- msg += functions::asString(instance->copyCounter);
- msg += " | Cannot delete object";
- throw RuntimeException(msg, ANNA_FILE_LOCATION);
- }
- }
- }
-
- ResultCode resultCode = connection.execute(eraser.getStatement());
-
- if(resultCode.successful() == false)
- throw DatabaseException(resultCode, ANNA_FILE_LOCATION);
-
- if(instance != NULL) {
- instance->copyCounter = 0;
- quickReusing(instance); // (1)
- }
-}
-
-//------------------------------------------------------------------------------------------------
-// Decrementa la cuenta de utilizacin del objeto recibido como parametro.
-//
-// (1) Si la instancia que estamos liberando esta marcada como 'Incoherente' y es la ultima
-// referencia => es el momento de expulsarla de la memoria.
-// (2) Queda a la espera de que se vuelva a usar la referencia o que el numero de registros en
-// memoria alcance un numero tal que implique comenzar a reusar objetos liberados.
-//------------------------------------------------------------------------------------------------
-void StorageArea::release(Object** object)
-throw(RuntimeException) {
- if(object == NULL) return;
-
- if(*object == NULL) return;
-
- std::string name("dbos::StorageArea::release with ");
- name += typeid(**object).name();
- Guard guard(this, name.c_str());
- iterator ii = a_directory.find((*object)->getIndex());
-
- if(ii == a_directory.end())
- return;
-
- Instance* instance = StorageArea::instance(ii);
-
- if(instance->copyCounter > 0) {
- if(-- instance->copyCounter == 0) {
- if(instance->flags & Flag::Incoherent) // (1)
- quickReusing(instance);
- else
- a_holes.insert(instance, Holes::Mode::TimeWait); // (2)
- }
- }
-
- LOGINFORMATION(
- string msg("Release | ");
- msg += asString();
- msg += " | ";
- msg += asString(instance);
- Logger::information(msg, ANNA_FILE_LOCATION)
- );
- *object = NULL;
-}
-
-//------------------------------------------------------------------------------------------------
-// Elimina toda la informacin referente al objeto recibido como parametro.
-//
-// (1) No la puede sacar de la memoria porque tiene referencias activas, pero por lo menos la
-// marca como no usable para intentar provocar los avisos de uso incorrecto y expulsar la
-// instancia en cuanto pueda.
-// (2) Como copyCounter = 0 => Lo metera en lista de huecos, le quitara del directorio y
-// si fuera necesario invocara al 'destroy'.
-//------------------------------------------------------------------------------------------------
-void StorageArea::erase(Object** object)
-throw(RuntimeException) {
- if(object == NULL) return;
-
- if(*object == NULL) return;
-
- std::string name("dbos::StorageArea::erase with ");
- name += typeid(**object).name();
- Guard guard(this, name.c_str());
- iterator ii = a_directory.find((*object)->getIndex());
-
- if(ii == a_directory.end())
- return;
-
- Instance* instance = StorageArea::instance(ii);
-
- if(instance->copyCounter > 1) {
- instance->flags |= Flag::Incoherent; // (1)
- string msg(asString());
- msg += " | ";
- msg += asString(instance);
- msg += " | Cannot dump instance";
- throw RuntimeException(msg, ANNA_FILE_LOCATION);
- }
-
- LOGDEBUG(
- string msg("Erase | ");
- msg += asString();
- msg += " | ";
- msg += asString(instance);
- Logger::debug(msg, ANNA_FILE_LOCATION)
- );
- instance->copyCounter = 0;
- quickReusing(instance); // (2)
- *object = NULL;
-}
-
-void StorageArea::dirty(Object* object)
-throw(RuntimeException) {
- if(object == NULL) return;
-
- std::string name("dbos::StorageArea::dirty with ");
- name += typeid(*object).name();
- Guard guard(this, name.c_str());
- iterator ii = a_directory.find(object->getIndex());
-
- if(ii == a_directory.end())
- return;
-
- Instance* instance = StorageArea::instance(ii);
-
- if(instance->copyCounter > 1 && Logger::isActive(Logger::Warning)) {
- string msg(asString());
- msg += " | ";
- msg += asString(instance);
- msg += " | More than one copy on instance to be selected";
- Logger::warning(msg, ANNA_FILE_LOCATION);
- }
-
- LOGDEBUG(
- string msg("Dirty | ");
- msg += asString();
- msg += " | ";
- msg += asString(instance);
- Logger::debug(msg, ANNA_FILE_LOCATION)
- );
-}
-
-//--------------------------------------------------------------------------------------------
-// Descarga todos los objetos de este area de almacenamiento.
-//
-// (1) Para que permite incluirla en los huecos.
-// (3) Si fuera necesario invoca al destroy => cuando se reuse no tendra que hacerlo.
-// (4) Si la entrada estaba marcada como 'incoherente' la desmarca, ya que hemos conseguido
-// expulsarla de cache.
-//--------------------------------------------------------------------------------------------
-void StorageArea::clear()
-throw(RuntimeException) {
- Guard guard(this, "dbos::StorageArea::clear");
- Instance* instance;
- int n = 0;
-
- for(iterator ii = begin(), maxii = end(); ii != maxii; ii ++) {
- instance = StorageArea::instance(ii);
- instance->copyCounter = 0; // (1)
- a_holes.insert(instance, Holes::Mode::ReadyToReuse);
-
- if((instance->flags & Flag::Empty) == 0) { // (3)
- LOGINFORMATION(
- string msg("Destroy (clear) | ");
- msg += asString();
- msg += " | ";
- msg += asString(instance);
- Logger::information(msg, ANNA_FILE_LOCATION);
- );
- instance->object->destroy();
- instance->flags |= Flag::Empty;
- }
-
- instance->flags &= Flag::NoIncoherent; // (4)
- n ++;
- }
-
- a_directory.clear();
- LOGWARNING(
- string msg("Clear | ");
- msg += asString();
- msg += functions::asText(" | Destroyed objects: ", n);
- Logger::warning(msg, ANNA_FILE_LOCATION)
- );
-}
-
-//---------------------------------------------------------------------------------------------------
-// Intenta recargar la informacion del medio fisico en la instancia del objeto.
-// Si hay algun problema y la instancia no puede guardarse en la de objetos disponibles
-// (a_holes.insert == false) => se marca como corrupto y no se podra usar hasta que
-// que no se libere su ultima instancia.
-//
-// (1) Si hubiera algun problema al invocar al 'initialize' no habria que volver a invocar
-// a este metodo.
-// (2) Recordar que la recarga solo se intenta cuando la copyCounter = 0, por tanto en el caso de
-// intentar recargar un registro que ha sido borrado no se vuelve a grabar como Ready porque
-// YA esta en la lista de huecos y seria necesario borrarlo de esta, cambiarle el msHoleTime y
-// volverlo a grabar, pero la cosa funciona porque se saca del directorio de objetos cargados
-// y se libera su memoria.
-//---------------------------------------------------------------------------------------------------
-Object* StorageArea::reload(dbms::Connection* connection, Loader& loader, StorageArea::Instance* instance)
-throw(RuntimeException, dbms::DatabaseException) {
- const bool enableUpdate = (instance->flags & Flag::Dirty) ? true : instance->object->enableUpdate();
- bool hasChanges(false);
-
- if(enableUpdate == true) {
- try {
- if(loader.load(connection, this) == false) {
- checkIncoherence(instance); // (2)
- return NULL;
- }
- } catch(RuntimeException&) {
- checkIncoherence(instance);
- throw;
- } catch(dbms::DatabaseException&) {
- checkIncoherence(instance);
- throw;
- }
-
- hasChanges = (instance->flags & Flag::Dirty) ? true : instance->object->hasChanges(loader);
- }
-
- LOGDEBUG(
- string msg("Reload | ");
- msg += asString();
- msg += " | ";
- msg += asString(instance);
- msg += anna::functions::asText(" | EnableUpdate: ", enableUpdate);
- msg += anna::functions::asText(" | HasChanges: ", hasChanges);
- Logger::debug(msg, ANNA_FILE_LOCATION);
- );
-
- if(hasChanges == true) {
- LOGINFORMATION(
- string msg("Destroy (reload) | ");
- msg += asString();
- msg += " | ";
- msg += asString(instance);
- Logger::information(msg, ANNA_FILE_LOCATION);
- );
- instance->object->destroy();
- instance->flags |= Flag::Empty; // (1)
- instance->object->initialize(loader);
- instance->flags &= Flag::NoEmpty;
- instance->flags &= Flag::NoDirty;
- }
-
- return instance->object;
-}
-
-//------------------------------------------------------------------------------------------------
-// Cuando intenta recargar la informacion de una instancia desde el medio fisico, pero el
-// registro ha sido borrado =>
-// 1.- Si hay alguna instancia en uso => no puede liberar la instancia porque algun otro
-// objeto la tiene referenciada => la marca como corrupta.
-// 2.- Si hay una unica instancia en uso => puede liberarla
-//
-// (1) si la puede grabar en los huecos o la instancia ya esta en los huecos => saca el objeto
-// del directorio porque yo no es valido. Recupera la coherencia memoria-medio_fisico
-// porque ha conseguido "expulsar" de la cache el registro borrado.
-// (2) No puede "expulsar" el registro de la cache porque hay algun otro objeto que lo esta
-// referenciando => Marca ESTA instancia como incoherente => no se podra duplicar y volver
-// a instanciar, etc, etc
-//------------------------------------------------------------------------------------------------
-void StorageArea::checkIncoherence(StorageArea::Instance* instance)
-throw() {
- if(quickReusing(instance) == true) {
- LOGWARNING(
- string msg("dbos::StorageArea::checkIncoherence | ");
- msg += asString();
- msg += " | ";
- msg += asString(instance);
- msg += " | Recover coherence between physical media and memory";
- Logger::warning(msg, ANNA_FILE_LOCATION);
- );
- } else { // (2)
- instance->flags |= Flag::Incoherent;
- LOGWARNING(
- string msg("dbos::StorageArea::checkIncoherence | ");
- msg += asString();
- msg += " | ";
- msg += asString(instance);
- msg += " | Detected incoherence between physical media and memory";
- Logger::warning(msg, ANNA_FILE_LOCATION);
- );
- }
-}
-
-//------------------------------------------------------------------------------------------------
-// (1) si la puede grabar en los huecos o la instancia ya esta en los huecos => (2)
-// (2) saca el objeto del directorio porque yo no es valido.
-// (3) Si fuera necesario invoca al destroy => cuando se reuse no tendra que hacerlo.
-// (4) Si la entrada estaba marcada como 'incoherente' la desmarca, ya que hemos conseguido
-// expulsarla de cache.
-//
-// Recordar que en el caso de intentar recargar un registro que ha sido borrado no se vuelve
-// a grabar como Ready porque ya esta en la lista de huecos y seria necesario borrarlo de
-// esta, cambiarle el msHoleTime y volverlo a grabar.
-//------------------------------------------------------------------------------------------------
-bool StorageArea::quickReusing(StorageArea::Instance* instance)
-throw() {
- bool result(false);
-
- if(a_holes.insert(instance, Holes::Mode::ReadyToReuse) == true) { // (1)
- iterator ii = a_directory.find(instance->object->getIndex());
-
- if(ii != a_directory.end()) // (2)
- a_directory.erase(ii);
-
- if((instance->flags & Flag::Empty) == 0) { // (3)
- LOGINFORMATION(
- string msg("Destroy (quickreusing) | ");
- msg += asString();
- msg += " | ";
- msg += asString(instance);
- Logger::information(msg, ANNA_FILE_LOCATION);
- );
- instance->object->destroy();
- instance->flags |= Flag::Empty;
- }
-
- instance->flags &= Flag::NoIncoherent; // (4)
- result = true;
- }
-
- return result;
-}
-
-void StorageArea::verifyStatus(StorageArea::Instance* instance, const bool ignoreDirty)
-throw(RuntimeException) {
- if(instance->flags & Flag::Incoherent) {
- string msg(asString());
- msg += " | ";
- msg += asString(instance);
- msg += " | Physical media and memory do not match";
- throw RuntimeException(msg, ANNA_FILE_LOCATION);
- }
-
- if(instance->flags & Flag::Empty) {
- string msg(asString());
- msg += " | ";
- msg += asString(instance);
- msg += " | Instance is empty";
- throw RuntimeException(msg, ANNA_FILE_LOCATION);
- }
-
- if(ignoreDirty == false && (instance->flags & Flag::Dirty)) {
- string msg(asString());
- msg += " | ";
- msg += asString(instance);
- msg += " | Instance is temporary locked";
- throw RuntimeException(msg, ANNA_FILE_LOCATION);
- }
-
- if(instance->flags & Flag::InProgress) {
- string msg(asString());
- msg += " | ";
- msg += asString(instance);
- msg += " | Instance already has word in progress";
- throw RuntimeException(msg, ANNA_FILE_LOCATION);
- }
-}
-
-string StorageArea::asString() const
-throw() {
- string result("dbos::StorageArea { Name: ");
- const int ratio = (a_hit == 0) ? 0 : (a_hit * 100) / (a_fault + a_hit);
- /* Nº real de objetos en uso. En el directorio también se mantienen los que tienen la cuenta de utilización a 0 */
- const int n = a_directory.size() - a_holes.size();
- result += a_name;
- result += " | N: ";
- result += functions::asString(a_maxSize);
- result += " | n: ";
- result += functions::asString(n);
- result += " | r: ";
- result += functions::asString(a_directory.size());
- result += " | AccessMode: ";
- result += AccessMode::asString(a_accessMode);
- result += " | Holes: ";
- result += functions::asString(a_holes.size());
- result += " | Reuse: ";
- result += functions::asString(a_doneReuse);
- result += " | Hit: ";
- result += functions::asString(a_hit);
- result += " | Fault: ";
- result += functions::asString(a_fault);
- result += " | Ratio: ";
- result += functions::asString(ratio);
- return result += "% }";
-}
-
-xml::Node* StorageArea::asXML(xml::Node* parent) const
-throw() {
- xml::Node* result = parent->createChild("dbos.StorageArea");
- xml::Node* node;
- const int ratio = (a_hit == 0) ? 0 : (a_hit * 100) / (a_fault + a_hit);
- result->createAttribute("Name", a_name);
- result->createAttribute("AccessMode", AccessMode::asString(a_accessMode));
- node = result->createChild("Size");
- node->createAttribute("Value", a_directory.size() - a_holes.size());
- node->createAttribute("Reserve", a_directory.size());
- node->createAttribute("MaxValue", a_maxSize);
- node->createAttribute("Holes", a_holes.size());
- node = result->createChild("SizeOf");
- node->createAttribute("Value", asMemorySize(getSizeOf()));
- node->createAttribute("MaxValue", asMemorySize(getMaxSizeOf()));
- node = result->createChild("Statistics");
- node->createAttribute("Hit", a_hit);
- node->createAttribute("Fault", a_fault);
- node->createAttribute("Ratio", anna::functions::asString("%d%%", ratio));
- node->createAttribute("DoneReuse", a_doneReuse);
- return result;
-}
-
-string StorageArea::asMemorySize(const Size size)
-throw() {
- string result;
-
- if(size < 1024) {
- result = functions::asString("%u bytes", size);
- } else if(size < 1024 * 1024) {
- static const Size ka = 1024;
- result += functions::asString("%u Kb", size / ka);
- } else {
- static const Size mega = 1024 * 1024;
- result += functions::asString("%u Mb", size / mega);
- }
-
- return result;
-}
-
-StorageArea::Instance* StorageArea::allocate()
-throw() {
- Instance* result = NULL;
-
- if((result = reuse()) == NULL) {
- if((result = a_currentBlock->getInstance()) == NULL) {
- if(++ a_indexBlock == a_blocks.size())
- a_blocks.push_back(a_currentBlock = new Block(a_objectAllocator, a_maxSize));
- else
- a_currentBlock = a_blocks [a_indexBlock];
-
- result = a_currentBlock->getInstance();
- }
- }
-
- result->copyCounter = 1;
-//xxx result->msHoleTime = 0;
- result->flags = Flag::None;
-//xxx result->hasHole = false;
- return result;
-}
-
-//-----------------------------------------------------------------------------------------------------
-// Reusa un objeto que lleva demasiado tiempo sin ser utilizado.
-//
-// (0) Si el tiempo que lleva en la lista de objetos liberados es cero => Podemos usar el re-usado
-// rapido; ya ha sido eliminado del directorio, invoca al destroy, etc, etc.
-// (0.1) Para asegurar que NO desborde los 32 bits.
-// (1) Cuando n -> Nmax => Talpha = now => a poco tiempo que pase sin reusar los registros, estos
-// se comienzan a resuar. Cuando n -> 0 => talpha = 0 => No se reusan registros, sino que se crearan
-// nuevos.
-// (2) Si el primero de los registros disponibles no es suficientemente antiguo => no hay huecos libres
-//-----------------------------------------------------------------------------------------------------
-StorageArea::Instance* StorageArea::reuse()
-throw() {
- if(a_holes.empty() == true)
- return NULL;
-
- Instance* result = NULL;
- Instance* front = a_holes.front();
- bool quickReuse;
-
- if((front->flags & Flag::Ready) == false) {
- if(a_directory.size() >= a_maxSize) { // El directorio contiene los que tienen cuenta 0 + los que están activos.
- result = front;
- iterator ii = a_directory.find(result->object->getIndex());
-
- if(ii != a_directory.end())
- a_directory.erase(ii);
-
- if((result->flags & Flag::Empty) == 0) {
- LOGINFORMATION(
- string msg("Destroy (reuse) | ");
- msg += asString();
- msg += " | ";
- msg += asString(result);
- Logger::information(msg, ANNA_FILE_LOCATION);
- );
- result->object->destroy();
- result->flags &= Flag::NoEmpty;
- }
- }
-
- quickReuse = false;
- } else {
- // Si la entrada se cargó en los huecos como "usado rápido" se toma
- result = front;
- quickReuse = true;
- }
-
- if(result != NULL) {
- a_doneReuse ++;
- result->flags &= Flag::NoReady;
- result->flags &= Flag::NoHasHole;
- a_holes.pop_front();
- }
-
- LOGDEBUG(
- string msg("dbos::StorageArea::reuse | ");
- msg += asString();
- msg += " | ";
- msg += StorageArea::asString(result);
- msg += functions::asText(" | QuickReuse: ", quickReuse);
- Logger::debug(msg, ANNA_FILE_LOCATION);
- );
- return result;
-}
-
-std::string StorageArea::asString(const Instance* instance)
-throw() {
- std::string result("Instance { ");
-
- if(instance == NULL)
- return result += "<null> } ";
-
- result += "Reference: ";
- result += functions::asHexString(anna_ptrnumber_cast(instance->object));
- result += " | Index: ";
- result += functions::asHexString(instance->object->getIndex());
- result += functions::asText(" | Stored: ", instance->object->a_isStored);
- result += " | CopyCounter: ";
- result += functions::asString((unsigned int) instance->copyCounter);
- result += " | Flags (";
- result += functions::asHexString(instance->flags);
- result += "):";
-
- if(instance->flags == Flag::None)
- result += " None";
- else {
- if(instance->flags & Flag::Dirty)
- result += " Dirty";
-
- if(instance->flags & Flag::Incoherent)
- result += " Incoherent";
-
- if(instance->flags & Flag::Empty)
- result += " Empty";
-
- if(instance->flags & Flag::HasHole)
- result += " HasHole";
-
- if(instance->flags & Flag::InProgress)
- result += " InProgress";
-
- result += (instance->flags & Flag::Ready) ? " Ready" : " TimeWait";
- }
-
- return result += " }";
-}
-
-const char* StorageArea::AccessMode::asString(const AccessMode::_v v)
-throw() {
- static const char* text [] = { "ReadOnly", "ReadWrite", "ReadEver" };
- return text [v];
-}
-
-/****************************************************************************************
-* Bloque de memoria.
-****************************************************************************************/
-StorageArea::Block::Block(ObjectAllocator objectAllocator, const Size maxSize) :
- a_size(0) {
- a_maxSize = std::min(8U, std::max(256U, maxSize >> 7));
- a_instances = new Instance [a_maxSize];
-
- for(int i = 0; i < a_maxSize; i ++)
- a_instances [i].object = (*objectAllocator)();
-}
-
-bool StorageArea::Holes::insert(Instance* instance, const StorageArea::Holes::Mode::_v mode)
-throw() {
- if(instance->copyCounter > 0)
- return false;
-
- /* Si la instancia ya ha sido registrada en la lista de huecos, sale sin más */
- if((instance->flags & Flag::HasHole) == true)
- return true;
-
- switch(mode) {
- case Mode::ReadyToReuse:
- instance->holeIterator = a_holes.insert(a_holes.begin(), instance);
- instance->flags |= Flag::HasHole;
- instance->flags |= Flag::Ready;
- a_size ++;
- break;
- case Mode::TimeWait:
- instance->holeIterator = a_holes.insert(a_holes.end(), instance);
- instance->flags |= Flag::HasHole;
- instance->flags &= Flag::NoReady;
- a_size ++;
- break;
- }
-
- LOGLOCAL6(
- string msg("dbos::StorageArea::Holes::insert | This: ");
- msg += functions::asHexString(anna_ptrnumber_cast(this));
- msg += " | ";
- msg += StorageArea::asString(instance);
- Logger::write(Logger::Local6, msg, ANNA_FILE_LOCATION);
- );
- return true;
-}
-
-void StorageArea::Holes::erase(Instance* instance)
-throw() {
- // instance->msHoleTime = 0;
- instance->flags |= Flag::Ready;
-
- if(instance->copyCounter != 0)
- return;
-
- /* Si la instancia NO ha sido registrada en la lista de huecos, sale sin más */
- if((instance->flags & Flag::HasHole) == false)
- return;
-
- LOGLOCAL6(
- string msg("dbos::StorageArea::Holes::erase | This: ");
- msg += functions::asHexString(anna_ptrnumber_cast(this));
- msg += " | ";
- msg += StorageArea::asString(instance);
- Logger::write(Logger::Local6, msg, ANNA_FILE_LOCATION);
- );
- a_holes.erase(instance->holeIterator);
- instance->flags &= Flag::NoHasHole;
- a_size --;
-}
-
-/****************************************************************************************
-* Iterador
-
-class A {
-public:
- A () : a (0) { cout << "C0: " << (int) this << endl; }
- A (const int _a): a (_a) { cout << "C1: " << (int) this << " " << a << endl; }
- A (const A& other) : a (other.a) { cout << "C2: " << (int) this << " " << a << endl; }
-
- A& operator = (const A& other) {
- cout << "CP: " << (int) this << " " << (a = other.a) << endl;
- return *this;
- }
-
- int get () const { return a; }
-private:
- int a;
-};
-
-A fx () { return A (2000); }
-
-int main ()
-{
- A aa = 100;
- A bb (200);
- A xx = aa;
- A cc = fx ();
-
- cout << "CC: " << (int) &cc << " " << cc.get () << endl;
-
-}
-
-La salida del programucho es la siguiente:
-
-C1: -4198808 100
-C1: -4198812 200
-C2: -4198816 100
-C1: -4198820 2000
-CC: -4198820 2000
-
-Lo que quiere decir que la "cc" la crea directamente sobre la pila y la asigna en fx sin aplicar ningn
-otro constructor.
-
-Por eso cuando hac� StorageArea::Iterator ii = xxx->begin (), maxi = xxx->end (); .....
-no estaba pasando por el contructor copia ni por ningn otro constructor.
-
-****************************************************************************************/
-// Dejo todo el ejemplo para que sirva de recordatorio.
-
+++ /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 //
-
-
-#include <anna/core/internal/sccs.hpp>
-#include <anna/dbms/internal/sccs.hpp>
-
-#include <anna/dbos/internal/sccs.hpp>
-
-#include <anna/core/internal/ModuleManager.hpp>
-
-anna_define_sccs_tag(dbos, 1);
-
-void anna::dbos::sccs::activate()
-throw() {
- dbms::sccs::activate();
- ModuleManager::instantiate().insert(anna_use_sccs_tag(dbos), "00");
-}
-