sync with tizen_2.0
[platform/framework/native/appfw.git] / src / io / FIo_DatabaseImpl.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17
18 /**
19  * @file        FIo_DatabaseImpl.cpp
20  * @brief       This is the implementation file for _DatabaseImpl class.
21  */
22
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <unistd.h>
26 #include <semaphore.h>
27 #include <fcntl.h>
28 #include <limits.h>
29 #include <errno.h>
30 #include <new>
31 #include <unique_ptr.h>
32 #include <sqlite3.h>
33 #include <dlfcn.h>
34
35 #include <FBaseResult.h>
36 #include <FBaseSysLog.h>
37 #include <FIoFile.h>
38 #include <FIoDirectory.h>
39 #include <FIoDbTypes.h>
40 #include <FIoDatabase.h>
41 #include <FIoDbStatement.h>
42 #include <FIoDbEnumerator.h>
43 #include <FSysSystemInfo.h>
44
45 #include <FBase_StringConverter.h>
46 #include <FBaseUtilStringUtil.h>
47 #include <FBase_NativeError.h>
48 #include <FApp_AppInfo.h>
49 #include <FIo_FileImpl.h>
50 #include <FIo_DatabaseImpl.h>
51 #include <FIo_DbStatementImpl.h>
52 #include <FIo_DbEnumeratorImpl.h>
53 #include <FIo_DbContextImpl.h>
54 #include <FIo_SecureIoUtil.h>
55 #include <FIo_IDbUserListener.h>
56
57 using namespace std;
58 using namespace Tizen::Base;
59 using namespace Tizen::App;
60 using namespace Tizen::Base::Runtime;
61 using namespace Tizen::Base::Utility;
62 using namespace Tizen::System;
63
64 namespace Tizen { namespace Io
65 {
66
67 // maximum argument count that can be passed to register user defined functions
68 const int MAX_FUNCTION_ARGUMENT_COUNT = 127;
69 const int MAX_UTF8_BYTES = 255;         // maximum length of UTF8 bytes
70 const int MAX_MUTEX_NAME_LENGTH = 32;   // maximum length of mutex name
71 const int MAX_DATABASE_AES_KEY_LENGTH = 16;     //default key size for AES 128
72 const int MAX_DATABASE_SQL_LENGTH = 4096;       //buffer length required to make sql query
73 const int MAX_SQLCIPHER_SCHEMA_PREFIX_SIZE = 13;//size of sqlCipher_ schema prefix name.
74
75 static const size_t _MAX_DB_OPENMODE_LENGTH = 2;
76 static const char _DATABASE_LIBRARY_PATH[] = "/usr/lib/libsqlite3.so.0";
77 static const char _DATABASE_ENCRYPTION_SYMBOL[] = "sqlite3_key";
78
79 _DatabaseImpl::_DatabaseImpl(void)
80         : __pDatabase(null)
81         , __transactionGoingOn(false)
82 {
83 }
84
85 _DatabaseImpl::~_DatabaseImpl(void)
86 {
87         result r = E_SUCCESS;
88         sqlite3_stmt* pSqlStmt = null;
89
90         if (__pDatabase)
91         {
92                 pSqlStmt = sqlite3_next_stmt((sqlite3*) __pDatabase, 0);
93                 while (pSqlStmt != null)
94                 {
95                         sqlite3_finalize(pSqlStmt);
96                         pSqlStmt = sqlite3_next_stmt((sqlite3*) __pDatabase, 0);
97                 }
98
99                 int ret = sqlite3_close((sqlite3*) __pDatabase);
100                 if (ret != SQLITE_OK)
101                 {
102                         r = __ConvertNativeSqliteErrorToResult(ret);
103                         SysLog(NID_IO, "[%s] ERROR Message: [%s], Failed to close database.", GetErrorMessage(r),
104                                                 sqlite3_errmsg((sqlite3*) __pDatabase));
105                 }
106                 else
107                 {
108                         __pDatabase = null;
109                         __transactionGoingOn = false;
110                 }
111         }
112
113         // release user context info
114         __userFunctionContextList.RemoveAll(true);
115         __userCollationContextList.RemoveAll(true);
116
117 }
118
119 bool
120 _DatabaseImpl::IsDirectory(const String& databasePath)
121 {
122         FileAttributes attr;
123         result r = E_SUCCESS;
124
125         SysTryReturnResult(NID_IO, _FileImpl::VerifyFilePathCompatibility(databasePath, _AppInfo::IsOspCompat()) == true,
126                         E_INVALID_ARG, " [%ls] is not compatible.", databasePath.GetPointer());
127
128         r = _FileImpl::GetAttributes(databasePath, attr);
129         if (IsFailed(r))
130         {
131                 SetLastResult(r);
132                 return false;
133         }
134
135         SetLastResult(E_SUCCESS);
136         return attr.IsDirectory();
137 }
138
139 bool
140 _DatabaseImpl::VerifyDatabaseOpenMode(const char* pOpenMode, long& legacyMode)
141 {
142         if (pOpenMode == null)
143         {
144                 SysLog(NID_IO, "[E_INVALID_ARG] The specified openMode is null.");
145                 return false;
146         }
147
148         if (strlen(pOpenMode) > _MAX_DB_OPENMODE_LENGTH)
149         {
150                 SysLog(NID_IO, "[E_INVALID_ARG] The specified openMode (%s) is invalid.", pOpenMode);
151                 return false;
152         }
153
154         if (pOpenMode[0] == 'r')
155         {
156                 if (pOpenMode[1] == '\0')
157                 {
158                         legacyMode = DB_OPEN_READ_ONLY;
159                 }
160                 else if (pOpenMode[1] == '+')
161                 {
162                         if (pOpenMode[2] == '\0')
163                         {
164                                 legacyMode = DB_OPEN_READ_WRITE;
165                         }
166                 }
167         }
168         else if (pOpenMode[0] == 'a' && pOpenMode[1] == '+' && pOpenMode[2] == '\0')
169         {
170                 legacyMode = (DB_OPEN_CREATE | DB_OPEN_READ_WRITE);
171         }
172         else
173         {
174                 SysLog(NID_IO, "[E_INVALID_ARG] The specified openMode (%s) is invalid.", pOpenMode);
175                 return false;
176         }
177
178         return true;
179 }
180
181 result
182 _DatabaseImpl::Construct(const String& dbPath, bool createIfNotExist)
183 {
184         long openMode = DB_OPEN_READ_WRITE;
185
186         if (!_FileImpl::IsFileExist(dbPath))
187         {
188                 SysTryReturn(NID_IO, createIfNotExist == true, E_FILE_NOT_FOUND, E_FILE_NOT_FOUND,
189                                 "[E_FILE_NOT_FOUND] Database file does not exist. Create it first.");
190                 openMode = DB_OPEN_READ_WRITE | DB_OPEN_CREATE;
191         }
192
193         return Construct(dbPath, openMode, null);
194 }
195
196 result
197 _DatabaseImpl::Construct(const String& dbPath, long openMode, const ByteBuffer* pSecretKey)
198 {
199         SysAssertf(__pDatabase == null, "Already constructed. Calling Construct() twice or more on a same instance is not allowed for this class\n");
200         SysTryReturnResult(NID_IO, _FileImpl::VerifyFilePathCompatibility(dbPath, _AppInfo::IsOspCompat()) == true,
201                         E_INVALID_ARG, " [%ls] is not compatible.", dbPath.GetPointer());
202         SysTryReturnResult(NID_IO, !(pSecretKey && pSecretKey->GetRemaining() <= 0), E_INVALID_ARG,
203                         "The specified secretKey is invalid.");
204
205         result r = E_SUCCESS;
206         int ret = 0;
207         int openFlags = 0;
208         sqlite3* pDb = null;
209         bool isFilePathExist = false;
210         bool isParentDirPathExist = false;
211         int lastIndex = -1;
212         String parentDirPath;
213
214         switch (openMode)
215         {
216         case (DB_OPEN_READ_WRITE):
217                 openFlags = SQLITE_OPEN_READWRITE;
218                 break;
219
220         case (DB_OPEN_READ_ONLY):
221                 openFlags = SQLITE_OPEN_READONLY;
222                 break;
223
224         case (DB_OPEN_READ_WRITE | DB_OPEN_CREATE):
225                 openFlags = (SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE);
226                 break;
227
228         default:
229                 SysLog(NID_IO, "[E_INVALID_ARG] The specified open mode flags are invalid.");
230                 return E_INVALID_ARG;
231         }
232
233         // extract directory path from a given Db file path
234         // Find index of last occurrence  of character '/' in dbPath
235         r = dbPath.LastIndexOf(L'/', dbPath.GetLength() - 1, lastIndex);
236         SysTryReturnResult(NID_IO, !IsFailed(r),
237                 E_INVALID_ARG, "Missing directory path. SHOULD not happen.");
238
239         // extract directory path from dbPath starting from index 0 to lastIndex.
240         r = dbPath.SubString(0, lastIndex, parentDirPath);
241         SysTryReturnResult(NID_IO, !IsFailed(r),
242                 E_INVALID_ARG, "Missing directory path. SHOULD not happen.");
243
244         // TODO: Test sqlite3_open_v3() without parent directory.
245         //check existence of parent directory
246         isParentDirPathExist = _FileImpl::IsFileExist(String(parentDirPath));
247         SysTryReturnResult(NID_IO, isParentDirPathExist == true, E_INVALID_ARG,
248                            "Parent Directory does not exist.");
249
250         unique_ptr<char[]> pDbPath(_StringConverter::CopyToCharArrayN(dbPath));
251         r = GetLastResult();
252         SysTryCatch(NID_IO, pDbPath, , r, "[%s] pDbPath is null.", GetErrorMessage(r));
253
254         // check existence of file
255         isFilePathExist = _FileImpl::IsFileExist(dbPath);
256         if (isFilePathExist == true)
257         {
258                 if (openMode == (DB_OPEN_READ_WRITE | DB_OPEN_CREATE))
259                 {
260                         SysLog(NID_IO, "[E_FILE_ALREADY_EXIST] File already exists.");
261                         r = E_FILE_ALREADY_EXIST;
262                         goto CATCH;
263                 }
264
265                 //check if it is a directory
266                 if (IsDirectory(dbPath))
267                 {
268                         SysLog(NID_IO, "[E_DATABASE] Given path is not a File.");
269                         r = E_DATABASE;
270                         goto CATCH;
271                 }
272
273 #if 0
274                 _DatabaseMode dbMode = DATABASE_MODE_NONE;
275                 dbMode = _SecureIoUtil::GetDatabaseMode(pDbPath.get());
276                 SysTryCatch(NID_IO, dbMode != DATABASE_MODE_ERROR, r = E_IO, E_IO, "[E_IO] GetDatabaseMode function failed.");
277
278                 if (pSecretKey && _SecureIoUtil::IsNormalDatabase(dbMode))
279                 {
280                         SysTryCatch(NID_IO, false, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] Trying to open a normal database in secure mode.");
281                 }
282                 else if (!pSecretKey && _SecureIoUtil::IsSecureDatabase(dbMode))
283                 {
284                         SysTryCatch(NID_IO, false, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] Trying to open a secure database in normal mode.");
285                 }
286                 else
287                 {
288                         //Do Nothing
289                 }
290 #endif
291         }
292         else
293         {
294                 if (openMode == DB_OPEN_READ_WRITE || openMode == DB_OPEN_READ_ONLY)
295                 {
296                         SysLog(NID_IO, "[E_FILE_NOT_FOUND] File not found when opened in DB_OPEN_READ_WRITE/DB_OPEN_READ_ONLY mode.");
297                         r = E_FILE_NOT_FOUND;
298                         goto CATCH;
299                 }
300         }
301
302         // open/create the database
303         ret = sqlite3_open_v2(pDbPath.get(), &pDb, openFlags, null);
304         if (ret != SQLITE_OK)
305         {
306                 r = __ConvertNativeSqliteErrorToResult(ret);
307                 SysLog(NID_IO, "[%s] sqlite3_open_v2() failed (%d, %s).", GetErrorMessage(r), ret, sqlite3_errmsg(pDb));
308                 goto CATCH;
309         }
310
311         if (pSecretKey)
312         {
313                 unique_ptr<byte[]> pDbKey(_SecureIoUtil::GenerateDatabaseKeyN(pSecretKey));
314                 SysTryReturnResult(NID_IO, pDbKey != null, E_IO, "GenerateDatabaseKeyN returned null.");
315
316 #if 0
317                 bool secure = false;
318                 r = SystemInfo::GetValue(L"http://tizen.org/feature/database.encryption", secure);
319                 SysTryReturnResult(NID_IO, !IsFailed(r), E_SYSTEM, "The method cannot proceed due to a severe system error.");
320                 SysTryReturnResult(NID_IO, secure == true, E_UNSUPPORTED_OPERATION, "This operation is not supported.");
321
322                 ret = sqlite3_key(pDb, pDbKey.get(), MAX_DATABASE_AES_KEY_LENGTH * 2);
323 #else
324                 int (* sqlite3_key_func)(sqlite3*, const void*, int) = null;
325                 void* handle = dlopen(_DATABASE_LIBRARY_PATH, RTLD_LAZY | RTLD_LOCAL);
326                 SysTryReturnResult(NID_IO, handle != null, E_SYSTEM,
327                                 "Failed to dlopen database library file (%s)", dlerror());
328
329                 sqlite3_key_func = reinterpret_cast< int (*)(sqlite3*, const void*, int) >(dlsym(handle, _DATABASE_ENCRYPTION_SYMBOL));
330                 if (sqlite3_key_func == null)
331                 {
332                         SysLog(NID_IO, "This operation is not supported. (%s)", dlerror());
333                         dlclose(handle);
334                         r = E_UNSUPPORTED_OPERATION;
335                         goto CATCH;
336                 }
337
338                 ret = sqlite3_key_func(pDb, pDbKey.get(), MAX_DATABASE_AES_KEY_LENGTH * 2);
339                 dlclose(handle);
340 #endif
341                 if (ret != SQLITE_OK)
342                 {
343                         r = __ConvertNativeSqliteErrorToResult(ret);
344                         SysLog(NID_IO, "[%s] sqlite3_key() failed (%d, %s).", GetErrorMessage(r), ret, sqlite3_errmsg(pDb));
345                         goto CATCH;
346                 }
347         }
348
349         __pDatabase = pDb;
350         __dbName = dbPath;
351
352         return E_SUCCESS;
353
354 CATCH:
355         return r;
356 }
357
358 result
359 _DatabaseImpl::Construct(const String& dbPath, const char* pOpenMode, const ByteBuffer* pSecretKey)
360 {
361         SysAssertf(__pDatabase == null, "Already constructed. Calling Construct() twice or more on a same instance is not allowed for this class\n");
362         SysTryReturnResult(NID_IO, _FileImpl::VerifyFilePathCompatibility(dbPath, _AppInfo::IsOspCompat()) == true,
363                         E_INVALID_ARG, "The specified dbPath (%ls) is invalid.", dbPath.GetPointer());
364         SysTryReturnResult(NID_IO, !(pSecretKey && pSecretKey->GetRemaining() <= 0), E_INVALID_ARG,
365                         "The specified secretKey is invalid.");
366
367         long legacyMode = 0;
368         bool isValidOpenMode = _DatabaseImpl::VerifyDatabaseOpenMode(pOpenMode, legacyMode);
369         SysTryReturnResult(NID_IO, isValidOpenMode == true, E_INVALID_ARG, "The specified openMode is invalid. (%s)", pOpenMode);
370
371         int ret = 0;
372         int openFlags = 0;
373         sqlite3* pDb = null;
374         bool isFilePathExist = false;
375         bool isParentDirPathExist = false;
376         int lastIndex = -1;
377         String parentDirPath;
378
379         switch (legacyMode)
380         {
381         case DB_OPEN_READ_WRITE:
382                 openFlags = SQLITE_OPEN_READWRITE;
383                 break;
384         case DB_OPEN_READ_ONLY:
385                 openFlags = SQLITE_OPEN_READONLY;
386                 break;
387         case (DB_OPEN_READ_WRITE | DB_OPEN_CREATE):
388                 openFlags = (SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE);
389                 break;
390         default:
391                 SysLog(NID_IO, "[E_INVALID_ARG] The specified openMode (%s) is invalid.", pOpenMode);
392                 return E_INVALID_ARG;
393         }
394
395         // extract directory path from a given Db file path
396         // Find index of last occurrence  of character '/' in dbPath
397         result r = dbPath.LastIndexOf(L'/', dbPath.GetLength() - 1, lastIndex);
398         SysTryReturnResult(NID_IO, !IsFailed(r), E_INVALID_ARG,
399                         "Missing directory path. SHOULD not happen.");
400
401         // extract directory path from dbPath starting from index 0 to lastIndex.
402         r = dbPath.SubString(0, lastIndex, parentDirPath);
403         SysTryReturnResult(NID_IO, !IsFailed(r), E_INVALID_ARG,
404                         "Missing directory path. SHOULD not happen.");
405
406         // TODO: Test sqlite3_open_v3() without parent directory.
407         //check existence of parent directory
408         isParentDirPathExist = _FileImpl::IsFileExist(String(parentDirPath));
409         SysTryReturnResult(NID_IO, isParentDirPathExist == true, E_INVALID_ARG,
410                            "Parent Directory dose not exist.");
411
412         unique_ptr<char[]> pDbPath(_StringConverter::CopyToCharArrayN(dbPath));
413         SysTryReturn(NID_IO, pDbPath, GetLastResult(), GetLastResult(), "[%s] pDbPath is null.", GetErrorMessage(GetLastResult()));
414
415         //check existence of file
416         isFilePathExist = _FileImpl::IsFileExist(dbPath);
417         if (isFilePathExist == true)
418         {
419                 //check if it is a directory
420                 SysTryReturnResult(NID_IO, !IsDirectory(dbPath), E_INVALID_ARG, "Given path is not a File.");
421
422 #if 0
423                 _DatabaseMode dbMode = DATABASE_MODE_NONE;
424                 dbMode = _SecureIoUtil::GetDatabaseMode(pDbPath.get());
425                 SysTryReturnResult(NID_IO, dbMode != DATABASE_MODE_ERROR, E_INVALID_FORMAT,
426                                 "GetDatabaseMode function failed.");
427
428                 if (pSecretKey && _SecureIoUtil::IsNormalDatabase(dbMode))
429                 {
430                         SysTryReturnResult(NID_IO, false, E_INVALID_ARG,
431                                         "Trying to open a normal database in secure mode.");
432                 }
433                 else if (!pSecretKey && _SecureIoUtil::IsSecureDatabase(dbMode))
434                 {
435                         SysTryReturnResult(NID_IO, false, E_INVALID_ARG,
436                                         "Trying to open a secure database in normal mode.");
437                 }
438                 else
439                 {
440                         //Do Nothing
441                 }
442 #endif
443         }
444         else
445         {
446                 if (legacyMode == DB_OPEN_READ_WRITE || legacyMode == DB_OPEN_READ_ONLY)
447                 {
448                         SysLog(NID_IO, "[E_FILE_NOT_FOUND] File not found.");
449                         r = E_FILE_NOT_FOUND;
450                         goto CATCH;
451                 }
452         }
453
454         // open/create the database
455         ret = sqlite3_open_v2(pDbPath.get(), &pDb, openFlags, null);
456         if (ret != SQLITE_OK)
457         {
458                 if (!_AppInfo::IsOspCompat())
459                 {
460                         r = __ConvertNativeSqliteErrorToDetailResult(ret);
461                         switch (r)
462                         {
463                         case E_INVALID_ARG:
464                         case E_OBJECT_LOCKED:
465                         case E_INVALID_OPERATION:
466                         case E_UNKNOWN:
467                                 r = E_SYSTEM;
468                                 break;
469                         }
470                 }
471                 else
472                 {
473                         r = __ConvertNativeSqliteErrorToResult(ret);
474                 }
475
476                 SysLog(NID_IO, "[%s] Failed to open database file (%s). (%d, %s).", GetErrorMessage(r), pDbPath.get(),
477                                 ret, sqlite3_errmsg(static_cast< sqlite3* >(pDb)));
478                 goto CATCH;
479         }
480
481         if (pSecretKey)
482         {
483                 unique_ptr<byte[]> pDbKey(_SecureIoUtil::GenerateDatabaseKeyN(pSecretKey));
484                 SysTryReturnResult(NID_IO, pDbKey != null, E_IO, "GenerateDatabaseKeyN returned null.");
485
486 #if 0
487                 bool secure = false;
488                 r = SystemInfo::GetValue(L"http://tizen.org/feature/database.encryption", secure);
489                 SysTryReturnResult(NID_IO, !IsFailed(r), E_SYSTEM, "The method cannot proceed due to a severe system error.");
490                 SysTryReturnResult(NID_IO, secure == true, E_UNSUPPORTED_OPERATION, "This operation is not supported.");
491
492                 ret = sqlite3_key(pDb, pDbKey.get(), MAX_DATABASE_AES_KEY_LENGTH * 2);
493 #else
494                 int (* sqlite3_key_func)(sqlite3*, const void*, int) = null;
495                 void* handle = dlopen(_DATABASE_LIBRARY_PATH, RTLD_LAZY | RTLD_LOCAL);
496                 SysTryReturnResult(NID_IO, handle != null, E_SYSTEM,
497                                 "Failed to dlopen database library file (%s)", dlerror());
498
499                 sqlite3_key_func = reinterpret_cast< int (*)(sqlite3*, const void*, int) >(dlsym(handle, _DATABASE_ENCRYPTION_SYMBOL));
500                 if (sqlite3_key_func == null)
501                 {
502                         SysLog(NID_IO, "This operation is not supported. (%s)", dlerror());
503                         dlclose(handle);
504                         r = E_UNSUPPORTED_OPERATION;
505                         goto CATCH;
506                 }
507
508                 ret = sqlite3_key_func(pDb, pDbKey.get(), MAX_DATABASE_AES_KEY_LENGTH * 2);
509                 dlclose(handle);
510 #endif
511                 if (ret != SQLITE_OK)
512                 {
513                         if (!_AppInfo::IsOspCompat())
514                         {
515                                 r = E_INVALID_ARG;
516                         }
517                         else
518                         {
519                                 r = E_DATABASE;
520                         }
521
522                         SysLog(NID_IO, "[%s] Failed to create secret key (%d, %s).", GetErrorMessage(r), ret,
523                                         sqlite3_errmsg(static_cast< sqlite3* >(pDb)));
524                         goto CATCH;
525                 }
526         }
527
528         __pDatabase = pDb;
529         __dbName = dbPath;
530
531         return E_SUCCESS;
532
533 CATCH:
534         return r;
535 }
536
537 DbStatement*
538 _DatabaseImpl::CreateStatementN(const String& statement)
539 {
540         SysAssertf(__pDatabase != null, "Not yet constructed. Construct() should be called before use.\n");
541
542         int ret = 0;
543         char* pStrStmt = null;
544         sqlite3_stmt* pSqlStmt = null;
545         result r = E_SUCCESS;
546
547         unique_ptr<DbStatement> pDbStatement(_DbStatementImpl::CreateDbStatementInstanceN());
548
549         SysTryReturn(NID_IO, pDbStatement != null, null, E_OUT_OF_MEMORY,
550                            "[E_OUT_OF_MEMORY] The memory is insufficient.");
551
552         unique_ptr<char[]> pUnTrimStatement(_StringConverter::CopyToCharArrayN(statement));
553         if (pUnTrimStatement == null)
554         {
555                 r = GetLastResult();
556                 goto CATCH;
557         }
558
559         // trim leading spaces
560         pStrStmt = pUnTrimStatement.get();
561         while ((*pStrStmt == ' ') || (*pStrStmt == '\t'))
562         {
563                 pStrStmt++;
564         }
565
566         // prepare the sql statement
567         ret = sqlite3_prepare_v2((sqlite3*) __pDatabase, pStrStmt, strlen(pStrStmt), &pSqlStmt, null);
568         if (ret != SQLITE_OK)
569         {
570                 if (!_AppInfo::IsOspCompat())
571                 {
572                         r = __ConvertNativeSqliteErrorToDetailResult(ret);
573                         switch (ret)
574                         {
575                         case E_ILLEGAL_ACCESS:
576                         case E_IO:
577                         case E_INVALID_FORMAT:
578                         case E_STORAGE_FULL:
579                         case E_INVALID_OPERATION:
580                         case E_UNKNOWN:
581                                 r = E_SYSTEM;
582                                 break;
583                         }
584                 }
585                 else
586                 {
587                         r = __ConvertNativeSqliteErrorToResult(ret);
588                 }
589
590                 SysLog(NID_IO, "[%s] Failed to prepare SQL statement (%s). (%d, %s).", GetErrorMessage(r), pStrStmt,
591                                 ret, sqlite3_errmsg(static_cast< sqlite3* >(__pDatabase)));
592                 goto CATCH;
593         }
594
595         // register the sql stmt in DbStatement
596         // accessing private variable of DbStatement.
597         _DbStatementImpl::GetInstance(*pDbStatement)->__pStmt = pSqlStmt;
598         _DbStatementImpl::GetInstance(*pDbStatement)->__pDatabase = __pDatabase;
599
600         // "SELECT" or other statement?
601         if (strncasecmp(pStrStmt, "select", 5) == 0)
602         {
603                 _DbStatementImpl::GetInstance(*pDbStatement)->__stmtType = DB_STATEMENT_TYPE_SELECT;
604         }
605         else
606         {
607                 _DbStatementImpl::GetInstance(*pDbStatement)->__stmtType = DB_STATEMENT_TYPE_OTHER;
608         }
609
610         ClearLastResult();
611         return pDbStatement.release();
612
613 CATCH:
614         SetLastResult(r);
615         return null;
616 }
617
618 DbEnumerator*
619 _DatabaseImpl::ExecuteStatementN(const DbStatement& statement)
620 {
621         SysAssertf(__pDatabase != null, "Not yet constructed. Construct() should be called before use.\n");
622         SysTryReturn(NID_IO, _DbStatementImpl::GetInstance(statement)->__pStmt != null, null, E_INVALID_ARG,
623                            "[E_INVALID_ARG] Invalid DbStatement was passed.(null handle was assigned)");
624
625         int ret = 0;
626         DbEnumerator* pDbEnum = null;
627         result r = E_SUCCESS;
628
629         ret = sqlite3_reset((sqlite3_stmt*) _DbStatementImpl::GetInstance(statement)->__pStmt);
630         if (ret != SQLITE_OK)
631         {
632                 if (!_AppInfo::IsOspCompat())
633                 {
634                         r = __ConvertNativeSqliteErrorToDetailResult(ret);
635                         switch (ret)
636                         {
637                                 case E_INVALID_ARG:
638                                 case E_ILLEGAL_ACCESS:
639                                 case E_IO:
640                                 case E_INVALID_FORMAT:
641                                 case E_STORAGE_FULL:
642                                 case E_INVALID_OPERATION:
643                                 case E_UNKNOWN:
644                                         r = E_SYSTEM;
645                                         break;
646                         }
647                 }
648                 else
649                 {
650                         r = __ConvertNativeSqliteErrorToResult(ret);
651                 }
652
653                 SysLog(NID_IO, "[%s] Failed to reset SQL statement. (%d, %s).", GetErrorMessage(r),
654                                 ret, sqlite3_errmsg(static_cast< sqlite3* >(__pDatabase)));
655                 goto CATCH;
656         }
657
658 REDO_SQLITE_STEP:
659         ret = sqlite3_step((sqlite3_stmt*) _DbStatementImpl::GetInstance(statement)->__pStmt);
660         switch (ret)
661         {
662         case SQLITE_OK:
663         case SQLITE_DONE:
664                 ret = sqlite3_reset((sqlite3_stmt*) _DbStatementImpl::GetInstance(statement)->__pStmt);
665                 if (ret != SQLITE_OK)
666                 {
667                         if (!_AppInfo::IsOspCompat())
668                         {
669                                 r = __ConvertNativeSqliteErrorToDetailResult(ret);
670                                 switch (ret)
671                                 {
672                                 case E_INVALID_ARG:
673                                 case E_ILLEGAL_ACCESS:
674                                 case E_IO:
675                                 case E_INVALID_FORMAT:
676                                 case E_STORAGE_FULL:
677                                 case E_INVALID_OPERATION:
678                                 case E_UNKNOWN:
679                                         r = E_SYSTEM;
680                                         break;
681                                 }
682                         }
683                         else
684                         {
685                                 r = __ConvertNativeSqliteErrorToResult(ret);
686                         }
687
688                         SysLog(NID_IO, "[%s] Failed to reset SQL statement. (%d, %s).", GetErrorMessage(r),
689                                         ret, sqlite3_errmsg(static_cast< sqlite3* >(__pDatabase)));
690                         goto CATCH;
691                 }
692                 break;
693
694         case SQLITE_ROW:
695                 if (_DbStatementImpl::GetInstance(statement)->__stmtType == DB_STATEMENT_TYPE_SELECT)
696                 {
697                         unique_ptr<DbEnumerator> pTempDbEnum(_DbEnumeratorImpl::CreateDbEnumeratorInstanceN());
698
699                         SysTryReturn(NID_IO, pTempDbEnum != null, null, E_OUT_OF_MEMORY,
700                                         "[E_OUT_OF_MEMORY] The memory is insufficient.");
701
702                         _DbEnumeratorImpl::GetInstance(*pTempDbEnum)->__pEnum = _DbStatementImpl::GetInstance(statement)->__pStmt;
703                         _DbEnumeratorImpl::GetInstance(*pTempDbEnum)->__pDatabase = _DbStatementImpl::GetInstance(statement)->__pDatabase;
704
705 #if 1
706                         ret = sqlite3_reset((sqlite3_stmt*) _DbStatementImpl::GetInstance(statement)->__pStmt);
707                         if (ret != SQLITE_OK)
708                         {
709                                 if (!_AppInfo::IsOspCompat())
710                                 {
711                                         r = __ConvertNativeSqliteErrorToDetailResult(ret);
712                                         switch (ret)
713                                         {
714                                         case E_INVALID_ARG:
715                                         case E_ILLEGAL_ACCESS:
716                                         case E_IO:
717                                         case E_INVALID_FORMAT:
718                                         case E_STORAGE_FULL:
719                                         case E_INVALID_OPERATION:
720                                         case E_UNKNOWN:
721                                                 r = E_SYSTEM;
722                                                 break;
723                                         }
724                                 }
725                                 else
726                                 {
727                                         r = __ConvertNativeSqliteErrorToResult(ret);
728                                 }
729
730                                 SysLog(NID_IO, "[%s] Failed to reset SQL statement. (%d, %s).", GetErrorMessage(r),
731                                                 ret, sqlite3_errmsg(static_cast< sqlite3* >(__pDatabase)));
732                                 goto CATCH;
733                         }
734 #endif
735
736                         pDbEnum = pTempDbEnum.release();
737
738                 }
739                 else
740                 {
741                         goto REDO_SQLITE_STEP;
742                 }
743                 break;
744
745         default:
746                 if (!_AppInfo::IsOspCompat())
747                 {
748                         r = __ConvertNativeSqliteErrorToDetailResult(ret);
749                         switch (r)
750                         {
751                         case E_ILLEGAL_ACCESS:
752                         case E_INVALID_OPERATION:
753                         case E_UNKNOWN:
754                                 r = E_SYSTEM;
755                                 break;
756                         }
757                 }
758                 else
759                 {
760                         r = __ConvertNativeSqliteErrorToResult(ret);
761                 }
762
763                 SysLog(NID_IO, "[%s] Failed to execute SQL statement. (%d, %s).", GetErrorMessage(r), ret,
764                                 sqlite3_errmsg(static_cast< sqlite3* >(__pDatabase)));
765                 goto CATCH;
766         }
767
768         SetLastResult(E_SUCCESS);
769         return pDbEnum;
770
771 CATCH:
772         SetLastResult(r);
773         return null;
774 }
775
776 result
777 _DatabaseImpl::ExecuteSql(const String& sql, bool autoCommit)
778 {
779         SysAssertf(__pDatabase != null, "Not yet constructed. Construct() should be called before use.\n");
780
781         int ret = 0;
782         char* pSqlStr = null;
783         result r = E_SUCCESS;
784
785         unique_ptr<char[]> pUnTrimStatement(_StringConverter::CopyToCharArrayN(sql));
786         if (pUnTrimStatement == null)
787         {
788                 r = GetLastResult();
789                 goto CATCH;
790         }
791
792         // trim leading spaces
793         pSqlStr = pUnTrimStatement.get();
794         while ((*pSqlStr == ' ') || (*pSqlStr == '\t'))
795         {
796                 pSqlStr++;
797         }
798
799         // "SELECT" or other statement?
800         if (strncasecmp(pSqlStr, "select", 5) == 0)
801         {
802                 r = E_INVALID_OPERATION;
803                 goto CATCH;
804         }
805
806         ret = sqlite3_exec((sqlite3*) __pDatabase, pSqlStr, null, null, null);
807         if (ret != SQLITE_OK)
808         {
809                 if (!_AppInfo::IsOspCompat())
810                 {
811                         r = __ConvertNativeSqliteErrorToDetailResult(ret);
812                         switch (r)
813                         {
814                         case E_ILLEGAL_ACCESS:
815                         case E_INVALID_OPERATION:
816                         case E_UNKNOWN:
817                                 r = E_SYSTEM;
818                                 break;
819                         }
820                 }
821                 else
822                 {
823                         r = __ConvertNativeSqliteErrorToResult(ret);
824                 }
825
826                 SysLog(NID_IO, "[%s] Failed to execute SQL statement. (%d, %s).", GetErrorMessage(r), ret,
827                                 sqlite3_errmsg(static_cast< sqlite3* >(__pDatabase)));
828                 goto CATCH;
829         }
830
831         return E_SUCCESS;
832
833 CATCH:
834         return r;
835 }
836
837 DbEnumerator*
838 _DatabaseImpl::QueryN(const String& query)
839 {
840         SysAssertf(__pDatabase != null, "Not yet constructed. Construct() should be called before use.\n");
841
842         int ret = 0;
843         char* pQuery = null;
844         sqlite3_stmt* pSqlStmt = null;
845         unique_ptr<DbEnumerator> pDbEnum(null);
846         result r = E_SUCCESS;
847
848         unique_ptr<char[]> pUnTrimStatement(_StringConverter::CopyToCharArrayN(query));
849         if (pUnTrimStatement == null)
850         {
851                 r = GetLastResult();
852                 goto CATCH;
853         }
854
855         // trim leading spaces
856         pQuery = pUnTrimStatement.get();
857         while ((*pQuery == ' ') || (*pQuery == '\t'))
858         {
859                 pQuery++;
860         }
861
862         // "SELECT" or other statement?
863         if (strncasecmp(pQuery, "select", 5) != 0)
864         {
865                 r = E_INVALID_OPERATION;
866                 goto CATCH;
867         }
868
869         // prepare the sql statement
870         ret = sqlite3_prepare_v2((sqlite3*) __pDatabase, pQuery, strlen(pQuery), &pSqlStmt, null);
871         if (ret != SQLITE_OK)
872         {
873                 if (!_AppInfo::IsOspCompat())
874                 {
875                         r = __ConvertNativeSqliteErrorToDetailResult(ret);
876                         switch (ret)
877                         {
878                         case E_ILLEGAL_ACCESS:
879                         case E_IO:
880                         case E_INVALID_FORMAT:
881                         case E_STORAGE_FULL:
882                         case E_INVALID_OPERATION:
883                         case E_UNKNOWN:
884                                 r = E_SYSTEM;
885                                 break;
886                         }
887                 }
888                 else
889                 {
890                         r = __ConvertNativeSqliteErrorToResult(ret);
891                 }
892
893                 SysLog(NID_IO, "[%s] Failed to prepare SQL statement (%s). (%d, %s).", GetErrorMessage(r), pQuery,
894                                 ret, sqlite3_errmsg(static_cast< sqlite3* >(__pDatabase)));
895                 goto CATCH;
896         }
897
898 //    ret = sqlite3_reset((sqlite3_stmt *) pSqlStmt);
899 //      if (ret != SQLITE_OK)
900 //      {
901 //              r = __ConvertNativeSqliteErrorToResult(ret);
902 //              SysLog(NID_IO, "[_DatabaseImpl] ERROR: [%s] Failed to reset SQL statement.", GetErrorMessage(r));
903 //              goto CATCH;
904 //      }
905
906         ret = sqlite3_step(pSqlStmt);
907         switch (ret)
908         {
909         case SQLITE_OK:
910         case SQLITE_DONE:
911                 break;
912
913         case SQLITE_ROW:
914                 pDbEnum.reset(_DbEnumeratorImpl::CreateDbEnumeratorInstanceN());
915
916                 SysTryCatch(NID_IO, pDbEnum != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
917                                 "[E_OUT_OF_MEMORY] The memory is insufficient.");
918
919                 _DbEnumeratorImpl::GetInstance(*pDbEnum)->__pEnum = pSqlStmt;
920                 _DbEnumeratorImpl::GetInstance(*pDbEnum)->__pDatabase = __pDatabase;
921                 _DbEnumeratorImpl::GetInstance(*pDbEnum)->__shouldReleaseResource = true;
922
923                 // doing a reset again, so that enumerator first MoveNext() give the first row.
924                 ret = sqlite3_reset((sqlite3_stmt*) pSqlStmt);
925                 if (ret != SQLITE_OK)
926                 {
927                         if (!_AppInfo::IsOspCompat())
928                         {
929                                 r = __ConvertNativeSqliteErrorToDetailResult(ret);
930                                 switch (ret)
931                                 {
932                                         case E_INVALID_ARG:
933                                         case E_ILLEGAL_ACCESS:
934                                         case E_IO:
935                                         case E_INVALID_FORMAT:
936                                         case E_STORAGE_FULL:
937                                         case E_INVALID_OPERATION:
938                                         case E_UNKNOWN:
939                                                 r = E_SYSTEM;
940                                                 break;
941                                 }
942                         }
943                         else
944                         {
945                                 r = __ConvertNativeSqliteErrorToResult(ret);
946                         }
947
948                         SysLog(NID_IO, "[%s] Failed to reset SQL statement. (%d, %s).", GetErrorMessage(r),
949                                 ret, sqlite3_errmsg(static_cast< sqlite3* >(__pDatabase)));
950                         goto CATCH;
951                 }
952                 break;
953
954         default:
955                 if (!_AppInfo::IsOspCompat())
956                 {
957                         r = __ConvertNativeSqliteErrorToDetailResult(ret);
958                         switch (r)
959                         {
960                         case E_ILLEGAL_ACCESS:
961                         case E_STORAGE_FULL:
962                         case E_INVALID_OPERATION:
963                         case E_UNKNOWN:
964                                 r = E_SYSTEM;
965                                 break;
966                         }
967                 }
968                 else
969                 {
970                         r = __ConvertNativeSqliteErrorToResult(ret);
971                 }
972
973                 SysLog(NID_IO, "[%s] Failed to exectue SQL statement (%s). (%d, %s).", GetErrorMessage(r), pQuery,
974                                 ret, sqlite3_errmsg(static_cast< sqlite3* >(__pDatabase)));
975                 goto CATCH;
976         }
977
978         ClearLastResult();
979         return pDbEnum.release();
980
981 CATCH:
982         sqlite3_finalize(pSqlStmt);
983         SetLastResult(r);
984         return null;
985 }
986
987 result
988 _DatabaseImpl::BeginTransaction(void)
989 {
990         SysAssertf(__pDatabase != null, "Not yet constructed. Construct() should be called before use.\n");
991         SysTryReturnResult(NID_IO, __transactionGoingOn == false, E_INVALID_STATE,
992                                 "A transaction is already in progress.");
993
994         result r = E_SUCCESS;
995
996         if (sqlite3_get_autocommit((sqlite3*) __pDatabase) == 0)
997         {
998                 SysLog(NID_IO, "[E_INVALID_STATE] Already in transaction mode.");
999                 return E_INVALID_STATE;
1000         }
1001
1002         int ret = sqlite3_exec((sqlite3*) __pDatabase, "BEGIN", null, null, null);
1003         if (ret != SQLITE_OK)
1004         {
1005                 if (!_AppInfo::IsOspCompat())
1006                 {
1007                         r = __ConvertNativeSqliteErrorToDetailResult(ret);
1008                         switch (r)
1009                         {
1010                         case E_INVALID_ARG:
1011                         case E_ILLEGAL_ACCESS:
1012                         case E_OBJECT_LOCKED:
1013                         case E_IO:
1014                         case E_INVALID_FORMAT:
1015                         case E_STORAGE_FULL:
1016                         case E_INVALID_OPERATION:
1017                                 r = E_SYSTEM;
1018                                 break;
1019                         }
1020                 }
1021                 else
1022                 {
1023                         r = __ConvertNativeSqliteErrorToResult(ret);
1024                 }
1025
1026                 SysLog(NID_IO, "[%s] Failed to begin transaction. (%d, %s)", GetErrorMessage(r), ret,
1027                                 sqlite3_errmsg(static_cast< sqlite3* >(__pDatabase)));
1028         }
1029         else
1030         {
1031                 __transactionGoingOn = true;
1032         }
1033
1034         return r;
1035 }
1036
1037 result
1038 _DatabaseImpl::CommitTransaction(void)
1039 {
1040         SysAssertf(__pDatabase != null, "Not yet constructed. Construct() should be called before use.\n");
1041         SysTryReturnResult(NID_IO, __transactionGoingOn == true, E_INVALID_STATE,
1042                                 "A transaction is already in progress.");
1043
1044         int ret = 0;
1045         result r = E_SUCCESS;
1046
1047         if (sqlite3_get_autocommit((sqlite3*) __pDatabase) != 0)
1048         {
1049                 SysLog(NID_IO, "[E_INVALID_STATE] ERROR Message: Not in transaction mode.");
1050                 return E_INVALID_STATE;
1051         }
1052
1053         ret = sqlite3_exec((sqlite3*) __pDatabase, "COMMIT", null, null, null);
1054         if (ret != SQLITE_OK)
1055         {
1056                 if (!_AppInfo::IsOspCompat())
1057                 {
1058                         r = __ConvertNativeSqliteErrorToDetailResult(ret);
1059                         switch (r)
1060                         {
1061                         case E_INVALID_ARG:
1062                         case E_ILLEGAL_ACCESS:
1063                         case E_INVALID_OPERATION:
1064                                 r = E_SYSTEM;
1065                                 break;
1066                         }
1067                 }
1068                 else
1069                 {
1070                         r = __ConvertNativeSqliteErrorToResult(ret);
1071                 }
1072
1073                 SysLog(NID_IO, "[%s] Failed to commit transaction. (%d, %s)", GetErrorMessage(r), ret,
1074                                 sqlite3_errmsg(static_cast< sqlite3* >(__pDatabase)));
1075         }
1076         else
1077         {
1078                 __transactionGoingOn = false;
1079         }
1080
1081         return r;
1082 }
1083
1084 result
1085 _DatabaseImpl::RollbackTransaction(void)
1086 {
1087         SysAssertf(__pDatabase != null, "Not yet constructed. Construct() should be called before use.\n");
1088         SysTryReturnResult(NID_IO, __transactionGoingOn == true, E_INVALID_STATE,
1089                                 "No transaction in progress.");
1090
1091         int ret = 0;
1092         result r = E_SUCCESS;
1093
1094         if (sqlite3_get_autocommit((sqlite3*) __pDatabase) != 0)
1095         {
1096                 SysLog(NID_IO, "[E_SUCCESS] No transaction in progress.");
1097                 //return E_INVALID_STATE;
1098                 return E_SUCCESS;
1099         }
1100
1101         ret = sqlite3_exec((sqlite3*) __pDatabase, "ROLLBACK", null, null, null);
1102         if (ret != SQLITE_OK)
1103         {
1104                 if (!_AppInfo::IsOspCompat())
1105                 {
1106                         r = __ConvertNativeSqliteErrorToDetailResult(ret);
1107                         switch (r)
1108                         {
1109                         case E_INVALID_ARG:
1110                         case E_ILLEGAL_ACCESS:
1111                         case E_INVALID_OPERATION:
1112                                 r = E_SYSTEM;
1113                                 break;
1114                         }
1115                 }
1116                 else
1117                 {
1118                         r = __ConvertNativeSqliteErrorToResult(ret);
1119                 }
1120
1121                 SysLog(NID_IO, "[%s] Failed to rollback the transaction. (%d, %s)", GetErrorMessage(r), ret,
1122                                 sqlite3_errmsg(static_cast< sqlite3* >(__pDatabase)));
1123         }
1124         else
1125         {
1126                 __transactionGoingOn = false;
1127         }
1128
1129         return r;
1130 }
1131
1132 String
1133 _DatabaseImpl::GetName(void) const
1134 {
1135         SysAssertf(__pDatabase != null, "Not yet constructed. Construct() should be called before use.\n");
1136
1137         SetLastResult(E_SUCCESS);
1138         return __dbName;
1139 }
1140
1141 result
1142 _DatabaseImpl::RegisterUserFunction(const String& functionName, const int argumentCount, void* pUserData,
1143                                                                         _IDbUserFunctionListener* pUserFunctionListener,
1144                                                                         _IDbUserAggregateListener* pUserAggregateListener)
1145 {
1146         result r = E_SUCCESS;
1147         int sqliteEncoding = 0;
1148         int ret = 0;
1149         int utf8len = 0;
1150         unique_ptr<_DbContextImpl> pDbContext(null);
1151         _DbContextImpl* pTempDbContext = null;
1152         bool entryFound = false;
1153         int i = 0;
1154
1155         // Validate input parameters
1156         SysAssertf(__pDatabase != null, "Not yet constructed. Construct() should be called before use.\n");
1157         SysTryReturnResult(NID_IO, functionName.GetLength() > 0, E_INVALID_ARG,
1158                         "Invalid funcName length.");
1159         SysTryReturnResult(NID_IO, argumentCount >= 0 && argumentCount <= MAX_FUNCTION_ARGUMENT_COUNT, E_INVALID_ARG,
1160                                 "argumentCount < 0 or > 127.");
1161
1162         if (pUserFunctionListener != null && pUserAggregateListener != null)
1163         {
1164                 SysTryReturnResult(NID_IO, 0, E_INVALID_ARG,
1165                                         "FunctionListener and AggregateListener cannot be registered together");
1166         }
1167
1168         //select the equivalent sqlite encoding.
1169
1170         unique_ptr<ByteBuffer> pFuncNameBuf(StringUtil::StringToUtf8N(functionName));
1171         SysTryReturn(NID_IO, pFuncNameBuf != null, GetLastResult(),
1172                                 GetLastResult(), "[%s] Invalid Function name.", GetErrorMessage(GetLastResult()));
1173
1174         utf8len = pFuncNameBuf->GetLimit();
1175         SysTryReturnResult(NID_IO, utf8len > 0 && utf8len <= MAX_UTF8_BYTES, E_INVALID_ARG,
1176                            "functionName length in utf8 bytes should be >0 && <=255.");
1177
1178         sqliteEncoding = SQLITE_UTF8; // support only UTF8
1179
1180         //check if the (FunctionName, argumentCount) already exist in the list
1181         for (i = 0; i < __userFunctionContextList.GetCount(); i++)
1182         {
1183                 pTempDbContext = dynamic_cast<_DbContextImpl*> (__userFunctionContextList.GetAt(i));
1184                 SysTryReturnResult(NID_IO, pTempDbContext, E_IO, "The __userFunctionContextList has an invalid element.");
1185                 if ((pTempDbContext->__argumentCount == argumentCount) &&
1186                         (pTempDbContext->__functionName == functionName))
1187                 {
1188                         entryFound = true;
1189                         break;
1190                 }
1191         }
1192
1193         if (entryFound && (null != pUserFunctionListener || null != pUserAggregateListener))
1194         {
1195                 SysTryReturnResult(NID_IO, 0, E_INVALID_ARG,
1196                                    "(functionName, argumentCount) already registered");
1197         }
1198
1199         if (pUserFunctionListener != null) // register FunctionListener
1200         {
1201                 pDbContext.reset(new (std::nothrow) _DbContextImpl());
1202                 SysTryReturnResult(NID_IO, pDbContext != null, E_OUT_OF_MEMORY,
1203                                 "The memory is insufficient.");
1204
1205                 ret = sqlite3_create_function((sqlite3*) __pDatabase,
1206                         (const char*) pFuncNameBuf->GetPointer(), argumentCount, sqliteEncoding, pDbContext.get(),
1207                         _DatabaseImpl::UserFunctionListener, null, null);
1208         }
1209         else if (pUserAggregateListener != null) // register both FunctionStepListener and FunctionFinalListener
1210         {
1211                 pDbContext.reset(new (std::nothrow) _DbContextImpl());
1212
1213                 SysTryReturnResult(NID_IO, pDbContext != null, E_OUT_OF_MEMORY,
1214                                 "The memory is insufficient.");
1215
1216                 ret = sqlite3_create_function((sqlite3*) __pDatabase,
1217                         (const char*) pFuncNameBuf->GetPointer(), argumentCount, sqliteEncoding, pDbContext.get(),
1218                          null, _DatabaseImpl::UserFunctionStepListener, _DatabaseImpl::UserFunctionFinalListener);
1219         }
1220         else // Delete registered user function/Aggregate
1221         {
1222                 ret = sqlite3_create_function((sqlite3*) __pDatabase,
1223                          (const char*) pFuncNameBuf->GetPointer(), argumentCount, sqliteEncoding, null, null, null, null);
1224         }
1225
1226         if (ret != SQLITE_OK) //error
1227         {
1228                 r = __ConvertNativeSqliteErrorToResult(ret);
1229                 SysLog(NID_IO, "[%s] ERROR Message: [%s], Failed to create/delete user defined SQL function.", GetErrorMessage(r),
1230                                         sqlite3_errmsg((sqlite3*)__pDatabase));
1231                 return r;
1232         }
1233
1234         if (entryFound && (!pUserFunctionListener && !pUserAggregateListener)) // delete the user function entry from list
1235         {
1236                 r = __userFunctionContextList.Remove(*pTempDbContext, true);
1237                 SysTryReturn(NID_IO, !IsFailed(r), GetLastResult(),
1238                                         GetLastResult(), "[%s] Failed to remove user function context to the list.", GetErrorMessage(GetLastResult()));
1239         }
1240
1241         if (pDbContext != null)
1242         {
1243                 //store listener and user data
1244                 pDbContext->__pUserData = pUserData;
1245                 pDbContext->__argumentCount = argumentCount;
1246                 pDbContext->__functionName = functionName;
1247                 if (pUserFunctionListener != null)
1248                 {
1249                         pDbContext->__pUserFunctionListener = pUserFunctionListener;
1250                 }
1251                 if (pUserAggregateListener != null)
1252                 {
1253                         pDbContext->__pUserAggregateListener = pUserAggregateListener;
1254                 }
1255
1256                 // add entry to the list
1257                 r = __userFunctionContextList.Add(*(pDbContext.release()));
1258                 SysTryReturn(NID_IO, !IsFailed(r), GetLastResult(),
1259                                         GetLastResult(), "[%s] Failed to add user function context to the list.", GetErrorMessage(GetLastResult()));
1260         }
1261
1262         return E_SUCCESS;
1263 }
1264
1265 result
1266 _DatabaseImpl::RegisterUserCollation(const String& collationName, void* pUserData,
1267                                                                          _IDbUserCollationListener* pUserCollationListener)
1268 {
1269         result r = E_SUCCESS;
1270         int sqliteEncoding = 0;
1271         int ret = 0;
1272         int utf8len = 0;
1273         unique_ptr<_DbContextImpl> pDbContext(null);
1274         _DbContextImpl* pTempDbContext = null;
1275         bool entryFound = false;
1276         int i = 0;
1277
1278         SysAssertf(__pDatabase != null, "Not yet constructed. Construct() should be called before use.\n");
1279         SysTryReturnResult(NID_IO, collationName.GetLength() > 0, E_INVALID_ARG,
1280                         "Invalid collationName length.");
1281
1282         sqliteEncoding = SQLITE_UTF8; // support only UTF8
1283
1284         unique_ptr<ByteBuffer> pColNameBuf(StringUtil::StringToUtf8N(collationName));
1285         SysTryReturn(NID_IO, pColNameBuf != null, GetLastResult(), GetLastResult(), "[%s] Invalid Function name.",
1286                                 GetErrorMessage(GetLastResult()));
1287
1288         utf8len = pColNameBuf->GetLimit(); // get UTF_8 bytes length
1289         SysTryReturnResult(NID_IO, utf8len > 0 && utf8len <= MAX_UTF8_BYTES, E_INVALID_ARG,
1290                         "functionName length in utf8 bytes should be >0 && <=255.");
1291
1292         //check if the (FunctionName) already registered
1293         for (i = 0; i < __userCollationContextList.GetCount(); i++)
1294         {
1295                 pTempDbContext = dynamic_cast< _DbContextImpl* >(__userCollationContextList.GetAt(i));
1296                 SysTryReturnResult(NID_IO, pTempDbContext, E_IO, "The __userCollationContextList has an invalid element.");
1297                 if (pTempDbContext->__collationName == collationName)
1298                 {
1299                         entryFound = true;
1300                         break;
1301                 }
1302         }
1303
1304         if (entryFound && (pUserCollationListener != null)) // check if the operation is to delete the user function
1305         {
1306                 SysTryReturnResult(NID_IO, 0, E_INVALID_ARG, "(collationName) already registered");
1307         }
1308
1309         if (pUserCollationListener != null)
1310         {
1311                 pDbContext.reset(new (std::nothrow) _DbContextImpl());
1312                 SysTryReturnResult(NID_IO, pDbContext != null, E_OUT_OF_MEMORY,
1313                                 "The memory is insufficient.");
1314
1315                 // register CollationListener()
1316                 ret = sqlite3_create_collation((sqlite3*) __pDatabase, (const char*) pColNameBuf->GetPointer(), sqliteEncoding, pDbContext.get(),
1317                                 _DatabaseImpl::UserCollationListener);
1318         }
1319         else // delete Collating function
1320         {
1321                 ret = sqlite3_create_collation((sqlite3*) __pDatabase, (const char*) pColNameBuf->GetPointer(), sqliteEncoding, null, null);
1322         }
1323
1324         if (ret != SQLITE_OK)
1325         {
1326                 r = __ConvertNativeSqliteErrorToResult(ret);
1327                 SysLog(NID_IO, "[%s] ERROR Message: [%s], Failed to create/delete user defined SQL Collation.", GetErrorMessage(r),
1328                                 sqlite3_errmsg((sqlite3*)__pDatabase));
1329                 return r;
1330         }
1331
1332         if (entryFound && !pUserCollationListener) // delete the user collation entry from list
1333         {
1334                 r = __userCollationContextList.Remove(*pTempDbContext, true);
1335                 SysTryReturn(NID_IO, !IsFailed(r), GetLastResult(),
1336                                         GetLastResult(), "[%s] Failed to remove user collation context from the list.", GetErrorMessage(GetLastResult()));
1337         }
1338
1339         if (pDbContext != null)
1340         {
1341                 //store listener and user data
1342                 pDbContext->__pUserData = pUserData;
1343                 pDbContext->__collationName = collationName;
1344                 pDbContext->__pUserCollationListener = pUserCollationListener;
1345                 // add entry to the list
1346                 r = __userCollationContextList.Add((*(pDbContext.release())));
1347                 SysTryReturn(NID_IO, !IsFailed(r), GetLastResult(),
1348                                         GetLastResult(), "[%s] Failed to add user collation context to the list.", GetErrorMessage(GetLastResult()));
1349
1350         }
1351
1352         return E_SUCCESS;
1353 }
1354
1355 long long 
1356 _DatabaseImpl::GetLastInsertRowId(void) const
1357 {
1358         SysAssertf(__pDatabase != null, "Not yet constructed. Construct() should be called before use.\n");
1359
1360         // Retrieve last inserted row Id of the specified Db connection.
1361         // sqlite rowIds starts from 1 to max. 0 means no rows available in the database.
1362         // even if we delete the last inserted row, it still returns the rowid of last insert.
1363         // and does not care about any deletions happened.
1364         long long insertRowId = sqlite3_last_insert_rowid(static_cast< sqlite3* >(__pDatabase));
1365         if (insertRowId == 0)
1366         {
1367                 return -1;
1368         }
1369         else
1370         {
1371                 return insertRowId;
1372         }
1373 }
1374
1375 result
1376 _DatabaseImpl::Delete(const String& databasePath)
1377 {
1378         result r = E_SUCCESS;
1379         int ret = 0;
1380
1381         SysTryReturnResult(NID_IO, _FileImpl::VerifyFilePathCompatibility(databasePath, _AppInfo::IsOspCompat()) == true,
1382                         E_INVALID_ARG, " [%ls] is not compatible.", databasePath.GetPointer());
1383
1384         unique_ptr<char[]> pDbPath(_StringConverter::CopyToCharArrayN(databasePath));
1385         if (pDbPath == null)
1386         {
1387                 return GetLastResult();
1388         }
1389
1390         // remove the file
1391         ret = unlink(pDbPath.get());
1392         if (ret != 0)
1393         {
1394                 r = __ConvertNativeErrorToResult(errno);
1395         }
1396
1397         return r;
1398 }
1399
1400 bool
1401 _DatabaseImpl::Exists(const String& databasePath)
1402 {
1403         return _FileImpl::IsFileExist(databasePath);
1404 }
1405
1406 void
1407 _DatabaseImpl::UserFunctionListener(sqlite3_context* pContext, int argumentCount, sqlite3_value** pArgList)
1408 {
1409         _DbContextImpl* pDbContext = null;
1410
1411         pDbContext = static_cast< _DbContextImpl* >(sqlite3_user_data(pContext));
1412
1413         SysTryReturnVoidResult(NID_IO, pDbContext, E_INVALID_STATE, "[E_INVALID_STATE] pDbContext is null.");
1414         SysTryReturnVoidResult(NID_IO, pDbContext->__pUserFunctionListener, E_INVALID_STATE,
1415                                         "[E_INVALID_STATE] UserAggregateListener is null.");
1416
1417         //Set DbContext data
1418         if (pDbContext->__pContext != (void*) pContext)
1419         {
1420                 pDbContext->__pContext = (void*) pContext;
1421         }
1422
1423         if (pDbContext->__argumentCount != argumentCount)
1424         {
1425                 SysLog(NID_IO, "Message: __argumentCount mismatch.");
1426                 pDbContext->__argumentCount = argumentCount;
1427         }
1428
1429         if (pDbContext->__pArgList != (void**) pArgList)
1430         {
1431                 pDbContext->__pArgList = (void**) pArgList;
1432         }
1433         // Invoke the user listener method
1434         pDbContext->__pUserFunctionListener->OnDbUserFunction(*pDbContext, argumentCount);
1435
1436         SetLastResult(E_SUCCESS);
1437 }
1438
1439 void
1440 _DatabaseImpl::UserFunctionStepListener(sqlite3_context* pContext, int argumentCount, sqlite3_value** pArgList)
1441 {
1442         _DbContextImpl* pDbContext = null;
1443
1444         pDbContext = static_cast< _DbContextImpl* >(sqlite3_user_data(pContext));
1445
1446         SysTryReturnVoidResult(NID_IO, pDbContext, E_INVALID_STATE, "[E_INVALID_STATE] pDbContext is null.");
1447         SysTryReturnVoidResult(NID_IO, pDbContext->__pUserAggregateListener, E_INVALID_STATE,
1448                                         "[E_INVALID_STATE] __pDbContextImpl->__pUserAggregateListener is null.");
1449
1450         //Set DbContext data
1451         if (pDbContext->__pContext != (void*) pContext)
1452         {
1453                 pDbContext->__pContext = (void*) pContext;
1454         }
1455
1456         if (pDbContext->__argumentCount != argumentCount)
1457         {
1458                 pDbContext->__argumentCount = argumentCount;
1459         }
1460
1461         if (pDbContext->__pArgList != (void**) pArgList)
1462         {
1463                 pDbContext->__pArgList = (void**) pArgList;
1464         }
1465
1466         // invoke the user listener method
1467         pDbContext->__pUserAggregateListener->OnDbUserAggregateStep(*pDbContext, argumentCount);
1468
1469         SetLastResult(E_SUCCESS);
1470 }
1471
1472 void
1473 _DatabaseImpl::UserFunctionFinalListener(sqlite3_context* pContext)
1474 {
1475         _DbContextImpl* pDbContext = null;
1476
1477         pDbContext = static_cast< _DbContextImpl* >(sqlite3_user_data(pContext));
1478
1479         SysTryReturnVoidResult(NID_IO, pDbContext, E_INVALID_STATE, "[E_INVALID_STATE] pDbContext is null.");
1480         SysTryReturnVoidResult(NID_IO, pDbContext->__pUserAggregateListener, E_INVALID_STATE,
1481                                         "[E_INVALID_STATE] UserAggregateListener is null.");
1482
1483         // set context and user data
1484         if (pDbContext->__pContext != (void*) pContext)
1485         {
1486                 pDbContext->__pContext = (void*) pContext;
1487         }
1488
1489         // invoke the user listener method
1490         pDbContext->__pUserAggregateListener->OnDbUserAggregateFinal(*pDbContext);
1491
1492         SetLastResult(E_SUCCESS);
1493 }
1494
1495 int
1496 _DatabaseImpl::UserCollationListener(void* pUserData, int length1, const void* pInput1, int length2, const void* pInput2)
1497 {
1498         _DbContextImpl* pDbContext = null;
1499         char* pDataInput = null;
1500         String string1("");
1501         String string2("");
1502
1503         pDbContext = static_cast< _DbContextImpl* >(pUserData);
1504
1505         SysTryReturn(NID_IO, pDbContext, 0, E_INVALID_STATE, "[E_INVALID_STATE] pDbContext is null.");
1506         SysTryReturn(NID_IO, pDbContext->__pUserCollationListener, 0, E_INVALID_STATE,
1507                                 "[E_INVALID_STATE] UserCollationListener is null.");
1508
1509         if (length1 > 0 && (const char*) pInput1 != null)
1510         {
1511                 pDataInput = (char*) malloc((length1 + 1) * sizeof(char));
1512
1513                 if (pDataInput == null)
1514                 {
1515                         return 0;
1516                 }
1517
1518                 memset(pDataInput, 0, length1 + 1);
1519                 strncpy(pDataInput, (const char*) pInput1, length1);
1520                 string1.Clear();
1521                 string1.Append((const char*) pDataInput);
1522                 free(pDataInput);
1523         }
1524
1525         if (length2 > 0 && (const char*) pInput2 != null)
1526         {
1527                 pDataInput = (char*) malloc((length2 + 1) * sizeof(char));
1528
1529                 if (pDataInput == null)
1530                 {
1531                         return 0;
1532                 }
1533
1534                 memset(pDataInput, 0, length2 + 1);
1535                 strncpy(pDataInput, (const char*) pInput2, length2);
1536                 string2.Clear();
1537                 string2.Append((const char*) pDataInput);
1538                 free(pDataInput);
1539         }
1540
1541         SetLastResult(E_SUCCESS);
1542
1543         return pDbContext->__pUserCollationListener->OnDbUserCollation(string1, string2, pUserData);
1544 }
1545
1546 result
1547 _DatabaseImpl::ConvertToSecureDatabase(const String& plainDbPath, const String& secureDbPath, const ByteBuffer* pKey)
1548 {
1549         result  r = E_SUCCESS;
1550         String  sql;
1551         String  parentDirPath;
1552         FileAttributes  attr;
1553
1554         if (Database::Exists(secureDbPath))
1555         {
1556                 if (GetLastResult() == E_SUCCESS)
1557                 {
1558                         r = File::GetAttributes(secureDbPath, attr);
1559                         if (r == E_SUCCESS)
1560                         {
1561                                 if (attr.IsDirectory())
1562                                 {
1563                                         return E_INVALID_ARG;
1564                                 }
1565                                 else
1566                                 {
1567                                         return E_FILE_ALREADY_EXIST;
1568                                 }
1569                         }
1570                         else
1571                         {
1572                                 return r;
1573                         }
1574                 }
1575                 else
1576                 {
1577                         return E_SYSTEM;
1578                 }
1579         }
1580
1581         unique_ptr<Database>pDatabase(new (std::nothrow) Database());
1582         SysTryReturnResult(NID_IO, pDatabase, E_OUT_OF_MEMORY, "The memory is insufficient.");
1583
1584         r = pDatabase->Construct(secureDbPath, "a+");
1585         SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Propagating to the caller...", GetErrorMessage(r));
1586
1587         pDatabase.reset(new (std::nothrow) Database());
1588         SysTryReturnResult(NID_IO, pDatabase, E_OUT_OF_MEMORY, "The memory is insufficient.");
1589
1590         r = pDatabase->Construct(plainDbPath, "r+");
1591         SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Propagating to the caller...", GetErrorMessage(r));
1592
1593         unique_ptr<String> pSqlStr(new (std::nothrow) String(MAX_DATABASE_SQL_LENGTH));
1594         SysTryReturnResult(NID_IO, pSqlStr != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
1595
1596         unique_ptr<char[]> pPhysicalDbPath(_StringConverter::CopyToCharArrayN(secureDbPath));
1597         SysTryReturn(NID_IO, pPhysicalDbPath != null, GetLastResult(), GetLastResult(), "[%s] Invalid file path.", GetErrorMessage(GetLastResult()));
1598
1599         unique_ptr<byte[]> pDbKey(_SecureIoUtil::GenerateDatabaseKeyN(pKey));
1600         SysTryReturnResult(NID_IO, pDbKey != null, E_INVALID_ARG, "GenerateDatabaseKeyN returned null.");
1601
1602         pSqlStr->Format(MAX_DATABASE_SQL_LENGTH, L"ATTACH DATABASE '%s' AS encrypted KEY '%s'", pPhysicalDbPath.get(), pDbKey.get());
1603
1604         sql.Append(*pSqlStr);
1605         r = pDatabase->ExecuteSql(sql, true);
1606         SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Propagating to the caller...", GetErrorMessage(r));
1607         sql.Clear();
1608
1609         unique_ptr<DbEnumerator> pEnum(pDatabase->QueryN(L"SELECT sql FROM (SELECT * FROM sqlite_master UNION ALL  SELECT * FROM sqlite_temp_master) WHERE type!='meta' ORDER BY tbl_name, type DESC, name"));
1610         r = GetLastResult();
1611         if (r == E_SUCCESS)
1612         {
1613                 if (pEnum)
1614                 {
1615                         String schema;
1616                         String tempQuery(L"encrypted.");
1617
1618                         while (pEnum->MoveNext() == E_SUCCESS)
1619                         {
1620                                 r = pEnum->GetStringAt(0, schema);
1621                                 if (r != E_SUCCESS)
1622                                 {
1623                                         if (r == E_INVALID_STATE || r == E_TYPE_MISMATCH || r == E_INVALID_ENCODING_RANGE) //internal exception by this method
1624                                         {
1625                                                 r = E_SYSTEM;
1626                                         }
1627                                         return r;
1628                                 }
1629
1630                                 if (schema.StartsWith(L"sqlite_", MAX_SQLCIPHER_SCHEMA_PREFIX_SIZE))
1631                                 {
1632                                         continue;
1633                                 }
1634
1635                                 r = schema.Insert(tempQuery, MAX_SQLCIPHER_SCHEMA_PREFIX_SIZE);
1636                                 if (IsFailed(r))
1637                                 {
1638                                         return E_SYSTEM;
1639                                 }
1640
1641                                 r = pDatabase->ExecuteSql(schema, true);
1642                                 SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Propagating to caller...", GetErrorMessage(r));
1643                         }
1644                 }
1645         }
1646         else
1647         {
1648                 SysPropagate(NID_IO, r);
1649                 return r;
1650         }
1651
1652         pEnum.reset(pDatabase->QueryN(L"SELECT name FROM sqlite_master WHERE type='table' ORDER BY name"));
1653         r = GetLastResult();
1654         if (r == E_SUCCESS)
1655         {
1656                 if (pEnum)
1657                 {
1658                         String tableName;
1659                         while (pEnum->MoveNext() == E_SUCCESS)
1660                         {
1661                                 r = pEnum->GetStringAt(0, tableName);
1662                                 if (r != E_SUCCESS)
1663                                 {
1664                                         if (r == E_INVALID_STATE || r == E_TYPE_MISMATCH || r == E_INVALID_ENCODING_RANGE) //internal exception by this method
1665                                         {
1666                                                 r = E_IO;
1667                                         }
1668
1669                                         return r;
1670                                 }
1671
1672                                 if (tableName.StartsWith(L"sqlite_", 0))
1673                                 {
1674                                         continue;
1675                                 }
1676
1677                                 pSqlStr.reset(new (std::nothrow) String(MAX_DATABASE_SQL_LENGTH));
1678                                 SysTryReturnResult(NID_IO, pSqlStr, E_OUT_OF_MEMORY, "The memory is insufficient.");
1679
1680                                 pSqlStr->Format(MAX_DATABASE_SQL_LENGTH, L"INSERT INTO encrypted.%ls SELECT * FROM %ls", tableName.GetPointer(), tableName.GetPointer());
1681
1682                                 sql.Append(*pSqlStr);
1683                                 r = pDatabase->ExecuteSql(sql, true);
1684                                 SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Propagating to the caller...", GetErrorMessage(r));
1685                                 sql.Clear();
1686                         }
1687                 }
1688         }
1689         else
1690         {
1691                 SysPropagate(NID_IO, r);
1692                 return r;
1693         }
1694
1695         sql.Append(L"DETACH DATABASE encrypted");
1696
1697         r = pDatabase->ExecuteSql(sql, true);
1698         SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Propagating to the caller...", GetErrorMessage(r));
1699
1700         return E_SUCCESS;
1701 }
1702
1703 _DatabaseImpl*
1704 _DatabaseImpl::GetInstance(Database& database)
1705 {
1706         return database.__pDatabaseImpl;
1707 }
1708
1709 const _DatabaseImpl*
1710 _DatabaseImpl::GetInstance(const Database& database)
1711 {
1712         return database.__pDatabaseImpl;
1713 }
1714
1715 }} // Tizen::Io
1716