Index: src/libchcore/TSQLiteSerializerRowData.cpp =================================================================== diff -u -N --- src/libchcore/TSQLiteSerializerRowData.cpp (revision e98c03b108baad889dfd7c7fbb1a49f5ea5a55d8) +++ src/libchcore/TSQLiteSerializerRowData.cpp (revision 0) @@ -1,530 +0,0 @@ -// ============================================================================ -// 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 "TSQLiteSerializerRowData.h" -#include "TSQLiteStatement.h" -#include -#include "TSerializerException.h" -#include "ErrorCodes.h" -#include "TPlainStringPool.h" - -namespace chcore -{ - /////////////////////////////////////////////////////////////////////////// - TSQLiteSerializerRowData::TSQLiteSerializerRowData(object_id_t oidRowID, TSQLiteColumnsDefinition& rColumnDefinition, bool bAdded, unsigned long long* pPoolMemory, size_t stPoolMemorySizeInBytes, TPlainStringPool& poolStrings, const logger::TLogFileDataPtr& spLogFileData) : - m_pPoolMemory(pPoolMemory), - m_rColumns(rColumnDefinition), - m_poolStrings(poolStrings), - m_spLog(logger::MakeLogger(spLogFileData, L"Serializer-RowData")) - { - if (!m_pPoolMemory) - throw TSerializerException(eErr_InvalidArgument, _T("Null memory provided"), LOCATION); - if (rColumnDefinition.GetCount() > 63) - throw TSerializerException(eErr_InternalProblem, _T("Serializer supports up to 63 columns. If more is needed the block header needs to be increased."), LOCATION); - - // initialize memory - memset((void*)pPoolMemory, 0, stPoolMemorySizeInBytes); - - // set id - size_t stIDIndex = rColumnDefinition.GetColumnIndex(_T("id")); - InternalSetValue(stIDIndex, oidRowID); - - if (bAdded) - MarkAsAdded(); - } - - TSQLiteSerializerRowData::~TSQLiteSerializerRowData() - { - } - - ISerializerRowData& TSQLiteSerializerRowData::SetValue(size_t stColIndex, bool bValue) - { - if (m_rColumns.GetColumnType(stColIndex) != IColumnsDefinition::eType_bool) - throw TSerializerException(eErr_InvalidArgument, _T("Invalid argument type provided"), LOCATION); - - ModifyColumnData(stColIndex) = (bValue ? 1ULL : 0ULL); - return *this; - } - - ISerializerRowData& TSQLiteSerializerRowData::SetValue(size_t stColIndex, short siValue) - { - if (m_rColumns.GetColumnType(stColIndex) != IColumnsDefinition::eType_short) - throw TSerializerException(eErr_InvalidArgument, _T("Invalid argument type provided"), LOCATION); - - ModifyColumnData(stColIndex) = (unsigned long long)*(unsigned short*)&siValue; - return *this; - } - - ISerializerRowData& TSQLiteSerializerRowData::SetValue(size_t stColIndex, unsigned short usiValue) - { - if (m_rColumns.GetColumnType(stColIndex) != IColumnsDefinition::eType_ushort) - throw TSerializerException(eErr_InvalidArgument, _T("Invalid argument type provided"), LOCATION); - - ModifyColumnData(stColIndex) = (unsigned long long)usiValue; - return *this; - } - - ISerializerRowData& TSQLiteSerializerRowData::SetValue(size_t stColIndex, int iValue) - { - if (m_rColumns.GetColumnType(stColIndex) != IColumnsDefinition::eType_int) - throw TSerializerException(eErr_InvalidArgument, _T("Invalid argument type provided"), LOCATION); - - ModifyColumnData(stColIndex) = (unsigned long long)*(unsigned int*)&iValue; - return *this; - } - - ISerializerRowData& TSQLiteSerializerRowData::SetValue(size_t stColIndex, unsigned int uiValue) - { - if (m_rColumns.GetColumnType(stColIndex) != IColumnsDefinition::eType_uint) - throw TSerializerException(eErr_InvalidArgument, _T("Invalid argument type provided"), LOCATION); - - ModifyColumnData(stColIndex) = (unsigned long long)uiValue; - return *this; - } - - ISerializerRowData& TSQLiteSerializerRowData::SetValue(size_t stColIndex, long lValue) - { - if (m_rColumns.GetColumnType(stColIndex) != IColumnsDefinition::eType_long) - throw TSerializerException(eErr_InvalidArgument, _T("Invalid argument type provided"), LOCATION); - - ModifyColumnData(stColIndex) = (unsigned long long)*(unsigned long*)&lValue; - return *this; - } - - ISerializerRowData& TSQLiteSerializerRowData::InternalSetValue(size_t stColIndex, unsigned long ulValue) - { - if(m_rColumns.GetColumnType(stColIndex) != IColumnsDefinition::eType_ulong) - throw TSerializerException(eErr_InvalidArgument, _T("Invalid argument type provided"), LOCATION); - - ModifyColumnData(stColIndex) = (unsigned long long)ulValue; - return *this; - } - - ISerializerRowData& TSQLiteSerializerRowData::SetValue(size_t stColIndex, unsigned long ulValue) - { - InternalSetValue(stColIndex, ulValue); - return *this; - } - - ISerializerRowData& TSQLiteSerializerRowData::SetValue(size_t stColIndex, long long llValue) - { - if (m_rColumns.GetColumnType(stColIndex) != IColumnsDefinition::eType_longlong) - throw TSerializerException(eErr_InvalidArgument, _T("Invalid argument type provided"), LOCATION); - - ModifyColumnData(stColIndex) = *(unsigned long long*)&llValue; - return *this; - } - - ISerializerRowData& TSQLiteSerializerRowData::SetValue(size_t stColIndex, unsigned long long ullValue) - { - if (m_rColumns.GetColumnType(stColIndex) != IColumnsDefinition::eType_ulonglong) - throw TSerializerException(eErr_InvalidArgument, _T("Invalid argument type provided"), LOCATION); - - ModifyColumnData(stColIndex) = ullValue; - return *this; - } - - ISerializerRowData& TSQLiteSerializerRowData::SetValue(size_t stColIndex, double dValue) - { - if (m_rColumns.GetColumnType(stColIndex) != IColumnsDefinition::eType_double) - throw TSerializerException(eErr_InvalidArgument, _T("Invalid argument type provided"), LOCATION); - - BOOST_STATIC_ASSERT(sizeof(double) == sizeof(unsigned long long)); - // cppcheck-suppress invalidPointerCast - ModifyColumnData(stColIndex) = *(unsigned long long*)&dValue; - return *this; - } - - ISerializerRowData& TSQLiteSerializerRowData::SetValue(size_t stColIndex, const TString& strValue) - { - if (m_rColumns.GetColumnType(stColIndex) != IColumnsDefinition::eType_string) - throw TSerializerException(eErr_InvalidArgument, _T("Invalid argument type provided"), LOCATION); - - if (strValue.IsEmpty()) - ModifyColumnData(stColIndex) = (unsigned long long)0; - else - { - wchar_t* pszBuffer = m_poolStrings.AllocForString(strValue.c_str()); - ModifyColumnData(stColIndex) = (unsigned long long)(void*)pszBuffer; - } - - return *this; - } - - ISerializerRowData& TSQLiteSerializerRowData::SetValue(size_t stColIndex, const TSmartPath& pathValue) - { - if (m_rColumns.GetColumnType(stColIndex) != IColumnsDefinition::eType_path) - throw TSerializerException(eErr_InvalidArgument, _T("Invalid argument type provided"), LOCATION); - - if (pathValue.IsEmpty()) - ModifyColumnData(stColIndex) = (unsigned long long)0; - else - { - wchar_t* pszBuffer = m_poolStrings.AllocForString(pathValue.ToString()); - ModifyColumnData(stColIndex) = (unsigned long long)(void*)pszBuffer; - } - - return *this; - } - - ISerializerRowData& TSQLiteSerializerRowData::SetValue(const wchar_t* strColumnName, bool bValue) - { - return SetValue(m_rColumns.GetColumnIndex(strColumnName), bValue); - } - - ISerializerRowData& TSQLiteSerializerRowData::SetValue(const wchar_t* strColumnName, short iValue) - { - return SetValue(m_rColumns.GetColumnIndex(strColumnName), iValue); - } - - ISerializerRowData& TSQLiteSerializerRowData::SetValue(const wchar_t* strColumnName, unsigned short uiValue) - { - return SetValue(m_rColumns.GetColumnIndex(strColumnName), uiValue); - } - - ISerializerRowData& TSQLiteSerializerRowData::SetValue(const wchar_t* strColumnName, int iValue) - { - return SetValue(m_rColumns.GetColumnIndex(strColumnName), iValue); - } - - ISerializerRowData& TSQLiteSerializerRowData::SetValue(const wchar_t* strColumnName, unsigned int uiValue) - { - return SetValue(m_rColumns.GetColumnIndex(strColumnName), uiValue); - } - - ISerializerRowData& TSQLiteSerializerRowData::SetValue(const wchar_t* strColumnName, long lValue) - { - return SetValue(m_rColumns.GetColumnIndex(strColumnName), lValue); - } - - ISerializerRowData& TSQLiteSerializerRowData::SetValue(const wchar_t* strColumnName, unsigned long ulValue) - { - return SetValue(m_rColumns.GetColumnIndex(strColumnName), ulValue); - } - - ISerializerRowData& TSQLiteSerializerRowData::SetValue(const wchar_t* strColumnName, long long llValue) - { - return SetValue(m_rColumns.GetColumnIndex(strColumnName), llValue); - } - - ISerializerRowData& TSQLiteSerializerRowData::SetValue(const wchar_t* strColumnName, unsigned long long llValue) - { - return SetValue(m_rColumns.GetColumnIndex(strColumnName), llValue); - } - - ISerializerRowData& TSQLiteSerializerRowData::SetValue(const wchar_t* strColumnName, double dValue) - { - return SetValue(m_rColumns.GetColumnIndex(strColumnName), dValue); - } - - ISerializerRowData& TSQLiteSerializerRowData::SetValue(const wchar_t* strColumnName, const TString& strValue) - { - return SetValue(m_rColumns.GetColumnIndex(strColumnName), strValue); - } - - ISerializerRowData& TSQLiteSerializerRowData::SetValue(const wchar_t* strColumnName, const TSmartPath& pathValue) - { - return SetValue(m_rColumns.GetColumnIndex(strColumnName), pathValue); - } - - void TSQLiteSerializerRowData::BindParamsAndExec(sqlite::TSQLiteStatement& tStatement) - { - using namespace sqlite; - - if (IsAdded()) - { - // exec query - int iColumn = 1; - BindParams(tStatement, iColumn); - - tStatement.Step(); - } - else if (HasAnyData()) - { - int iColumn = 1; - - size_t stIDColumnIndex = m_rColumns.GetColumnIndex(_T("id")); - - BindParams(tStatement, iColumn, stIDColumnIndex); - - // bind id as the last argument - tStatement.BindValue(iColumn++, GetDataForColumn(stIDColumnIndex)); - tStatement.Step(); - - int iChanges = tStatement.Changes(); - _ASSERTE(iChanges == 1); - if (iChanges != 1) - throw TSerializerException(eErr_InvalidData, _T("Update query did not update record in the database"), LOCATION); - } - } - - TString TSQLiteSerializerRowData::GetQuery(const TString& strContainerName) const - { - if (IsAdded()) - { - // prepare insert query - TString strQuery = boost::str(boost::wformat(L"INSERT INTO %1%(") % strContainerName).c_str(); - TString strParams; - - size_t stCount = m_rColumns.GetCount(); - for (size_t stIndex = 0; stIndex < stCount; ++stIndex) - { - strQuery += boost::str(boost::wformat(_T("%1%,")) % m_rColumns.GetColumnName(stIndex)).c_str(); - strParams += _T("?,"); - } - - strQuery.TrimRightSelf(_T(",")); - strQuery += _T(") VALUES("); - - strParams.TrimRightSelf(_T(",")); - strQuery += strParams; - strQuery += _T(")"); - - return strQuery; - } - else if (HasAnyData()) - { - // prepare update query - TString strQuery = boost::str(boost::wformat(L"UPDATE %1% SET ") % strContainerName).c_str(); - - size_t stCountOfAssignments = 0; - size_t stIDColumnIndex = m_rColumns.GetColumnIndex(_T("id")); - size_t stCount = m_rColumns.GetCount(); - for (size_t stIndex = 0; stIndex < stCount; ++stIndex) - { - if (stIndex != stIDColumnIndex && HasData(stIndex)) - { - strQuery += boost::str(boost::wformat(_T("%1%=?,")) % m_rColumns.GetColumnName(stIndex)).c_str(); - ++stCountOfAssignments; - } - } - - if (stCountOfAssignments == 0) - return TString(); - - strQuery.TrimRightSelf(_T(",")); - strQuery += _T(" WHERE id=?"); - - return strQuery; - } - else - return TString(); - } - - unsigned long long TSQLiteSerializerRowData::GetChangeIdentification() const - { - return GetDataHeader(); - } - - void TSQLiteSerializerRowData::MarkAsAdded() - { - // first bit is always the "added" bit - m_pPoolMemory[0] |= AddedBit; - } - - const unsigned long long& TSQLiteSerializerRowData::GetDataForColumn(size_t stColIndex) const - { - return (m_pPoolMemory[stColIndex + 1]); - } - - unsigned long long& TSQLiteSerializerRowData::ModifyColumnData(size_t stColIndex) - { - FreeColumnData(stColIndex); - - MarkColumnUsage(stColIndex, true); - return (m_pPoolMemory[stColIndex + 1]); - } - - void TSQLiteSerializerRowData::MarkColumnUsage(size_t stIndex, bool bUsed) - { - if (stIndex >= m_rColumns.GetCount()) - throw TSerializerException(eErr_BoundsExceeded, _T("Wrong column provided"), LOCATION); - - unsigned long long ullMask = 2ULL << stIndex; - if (bUsed) - m_pPoolMemory[0] |= ullMask; - else - m_pPoolMemory[0] &= ~ullMask; - } - - bool TSQLiteSerializerRowData::IsAdded() const - { - return (m_pPoolMemory[0] & AddedBit) != 0; - } - - bool TSQLiteSerializerRowData::HasAnyData() const - { - return GetDataHeader() != 0; - } - - bool TSQLiteSerializerRowData::HasData(size_t stColumnIndex) const - { - return (GetDataHeader() & (2ULL << stColumnIndex)) != 0; - } - - void TSQLiteSerializerRowData::BindParams(sqlite::TSQLiteStatement &tStatement, int& iSQLiteColumnNumber, size_t stSkipColumn) - { - LOG_DEBUG(m_spLog) << L"Binding parameters"; - - size_t stCount = m_rColumns.GetCount(); - for (size_t stColumn = 0; stColumn < stCount; ++stColumn) - { - if (stColumn == stSkipColumn) - continue; - - if (HasData(stColumn)) - { - switch (m_rColumns.GetColumnType(stColumn)) - { - case IColumnsDefinition::eType_bool: - { - bool bValue = GetDataForColumn(stColumn) != 0 ? true : false; - LOG_TRACE(m_spLog) << L"BindValue - column: " << stColumn << L", value(bool): " << (bValue ? 1l : 0l); - tStatement.BindValue(iSQLiteColumnNumber++, bValue); - break; - } - - case IColumnsDefinition::eType_short: - { - short siValue = *(short*)(unsigned short*)&GetDataForColumn(stColumn); - LOG_TRACE(m_spLog) << L"BindValue - column: " << stColumn << L", value(short): " << siValue; - tStatement.BindValue(iSQLiteColumnNumber++, siValue); - break; - } - - case IColumnsDefinition::eType_ushort: - { - unsigned short usiValue = (unsigned short)GetDataForColumn(stColumn); - LOG_TRACE(m_spLog) << L"BindValue - column: " << stColumn << L", value(ushort): " << usiValue; - tStatement.BindValue(iSQLiteColumnNumber++, usiValue); - break; - } - - case IColumnsDefinition::eType_int: - { - int iValue = *(int*)(unsigned int*)&GetDataForColumn(stColumn); - LOG_TRACE(m_spLog) << L"BindValue - column: " << stColumn << L", value(int): " << iValue; - tStatement.BindValue(iSQLiteColumnNumber++, iValue); - break; - } - - case IColumnsDefinition::eType_uint: - { - unsigned int uiValue = (unsigned int)GetDataForColumn(stColumn); - LOG_TRACE(m_spLog) << L"BindValue - column: " << stColumn << L", value(uint): " << uiValue; - tStatement.BindValue(iSQLiteColumnNumber++, uiValue); - break; - } - - case IColumnsDefinition::eType_long: - { - long lValue = *(long*)(unsigned long*)&GetDataForColumn(stColumn); - LOG_TRACE(m_spLog) << L"BindValue - column: " << stColumn << L", value(long): " << lValue; - tStatement.BindValue(iSQLiteColumnNumber++, lValue); - break; - } - - case IColumnsDefinition::eType_ulong: - { - unsigned long ulValue = (unsigned long)GetDataForColumn(stColumn); - LOG_TRACE(m_spLog) << L"BindValue - column: " << stColumn << L", value(ulong): " << ulValue; - tStatement.BindValue(iSQLiteColumnNumber++, ulValue); - break; - } - - case IColumnsDefinition::eType_longlong: - { - long long llValue = *(long long*)(unsigned long long*)&GetDataForColumn(stColumn); - LOG_TRACE(m_spLog) << L"BindValue - column: " << stColumn << L", value(llong): " << llValue; - tStatement.BindValue(iSQLiteColumnNumber++, llValue); - break; - } - - case IColumnsDefinition::eType_ulonglong: - { - unsigned long long ullValue = GetDataForColumn(stColumn); - LOG_TRACE(m_spLog) << L"BindValue - column: " << stColumn << L", value(ullong): " << ullValue; - tStatement.BindValue(iSQLiteColumnNumber++, ullValue); - break; - } - - case IColumnsDefinition::eType_double: - { - // cppcheck-suppress invalidPointerCast - double dValue = *(double*)(unsigned long long*)&GetDataForColumn(stColumn); - LOG_TRACE(m_spLog) << L"BindValue - column: " << stColumn << L", value(double): " << dValue; - tStatement.BindValue(iSQLiteColumnNumber++, dValue); - break; - } - - case IColumnsDefinition::eType_string: - { - const wchar_t* pszValue = (const wchar_t*)(unsigned long long*)GetDataForColumn(stColumn); - LOG_TRACE(m_spLog) << L"BindValue - column: " << stColumn << L", value(string): " << (pszValue ? pszValue : _T("")); - tStatement.BindValue(iSQLiteColumnNumber++, pszValue ? pszValue : _T("")); - break; - } - - case IColumnsDefinition::eType_path: - { - const wchar_t* pszValue = (const wchar_t*)(unsigned long long*)GetDataForColumn(stColumn); - LOG_TRACE(m_spLog) << L"BindValue - column: " << stColumn << L", value(path): " << (pszValue ? pszValue : _T("")); - tStatement.BindValue(iSQLiteColumnNumber++, pszValue ? PathFromString(pszValue) : TSmartPath()); - break; - } - - default: - throw TSerializerException(eErr_InvalidArgument, _T("Invalid type"), LOCATION); - } - } - } - } - - unsigned long long TSQLiteSerializerRowData::GetDataHeader() const - { - return m_pPoolMemory[0]; - } - - void TSQLiteSerializerRowData::FreeColumnData(size_t stColumnID) - { - if (!HasData(stColumnID)) - return; - - switch (m_rColumns.GetColumnType(stColumnID)) - { - case IColumnsDefinition::eType_path: - case IColumnsDefinition::eType_string: - { - unsigned long long& ullColumnData = m_pPoolMemory[stColumnID + 1]; - ullColumnData = 0ULL; - - break; - } - } - } - - void TSQLiteSerializerRowData::FreeAllColumnData() - { - size_t stCount = m_rColumns.GetCount(); - for (size_t stColumn = 0; stColumn < stCount; ++stColumn) - { - FreeColumnData(stColumn); - } - } -}