secureswitools/swisistools/source/dbmanager/dbprocessor.cpp
branchRCL_3
changeset 25 7333d7932ef7
parent 0 ba25891c3a9e
child 26 8b7f4e561641
equal deleted inserted replaced
24:5cc91383ab1e 25:7333d7932ef7
     1 /*
     1 /*
     2 * Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 * Copyright (c) 2008-2010 Nokia Corporation and/or its subsidiary(-ies).
     3 * All rights reserved.
     3 * All rights reserved.
     4 * This component and the accompanying materials are made available
     4 * This component and the accompanying materials are made available
     5 * under the terms of the License "Eclipse Public License v1.0"
     5 * under the terms of the License "Eclipse Public License v1.0"
     6 * which accompanies this distribution, and is available
     6 * which accompanies this distribution, and is available
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
    28 #include "dbprocessor.h"
    28 #include "dbprocessor.h"
    29 #include "exception.h"
    29 #include "exception.h"
    30 #include "logs.h"
    30 #include "logs.h"
    31 #include "util.h"
    31 #include "util.h"
    32 #include "symbiantypes.h"
    32 #include "symbiantypes.h"
    33 
    33 #include "utf8_wrapper.h"
       
    34 #include "../sisxlibrary/utility.h"
    34 #include <string>
    35 #include <string>
    35 #include <cassert>
    36 #include <cassert>
       
    37 
       
    38 #ifdef __linux__
       
    39 #include <dlfcn.h>
       
    40 
       
    41 
       
    42 void* GetProcAddress(HINSTANCE aHandle, const char* aSymbol)
       
    43 	{
       
    44 	return dlsym(aHandle, aSymbol);
       
    45 	}
       
    46 
       
    47 HINSTANCE LoadLibraryA(const char* aLibraryName)
       
    48 	{
       
    49 	HINSTANCE handleUsingDefaultSearchPath = dlopen(aLibraryName, RTLD_LAZY);
       
    50 
       
    51 	if( handleUsingDefaultSearchPath == NULL )
       
    52 	{
       
    53 		// Once the dlopen() fails by not finding the aLibraryName in the default
       
    54 		// path specified by LD_LIBRARY_PATH, we will look in the epoc32/tools 
       
    55 		// path as the second option.
       
    56 
       
    57 		const char* epocRoot = getenv("EPOCROOT");		
       
    58 		if(NULL == epocRoot)
       
    59 			{
       
    60 			throw CException("EPOCROOT environment variable not specified.", ExceptionCodes::EEnvNotSpecified);
       
    61 			}
       
    62 		std::string epocRootStr(epocRoot); 
       
    63 
       
    64 		std::string absPathToLibrary = epocRootStr + std::string("epoc32/tools/") + std::string(aLibraryName);
       
    65 		HINSTANCE handleUsingAbsSearchPath = dlopen(absPathToLibrary.c_str(), RTLD_LAZY);
       
    66 
       
    67 		return handleUsingAbsSearchPath;
       
    68 	}
       
    69 
       
    70 	return handleUsingDefaultSearchPath;
       
    71 	}
       
    72 
       
    73 int FreeLibrary(HINSTANCE aHandle)
       
    74 	{
       
    75 	// FreeLibrary returns non-zero value on success whereas
       
    76 	// dlcose returns zero on success.
       
    77 	return (dlclose(aHandle) == 0)? true: false;
       
    78 	}
       
    79 
       
    80 std::string GetErrorMessage()
       
    81 	{
       
    82 	return dlerror();
       
    83 	}
       
    84 
       
    85 static utf16WString utf32WString2utf16WString(std::wstring& aParameter)
       
    86 {
       
    87 	int strLen = aParameter.length();
       
    88 	const wchar_t * source = aParameter.c_str();
       
    89 	unsigned short int* buffer = new unsigned short int[(strLen + 1) * 2];
       
    90 
       
    91 	// Using a temp variable in place of buffer as ConvertUTF32toUTF16 modifies the source pointer passed.
       
    92 	unsigned short int* temp = buffer;
       
    93 
       
    94 	ConvertUTF32toUTF16(&source, source + strLen, &temp,  temp + strLen, lenientConversion);
       
    95 
       
    96 	// Appending NUL to the converted buffer.
       
    97 	*temp = 0;
       
    98 
       
    99 	utf16WString utf16Ws;
       
   100 	utf16Ws.resize(strLen);
       
   101 
       
   102 	// The built-in basic_string template class copy operation
       
   103 	// truncates when a NUL is encountered when a c_str() is
       
   104 	// used to construct the required string.
       
   105 	// So, if aParameter is any hashable string having the
       
   106 	// syntax : swtypeName + L'\0' + someId then, we will end
       
   107 	// up returning only part of the converted UTF-16 string.
       
   108 	// Hence, we resort to the explicit copy operation with
       
   109 	// two bytes at a time.
       
   110 	while( strLen-- )
       
   111 	{
       
   112 		utf16Ws[ strLen ] = buffer[ strLen ];
       
   113 	}
       
   114 
       
   115 	delete[] buffer;
       
   116 
       
   117 	return utf16Ws;
       
   118 }
       
   119 
       
   120 static std::wstring utf16WString2utf32WString(utf16WString& aParameter)
       
   121 {	
       
   122 	int strLen = aParameter.length();
       
   123 	const unsigned short int* source = aParameter.c_str();
       
   124 	wchar_t* buffer = new wchar_t[ strLen + 1 ];
       
   125 
       
   126 	// Using a temp variable in place of buffer as ConvertUTF16toUCS4 modifies the source pointer passed.
       
   127 	wchar_t* temp = buffer;
       
   128 
       
   129 	ConvertUTF16toUCS4(&source, source + strLen, &temp, temp + strLen);
       
   130 
       
   131 	// Appending NUL to the converted buffer.
       
   132 	*temp = 0;
       
   133 
       
   134 	std::wstring utf32Ws(buffer);
       
   135 
       
   136 	delete[] buffer;
       
   137 
       
   138 	return utf32Ws;
       
   139 }
       
   140 
       
   141 #else
       
   142 std::string GetErrorMessage()
       
   143 	{
       
   144 	LPCVOID lpMsgBuf;
       
   145 		
       
   146 	DWORD err = GetLastError();
       
   147 	FormatMessage	(	FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
       
   148 						FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err,
       
   149 						MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf,
       
   150 						0, NULL 
       
   151 					);
       
   152 	std::wstring wErrMsg((wchar_t*)lpMsgBuf);
       
   153 	return wstring2string(wErrMsg);
       
   154 	}
       
   155 #endif // __linux__
    36 
   156 
    37 TDbLibrary* iLibraryHandler = NULL;
   157 TDbLibrary* iLibraryHandler = NULL;
    38 
   158 
    39 TDbLibrary::TDbLibrary(const std::string& aDllPath)
   159 TDbLibrary::TDbLibrary(const std::string& aDllPath)
    40 	{
   160 	{
    53 TDbLibrary::~TDbLibrary()
   173 TDbLibrary::~TDbLibrary()
    54 	{
   174 	{
    55 	int retCode = FreeLibrary(sqLiteHndl);
   175 	int retCode = FreeLibrary(sqLiteHndl);
    56 	if(retCode == 0)
   176 	if(retCode == 0)
    57 		{
   177 		{
    58 		LPCVOID lpMsgBuf;
   178 		//LOGERROR(GetErrorMessage());
    59 		
       
    60 		DWORD err = GetLastError();
       
    61 		FormatMessage	(	FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
       
    62 							FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err,
       
    63 							MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf,
       
    64 							0, NULL 
       
    65 						);
       
    66 		std::wstring wErrMsg((wchar_t*)lpMsgBuf);
       
    67 		std::string errMsg = Util::wstring2string(wErrMsg);
       
    68 		//LOGERROR(errMsg);
       
    69 		
       
    70 		}
   179 		}
    71 	}
   180 	}
    72 
   181 
    73 void TDbLibrary::LoadSqlLibrary(const std::string& aDllPath)
   182 void TDbLibrary::LoadSqlLibrary(const std::string& aDllPath)
    74 	{
   183 	{
   165 void TDbLibrary::VerifyLoadedFunction(void* aFnPtr)
   274 void TDbLibrary::VerifyLoadedFunction(void* aFnPtr)
   166 	{
   275 	{
   167 	if(aFnPtr != NULL)
   276 	if(aFnPtr != NULL)
   168 		return;
   277 		return;
   169 
   278 
   170 	LPCVOID lpMsgBuf;
   279 	std::string errMsg = GetErrorMessage();
   171 		
       
   172 	DWORD err = GetLastError();
       
   173 	FormatMessage	(	FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
       
   174 						FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err,
       
   175 						MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf,
       
   176 						0, NULL 
       
   177 					);
       
   178 	std::wstring wErrMsg((wchar_t*)lpMsgBuf);
       
   179 	std::string errMsg = Util::wstring2string(wErrMsg);
       
   180 	//LOGERROR(errMsg);
   280 	//LOGERROR(errMsg);
   181 	throw CException(errMsg,ExceptionCodes::ELibraryLoadError);
   281 	throw CException(errMsg,ExceptionCodes::ELibraryLoadError);
   182 	}
   282 	}
   183 
   283 
   184 
   284 
   360 	{
   460 	{
   361 	TInt err = iLibraryHandler.sqlite3_bind_int64(iStmtHandle, aParameterIndex, aParameterValue);
   461 	TInt err = iLibraryHandler.sqlite3_bind_int64(iStmtHandle, aParameterIndex, aParameterValue);
   362 	CheckSqlErrCode(err);
   462 	CheckSqlErrCode(err);
   363 	}
   463 	}
   364 
   464 
       
   465 
       
   466 #ifdef __TOOLS2_LINUX__
       
   467 void CStatement::BindStr(TInt aParameterIndex, const std::wstring &aParameterStr, int aConvertSlash=allowSlashConversion)
       
   468 #else
   365 void CStatement::BindStr(TInt aParameterIndex, const std::wstring &aParameterStr)
   469 void CStatement::BindStr(TInt aParameterIndex, const std::wstring &aParameterStr)
   366 	{
   470 #endif
       
   471 	{
       
   472 	/*
       
   473 	 * Under LINUX : Because of the UTF-32 format of wstring, we can't directly use the sqlite3_bind_text16() which
       
   474 	 * requires UTF-16 format. So, we convert the UTF-32 data into UTF-16 before using it.
       
   475 	 *
       
   476 	 * Under WINDOWS : No conversion required since wstring will be in UTF-16 format itself.
       
   477 	 */
       
   478 
       
   479     #ifdef __LINUX__
       
   480 	// Make sure that the wstring passed to this function is not having any trailing
       
   481 	// explicit NUL( Preferably, pass c_str() part of wstring ).
       
   482     //
       
   483 	// Only case in which you shouldn't pass c_str() is that the wstring has NUL as
       
   484 	// part of its actual string content(like swtypename + L'\0' + someID etc).
       
   485 
       
   486 	// In order to maintain the consistency of DB contents across the WINDOWS and LINUX platforms, before interacting
       
   487 	// with the DB we convert the local paths into WINDOWS specific paths.
       
   488     //
       
   489 	// If aParameterStr is not a PATH but contains a forward slash, we should restrain 
       
   490 	// from the slash conversion. One such instance is MimeType.
       
   491 	//
       
   492 	std::wstring temp = aParameterStr;
       
   493 	if( aConvertSlash == allowSlashConversion )
       
   494 	{
       
   495 	    ConvertToWindowsSpecificPaths(temp);
       
   496 	}
       
   497 
       
   498     utf16WString utf16s = utf32WString2utf16WString(temp);
       
   499 
       
   500 	TInt err = iLibraryHandler.sqlite3_bind_text16(iStmtHandle, aParameterIndex, utf16s.c_str(), aParameterStr.size()*2, SQLITE_TRANSIENT);
       
   501 
       
   502     #else
   367 	TInt err = iLibraryHandler.sqlite3_bind_text16(iStmtHandle, aParameterIndex, aParameterStr.c_str(), aParameterStr.size()*2, SQLITE_TRANSIENT);
   503 	TInt err = iLibraryHandler.sqlite3_bind_text16(iStmtHandle, aParameterIndex, aParameterStr.c_str(), aParameterStr.size()*2, SQLITE_TRANSIENT);
       
   504 	#endif
   368 	// The fifth argument has the value SQLITE_TRANSIENT, it means that SQLite makes its own private copy of the data immediately
   505 	// The fifth argument has the value SQLITE_TRANSIENT, it means that SQLite makes its own private copy of the data immediately
   369 	CheckSqlErrCode(err);
   506 	CheckSqlErrCode(err);
   370 	}
   507 	}
   371 
   508 
   372 void CStatement::BindBinary(TInt aParameterIndex, const std::string &aParameterStr)
   509 void CStatement::BindBinary(TInt aParameterIndex, const std::string &aParameterStr)
   373 	{
   510 	{
   374 	TInt err = iLibraryHandler.sqlite3_bind_blob(iStmtHandle, aParameterIndex, aParameterStr.c_str(), aParameterStr.size(), SQLITE_TRANSIENT);
   511 	TInt err = iLibraryHandler.sqlite3_bind_blob(iStmtHandle, aParameterIndex, aParameterStr.c_str(), aParameterStr.size(), SQLITE_TRANSIENT);
       
   512 	// The fifth argument has the value SQLITE_TRANSIENT, it means that SQLite makes its own private copy of the data immediately
       
   513 	CheckSqlErrCode(err);
       
   514 	}
       
   515 
       
   516 void CStatement::BindBinary(TInt aParameterIndex, const std::wstring &aParameterStr)
       
   517 	{
       
   518 	#ifdef __LINUX__
       
   519 	// To maintain consistency of the binary equivalent of the wstring
       
   520 	// being binded, we convert the wstring with UTF-32 encoding under LINUX
       
   521 	// to UTF-16 encoding which is same as that of wstring under WINDOWS.
       
   522 	
       
   523 	std::wstring temp = aParameterStr;
       
   524 	utf16WString utf16s = utf32WString2utf16WString(temp);
       
   525 
       
   526 	TInt err = iLibraryHandler.sqlite3_bind_blob(iStmtHandle, aParameterIndex, utf16s.c_str(), aParameterStr.size()*2, SQLITE_TRANSIENT);
       
   527 	#else
       
   528 	TInt err = iLibraryHandler.sqlite3_bind_blob(iStmtHandle, aParameterIndex, aParameterStr.c_str(), aParameterStr.size()*2, SQLITE_TRANSIENT);
       
   529 	#endif
       
   530 
   375 	// The fifth argument has the value SQLITE_TRANSIENT, it means that SQLite makes its own private copy of the data immediately
   531 	// The fifth argument has the value SQLITE_TRANSIENT, it means that SQLite makes its own private copy of the data immediately
   376 	CheckSqlErrCode(err);
   532 	CheckSqlErrCode(err);
   377 	}
   533 	}
   378 
   534 
   379 void CStatement::Reset()
   535 void CStatement::Reset()
   402 	return iLibraryHandler.sqlite3_column_int(iStmtHandle, aColumnId);
   558 	return iLibraryHandler.sqlite3_column_int(iStmtHandle, aColumnId);
   403 	}
   559 	}
   404 
   560 
   405 std::wstring CStatement::StrColumn(int aColumnId ) const
   561 std::wstring CStatement::StrColumn(int aColumnId ) const
   406 	{
   562 	{
   407 	std::wstring columnValue(static_cast<const wchar_t*>(iLibraryHandler.sqlite3_column_text16(iStmtHandle, aColumnId)));
   563 	/*
   408 	return columnValue;
   564 	 * Under LINUX : While writing onto DB, we bind the wstring after converting it into UTF-16 from
       
   565 	 * UTF-32 format. So, now while reading we need to convert the UTF-16 data back to UTF-32
       
   566 	 * format so that we can return the required UTF-32 wstring.
       
   567 	 *
       
   568 	 * Under WINDOWS : No conversion required since wstring will be in UTF-16 format itself.
       
   569 	 */
       
   570 	#ifdef __LINUX__
       
   571 
       
   572 	utf16WString utf16S = iLibraryHandler.sqlite3_column_text16(iStmtHandle, aColumnId);
       
   573 	std::wstring utf32S = utf16WString2utf32WString(utf16S);
       
   574 
       
   575 	// The DB will have WINDOWS specific paths to maintain the consistency of DB contents across WINDOWS and LINUX platforms.
       
   576 	// So, after reading under LINUX we will convert them into local paths.
       
   577 
       
   578     ConvertToLinuxSpecificPaths(utf32S);
       
   579 
       
   580 	#else
       
   581 	std::wstring utf32S(static_cast<const wchar_t*>(iLibraryHandler.sqlite3_column_text16(iStmtHandle, aColumnId)));
       
   582 	#endif
       
   583 
       
   584 	return utf32S;
   409 	}
   585 	}
   410 
   586 
   411 TInt64 CStatement::Int64Column(int aColumnId ) const
   587 TInt64 CStatement::Int64Column(int aColumnId ) const
   412 	{
   588 	{
   413 	return iLibraryHandler.sqlite3_column_int64(iStmtHandle, aColumnId);
   589 	return iLibraryHandler.sqlite3_column_int64(iStmtHandle, aColumnId);