X-Git-Url: https://git.stg.codes/stg.git/blobdiff_plain/8c6fa3fbaccc22127280bf77a48fab5a3ee0716e..46b0747592074017ff0ea4b33d4a7194235886e5:/stglibs/ibpp.lib/statement.cpp diff --git a/stglibs/ibpp.lib/statement.cpp b/stglibs/ibpp.lib/statement.cpp deleted file mode 100644 index e2271cf4..00000000 --- a/stglibs/ibpp.lib/statement.cpp +++ /dev/null @@ -1,1307 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// File : $Id: statement.cpp,v 1.2 2009/03/19 20:00:28 faust Exp $ -// Subject : IBPP, Service class implementation -// -/////////////////////////////////////////////////////////////////////////////// -// -// (C) Copyright 2000-2006 T.I.P. Group S.A. and the IBPP Team (www.ibpp.org) -// -// The contents of this file are subject to the IBPP License (the "License"); -// you may not use this file except in compliance with the License. You may -// obtain a copy of the License at http://www.ibpp.org or in the 'license.txt' -// file which must have been distributed along with this file. -// -// This software, distributed under the License, is distributed on an "AS IS" -// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the -// License for the specific language governing rights and limitations -// under the License. -// -/////////////////////////////////////////////////////////////////////////////// -// -// COMMENTS -// * Tabulations should be set every four characters when editing this file. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifdef _MSC_VER -#pragma warning(disable: 4786 4996) -#ifndef _DEBUG -#pragma warning(disable: 4702) -#endif -#endif - -#include "_ibpp.h" - -#ifdef HAS_HDRSTOP -#pragma hdrstop -#endif - -#include - -using namespace ibpp_internals; - -// (((((((( OBJECT INTERFACE IMPLEMENTATION )))))))) - -void StatementImpl::Prepare(const std::string& sql) -{ - if (mDatabase == 0) - throw LogicExceptionImpl("Statement::Prepare", _("An IDatabase must be attached.")); - if (mDatabase->GetHandle() == 0) - throw LogicExceptionImpl("Statement::Prepare", _("IDatabase must be connected.")); - if (mTransaction == 0) - throw LogicExceptionImpl("Statement::Prepare", _("An ITransaction must be attached.")); - if (mTransaction->GetHandle() == 0) - throw LogicExceptionImpl("Statement::Prepare", _("ITransaction must be started.")); - if (sql.empty()) - throw LogicExceptionImpl("Statement::Prepare", _("SQL statement can't be 0.")); - - // Saves the SQL sentence, only for reporting reasons in case of errors - mSql = sql; - - IBS status; - - // Free all resources currently attached to this Statement, then allocate - // a new statement descriptor. - Close(); - (*gds.Call()->m_dsql_allocate_statement)(status.Self(), mDatabase->GetHandlePtr(), &mHandle); - if (status.Errors()) - throw SQLExceptionImpl(status, "Statement::Prepare", - _("isc_dsql_allocate_statement failed")); - - // Empirical estimate of parameters count and output columns count. - // This is by far not an exact estimation, which would require parsing the - // SQL statement. If the SQL statement contains '?' and ',' in string - // constants, this count will obviously be wrong, but it will be exagerated. - // It won't hurt. We just try to not have to re-allocate those descriptors later. - // So we prefer to get them a little bit larger than needed than the other way. - int16_t inEstimate = 0; - int16_t outEstimate = 1; - for (size_t i = 0; i < strlen(sql.c_str()); i++) - { - if (sql[i] == '?') ++inEstimate; - if (sql[i] == ',') ++outEstimate; - } - - /* - DebugStream()<< "Prepare(\""<< sql<< "\")"<< fds; - DebugStream()<< _("Estimation: ")<< inEstimate<< _(" IN parameters and ") - << outEstimate<< _(" OUT columns")<< fds; - */ - - // Allocates output descriptor and prepares the statement - mOutRow = new RowImpl(mDatabase->Dialect(), outEstimate, mDatabase, mTransaction); - mOutRow->AddRef(); - - status.Reset(); - (*gds.Call()->m_dsql_prepare)(status.Self(), mTransaction->GetHandlePtr(), - &mHandle, (short)sql.length(), const_cast(sql.c_str()), - short(mDatabase->Dialect()), mOutRow->Self()); - if (status.Errors()) - { - Close(); - std::string context = "Statement::Prepare( "; - context.append(mSql).append(" )"); - throw SQLExceptionImpl(status, context.c_str(), - _("isc_dsql_prepare failed")); - } - - // Read what kind of statement was prepared - status.Reset(); - char itemsReq[] = {isc_info_sql_stmt_type}; - char itemsRes[8]; - (*gds.Call()->m_dsql_sql_info)(status.Self(), &mHandle, 1, itemsReq, - sizeof(itemsRes), itemsRes); - if (status.Errors()) - { - Close(); - throw SQLExceptionImpl(status, "Statement::Prepare", - _("isc_dsql_sql_info failed")); - } - if (itemsRes[0] == isc_info_sql_stmt_type) - { - switch (itemsRes[3]) - { - case isc_info_sql_stmt_select : mType = IBPP::stSelect; break; - case isc_info_sql_stmt_insert : mType = IBPP::stInsert; break; - case isc_info_sql_stmt_update : mType = IBPP::stUpdate; break; - case isc_info_sql_stmt_delete : mType = IBPP::stDelete; break; - case isc_info_sql_stmt_ddl : mType = IBPP::stDDL; break; - case isc_info_sql_stmt_exec_procedure : mType = IBPP::stExecProcedure; break; - case isc_info_sql_stmt_select_for_upd : mType = IBPP::stSelectUpdate; break; - case isc_info_sql_stmt_set_generator : mType = IBPP::stSetGenerator; break; - case isc_info_sql_stmt_savepoint : mType = IBPP::stSavePoint; break; - default : mType = IBPP::stUnsupported; - } - } - if (mType == IBPP::stUnknown || mType == IBPP::stUnsupported) - { - Close(); - throw LogicExceptionImpl("Statement::Prepare", - _("Unknown or unsupported statement type")); - } - - if (mOutRow->Columns() == 0) - { - // Get rid of the output descriptor, if it wasn't required (no output) - mOutRow->Release(); - mOutRow = 0; - /* - DebugStream()<< _("Dropped output descriptor which was not required")<< fds; - */ - } - else if (mOutRow->Columns() > mOutRow->AllocatedSize()) - { - // Resize the output descriptor (which is too small). - // The statement does not need to be prepared again, though the - // output columns must be described again. - - /* - DebugStream()<< _("Resize output descriptor from ") - << mOutRow->AllocatedSize()<< _(" to ")<< mOutRow->Columns()<< fds; - */ - - mOutRow->Resize(mOutRow->Columns()); - status.Reset(); - (*gds.Call()->m_dsql_describe)(status.Self(), &mHandle, 1, mOutRow->Self()); - if (status.Errors()) - { - Close(); - throw SQLExceptionImpl(status, "Statement::Prepare", - _("isc_dsql_describe failed")); - } - } - - if (inEstimate > 0) - { - // Ready an input descriptor - mInRow = new RowImpl(mDatabase->Dialect(), inEstimate, mDatabase, mTransaction); - mInRow->AddRef(); - - status.Reset(); - (*gds.Call()->m_dsql_describe_bind)(status.Self(), &mHandle, 1, mInRow->Self()); - if (status.Errors()) - { - Close(); - throw SQLExceptionImpl(status, "Statement::Prepare", - _("isc_dsql_describe_bind failed")); - } - - if (mInRow->Columns() == 0) - { - // Get rid of the input descriptor, if it wasn't required (no parameters) - mInRow->Release(); - mInRow = 0; - /* - DebugStream()<< _("Dropped input descriptor which was not required")<< fds; - */ - } - else if (mInRow->Columns() > mInRow->AllocatedSize()) - { - // Resize the input descriptor (which is too small). - // The statement does not need to be prepared again, though the - // parameters must be described again. - - /* - DebugStream()<< _("Resize input descriptor from ") - << mInRow->AllocatedSize()<< _(" to ") - << mInRow->Columns()<< fds; - */ - - mInRow->Resize(mInRow->Columns()); - status.Reset(); - (*gds.Call()->m_dsql_describe_bind)(status.Self(), &mHandle, 1, mInRow->Self()); - if (status.Errors()) - { - Close(); - throw SQLExceptionImpl(status, "Statement::Prepare", - _("isc_dsql_describe_bind failed")); - } - } - } - - // Allocates variables of the input descriptor - if (mInRow != 0) - { - // Turn on 'can be NULL' on each input parameter - for (int i = 0; i < mInRow->Columns(); i++) - { - XSQLVAR* var = &(mInRow->Self()->sqlvar[i]); - if (! (var->sqltype & 1)) var->sqltype += short(1); - } - mInRow->AllocVariables(); - } - - // Allocates variables of the output descriptor - if (mOutRow != 0) mOutRow->AllocVariables(); -} - -void StatementImpl::Plan(std::string& plan) -{ - if (mHandle == 0) - throw LogicExceptionImpl("Statement::Plan", _("No statement has been prepared.")); - if (mDatabase == 0) - throw LogicExceptionImpl("Statement::Plan", _("A Database must be attached.")); - if (mDatabase->GetHandle() == 0) - throw LogicExceptionImpl("Statement::Plan", _("Database must be connected.")); - - IBS status; - RB result(4096); - char itemsReq[] = {isc_info_sql_get_plan}; - - (*gds.Call()->m_dsql_sql_info)(status.Self(), &mHandle, 1, itemsReq, - result.Size(), result.Self()); - if (status.Errors()) throw SQLExceptionImpl(status, - "Statement::Plan", _("isc_dsql_sql_info failed.")); - - result.GetString(isc_info_sql_get_plan, plan); - if (plan[0] == '\n') plan.erase(0, 1); -} - -void StatementImpl::Execute(const std::string& sql) -{ - if (! sql.empty()) Prepare(sql); - - if (mHandle == 0) - throw LogicExceptionImpl("Statement::Execute", - _("No statement has been prepared.")); - - // Check that a value has been set for each input parameter - if (mInRow != 0 && mInRow->MissingValues()) - throw LogicExceptionImpl("Statement::Execute", - _("All parameters must be specified.")); - - CursorFree(); // Free a previous 'cursor' if any - - IBS status; - if (mType == IBPP::stSelect) - { - // Could return a result set (none, single or multi rows) - (*gds.Call()->m_dsql_execute)(status.Self(), mTransaction->GetHandlePtr(), - &mHandle, 1, mInRow == 0 ? 0 : mInRow->Self()); - if (status.Errors()) - { - //Close(); Commented because Execute error should not free the statement - std::string context = "Statement::Execute( "; - context.append(mSql).append(" )"); - throw SQLExceptionImpl(status, context.c_str(), - _("isc_dsql_execute failed")); - } - if (mOutRow != 0) - { - mResultSetAvailable = true; - mCursorOpened = true; - } - } - else - { - // Should return at most a single row - (*gds.Call()->m_dsql_execute2)(status.Self(), mTransaction->GetHandlePtr(), - &mHandle, 1, mInRow == 0 ? 0 : mInRow->Self(), - mOutRow == 0 ? 0 : mOutRow->Self()); - if (status.Errors()) - { - //Close(); Commented because Execute error should not free the statement - std::string context = "Statement::Execute( "; - context.append(mSql).append(" )"); - throw SQLExceptionImpl(status, context.c_str(), - _("isc_dsql_execute2 failed")); - } - } -} - -void StatementImpl::CursorExecute(const std::string& cursor, const std::string& sql) -{ - if (cursor.empty()) - throw LogicExceptionImpl("Statement::CursorExecute", _("Cursor name can't be 0.")); - - if (! sql.empty()) Prepare(sql); - - if (mHandle == 0) - throw LogicExceptionImpl("Statement::CursorExecute", _("No statement has been prepared.")); - if (mType != IBPP::stSelectUpdate) - throw LogicExceptionImpl("Statement::CursorExecute", _("Statement must be a SELECT FOR UPDATE.")); - if (mOutRow == 0) - throw LogicExceptionImpl("Statement::CursorExecute", _("Statement would return no rows.")); - - // Check that a value has been set for each input parameter - if (mInRow != 0 && mInRow->MissingValues()) - throw LogicExceptionImpl("Statement::CursorExecute", - _("All parameters must be specified.")); - - CursorFree(); // Free a previous 'cursor' if any - - IBS status; - (*gds.Call()->m_dsql_execute)(status.Self(), mTransaction->GetHandlePtr(), - &mHandle, 1, mInRow == 0 ? 0 : mInRow->Self()); - if (status.Errors()) - { - //Close(); Commented because Execute error should not free the statement - std::string context = "Statement::CursorExecute( "; - context.append(mSql).append(" )"); - throw SQLExceptionImpl(status, context.c_str(), - _("isc_dsql_execute failed")); - } - - status.Reset(); - (*gds.Call()->m_dsql_set_cursor_name)(status.Self(), &mHandle, const_cast(cursor.c_str()), 0); - if (status.Errors()) - { - //Close(); Commented because Execute error should not free the statement - throw SQLExceptionImpl(status, "Statement::CursorExecute", - _("isc_dsql_set_cursor_name failed")); - } - - mResultSetAvailable = true; - mCursorOpened = true; -} - -void StatementImpl::ExecuteImmediate(const std::string& sql) -{ - if (mDatabase == 0) - throw LogicExceptionImpl("Statement::ExecuteImmediate", _("An IDatabase must be attached.")); - if (mDatabase->GetHandle() == 0) - throw LogicExceptionImpl("Statement::ExecuteImmediate", _("IDatabase must be connected.")); - if (mTransaction == 0) - throw LogicExceptionImpl("Statement::ExecuteImmediate", _("An ITransaction must be attached.")); - if (mTransaction->GetHandle() == 0) - throw LogicExceptionImpl("Statement::ExecuteImmediate", _("ITransaction must be started.")); - if (sql.empty()) - throw LogicExceptionImpl("Statement::ExecuteImmediate", _("SQL statement can't be 0.")); - - IBS status; - Close(); - (*gds.Call()->m_dsql_execute_immediate)(status.Self(), mDatabase->GetHandlePtr(), - mTransaction->GetHandlePtr(), 0, const_cast(sql.c_str()), - short(mDatabase->Dialect()), 0); - if (status.Errors()) - { - std::string context = "Statement::ExecuteImmediate( "; - context.append(sql).append(" )"); - throw SQLExceptionImpl(status, context.c_str(), - _("isc_dsql_execute_immediate failed")); - } -} - -int StatementImpl::AffectedRows() -{ - if (mHandle == 0) - throw LogicExceptionImpl("Statement::AffectedRows", _("No statement has been prepared.")); - if (mDatabase == 0) - throw LogicExceptionImpl("Statement::AffectedRows", _("A Database must be attached.")); - if (mDatabase->GetHandle() == 0) - throw LogicExceptionImpl("Statement::AffectedRows", _("Database must be connected.")); - - int count; - IBS status; - RB result; - char itemsReq[] = {isc_info_sql_records}; - - (*gds.Call()->m_dsql_sql_info)(status.Self(), &mHandle, 1, itemsReq, - result.Size(), result.Self()); - if (status.Errors()) throw SQLExceptionImpl(status, - "Statement::AffectedRows", _("isc_dsql_sql_info failed.")); - - if (mType == IBPP::stInsert) - count = result.GetValue(isc_info_sql_records, isc_info_req_insert_count); - else if (mType == IBPP::stUpdate) - count = result.GetValue(isc_info_sql_records, isc_info_req_update_count); - else if (mType == IBPP::stDelete) - count = result.GetValue(isc_info_sql_records, isc_info_req_delete_count); - else if (mType == IBPP::stSelect) - count = result.GetValue(isc_info_sql_records, isc_info_req_select_count); - else count = 0; // Returns zero count for unknown cases - - return count; -} - -bool StatementImpl::Fetch() -{ - if (! mResultSetAvailable) - throw LogicExceptionImpl("Statement::Fetch", - _("No statement has been executed or no result set available.")); - - IBS status; - ISC_STATUS code = (*gds.Call()->m_dsql_fetch)(status.Self(), &mHandle, 1, mOutRow->Self()); - if (code == 100) // This special code means "no more rows" - { - mResultSetAvailable = false; - // Oddly enough, fetching rows up to the last one seems to open - // an 'implicit' cursor that needs to be closed. - mCursorOpened = true; - CursorFree(); // Free the explicit or implicit cursor/result-set - return false; - } - if (status.Errors()) - { - Close(); - throw SQLExceptionImpl(status, "Statement::Fetch", - _("isc_dsql_fetch failed.")); - } - - return true; -} - -bool StatementImpl::Fetch(IBPP::Row& row) -{ - if (! mResultSetAvailable) - throw LogicExceptionImpl("Statement::Fetch(row)", - _("No statement has been executed or no result set available.")); - - RowImpl* rowimpl = new RowImpl(*mOutRow); - row = rowimpl; - - IBS status; - ISC_STATUS code = (*gds.Call()->m_dsql_fetch)(status.Self(), &mHandle, 1, - rowimpl->Self()); - if (code == 100) // This special code means "no more rows" - { - mResultSetAvailable = false; - // Oddly enough, fetching rows up to the last one seems to open - // an 'implicit' cursor that needs to be closed. - mCursorOpened = true; - CursorFree(); // Free the explicit or implicit cursor/result-set - row.clear(); - return false; - } - if (status.Errors()) - { - Close(); - row.clear(); - throw SQLExceptionImpl(status, "Statement::Fetch(row)", - _("isc_dsql_fetch failed.")); - } - - return true; -} - -void StatementImpl::Close() -{ - // Free all statement resources. - // Used before preparing a new statement or from destructor. - - if (mInRow != 0) { mInRow->Release(); mInRow = 0; } - if (mOutRow != 0) { mOutRow->Release(); mOutRow = 0; } - - mResultSetAvailable = false; - mCursorOpened = false; - mType = IBPP::stUnknown; - - if (mHandle != 0) - { - IBS status; - (*gds.Call()->m_dsql_free_statement)(status.Self(), &mHandle, DSQL_drop); - mHandle = 0; - if (status.Errors()) - throw SQLExceptionImpl(status, "Statement::Close(DSQL_drop)", - _("isc_dsql_free_statement failed.")); - } -} - -void StatementImpl::SetNull(int param) -{ - if (mHandle == 0) - throw LogicExceptionImpl("Statement::SetNull", _("No statement has been prepared.")); - if (mInRow == 0) - throw LogicExceptionImpl("Statement::SetNull", _("The statement does not take parameters.")); - - mInRow->SetNull(param); -} - -void StatementImpl::Set(int param, bool value) -{ - if (mHandle == 0) - throw LogicExceptionImpl("Statement::Set[bool]", _("No statement has been prepared.")); - if (mInRow == 0) - throw LogicExceptionImpl("Statement::Set[bool]", _("The statement does not take parameters.")); - - mInRow->Set(param, value); -} - -void StatementImpl::Set(int param, const char* cstring) -{ - if (mHandle == 0) - throw LogicExceptionImpl("Statement::Set[char*]", _("No statement has been prepared.")); - if (mInRow == 0) - throw LogicExceptionImpl("Statement::Set[char*]", _("The statement does not take parameters.")); - - mInRow->Set(param, cstring); -} - -void StatementImpl::Set(int param, const void* bindata, int len) -{ - if (mHandle == 0) - throw LogicExceptionImpl("Statement::Set[void*]", _("No statement has been prepared.")); - if (mInRow == 0) - throw LogicExceptionImpl("Statement::Set[void*]", _("The statement does not take parameters.")); - - mInRow->Set(param, bindata, len); -} - -void StatementImpl::Set(int param, const std::string& s) -{ - if (mHandle == 0) - throw LogicExceptionImpl("Statement::Set[string]", _("No statement has been prepared.")); - if (mInRow == 0) - throw LogicExceptionImpl("Statement::Set[string]", _("The statement does not take parameters.")); - - mInRow->Set(param, s); -} - -void StatementImpl::Set(int param, int16_t value) -{ - if (mHandle == 0) - throw LogicExceptionImpl("Statement::Set[int16_t]", _("No statement has been prepared.")); - if (mInRow == 0) - throw LogicExceptionImpl("Statement::Set[int16_t]", _("The statement does not take parameters.")); - - mInRow->Set(param, value); -} - -void StatementImpl::Set(int param, int32_t value) -{ - if (mHandle == 0) - throw LogicExceptionImpl("Statement::Set[int32_t]", _("No statement has been prepared.")); - if (mInRow == 0) - throw LogicExceptionImpl("Statement::Set[int32_t]", _("The statement does not take parameters.")); - - mInRow->Set(param, value); -} - -void StatementImpl::Set(int param, int64_t value) -{ - if (mHandle == 0) - throw LogicExceptionImpl("Statement::Set[int64_t]", _("No statement has been prepared.")); - if (mInRow == 0) - throw LogicExceptionImpl("Statement::Set[int64_t]", _("The statement does not take parameters.")); - - mInRow->Set(param, value); -} - -void StatementImpl::Set(int param, float value) -{ - if (mHandle == 0) - throw LogicExceptionImpl("Statement::Set[float]", _("No statement has been prepared.")); - if (mInRow == 0) - throw LogicExceptionImpl("Statement::Set[float]", _("The statement does not take parameters.")); - - mInRow->Set(param, value); -} - -void StatementImpl::Set(int param, double value) -{ - if (mHandle == 0) - throw LogicExceptionImpl("Statement::Set[double]", _("No statement has been prepared.")); - if (mInRow == 0) - throw LogicExceptionImpl("Statement::Set[double]", _("The statement does not take parameters.")); - - mInRow->Set(param, value); -} - -void StatementImpl::Set(int param, const IBPP::Timestamp& value) -{ - if (mHandle == 0) - throw LogicExceptionImpl("Statement::Set[Timestamp]", _("No statement has been prepared.")); - if (mInRow == 0) - throw LogicExceptionImpl("Statement::Set[Timestamp]", _("The statement does not take parameters.")); - - mInRow->Set(param, value); -} - -void StatementImpl::Set(int param, const IBPP::Date& value) -{ - if (mHandle == 0) - throw LogicExceptionImpl("Statement::Set[Date]", _("No statement has been prepared.")); - if (mInRow == 0) - throw LogicExceptionImpl("Statement::Set[Date]", _("The statement does not take parameters.")); - - mInRow->Set(param, value); -} - -void StatementImpl::Set(int param, const IBPP::Time& value) -{ - if (mHandle == 0) - throw LogicExceptionImpl("Statement::Set[Time]", _("No statement has been prepared.")); - if (mInRow == 0) - throw LogicExceptionImpl("Statement::Set[Time]", _("The statement does not take parameters.")); - - mInRow->Set(param, value); -} - -void StatementImpl::Set(int param, const IBPP::Blob& blob) -{ - if (mHandle == 0) - throw LogicExceptionImpl("Statement::Set[Blob]", _("No statement has been prepared.")); - if (mInRow == 0) - throw LogicExceptionImpl("Statement::Set[Blob]", _("The statement does not take parameters.")); - - mInRow->Set(param, blob); -} - -void StatementImpl::Set(int param, const IBPP::Array& array) -{ - if (mHandle == 0) - throw LogicExceptionImpl("Statement::Set[Array]", _("No statement has been prepared.")); - if (mInRow == 0) - throw LogicExceptionImpl("Statement::Set[Array]", _("The statement does not take parameters.")); - - mInRow->Set(param, array); -} - -void StatementImpl::Set(int param, const IBPP::DBKey& key) -{ - if (mHandle == 0) - throw LogicExceptionImpl("Statement::Set[DBKey]", _("No statement has been prepared.")); - if (mInRow == 0) - throw LogicExceptionImpl("Statement::Set[DBKey]", _("The statement does not take parameters.")); - - mInRow->Set(param, key); -} - -/* -void StatementImpl::Set(int param, const IBPP::Value& value) -{ - if (mHandle == 0) - throw LogicExceptionImpl("Statement::Set[Value]", _("No statement has been prepared.")); - if (mInRow == 0) - throw LogicExceptionImpl("Statement::Set[Value]", _("The statement does not take parameters.")); - - mInRow->Set(param, value); -} -*/ - -bool StatementImpl::IsNull(int column) -{ - if (mOutRow == 0) - throw LogicExceptionImpl("Statement::IsNull", _("The row is not initialized.")); - - return mOutRow->IsNull(column); -} - -bool StatementImpl::Get(int column, bool* retvalue) -{ - if (mOutRow == 0) - throw LogicExceptionImpl("Statement::Get", _("The row is not initialized.")); - if (retvalue == 0) - throw LogicExceptionImpl("Statement::Get", _("Null pointer detected")); - - return mOutRow->Get(column, *retvalue); -} - -bool StatementImpl::Get(int column, bool& retvalue) -{ - if (mOutRow == 0) - throw LogicExceptionImpl("Statement::Get", _("The row is not initialized.")); - - return mOutRow->Get(column, retvalue); -} - -bool StatementImpl::Get(int column, char* retvalue) -{ - if (mOutRow == 0) - throw LogicExceptionImpl("Statement::Get", _("The row is not initialized.")); - - return mOutRow->Get(column, retvalue); -} - -bool StatementImpl::Get(int column, void* bindata, int& userlen) -{ - if (mOutRow == 0) - throw LogicExceptionImpl("Statement::Get", _("The row is not initialized.")); - - return mOutRow->Get(column, bindata, userlen); -} - -bool StatementImpl::Get(int column, std::string& retvalue) -{ - if (mOutRow == 0) - throw LogicExceptionImpl("Statement::Get", _("The row is not initialized.")); - - return mOutRow->Get(column, retvalue); -} - -bool StatementImpl::Get(int column, int16_t* retvalue) -{ - if (mOutRow == 0) - throw LogicExceptionImpl("Statement::Get", _("The row is not initialized.")); - if (retvalue == 0) - throw LogicExceptionImpl("Statement::Get", _("Null pointer detected")); - - return mOutRow->Get(column, *retvalue); -} - -bool StatementImpl::Get(int column, int16_t& retvalue) -{ - if (mOutRow == 0) - throw LogicExceptionImpl("Statement::Get", _("The row is not initialized.")); - - return mOutRow->Get(column, retvalue); -} - -bool StatementImpl::Get(int column, int32_t* retvalue) -{ - if (mOutRow == 0) - throw LogicExceptionImpl("Statement::Get", _("The row is not initialized.")); - if (retvalue == 0) - throw LogicExceptionImpl("Statement::Get", _("Null pointer detected")); - - return mOutRow->Get(column, *retvalue); -} - -bool StatementImpl::Get(int column, int32_t& retvalue) -{ - if (mOutRow == 0) - throw LogicExceptionImpl("Statement::Get", _("The row is not initialized.")); - - return mOutRow->Get(column, retvalue); -} - -bool StatementImpl::Get(int column, int64_t* retvalue) -{ - if (mOutRow == 0) - throw LogicExceptionImpl("Statement::Get", _("The row is not initialized.")); - if (retvalue == 0) - throw LogicExceptionImpl("Statement::Get", _("Null pointer detected")); - - return mOutRow->Get(column, *retvalue); -} - -bool StatementImpl::Get(int column, int64_t& retvalue) -{ - if (mOutRow == 0) - throw LogicExceptionImpl("Statement::Get", _("The row is not initialized.")); - - return mOutRow->Get(column, retvalue); -} - -bool StatementImpl::Get(int column, float* retvalue) -{ - if (mOutRow == 0) - throw LogicExceptionImpl("Statement::Get", _("The row is not initialized.")); - if (retvalue == 0) - throw LogicExceptionImpl("Statement::Get", _("Null pointer detected")); - - return mOutRow->Get(column, *retvalue); -} - -bool StatementImpl::Get(int column, float& retvalue) -{ - if (mOutRow == 0) - throw LogicExceptionImpl("Statement::Get", _("The row is not initialized.")); - - return mOutRow->Get(column, retvalue); -} - -bool StatementImpl::Get(int column, double* retvalue) -{ - if (mOutRow == 0) - throw LogicExceptionImpl("Statement::Get", _("The row is not initialized.")); - if (retvalue == 0) - throw LogicExceptionImpl("Statement::Get", _("Null pointer detected")); - - return mOutRow->Get(column, *retvalue); -} - -bool StatementImpl::Get(int column, double& retvalue) -{ - if (mOutRow == 0) - throw LogicExceptionImpl("Statement::Get", _("The row is not initialized.")); - - return mOutRow->Get(column, retvalue); -} - -bool StatementImpl::Get(int column, IBPP::Timestamp& timestamp) -{ - if (mOutRow == 0) - throw LogicExceptionImpl("Statement::Get", _("The row is not initialized.")); - - return mOutRow->Get(column, timestamp); -} - -bool StatementImpl::Get(int column, IBPP::Date& date) -{ - if (mOutRow == 0) - throw LogicExceptionImpl("Statement::Get", _("The row is not initialized.")); - - return mOutRow->Get(column, date); -} - -bool StatementImpl::Get(int column, IBPP::Time& time) -{ - if (mOutRow == 0) - throw LogicExceptionImpl("Statement::Get", _("The row is not initialized.")); - - return mOutRow->Get(column, time); -} - -bool StatementImpl::Get(int column, IBPP::Blob& blob) -{ - if (mOutRow == 0) - throw LogicExceptionImpl("Statement::Get", _("The row is not initialized.")); - - return mOutRow->Get(column, blob); -} - -bool StatementImpl::Get(int column, IBPP::DBKey& key) -{ - if (mOutRow == 0) - throw LogicExceptionImpl("Statement::Get", _("The row is not initialized.")); - - return mOutRow->Get(column, key); -} - -bool StatementImpl::Get(int column, IBPP::Array& array) -{ - if (mOutRow == 0) - throw LogicExceptionImpl("Statement::Get", _("The row is not initialized.")); - - return mOutRow->Get(column, array); -} - -/* -const IBPP::Value StatementImpl::Get(int column) -{ - if (mOutRow == 0) - throw LogicExceptionImpl("Statement::Get", _("The row is not initialized.")); - - return mOutRow->Get(column); -} -*/ - -bool StatementImpl::IsNull(const std::string& name) -{ - if (mOutRow == 0) - throw LogicExceptionImpl("Statement::IsNull", _("The row is not initialized.")); - - return mOutRow->IsNull(name); -} - -bool StatementImpl::Get(const std::string& name, bool* retvalue) -{ - if (mOutRow == 0) - throw LogicExceptionImpl("Statement::Get", _("The row is not initialized.")); - if (retvalue == 0) - throw LogicExceptionImpl("Statement::Get", _("Null pointer detected")); - - return mOutRow->Get(name, *retvalue); -} - -bool StatementImpl::Get(const std::string& name, bool& retvalue) -{ - if (mOutRow == 0) - throw LogicExceptionImpl("Statement::Get", _("The row is not initialized.")); - - return mOutRow->Get(name, retvalue); -} - -bool StatementImpl::Get(const std::string& name, char* retvalue) -{ - if (mOutRow == 0) - throw LogicExceptionImpl("Statement::Get[char*]", _("The row is not initialized.")); - - return mOutRow->Get(name, retvalue); -} - -bool StatementImpl::Get(const std::string& name, void* retvalue, int& count) -{ - if (mOutRow == 0) - throw LogicExceptionImpl("Statement::Get[void*,int]", _("The row is not initialized.")); - - return mOutRow->Get(name, retvalue, count); -} - -bool StatementImpl::Get(const std::string& name, std::string& retvalue) -{ - if (mOutRow == 0) - throw LogicExceptionImpl("Statement::GetString", _("The row is not initialized.")); - - return mOutRow->Get(name, retvalue); -} - -bool StatementImpl::Get(const std::string& name, int16_t* retvalue) -{ - if (mOutRow == 0) - throw LogicExceptionImpl("Statement::Get", _("The row is not initialized.")); - if (retvalue == 0) - throw LogicExceptionImpl("Statement::Get", _("Null pointer detected")); - - return mOutRow->Get(name, *retvalue); -} - -bool StatementImpl::Get(const std::string& name, int16_t& retvalue) -{ - if (mOutRow == 0) - throw LogicExceptionImpl("Statement::Get", _("The row is not initialized.")); - - return mOutRow->Get(name, retvalue); -} - -bool StatementImpl::Get(const std::string& name, int32_t* retvalue) -{ - if (mOutRow == 0) - throw LogicExceptionImpl("Statement::Get", _("The row is not initialized.")); - if (retvalue == 0) - throw LogicExceptionImpl("Statement::Get", _("Null pointer detected")); - - return mOutRow->Get(name, *retvalue); -} - -bool StatementImpl::Get(const std::string& name, int32_t& retvalue) -{ - if (mOutRow == 0) - throw LogicExceptionImpl("Statement::Get", _("The row is not initialized.")); - - return mOutRow->Get(name, retvalue); -} - -bool StatementImpl::Get(const std::string& name, int64_t* retvalue) -{ - if (mOutRow == 0) - throw LogicExceptionImpl("Statement::Get", _("The row is not initialized.")); - if (retvalue == 0) - throw LogicExceptionImpl("Statement::Get", _("Null pointer detected")); - - return mOutRow->Get(name, *retvalue); -} - -bool StatementImpl::Get(const std::string& name, int64_t& retvalue) -{ - if (mOutRow == 0) - throw LogicExceptionImpl("Statement::Get", _("The row is not initialized.")); - - return mOutRow->Get(name, retvalue); -} - -bool StatementImpl::Get(const std::string& name, float* retvalue) -{ - if (mOutRow == 0) - throw LogicExceptionImpl("Statement::Get", _("The row is not initialized.")); - if (retvalue == 0) - throw LogicExceptionImpl("Statement::Get", _("Null pointer detected")); - - return mOutRow->Get(name, *retvalue); -} - -bool StatementImpl::Get(const std::string& name, float& retvalue) -{ - if (mOutRow == 0) - throw LogicExceptionImpl("Statement::Get", _("The row is not initialized.")); - - return mOutRow->Get(name, retvalue); -} - -bool StatementImpl::Get(const std::string& name, double* retvalue) -{ - if (mOutRow == 0) - throw LogicExceptionImpl("Statement::Get", _("The row is not initialized.")); - if (retvalue == 0) - throw LogicExceptionImpl("Statement::Get", _("Null pointer detected")); - - return mOutRow->Get(name, *retvalue); -} - -bool StatementImpl::Get(const std::string& name, double& retvalue) -{ - if (mOutRow == 0) - throw LogicExceptionImpl("Statement::Get", _("The row is not initialized.")); - - return mOutRow->Get(name, retvalue); -} - -bool StatementImpl::Get(const std::string& name, IBPP::Timestamp& retvalue) -{ - if (mOutRow == 0) - throw LogicExceptionImpl("Statement::Get", _("The row is not initialized.")); - - return mOutRow->Get(name, retvalue); -} - -bool StatementImpl::Get(const std::string& name, IBPP::Date& retvalue) -{ - if (mOutRow == 0) - throw LogicExceptionImpl("Statement::Get", _("The row is not initialized.")); - - return mOutRow->Get(name, retvalue); -} - -bool StatementImpl::Get(const std::string& name, IBPP::Time& retvalue) -{ - if (mOutRow == 0) - throw LogicExceptionImpl("Statement::Get", _("The row is not initialized.")); - - return mOutRow->Get(name, retvalue); -} - -bool StatementImpl::Get(const std::string&name, IBPP::Blob& retblob) -{ - if (mOutRow == 0) - throw LogicExceptionImpl("Statement::Get", _("The row is not initialized.")); - - return mOutRow->Get(name, retblob); -} - -bool StatementImpl::Get(const std::string& name, IBPP::DBKey& retvalue) -{ - if (mOutRow == 0) - throw LogicExceptionImpl("Statement::Get", _("The row is not initialized.")); - - return mOutRow->Get(name, retvalue); -} - -bool StatementImpl::Get(const std::string& name, IBPP::Array& retarray) -{ - if (mOutRow == 0) - throw LogicExceptionImpl("Statement::Get", _("The row is not initialized.")); - - return mOutRow->Get(name, retarray); -} - -/* -const IBPP::Value StatementImpl::Get(const std::string& name) -{ - if (mOutRow == 0) - throw LogicExceptionImpl("Statement::Get", _("The row is not initialized.")); - - return mOutRow->Get(name); -} -*/ - -int StatementImpl::Columns() -{ - if (mOutRow == 0) - throw LogicExceptionImpl("Statement::Columns", _("The row is not initialized.")); - - return mOutRow->Columns(); -} - -int StatementImpl::ColumnNum(const std::string& name) -{ - if (mOutRow == 0) - throw LogicExceptionImpl("Statement::ColumnNum", _("The row is not initialized.")); - - return mOutRow->ColumnNum(name); -} - -const char* StatementImpl::ColumnName(int varnum) -{ - if (mOutRow == 0) - throw LogicExceptionImpl("Statement::Columns", _("The row is not initialized.")); - - return mOutRow->ColumnName(varnum); -} - -const char* StatementImpl::ColumnAlias(int varnum) -{ - if (mOutRow == 0) - throw LogicExceptionImpl("Statement::Columns", _("The row is not initialized.")); - - return mOutRow->ColumnAlias(varnum); -} - -const char* StatementImpl::ColumnTable(int varnum) -{ - if (mOutRow == 0) - throw LogicExceptionImpl("Statement::Columns", _("The row is not initialized.")); - - return mOutRow->ColumnTable(varnum); -} - -IBPP::SDT StatementImpl::ColumnType(int varnum) -{ - if (mHandle == 0) - throw LogicExceptionImpl("Statement::ColumnType", _("No statement has been prepared.")); - if (mOutRow == 0) - throw LogicExceptionImpl("Statement::ColumnType", _("The statement does not return results.")); - - return mOutRow->ColumnType(varnum); -} - -int StatementImpl::ColumnSubtype(int varnum) -{ - if (mHandle == 0) - throw LogicExceptionImpl("Statement::ColumnSubtype", _("No statement has been prepared.")); - if (mOutRow == 0) - throw LogicExceptionImpl("Statement::ColumnSubtype", _("The statement does not return results.")); - - return mOutRow->ColumnSubtype(varnum); -} - -int StatementImpl::ColumnSize(int varnum) -{ - if (mHandle == 0) - throw LogicExceptionImpl("Statement::ColumnSize", _("No statement has been prepared.")); - if (mOutRow == 0) - throw LogicExceptionImpl("Statement::ColumnSize", _("The row is not initialized.")); - - return mOutRow->ColumnSize(varnum); -} - -int StatementImpl::ColumnScale(int varnum) -{ - if (mHandle == 0) - throw LogicExceptionImpl("Statement::ColumnScale", _("No statement has been prepared.")); - if (mOutRow == 0) - throw LogicExceptionImpl("Statement::ColumnScale", _("The row is not initialized.")); - - return mOutRow->ColumnScale(varnum); -} - -int StatementImpl::Parameters() -{ - if (mHandle == 0) - throw LogicExceptionImpl("Statement::Parameters", _("No statement has been prepared.")); - if (mInRow == 0) - throw LogicExceptionImpl("Statement::Parameters", _("The statement uses no parameters.")); - - return mInRow->Columns(); -} - -IBPP::SDT StatementImpl::ParameterType(int varnum) -{ - if (mHandle == 0) - throw LogicExceptionImpl("Statement::ParameterType", _("No statement has been prepared.")); - if (mInRow == 0) - throw LogicExceptionImpl("Statement::ParameterType", _("The statement uses no parameters.")); - - return mInRow->ColumnType(varnum); -} - -int StatementImpl::ParameterSubtype(int varnum) -{ - if (mHandle == 0) - throw LogicExceptionImpl("Statement::ParameterSubtype", _("No statement has been prepared.")); - if (mInRow == 0) - throw LogicExceptionImpl("Statement::ParameterSubtype", _("The statement uses no parameters.")); - - return mInRow->ColumnSubtype(varnum); -} - -int StatementImpl::ParameterSize(int varnum) -{ - if (mHandle == 0) - throw LogicExceptionImpl("Statement::ParameterSize", _("No statement has been prepared.")); - if (mInRow == 0) - throw LogicExceptionImpl("Statement::ParameterSize", _("The statement uses no parameters.")); - - return mInRow->ColumnSize(varnum); -} - -int StatementImpl::ParameterScale(int varnum) -{ - if (mHandle == 0) - throw LogicExceptionImpl("Statement::ParameterScale", _("No statement has been prepared.")); - if (mInRow == 0) - throw LogicExceptionImpl("Statement::ParameterScale", _("The statement uses no parameters.")); - - return mInRow->ColumnScale(varnum); -} - -IBPP::Database StatementImpl::DatabasePtr() const -{ - return mDatabase; -} - -IBPP::Transaction StatementImpl::TransactionPtr() const -{ - return mTransaction; -} - -IBPP::IStatement* StatementImpl::AddRef() -{ - ASSERTION(mRefCount >= 0); - ++mRefCount; - - return this; -} - -void StatementImpl::Release() -{ - // Release cannot throw, except in DEBUG builds on assertion - ASSERTION(mRefCount >= 0); - --mRefCount; - try { if (mRefCount <= 0) delete this; } - catch (...) { } -} - -// (((((((( OBJECT INTERNAL METHODS )))))))) - -void StatementImpl::AttachDatabaseImpl(DatabaseImpl* database) -{ - if (database == 0) - throw LogicExceptionImpl("Statement::AttachDatabase", - _("Can't attach a 0 IDatabase object.")); - - if (mDatabase != 0) mDatabase->DetachStatementImpl(this); - mDatabase = database; - mDatabase->AttachStatementImpl(this); -} - -void StatementImpl::DetachDatabaseImpl() -{ - if (mDatabase == 0) return; - - Close(); - mDatabase->DetachStatementImpl(this); - mDatabase = 0; -} - -void StatementImpl::AttachTransactionImpl(TransactionImpl* transaction) -{ - if (transaction == 0) - throw LogicExceptionImpl("Statement::AttachTransaction", - _("Can't attach a 0 ITransaction object.")); - - if (mTransaction != 0) mTransaction->DetachStatementImpl(this); - mTransaction = transaction; - mTransaction->AttachStatementImpl(this); -} - -void StatementImpl::DetachTransactionImpl() -{ - if (mTransaction == 0) return; - - Close(); - mTransaction->DetachStatementImpl(this); - mTransaction = 0; -} - -void StatementImpl::CursorFree() -{ - if (mCursorOpened) - { - mCursorOpened = false; - if (mHandle != 0) - { - IBS status; - (*gds.Call()->m_dsql_free_statement)(status.Self(), &mHandle, DSQL_close); - if (status.Errors()) - throw SQLExceptionImpl(status, "StatementImpl::CursorFree(DSQL_close)", - _("isc_dsql_free_statement failed.")); - } - } -} - -StatementImpl::StatementImpl(DatabaseImpl* database, TransactionImpl* transaction, - const std::string& sql) - : mRefCount(0), mHandle(0), mDatabase(0), mTransaction(0), - mInRow(0), mOutRow(0), - mResultSetAvailable(false), mCursorOpened(false), mType(IBPP::stUnknown) -{ - AttachDatabaseImpl(database); - if (transaction != 0) AttachTransactionImpl(transaction); - if (! sql.empty()) Prepare(sql); -} - -StatementImpl::~StatementImpl() -{ - try { Close(); } - catch (...) { } - try { if (mTransaction != 0) mTransaction->DetachStatementImpl(this); } - catch (...) { } - try { if (mDatabase != 0) mDatabase->DetachStatementImpl(this); } - catch (...) { } -} - -// -// EOF -//