Remove warnings
[anna.git] / source / dbms.oracle / Database.cpp
1 // ANNA - Anna is Not Nothingness Anymore                                                         //
2 //                                                                                                //
3 // (c) Copyright 2005-2015 Eduardo Ramos Testillano & Francisco Ruiz Rayo                         //
4 //                                                                                                //
5 // See project site at http://redmine.teslayout.com/projects/anna-suite                           //
6 // See accompanying file LICENSE or copy at http://www.teslayout.com/projects/public/anna.LICENSE //
7
8
9 #include <locale.h>
10
11 #include <oci.h>
12
13 #include <anna/core/tracing/Logger.hpp>
14 #include <anna/core/tracing/TraceMethod.hpp>
15
16 #include <anna/dbms.oracle/oracle.hpp>
17 #include <anna/dbms.oracle/internal/sccs.hpp>
18
19 using namespace std;
20 using namespace anna;
21 using namespace anna::dbms;
22
23 char oracle::Database::st_decimalPoint = 0;
24
25 oracle::Database::Database(const char* dbmsName) :
26   dbms::Database(getClassName(), dbmsName),
27   a_env(NULL),
28   a_error(NULL) {
29   oracle::sccs::activate();
30 }
31
32 oracle::Database::Database(const char* componentName, const char* dbmsName) :
33   dbms::Database(componentName, dbmsName),
34   a_env(NULL),
35   a_error(NULL) {
36   oracle::sccs::activate();
37 }
38
39 void oracle::Database::do_initialize()
40 throw(RuntimeException) {
41   LOGMETHOD(TraceMethod tm("anna::dbms::oracle::Database", "do_initialize", ANNA_FILE_LOCATION));
42
43   if(a_env != NULL) {
44     Logger::write(Logger::Warning, asString(), "Already initialized", ANNA_FILE_LOCATION);
45     return;
46   }
47
48   if(OCIInitialize(OCI_DEFAULT, 0, 0, 0, 0) != OCI_SUCCESS) {
49     string msg(asString());
50     msg += " | Cannot initialize Oracle access system";
51     throw RuntimeException(msg, ANNA_FILE_LOCATION);
52   }
53
54   if(OCIEnvInit(&a_env, OCI_DEFAULT, 0, 0) != OCI_SUCCESS) {
55     string msg(asString());
56     msg += " | Cannot create database environment";
57     throw RuntimeException(msg, ANNA_FILE_LOCATION);
58   }
59
60   if(OCIHandleAlloc(a_env, (void**) &a_error, OCI_HTYPE_ERROR, 0, 0) != OCI_SUCCESS) {
61     string msg(asString());
62     msg += " | Cannot create database error handler";
63     throw RuntimeException(msg, ANNA_FILE_LOCATION);
64   }
65
66   WHEN_MULTITHREAD(
67     OCIThreadProcessInit();
68     anna_dbms_oracle_check(OCIThreadInit(a_env, a_error), a_error);
69   );
70   initializeDecimalPoint();
71   dbms::Database::do_initialize();
72 }
73
74 //----------------------------------------------------------------------------------
75 // Libera todos los manejadores asociados a �te entorno.
76 //----------------------------------------------------------------------------------
77 oracle::Database::~Database() {
78   LOGMETHOD(TraceMethod tm("anna::dbms::oracle::Database", "~Database", ANNA_FILE_LOCATION));
79
80   if(a_error) {
81     OCIHandleFree(a_env, OCI_HTYPE_ERROR);
82     a_env = NULL;
83   }
84
85   if(a_env) {
86     OCIHandleFree(a_env, OCI_HTYPE_ENV);
87     a_env = NULL;
88   }
89 }
90
91 dbms::Connection* oracle::Database::allocateConnection(const std::string& name, const char* user, const char* password)
92 throw(RuntimeException) {
93   return new Connection(*this, name, user, password);
94 }
95
96 dbms::Statement* oracle::Database::allocateStatement(const char* name, const std::string& expression, const bool isCritical)
97 throw(RuntimeException) {
98   return new Statement(*this, name, expression, isCritical);
99 }
100
101 dbms::InputBind* oracle::Database::allocateInputBind(const char* name, Data& data)
102 throw(RuntimeException) {
103   return new InputBind(name, data);
104 }
105
106 void oracle::Database::deallocate(dbms::InputBind* inputBind)
107 throw() {
108   delete(InputBind*) inputBind;
109 }
110
111 dbms::OutputBind* oracle::Database::allocateOutputBind(const char* name, Data& data)
112 throw(RuntimeException) {
113   return new OutputBind(name, data);
114 }
115
116 void oracle::Database::deallocate(dbms::OutputBind* outputBind)
117 throw() {
118   delete(OutputBind*) outputBind;
119 }
120
121 /**
122  * Ojo no se activa el uso de forma definitiva porque afectaría a todo el programa, cualquier
123  * conversion texto -> float/double que se hiciera se vería afectado por este cambio, que sólo debería
124  * aplicar a temas relaciones con la base de datos.
125  *
126  * Carga el valor del LC_NUMERIC de la correspondiente variable del entorno y luego repone el
127  * usado por defecto en las librerias del core de C.
128  */
129 /*static*/
130 void oracle::Database::initializeDecimalPoint()
131 throw(RuntimeException) {
132   setlocale(LC_NUMERIC, "");
133   struct lconv *locale = localeconv();
134
135   if(*locale->decimal_point != '.')
136     st_decimalPoint = *locale->decimal_point;
137
138   setlocale(LC_NUMERIC, "C");
139 }