Index: src/libchcore/TSQLiteStatement.cpp =================================================================== diff -u -N -r8068e0c351055554340ac9755d1bc846893bf2b8 -ra4635addad389b9e117679437a3e1b64a739ea96 --- src/libchcore/TSQLiteStatement.cpp (.../TSQLiteStatement.cpp) (revision 8068e0c351055554340ac9755d1bc846893bf2b8) +++ src/libchcore/TSQLiteStatement.cpp (.../TSQLiteStatement.cpp) (revision a4635addad389b9e117679437a3e1b64a739ea96) @@ -1,350 +1,350 @@ -// ============================================================================ -// Copyright (C) 2001-2013 by Jozef Starosczyk -// ixen@copyhandler.com -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU Library General Public License -// (version 2) as published by the Free Software Foundation; -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Library General Public -// License along with this program; if not, write to the -// Free Software Foundation, Inc., -// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// ============================================================================ -#include "stdafx.h" -#include "TSQLiteStatement.h" -#include "sqlite3/sqlite3.h" -#include "ErrorCodes.h" -#include "TSQLiteException.h" -#include -#include "SerializerTrace.h" - -namespace chcore -{ - namespace sqlite - { - TSQLiteStatement::TSQLiteStatement(const TSQLiteDatabasePtr& spDatabase) : - m_pStatement(nullptr), - m_spDatabase(spDatabase), - m_bHasRow(false) - { - if (!m_spDatabase) - throw TSQLiteException(eErr_InvalidArgument, 0, _T("Invalid database provided"), LOCATION); - } - - TSQLiteStatement::~TSQLiteStatement() - { - int iResult = sqlite3_finalize(m_pStatement); - if(iResult != SQLITE_OK) - { - DBTRACE1(L"sqlite3_finalize failed with error code: %d", iResult); - } - } - - void TSQLiteStatement::Close() - { - if (m_pStatement != nullptr) - { - int iResult = sqlite3_finalize(m_pStatement); - if (iResult != SQLITE_OK) - throw TSQLiteException(eErr_SQLiteFinalizeError, iResult, _T("Cannot finalize statement"), LOCATION); - m_pStatement = nullptr; - } - m_bHasRow = false; - } - - void TSQLiteStatement::Prepare(PCWSTR pszQuery) - { - Close(); - - int iResult = sqlite3_prepare16_v2((sqlite3*)m_spDatabase->GetHandle(), pszQuery, -1, &m_pStatement, nullptr); - if (iResult != SQLITE_OK) - throw TSQLiteException(eErr_SQLitePrepareError, iResult, (PCTSTR)sqlite3_errmsg16((sqlite3*)m_spDatabase->GetHandle()), LOCATION); - } - - TSQLiteStatement::EStepResult TSQLiteStatement::Step() - { - m_bHasRow = false; - - if (!m_pStatement) - throw TSQLiteException(eErr_SQLiteStatementNotPrepared, 0, _T("Tried to step on unprepared statement"), LOCATION); - - int iResult = sqlite3_step(m_pStatement); - switch (iResult) - { - case SQLITE_ROW: - m_bHasRow = true; - return eStep_HasRow; - case SQLITE_OK: - case SQLITE_DONE: - Reset(); - return eStep_Finished; - default: - { - const wchar_t* pszErrMsg = (const wchar_t*)sqlite3_errmsg16((sqlite3*)m_spDatabase->GetHandle()); - const size_t stMaxSize = 1024; - wchar_t szText[stMaxSize]; - _snwprintf_s(szText, stMaxSize, _TRUNCATE, L"Cannot perform step on the statement. SQLite reported error: %s", pszErrMsg); - throw TSQLiteException(eErr_SQLiteStepError, iResult, szText, LOCATION); - } - } - } - - int TSQLiteStatement::Changes() - { - return sqlite3_changes((sqlite3*)m_spDatabase->GetHandle()); - } - - void TSQLiteStatement::BindValue(int iColumn, bool bValue) - { - BindValue(iColumn, bValue ? 1 : 0); - } - - void TSQLiteStatement::BindValue(int iColumn, short siValue) - { - BindValue(iColumn, (int)siValue); - } - - void TSQLiteStatement::BindValue(int iColumn, unsigned short usiValue) - { - BindValue(iColumn, (unsigned int)usiValue); - } - - void TSQLiteStatement::BindValue(int iColumn, int iValue) - { - if (!m_pStatement) - throw TSQLiteException(eErr_SQLiteStatementNotPrepared, 0, _T("Tried to step on unprepared statement"), LOCATION); - - int iResult = sqlite3_bind_int(m_pStatement, iColumn, iValue); - if (iResult != SQLITE_OK) - throw TSQLiteException(eErr_SQLiteBindError, iResult, _T("Cannot bind a parameter"), LOCATION); - } - - void TSQLiteStatement::BindValue(int iColumn, unsigned int uiValue) - { - BindValue(iColumn, *(int*)&uiValue); - } - - void TSQLiteStatement::BindValue(int iColumn, long lValue) - { - BindValue(iColumn, boost::numeric_cast(lValue)); - } - - void TSQLiteStatement::BindValue(int iColumn, unsigned long ulValue) - { - BindValue(iColumn, boost::numeric_cast(ulValue)); - } - - void TSQLiteStatement::BindValue(int iColumn, long long llValue) - { - if (!m_pStatement) - throw TSQLiteException(eErr_SQLiteStatementNotPrepared, 0, _T("Tried to step on unprepared statement"), LOCATION); - - int iResult = sqlite3_bind_int64(m_pStatement, iColumn, llValue); - if (iResult != SQLITE_OK) - throw TSQLiteException(eErr_SQLiteBindError, iResult, _T("Cannot bind a parameter"), LOCATION); - } - - void TSQLiteStatement::BindValue(int iColumn, unsigned long long ullValue) - { - BindValue(iColumn, *(long long*)&ullValue); - } - - void TSQLiteStatement::BindValue(int iColumn, double dValue) - { - if (!m_pStatement) - throw TSQLiteException(eErr_SQLiteStatementNotPrepared, 0, _T("Tried to step on unprepared statement"), LOCATION); - - int iResult = sqlite3_bind_double(m_pStatement, iColumn, dValue); - if (iResult != SQLITE_OK) - throw TSQLiteException(eErr_SQLiteBindError, iResult, _T("Cannot bind a parameter"), LOCATION); - } - - void TSQLiteStatement::BindValue(int iColumn, PCTSTR pszText) - { - if (!m_pStatement) - throw TSQLiteException(eErr_SQLiteStatementNotPrepared, 0, _T("Tried to step on unprepared statement"), LOCATION); - - int iResult = sqlite3_bind_text16(m_pStatement, iColumn, pszText, -1, SQLITE_TRANSIENT); - if (iResult != SQLITE_OK) - throw TSQLiteException(eErr_SQLiteBindError, iResult, _T("Cannot bind a parameter"), LOCATION); - } - - void TSQLiteStatement::BindValue(int iColumn, const TString& strText) - { - BindValue(iColumn, strText.c_str()); - } - - void TSQLiteStatement::BindValue(int iColumn, const TSmartPath& path) - { - BindValue(iColumn, path.ToString()); - } - - bool TSQLiteStatement::GetBool(int iCol) - { - return GetInt(iCol) != 0; - } - - short TSQLiteStatement::GetShort(int iCol) - { - return boost::numeric_cast(GetInt(iCol)); - } - - unsigned short TSQLiteStatement::GetUShort(int iCol) - { - return boost::numeric_cast(GetUInt(iCol)); - } - - int TSQLiteStatement::GetInt(int iCol) - { - if (!m_pStatement) - throw TSQLiteException(eErr_SQLiteStatementNotPrepared, 0, _T("Tried to step on unprepared statement"), LOCATION); - if (!m_bHasRow) - throw TSQLiteException(eErr_SQLiteNoRowAvailable, 0, _T("No row available"), LOCATION); - - return sqlite3_column_int(m_pStatement, iCol); - } - - unsigned int TSQLiteStatement::GetUInt(int iCol) - { - int iVal = GetInt(iCol); - return *(unsigned int*)&iVal; - } - - long TSQLiteStatement::GetLong(int iCol) - { - return boost::numeric_cast(GetInt(iCol)); - } - - unsigned long TSQLiteStatement::GetULong(int iCol) - { - return boost::numeric_cast(GetUInt(iCol)); - } - - long long TSQLiteStatement::GetInt64(int iCol) - { - if (!m_pStatement) - throw TSQLiteException(eErr_SQLiteStatementNotPrepared, 0, _T("Tried to step on unprepared statement"), LOCATION); - if (!m_bHasRow) - throw TSQLiteException(eErr_SQLiteNoRowAvailable, 0, _T("No row available"), LOCATION); - - return sqlite3_column_int64(m_pStatement, iCol); - } - - unsigned long long TSQLiteStatement::GetUInt64(int iCol) - { - long long llVal = GetInt64(iCol); - return *(unsigned long long*)&llVal; - } - - double TSQLiteStatement::GetDouble(int iCol) - { - if (!m_pStatement) - throw TSQLiteException(eErr_SQLiteStatementNotPrepared, 0, _T("Tried to step on unprepared statement"), LOCATION); - if (!m_bHasRow) - throw TSQLiteException(eErr_SQLiteNoRowAvailable, 0, _T("No row available"), LOCATION); - - return sqlite3_column_double(m_pStatement, iCol); - } - - TString TSQLiteStatement::GetText(int iCol) - { - if (!m_pStatement) - throw TSQLiteException(eErr_SQLiteStatementNotPrepared, 0, _T("Tried to step on unprepared statement"), LOCATION); - if (!m_bHasRow) - throw TSQLiteException(eErr_SQLiteNoRowAvailable, 0, _T("No row available"), LOCATION); - - return TString((const wchar_t*)sqlite3_column_text16(m_pStatement, iCol)); - } - - TSmartPath TSQLiteStatement::GetPath(int iCol) - { - return PathFromWString(GetText(iCol)); - } - - void TSQLiteStatement::ClearBindings() - { - if (!m_pStatement) - throw TSQLiteException(eErr_SQLiteStatementNotPrepared, 0, _T("Tried to step on unprepared statement"), LOCATION); - - int iResult = sqlite3_clear_bindings(m_pStatement); - if (iResult != SQLITE_OK) - throw TSQLiteException(eErr_SQLiteBindError, iResult, _T("Cannot clear bindings"), LOCATION); - } - - void TSQLiteStatement::Reset() - { - if (!m_pStatement) - throw TSQLiteException(eErr_SQLiteStatementNotPrepared, 0, _T("Tried to step on unprepared statement"), LOCATION); - - int iResult = sqlite3_reset(m_pStatement); - if (iResult != SQLITE_OK) - throw TSQLiteException(eErr_SQLiteBindError, iResult, _T("Cannot reset statement"), LOCATION); - } - - void TSQLiteStatement::GetValue(int iCol, bool& bValue) - { - bValue = GetBool(iCol); - } - - void TSQLiteStatement::GetValue(int iCol, short& iValue) - { - iValue = GetShort(iCol); - } - - void TSQLiteStatement::GetValue(int iCol, unsigned short& uiValue) - { - uiValue = GetUShort(iCol); - } - - void TSQLiteStatement::GetValue(int iCol, int& iValue) - { - iValue = GetInt(iCol); - } - - void TSQLiteStatement::GetValue(int iCol, unsigned int& uiValue) - { - uiValue = GetUInt(iCol); - } - - void TSQLiteStatement::GetValue(int iCol, long& lValue) - { - lValue = GetLong(iCol); - } - - void TSQLiteStatement::GetValue(int iCol, unsigned long& ulValue) - { - ulValue = GetULong(iCol); - } - - void TSQLiteStatement::GetValue(int iCol, long long& llValue) - { - llValue = GetInt64(iCol); - } - - void TSQLiteStatement::GetValue(int iCol, unsigned long long& ullValue) - { - ullValue = GetUInt64(iCol); - } - - void TSQLiteStatement::GetValue(int iCol, double& dValue) - { - dValue = GetDouble(iCol); - } - - void TSQLiteStatement::GetValue(int iCol, TString& strValue) - { - strValue = GetText(iCol); - } - - void TSQLiteStatement::GetValue(int iCol, TSmartPath& pathValue) - { - pathValue = GetPath(iCol); - } - } -} +// ============================================================================ +// Copyright (C) 2001-2013 by Jozef Starosczyk +// ixen@copyhandler.com +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU Library General Public License +// (version 2) as published by the Free Software Foundation; +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the +// Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// ============================================================================ +#include "stdafx.h" +#include "TSQLiteStatement.h" +#include "sqlite3/sqlite3.h" +#include "ErrorCodes.h" +#include "TSQLiteException.h" +#include +#include "SerializerTrace.h" + +namespace chcore +{ + namespace sqlite + { + TSQLiteStatement::TSQLiteStatement(const TSQLiteDatabasePtr& spDatabase) : + m_pStatement(nullptr), + m_spDatabase(spDatabase), + m_bHasRow(false) + { + if (!m_spDatabase) + throw TSQLiteException(eErr_InvalidArgument, 0, _T("Invalid database provided"), LOCATION); + } + + TSQLiteStatement::~TSQLiteStatement() + { + int iResult = sqlite3_finalize(m_pStatement); + if(iResult != SQLITE_OK) + { + DBTRACE1(L"sqlite3_finalize failed with error code: %d", iResult); + } + } + + void TSQLiteStatement::Close() + { + if (m_pStatement != nullptr) + { + int iResult = sqlite3_finalize(m_pStatement); + if (iResult != SQLITE_OK) + throw TSQLiteException(eErr_SQLiteFinalizeError, iResult, _T("Cannot finalize statement"), LOCATION); + m_pStatement = nullptr; + } + m_bHasRow = false; + } + + void TSQLiteStatement::Prepare(PCWSTR pszQuery) + { + Close(); + + int iResult = sqlite3_prepare16_v2((sqlite3*)m_spDatabase->GetHandle(), pszQuery, -1, &m_pStatement, nullptr); + if (iResult != SQLITE_OK) + throw TSQLiteException(eErr_SQLitePrepareError, iResult, (PCTSTR)sqlite3_errmsg16((sqlite3*)m_spDatabase->GetHandle()), LOCATION); + } + + TSQLiteStatement::EStepResult TSQLiteStatement::Step() + { + m_bHasRow = false; + + if (!m_pStatement) + throw TSQLiteException(eErr_SQLiteStatementNotPrepared, 0, _T("Tried to step on unprepared statement"), LOCATION); + + int iResult = sqlite3_step(m_pStatement); + switch (iResult) + { + case SQLITE_ROW: + m_bHasRow = true; + return eStep_HasRow; + case SQLITE_OK: + case SQLITE_DONE: + Reset(); + return eStep_Finished; + default: + { + const wchar_t* pszErrMsg = (const wchar_t*)sqlite3_errmsg16((sqlite3*)m_spDatabase->GetHandle()); + const size_t stMaxSize = 1024; + wchar_t szText[stMaxSize]; + _snwprintf_s(szText, stMaxSize, _TRUNCATE, L"Cannot perform step on the statement. SQLite reported error: %s", pszErrMsg); + throw TSQLiteException(eErr_SQLiteStepError, iResult, szText, LOCATION); + } + } + } + + int TSQLiteStatement::Changes() + { + return sqlite3_changes((sqlite3*)m_spDatabase->GetHandle()); + } + + void TSQLiteStatement::BindValue(int iColumn, bool bValue) + { + BindValue(iColumn, bValue ? 1 : 0); + } + + void TSQLiteStatement::BindValue(int iColumn, short siValue) + { + BindValue(iColumn, (int)siValue); + } + + void TSQLiteStatement::BindValue(int iColumn, unsigned short usiValue) + { + BindValue(iColumn, (unsigned int)usiValue); + } + + void TSQLiteStatement::BindValue(int iColumn, int iValue) + { + if (!m_pStatement) + throw TSQLiteException(eErr_SQLiteStatementNotPrepared, 0, _T("Tried to step on unprepared statement"), LOCATION); + + int iResult = sqlite3_bind_int(m_pStatement, iColumn, iValue); + if (iResult != SQLITE_OK) + throw TSQLiteException(eErr_SQLiteBindError, iResult, _T("Cannot bind a parameter"), LOCATION); + } + + void TSQLiteStatement::BindValue(int iColumn, unsigned int uiValue) + { + BindValue(iColumn, *(int*)&uiValue); + } + + void TSQLiteStatement::BindValue(int iColumn, long lValue) + { + BindValue(iColumn, boost::numeric_cast(lValue)); + } + + void TSQLiteStatement::BindValue(int iColumn, unsigned long ulValue) + { + BindValue(iColumn, boost::numeric_cast(ulValue)); + } + + void TSQLiteStatement::BindValue(int iColumn, long long llValue) + { + if (!m_pStatement) + throw TSQLiteException(eErr_SQLiteStatementNotPrepared, 0, _T("Tried to step on unprepared statement"), LOCATION); + + int iResult = sqlite3_bind_int64(m_pStatement, iColumn, llValue); + if (iResult != SQLITE_OK) + throw TSQLiteException(eErr_SQLiteBindError, iResult, _T("Cannot bind a parameter"), LOCATION); + } + + void TSQLiteStatement::BindValue(int iColumn, unsigned long long ullValue) + { + BindValue(iColumn, *(long long*)&ullValue); + } + + void TSQLiteStatement::BindValue(int iColumn, double dValue) + { + if (!m_pStatement) + throw TSQLiteException(eErr_SQLiteStatementNotPrepared, 0, _T("Tried to step on unprepared statement"), LOCATION); + + int iResult = sqlite3_bind_double(m_pStatement, iColumn, dValue); + if (iResult != SQLITE_OK) + throw TSQLiteException(eErr_SQLiteBindError, iResult, _T("Cannot bind a parameter"), LOCATION); + } + + void TSQLiteStatement::BindValue(int iColumn, PCTSTR pszText) + { + if (!m_pStatement) + throw TSQLiteException(eErr_SQLiteStatementNotPrepared, 0, _T("Tried to step on unprepared statement"), LOCATION); + + int iResult = sqlite3_bind_text16(m_pStatement, iColumn, pszText, -1, SQLITE_TRANSIENT); + if (iResult != SQLITE_OK) + throw TSQLiteException(eErr_SQLiteBindError, iResult, _T("Cannot bind a parameter"), LOCATION); + } + + void TSQLiteStatement::BindValue(int iColumn, const TString& strText) + { + BindValue(iColumn, strText.c_str()); + } + + void TSQLiteStatement::BindValue(int iColumn, const TSmartPath& path) + { + BindValue(iColumn, path.ToString()); + } + + bool TSQLiteStatement::GetBool(int iCol) + { + return GetInt(iCol) != 0; + } + + short TSQLiteStatement::GetShort(int iCol) + { + return boost::numeric_cast(GetInt(iCol)); + } + + unsigned short TSQLiteStatement::GetUShort(int iCol) + { + return boost::numeric_cast(GetUInt(iCol)); + } + + int TSQLiteStatement::GetInt(int iCol) + { + if (!m_pStatement) + throw TSQLiteException(eErr_SQLiteStatementNotPrepared, 0, _T("Tried to step on unprepared statement"), LOCATION); + if (!m_bHasRow) + throw TSQLiteException(eErr_SQLiteNoRowAvailable, 0, _T("No row available"), LOCATION); + + return sqlite3_column_int(m_pStatement, iCol); + } + + unsigned int TSQLiteStatement::GetUInt(int iCol) + { + int iVal = GetInt(iCol); + return *(unsigned int*)&iVal; + } + + long TSQLiteStatement::GetLong(int iCol) + { + return boost::numeric_cast(GetInt(iCol)); + } + + unsigned long TSQLiteStatement::GetULong(int iCol) + { + return boost::numeric_cast(GetUInt(iCol)); + } + + long long TSQLiteStatement::GetInt64(int iCol) + { + if (!m_pStatement) + throw TSQLiteException(eErr_SQLiteStatementNotPrepared, 0, _T("Tried to step on unprepared statement"), LOCATION); + if (!m_bHasRow) + throw TSQLiteException(eErr_SQLiteNoRowAvailable, 0, _T("No row available"), LOCATION); + + return sqlite3_column_int64(m_pStatement, iCol); + } + + unsigned long long TSQLiteStatement::GetUInt64(int iCol) + { + long long llVal = GetInt64(iCol); + return *(unsigned long long*)&llVal; + } + + double TSQLiteStatement::GetDouble(int iCol) + { + if (!m_pStatement) + throw TSQLiteException(eErr_SQLiteStatementNotPrepared, 0, _T("Tried to step on unprepared statement"), LOCATION); + if (!m_bHasRow) + throw TSQLiteException(eErr_SQLiteNoRowAvailable, 0, _T("No row available"), LOCATION); + + return sqlite3_column_double(m_pStatement, iCol); + } + + TString TSQLiteStatement::GetText(int iCol) + { + if (!m_pStatement) + throw TSQLiteException(eErr_SQLiteStatementNotPrepared, 0, _T("Tried to step on unprepared statement"), LOCATION); + if (!m_bHasRow) + throw TSQLiteException(eErr_SQLiteNoRowAvailable, 0, _T("No row available"), LOCATION); + + return TString((const wchar_t*)sqlite3_column_text16(m_pStatement, iCol)); + } + + TSmartPath TSQLiteStatement::GetPath(int iCol) + { + return PathFromWString(GetText(iCol)); + } + + void TSQLiteStatement::ClearBindings() + { + if (!m_pStatement) + throw TSQLiteException(eErr_SQLiteStatementNotPrepared, 0, _T("Tried to step on unprepared statement"), LOCATION); + + int iResult = sqlite3_clear_bindings(m_pStatement); + if (iResult != SQLITE_OK) + throw TSQLiteException(eErr_SQLiteBindError, iResult, _T("Cannot clear bindings"), LOCATION); + } + + void TSQLiteStatement::Reset() + { + if (!m_pStatement) + throw TSQLiteException(eErr_SQLiteStatementNotPrepared, 0, _T("Tried to step on unprepared statement"), LOCATION); + + int iResult = sqlite3_reset(m_pStatement); + if (iResult != SQLITE_OK) + throw TSQLiteException(eErr_SQLiteBindError, iResult, _T("Cannot reset statement"), LOCATION); + } + + void TSQLiteStatement::GetValue(int iCol, bool& bValue) + { + bValue = GetBool(iCol); + } + + void TSQLiteStatement::GetValue(int iCol, short& iValue) + { + iValue = GetShort(iCol); + } + + void TSQLiteStatement::GetValue(int iCol, unsigned short& uiValue) + { + uiValue = GetUShort(iCol); + } + + void TSQLiteStatement::GetValue(int iCol, int& iValue) + { + iValue = GetInt(iCol); + } + + void TSQLiteStatement::GetValue(int iCol, unsigned int& uiValue) + { + uiValue = GetUInt(iCol); + } + + void TSQLiteStatement::GetValue(int iCol, long& lValue) + { + lValue = GetLong(iCol); + } + + void TSQLiteStatement::GetValue(int iCol, unsigned long& ulValue) + { + ulValue = GetULong(iCol); + } + + void TSQLiteStatement::GetValue(int iCol, long long& llValue) + { + llValue = GetInt64(iCol); + } + + void TSQLiteStatement::GetValue(int iCol, unsigned long long& ullValue) + { + ullValue = GetUInt64(iCol); + } + + void TSQLiteStatement::GetValue(int iCol, double& dValue) + { + dValue = GetDouble(iCol); + } + + void TSQLiteStatement::GetValue(int iCol, TString& strValue) + { + strValue = GetText(iCol); + } + + void TSQLiteStatement::GetValue(int iCol, TSmartPath& pathValue) + { + pathValue = GetPath(iCol); + } + } +}