secureswitools/swisistools/source/dbmanager/dbprocessor.cpp
changeset 0 ba25891c3a9e
child 33 8110bf1194d1
child 65 7333d7932ef7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/secureswitools/swisistools/source/dbmanager/dbprocessor.cpp	Thu Dec 17 08:51:10 2009 +0200
@@ -0,0 +1,417 @@
+/*
+* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: 
+* scrdatabase.cpp
+* Implements the database handling which is mostly a replica of the SCR Data Layer API 
+* which performs all interaction with the underlying database.
+*
+*/
+
+
+/**
+ @file
+ @internalComponent
+ @released
+*/
+
+#include "dbprocessor.h"
+#include "exception.h"
+#include "logs.h"
+#include "util.h"
+#include "symbiantypes.h"
+
+#include <string>
+#include <cassert>
+
+TDbLibrary* iLibraryHandler = NULL;
+
+TDbLibrary::TDbLibrary(const std::string& aDllPath)
+	{
+	LoadSqlLibrary(aDllPath);
+	LoadFunctions();
+	}
+
+/** 
+* Failing to unload the library is not really a critical failure, when a dll is unloaded the 
+* current process sends a notification to the dll to detach itself from the process, which 
+* means the dll can process memory cleanup operations before it unloads. The only case where 
+* freelibrary might throw an error is if the library was not loaded in the first place, an 
+* error which would be caught beforehand. Hence if the library cannot be unloaded corresponding 
+* error message is logged.
+*/
+TDbLibrary::~TDbLibrary()
+	{
+	int retCode = FreeLibrary(sqLiteHndl);
+	if(retCode == 0)
+		{
+		LPCVOID lpMsgBuf;
+		
+		DWORD err = GetLastError();
+		FormatMessage	(	FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
+							FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err,
+							MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf,
+							0, NULL 
+						);
+		std::wstring wErrMsg((wchar_t*)lpMsgBuf);
+		std::string errMsg = Util::wstring2string(wErrMsg);
+		//LOGERROR(errMsg);
+		
+		}
+	}
+
+void TDbLibrary::LoadSqlLibrary(const std::string& aDllPath)
+	{
+	sqLiteHndl = LoadLibraryA(aDllPath.c_str());
+ 
+	// Check to see if the library was loaded successfully 
+
+	if (sqLiteHndl != 0)
+		{
+		//LOGINFO("Library successfully loaded!");
+		}
+	else
+		{
+		std::string errMsg("Failed to load SQLite library - ");
+		errMsg.append(aDllPath);
+		//LOGERROR(errMsg);
+		throw CException(errMsg,ExceptionCodes::ELibraryLoadError);
+		}
+	}
+
+void TDbLibrary::LoadFunctions()
+	{
+	sqlite3_open = (FnPtr_sqlite3_open)GetProcAddress(sqLiteHndl,"sqlite3_open");
+	VerifyLoadedFunction(sqlite3_open);
+	
+	sqlite3_prepare_v2	= (FnPtr_sqlite3_prepare_v2) GetProcAddress(sqLiteHndl,"sqlite3_prepare_v2");	
+	VerifyLoadedFunction(sqlite3_prepare_v2);
+	
+	sqlite3_step		= (FnPtr_sqlite3_step) GetProcAddress(sqLiteHndl,"sqlite3_step");
+	VerifyLoadedFunction(sqlite3_step);
+	
+	sqlite3_finalize	= (FnPtr_sqlite3_finalize) GetProcAddress(sqLiteHndl,"sqlite3_finalize");
+	VerifyLoadedFunction(sqlite3_finalize);
+	
+	sqlite3_bind_text	= (FnPtr_sqlite3_bind_text) GetProcAddress(sqLiteHndl,"sqlite3_bind_text");
+	VerifyLoadedFunction(sqlite3_bind_text);
+	
+	sqlite3_bind_text16 = (FnPtr_sqlite3_bind_text16) GetProcAddress(sqLiteHndl,"sqlite3_bind_text16");
+	VerifyLoadedFunction(sqlite3_bind_text16);
+	
+	sqlite3_bind_int	= (FnPtr_sqlite3_bind_int) GetProcAddress(sqLiteHndl,"sqlite3_bind_int");
+	VerifyLoadedFunction(sqlite3_bind_int);
+	
+	sqlite3_reset		= (FnPtr_sqlite3_reset) GetProcAddress(sqLiteHndl,"sqlite3_reset");
+	VerifyLoadedFunction(sqlite3_reset);
+	
+	sqlite3_clear_bindings		= (FnPtr_sqlite3_clear_bindings) GetProcAddress(sqLiteHndl,"sqlite3_clear_bindings");
+	VerifyLoadedFunction(sqlite3_clear_bindings);
+	
+	sqlite3_last_insert_rowid	= (FnPtr_sqlite3_last_insert_rowid) GetProcAddress(sqLiteHndl,"sqlite3_last_insert_rowid");
+	VerifyLoadedFunction(sqlite3_last_insert_rowid);
+	
+	sqlite3_extended_result_codes = (FnPtr_sqlite3_extended_result_codes) GetProcAddress(sqLiteHndl, "sqlite3_extended_result_codes" );
+	VerifyLoadedFunction(sqlite3_extended_result_codes);
+	
+	sqlite3_close			= (FnPtr_sqlite3_close)GetProcAddress(sqLiteHndl,"sqlite3_close");
+	VerifyLoadedFunction(sqlite3_close);
+	
+	sqlite3_errmsg			= (FnPtr_sqlite3_errmsg)GetProcAddress(sqLiteHndl,"sqlite3_errmsg");
+	VerifyLoadedFunction(sqlite3_errmsg);
+	
+	sqlite3_errcode			= (FnPtr_sqlite3_errcode)GetProcAddress(sqLiteHndl,"sqlite3_errcode");
+	VerifyLoadedFunction(sqlite3_errcode);
+	
+	sqlite3_bind_int64		= (FnPtr_sqlite3_bind_int64)GetProcAddress(sqLiteHndl,"sqlite3_bind_int64");
+	VerifyLoadedFunction(sqlite3_bind_int64);
+	
+	sqlite3_column_text16	= (FnPtr_sqlite3_column_text16)GetProcAddress(sqLiteHndl,"sqlite3_column_text16");
+	VerifyLoadedFunction(sqlite3_column_text16);
+	
+	sqlite3_column_bytes16	= (FnPtr_sqlite3_column_bytes16)GetProcAddress(sqLiteHndl,"sqlite3_column_bytes16");
+	VerifyLoadedFunction(sqlite3_column_bytes16);
+	
+	sqlite3_column_int64	= (FnPtr_sqlite3_column_int64)GetProcAddress(sqLiteHndl,"sqlite3_column_int64");
+	VerifyLoadedFunction(sqlite3_column_int64);
+	
+	sqlite3_column_int		= (FnPtr_sqlite3_column_int)GetProcAddress(sqLiteHndl,"sqlite3_column_int");
+	VerifyLoadedFunction(sqlite3_column_int);
+	
+	sqlite3_column_count	= (FnPtr_sqlite3_column_count)GetProcAddress(sqLiteHndl,"sqlite3_column_count");
+	VerifyLoadedFunction(sqlite3_column_count);
+	
+	sqlite3_column_type		= (FnPtr_sqlite3_column_type)GetProcAddress(sqLiteHndl,"sqlite3_column_type");
+	VerifyLoadedFunction(sqlite3_column_type);
+	
+	sqlite3_prepare16_v2	= (FnPtr_sqlite3_prepare16_v2)GetProcAddress(sqLiteHndl,"sqlite3_prepare16_v2");
+	VerifyLoadedFunction(sqlite3_prepare16_v2);
+
+	sqlite3_bind_blob = (FnPtr_sqlite3_bind_blob)GetProcAddress(sqLiteHndl,"sqlite3_bind_blob");
+	VerifyLoadedFunction(sqlite3_bind_blob);
+
+	}
+
+void TDbLibrary::VerifyLoadedFunction(void* aFnPtr)
+	{
+	if(aFnPtr != NULL)
+		return;
+
+	LPCVOID lpMsgBuf;
+		
+	DWORD err = GetLastError();
+	FormatMessage	(	FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
+						FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err,
+						MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf,
+						0, NULL 
+					);
+	std::wstring wErrMsg((wchar_t*)lpMsgBuf);
+	std::string errMsg = Util::wstring2string(wErrMsg);
+	//LOGERROR(errMsg);
+	throw CException(errMsg,ExceptionCodes::ELibraryLoadError);
+	}
+
+
+//
+// CDbProcessor
+// 
+
+// Constructor
+CDbProcessor::CDbProcessor(const std::string& aDllPath, const std::string& aDbName )
+	:iLibraryHandler(aDllPath)
+	{
+	
+	// Then open the SCR database
+	TInt err = iLibraryHandler.sqlite3_open(aDbName.c_str(), &iDbHandle);
+	
+	// Check the returned error code
+	CheckSqlErrCode(err);
+	// If comes here, means the database file has been opened successfully
+	// Now, enable the extended result codes feature of SQLite. In SQLite, this feature is 
+	// disabled by default for historical compatibility.
+	err = iLibraryHandler.sqlite3_extended_result_codes(iDbHandle, 0);
+	// Check the returned error code
+	CheckSqlErrCode(err,"Failed to activate the extended error mechanism.");
+	}
+
+// Destructor
+CDbProcessor::~CDbProcessor()
+	{
+	//LOGINFO("Closing the SCR database connection.");
+
+	// Close the db handle
+	TInt err = iLibraryHandler.sqlite3_close(iDbHandle);
+	
+	if(err != SQLITE_OK)
+		{
+		std::string errMsg("Failed to close the database handle.");
+		//LOGERROR(errMsg);
+		}
+	}
+
+
+CStatement* CDbProcessor::PrepareStatement(const std::string& aStatementStr)
+	{
+	// For statements which start with the SELECT key word, this function creates an sql statement  
+	// object and returns it.
+	sqlite3_stmt* stmtHandle = NULL; // Temporary statement handle
+	const char* stmtTail = NULL;	 // Pointer to unused portion of Sql statement.                         
+	TInt err = iLibraryHandler.sqlite3_prepare_v2(iDbHandle, aStatementStr.c_str(), aStatementStr.size(), &stmtHandle, &stmtTail);
+	
+	// Check the returned error code
+	CheckSqlErrCode(err);
+	// Since we expect single statement, stmtTail pointer should be NULL or point to zero.
+	if(stmtTail && stmtTail[0] != 0)
+		{
+		err = iLibraryHandler.sqlite3_finalize(stmtHandle);
+		std::string errMessage = "There is a problem with the provided SQL statement. It may contain more \
+								than one statement. Or It may not be terminated with semicolon. \
+								Or It may contain a space or invalid char after semicolon.";
+		//LOGERROR(errMessage);
+		CheckSqlErrCode(err,errMessage);
+		}
+	// stmtHandle can be NULL for statements like this: ";"
+	if(!stmtHandle)
+		{
+		throw CException(ExceptionCodes::ESqlArgumentError);
+		}
+
+	std::string str = "Query:";
+	//LOGINFO(str+aStatementStr);
+	// The statement object which carries handle to the result set of the sql statement
+	CStatement* stmtObj = new CStatement(stmtHandle,iLibraryHandler,*iDbHandle); 
+	
+	return stmtObj;	
+	}
+
+
+TInt64 CDbProcessor::LastInsertedId()
+	{
+	TInt retVal = (TInt)iLibraryHandler.sqlite3_last_insert_rowid(iDbHandle); 
+	// it is now expected that row ids in scr will require 64-bit storage, so cast the return value to TInt
+	if(retVal <= 0)
+		{
+		throw CException(ExceptionCodes::ESqlNotFoundError);
+		}
+	return retVal;
+	}
+
+void CDbProcessor::CheckSqlErrCode(TInt aErrorCode, std::string& aErrorMessage ) 
+	{
+	if(aErrorCode != SQLITE_OK)
+		{
+		TInt errorCode = iLibraryHandler.sqlite3_errcode(iDbHandle);
+		//LOGERROR(aErrorMessage);
+		throw CException(aErrorMessage,aErrorCode);
+		}
+	}
+
+void CDbProcessor::CheckSqlErrCode(TInt aErrorCode) 
+	{
+
+	if(aErrorCode != SQLITE_OK)
+		{
+		TInt errorCode = iLibraryHandler.sqlite3_errcode(iDbHandle);
+		const char* errMsg = iLibraryHandler.sqlite3_errmsg(iDbHandle);
+		CheckSqlErrCode(errorCode,errMsg);
+		}
+	}
+
+void CDbProcessor::CheckSqlErrCode(TInt aErrorCode, const char* aErrorMessage ) 
+	{
+	std::string errMsg(aErrorMessage);
+	CheckSqlErrCode(aErrorCode,errMsg);
+	}
+
+//
+// CStatement
+//
+
+// Constructor
+CStatement::CStatement(sqlite3_stmt* aStmtHandle, const TDbLibrary& aLibraryHandler , sqlite3& aDbHandle)
+	:iStmtHandle(aStmtHandle),
+	iLibraryHandler(aLibraryHandler),
+	iDbHandle(aDbHandle)
+	{
+	// Make sure that the statement handle is never NULL.
+	assert(iStmtHandle != NULL);
+	}
+
+// Destructor
+CStatement::~CStatement()
+	{
+	TInt err = iLibraryHandler.sqlite3_finalize(iStmtHandle);
+	if(SQLITE_OK != err)
+		{
+		std::string errMsg = "Failed to finalize the statement object.";
+		//LOGERROR(errMsg);
+		throw CException(errMsg,err);
+		}
+	}
+
+void CStatement::ExecuteStatement()
+	{
+	// If the statement doesn't return any result table, it should normally be executed
+	// with sqlite3_exec. However, sqlite does not have a 16-bit version of sqlite3_exec.  
+	// Therefore, the execution is made with PrepareStatementLC and ProcessNextRowL functions.
+	//LOGINFO("Executing the prepared SCR SQL statement.");
+	
+	// Now, execute and check if the function has completed successfully by calling ProcessNextRowL.
+	// If the function has failed, ProcessNextRowL will leave with one of the system wide error codes.
+	while(ProcessNextRow())
+		{}
+	}
+
+
+bool CStatement::ProcessNextRow()
+	{
+	TInt err = iLibraryHandler.sqlite3_step(iStmtHandle);
+	
+	switch(err)
+		{
+	case SQLITE_ROW: // A new row of data is ready for processing.
+		return true;
+	
+	case SQLITE_DONE: // The statement has finished executing successfully.
+		return false;
+	default:		 
+		CheckSqlErrCode(err);
+		}// End of switch
+	return false;
+	}
+
+void CStatement::BindInt(TInt aParameterIndex, TInt aParameterValue)
+	{
+	TInt err = iLibraryHandler.sqlite3_bind_int(iStmtHandle, aParameterIndex, aParameterValue);
+	CheckSqlErrCode(err);
+	}
+
+void CStatement::BindInt64(TInt aParameterIndex, TInt64 aParameterValue)
+	{
+	TInt err = iLibraryHandler.sqlite3_bind_int64(iStmtHandle, aParameterIndex, aParameterValue);
+	CheckSqlErrCode(err);
+	}
+
+void CStatement::BindStr(TInt aParameterIndex, const std::wstring &aParameterStr)
+	{
+	TInt err = iLibraryHandler.sqlite3_bind_text16(iStmtHandle, aParameterIndex, aParameterStr.c_str(), aParameterStr.size()*2, SQLITE_TRANSIENT);
+	// The fifth argument has the value SQLITE_TRANSIENT, it means that SQLite makes its own private copy of the data immediately
+	CheckSqlErrCode(err);
+	}
+
+void CStatement::BindBinary(TInt aParameterIndex, const std::string &aParameterStr)
+	{
+	TInt err = iLibraryHandler.sqlite3_bind_blob(iStmtHandle, aParameterIndex, aParameterStr.c_str(), aParameterStr.size(), SQLITE_TRANSIENT);
+	// The fifth argument has the value SQLITE_TRANSIENT, it means that SQLite makes its own private copy of the data immediately
+	CheckSqlErrCode(err);
+	}
+
+void CStatement::Reset()
+	{
+	TInt err = iLibraryHandler.sqlite3_reset(iStmtHandle);
+	CheckSqlErrCode(err);
+	err = iLibraryHandler.sqlite3_clear_bindings(iStmtHandle);
+	CheckSqlErrCode(err);
+	}
+
+void CStatement::CheckSqlErrCode(TInt aErrorCode) 
+	{
+	
+	if(aErrorCode != SQLITE_OK)
+		{
+		TInt errorCode = iLibraryHandler.sqlite3_errcode(&iDbHandle);
+		const char* errMsg = iLibraryHandler.sqlite3_errmsg(&iDbHandle);
+		std::string errStr(errMsg);
+		//LOGERROR(errStr);
+		throw CException(errStr,errorCode);
+		}
+	}
+
+int CStatement::IntColumn(int aColumnId ) const
+	{
+	return iLibraryHandler.sqlite3_column_int(iStmtHandle, aColumnId);
+	}
+
+std::wstring CStatement::StrColumn(int aColumnId ) const
+	{
+	std::wstring columnValue(static_cast<const wchar_t*>(iLibraryHandler.sqlite3_column_text16(iStmtHandle, aColumnId)));
+	return columnValue;
+	}
+
+TInt64 CStatement::Int64Column(int aColumnId ) const
+	{
+	return iLibraryHandler.sqlite3_column_int64(iStmtHandle, aColumnId);
+	}
+
+
+