X-Git-Url: https://git.teslayout.com/public/public/public/?a=blobdiff_plain;f=source%2Fdbms.mysql%2FStatement.cpp;fp=source%2Fdbms.mysql%2FStatement.cpp;h=df18acc09784ac358f1ab206874f45d3114afc25;hb=78be86969d2f26a9084b0c4af6ce43d5fa4ed3fd;hp=0000000000000000000000000000000000000000;hpb=a3b95648bd76140ef55e0b5941d423eee6c3856f;p=anna.git diff --git a/source/dbms.mysql/Statement.cpp b/source/dbms.mysql/Statement.cpp new file mode 100644 index 0000000..df18acc --- /dev/null +++ b/source/dbms.mysql/Statement.cpp @@ -0,0 +1,192 @@ +// 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 + +#include +#include + +#include + +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 (dbmsConnection)); + //Database& dbms(static_cast (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 (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; +}