Revert "Remove mysql and oracle resources for anna-ericsson project"
[anna.git] / source / dbms.oracle / Statement.cpp
diff --git a/source/dbms.oracle/Statement.cpp b/source/dbms.oracle/Statement.cpp
new file mode 100644 (file)
index 0000000..1cf6e8a
--- /dev/null
@@ -0,0 +1,128 @@
+// 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;
+}
+
+
+