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 { |
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); |