--- /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");
+}