Fix coding style according to tizen rule
[platform/core/security/drm-service-core-tizen.git] / tappsd / src / db / DTapps2SqliteDB.cpp
1 /*
2  * Copyright (c) 2000-2015 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Flora License, Version 1.1 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://floralicense.org/license/
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  * @file    DTapps2SqliteDB.cpp
17  * @brief   DataBase.
18  */
19 #include "DTapps2SqliteDB.h"
20 #include <map>
21 #include <memory>
22 #include <utility>
23
24 /* Define EXPORT_API temporary */
25 #ifndef EXPORT_API
26 #define EXPORT_API __attribute__((visibility("default")))
27 #endif
28
29 static dtapps_mutex_t dtapps_sqlite_db_mutex = PTHREAD_MUTEX_INITIALIZER;
30
31 typedef long int dtappsThreadID;
32
33 class DtappsDBConnectionInfo {
34 public:
35         DtappsDBConnectionInfo();
36         int countOpenConnection;
37         sqlite3 *pDBConnection;
38 };
39
40 using namespace std;
41 static std::map<dtappsThreadID, std::unique_ptr<DtappsDBConnectionInfo>>
42                 g_dtapps_sqlite_connection_table;
43
44 DtappsDBConnectionInfo::DtappsDBConnectionInfo()
45 {
46         countOpenConnection = 0;
47         pDBConnection = NULL;
48 }
49
50 class TAPPSDbApiLock {
51 public:
52         TAPPSDbApiLock();
53         ~TAPPSDbApiLock();
54 };
55
56 TAPPSDbApiLock::TAPPSDbApiLock()
57 {
58         DRM_TAPPS_FRQ_LOG("LOCK by TID = %ld", drmgettid());
59
60         if (0 != dtapps_mutex_lock(&dtapps_sqlite_db_mutex))
61                 DRM_TAPPS_EXCEPTION("Error while mutex locking.");
62 }
63
64 TAPPSDbApiLock::~TAPPSDbApiLock()
65 {
66         DRM_TAPPS_FRQ_LOG("UNLOCK by TID = %ld", drmgettid());
67
68         if (0 != dtapps_mutex_unlock(&dtapps_sqlite_db_mutex))
69                 DRM_TAPPS_EXCEPTION("Error while mutex unlocking");
70 }
71
72 #define __DTAPPS_DB_SQLITE_RETRY__  (10)
73
74 #define DTAPPS_SQLITE3_SQL_BEGIN_IMMEDIATE "BEGIN IMMEDIATE TRANSACTION"
75 #define DTAPPS_SQLITE3_SQL_COMMIT          "COMMIT TRANSACTION"
76 #define DTAPPS_SQLITE3_SQL_ROLLBACK        "ROLLBACK TRANSACTION"
77
78 /* DataBase Related API Wrappers */
79 BOOL DTappsDBOpen(void *&pDb, const char *CallingFun)
80 {
81         DRM_TAPPS_LOG("[%s]: started.Calling function = %s", __func__, CallingFun);
82
83         TAPPSDbApiLock Dblock;
84         dtappsThreadID id_curr_thread = drmgettid();
85
86         DRM_TAPPS_SECURE_LOG("id_curr_thread=[%ld]", id_curr_thread);
87
88         auto it = g_dtapps_sqlite_connection_table.find(id_curr_thread);
89
90         if (it != g_dtapps_sqlite_connection_table.end()) {
91                 DRM_TAPPS_FRQ_LOG("Connection already exists..");
92                 auto &pDBConnectionInfo = it->second;
93                 DRM_TAPPS_FRQ_LOG("pDBConnectionInfo=[0x%x]", pDBConnectionInfo.get());
94
95                 if (pDBConnectionInfo == NULL || pDBConnectionInfo->pDBConnection == NULL)
96                         return FALSE;
97
98                 DRM_TAPPS_FRQ_LOG("pDBConnectionInfo->countOpenConnection=[%d], "
99                                                   "pDBConnectionInfo->pDBConnection=[0x%x]",
100                                                   pDBConnectionInfo->countOpenConnection,
101                                                   pDBConnectionInfo->pDBConnection);
102
103                 ++(pDBConnectionInfo->countOpenConnection);
104                 pDb = pDBConnectionInfo->pDBConnection;
105         } else {
106                 DRM_TAPPS_LOG("no connection exists..");
107                 std::unique_ptr<DtappsDBConnectionInfo> pDBConnectionInfo(
108                         new(std::nothrow) DtappsDBConnectionInfo);
109
110                 if (pDBConnectionInfo == NULL)
111                         return FALSE;
112
113                 DRM_TAPPS_FRQ_LOG("Opening DB connection.");
114
115                 sqlite3 *h_db = NULL;
116                 int result = db_util_open(DTAPPS_DB_NAME, &h_db, 0);
117
118                 if (result != SQLITE_OK) {
119                         DRM_TAPPS_EXCEPTION("sqlite msg :[%d]%s", result, sqlite3_errmsg(h_db));
120                         DRM_TAPPS_SECURE_LOG("db name :%s", DTAPPS_DB_NAME);
121                         return FALSE;
122                 }
123
124                 DRM_TAPPS_FRQ_LOG("sqlite3_open() is success. h_db:%x", h_db);
125
126                 pDBConnectionInfo->countOpenConnection = 1;
127                 pDBConnectionInfo->pDBConnection = h_db;
128
129                 pDb = pDBConnectionInfo->pDBConnection;
130
131                 // Insert the node
132                 DRM_TAPPS_FRQ_LOG("pDBConnectionInfo->countOpenConnection=[%d], "
133                                                   "pDBConnectionInfo->pDBConnection=[0x%x]",
134                                                   pDBConnectionInfo->countOpenConnection,
135                                                   pDBConnectionInfo->pDBConnection);
136
137                 g_dtapps_sqlite_connection_table.emplace(
138                         std::make_pair(id_curr_thread, std::move(pDBConnectionInfo)));
139         }
140
141         DRM_TAPPS_LOG("This fn finishes successfully.");
142
143         return TRUE;
144 }
145
146 BOOL DTappsDBGet(void *&pDBConnection)
147 {
148         DRM_TAPPS_LOG("Inside %s", __func__);
149
150         TAPPSDbApiLock Dblock;
151         dtappsThreadID id_curr_thread = drmgettid();
152         pDBConnection = NULL;
153
154         DRM_TAPPS_LOG("id_curr_thread=[%ld]", id_curr_thread);
155
156         auto it = g_dtapps_sqlite_connection_table.find(id_curr_thread);
157
158         if (it == g_dtapps_sqlite_connection_table.end() ||
159                         it->second == NULL ||
160                         it->second->pDBConnection == NULL)
161                 return FALSE;
162
163         auto &pDBConnectionInfo = it->second;
164         DRM_TAPPS_FRQ_LOG("countOpenConnection=[%d], pDBConnection=[0x%x]",
165                                           pDBConnectionInfo->countOpenConnection,
166                                           pDBConnectionInfo->pDBConnection);
167
168         pDBConnection = pDBConnectionInfo->pDBConnection;
169
170         return TRUE;
171 }
172
173 BOOL DTappsDBClose(const char *CallingFun)
174 {
175         DRM_TAPPS_LOG("Inside %s Calling function = %s", __func__, CallingFun);
176
177         TAPPSDbApiLock Dblock;
178         dtappsThreadID id_curr_thread = drmgettid();
179
180         DRM_TAPPS_SECURE_LOG("id_curr_thread=[%ld]", id_curr_thread);
181
182         auto it = g_dtapps_sqlite_connection_table.find(id_curr_thread);
183
184         if (it == g_dtapps_sqlite_connection_table.end()) {
185                 return FALSE;
186         } else if (it->second == NULL || it->second->pDBConnection == NULL) {
187                 g_dtapps_sqlite_connection_table.erase(it);
188                 return FALSE;
189         }
190
191         auto &pDBConnectionInfo = it->second;
192         DRM_TAPPS_FRQ_LOG("countOpenConnection=[%d], pDBConnection=[0x%x]",
193                                           pDBConnectionInfo->countOpenConnection,
194                                           pDBConnectionInfo->pDBConnection);
195
196         int countConnection = --(pDBConnectionInfo->countOpenConnection);
197
198         DRM_TAPPS_LOG(" countConnection=[%d] ", countConnection);
199
200         if (countConnection != 0)
201                 return TRUE;
202
203         DRM_TAPPS_LOG("closing DB connection info ");
204
205         sqlite3 *pDBConnection = it->second->pDBConnection;
206
207         DRM_TAPPS_LOG("finalizing all statements..pDBConnection=[0x%x]", pDBConnection);
208         sqlite3_stmt *pstmt = NULL;
209
210         while ((pstmt = sqlite3_next_stmt(pDBConnection, pstmt)) != NULL) {
211                 DRM_TAPPS_LOG("finalizing DB statement..pstmt=[0x%x]", pstmt);
212                 sqlite3_finalize(pstmt);
213         }
214
215         BOOL ret = TRUE;
216
217         DRM_TAPPS_LOG(" Closing DB connection..pDBConnection=[0x%x]", pDBConnection);
218
219         if (db_util_close(pDBConnection) != SQLITE_OK) {
220                 DRM_TAPPS_EXCEPTION("db_util_close failed. errmsg:%s",
221                                                         sqlite3_errmsg(pDBConnection));
222                 ret = FALSE;
223         }
224
225         // erase map element regardless sqlite handle resource releasement
226         // because it's not usable anymore.
227         DRM_TAPPS_LOG("erasing map entry..pDBConnection=[0x%x]", pDBConnection);
228         g_dtapps_sqlite_connection_table.erase(it);
229
230         return ret;
231 }
232
233 BOOL DTappsDBBeginImmedTrans(const char *CallingFun)
234 {
235         DRM_TAPPS_LOG("Inside %s, Calling function = %s", __func__, CallingFun);
236
237         dtappsThreadID id_curr_thread = drmgettid();
238
239         int count_try_db = 0, rc = -1;
240
241         DRM_TAPPS_SECURE_LOG("id_curr_thread=[%ld]", id_curr_thread);
242
243         auto it = g_dtapps_sqlite_connection_table.find(id_curr_thread);
244
245         if (it == g_dtapps_sqlite_connection_table.end())
246                 return FALSE;
247
248         auto &pDBConnectionInfo = it->second;
249         DRM_TAPPS_FRQ_LOG("countOpenConnection=[%d], DBConnection=[0x%x]",
250                                           pDBConnectionInfo->countOpenConnection,
251                                           pDBConnectionInfo->pDBConnection);
252
253         auto pDBConnection = pDBConnectionInfo->pDBConnection;
254
255         DRM_TAPPS_LOG("Beginning DB operations..pDBConnection=[0x%x]", pDBConnection);
256
257         while (true) {
258                 DRM_TAPPS_LOG("START BEGIN");
259                 rc = sqlite3_exec(pDBConnection, DTAPPS_SQLITE3_SQL_BEGIN_IMMEDIATE, NULL, NULL,
260                                                   NULL);
261
262                 DRM_TAPPS_FRQ_LOG("START BEGIN rc=%d", rc);
263
264                 if (rc != SQLITE_OK) {
265                         DRM_TAPPS_FRQ_LOG("pDBConnection=0x%x rc=%d ErrMsg:%s", pDBConnection, rc,
266                                                           sqlite3_errmsg(pDBConnection));
267
268                         if (rc == SQLITE_BUSY) {
269                                 dtapps_sleep(2, 0);
270                                 DRM_TAPPS_FRQ_LOG("Tried [%d] times to begin", count_try_db);
271                                 count_try_db++;
272
273                                 if (count_try_db >= (int)__DTAPPS_DB_SQLITE_RETRY__) {
274                                         DRM_TAPPS_EXCEPTION("Error pDBConnection=0x%x rc=%d ErrMsg:%s",
275                                                                                 pDBConnection, rc,
276                                                                                 sqlite3_errmsg(pDBConnection));
277                                         MTHROW_BL
278                                 }
279                         } else {
280                                 DRM_TAPPS_EXCEPTION("Error pDBConnection=0x%x rc=%d ErrMsg:%s",
281                                                                         pDBConnection, rc,
282                                                                         sqlite3_errmsg(pDBConnection));
283                                 MTHROW_BL
284                         }
285                 } else {
286                         DRM_TAPPS_LOG("begin SUCCESS count_try_db=%d", count_try_db);
287                         break;
288                 }
289         }
290
291         DRM_TAPPS_LOG("This fn finishes successfully..pDBConnection=[0x%x]",
292                                   pDBConnection);
293
294         return TRUE;
295
296         MCATCH_B
297         DRM_TAPPS_EXCEPTION("This fn fails.. pDBConnection=[0x%x]", pDBConnection);
298         return FALSE;
299 }
300
301 BOOL DTappsDBCommit(const char *CallingFun)
302 {
303         DRM_TAPPS_LOG("Inside %s, Calling function = %s", __func__, CallingFun);
304         dtappsThreadID id_curr_thread = drmgettid();
305
306         int count_try_db_commit = 0, rc = -1;
307
308         DRM_TAPPS_SECURE_LOG("id_curr_thread=[%ld]", id_curr_thread);
309
310         auto it = g_dtapps_sqlite_connection_table.find(id_curr_thread);
311
312         if (it == g_dtapps_sqlite_connection_table.end())
313                 return FALSE;
314
315         auto &pDBConnectionInfo = it->second;
316         DRM_TAPPS_FRQ_LOG("countOpenConnection=[%d], pDBConnection=[0x%x]",
317                                           pDBConnectionInfo->countOpenConnection,
318                                           pDBConnectionInfo->pDBConnection);
319
320         auto pDBConnection = pDBConnectionInfo->pDBConnection;
321
322         DRM_TAPPS_LOG("Commiting DB operations..pDBConnection=[0x%x]", pDBConnection);
323
324         while (true) {
325                 DRM_TAPPS_FRQ_LOG("START Commit");
326                 rc = sqlite3_exec(pDBConnection, DTAPPS_SQLITE3_SQL_COMMIT, NULL, NULL, NULL);
327                 DRM_TAPPS_FRQ_LOG("START Commit rc=%d", rc);
328
329                 if (rc != SQLITE_OK) {
330                         DRM_TAPPS_FRQ_LOG("pDBConnection=0x%x rc=%d ErrMsg:%s", pDBConnection, rc,
331                                                           sqlite3_errmsg(pDBConnection));
332
333                         if (rc == SQLITE_BUSY) {
334                                 dtapps_sleep(2, 0);
335                                 DRM_TAPPS_FRQ_LOG("Tried [%d] times to Commit", count_try_db_commit);
336                                 count_try_db_commit++;
337
338                                 if (count_try_db_commit >= (int)__DTAPPS_DB_SQLITE_RETRY__) {
339                                         DRM_TAPPS_EXCEPTION("Error pDBConnection=0x%x rc=%d ErrMsg:%s",
340                                                                                 pDBConnection, rc,
341                                                                                 sqlite3_errmsg(pDBConnection));
342                                         MTHROW_BL
343                                 }
344                         } else {
345                                 DRM_TAPPS_EXCEPTION("Error pDBConnection=0x%x rc=%d ErrMsg:%s",
346                                                                         pDBConnection, rc,
347                                                                         sqlite3_errmsg(pDBConnection));
348                                 MTHROW_BL
349                         }
350                 } else {
351                         DRM_TAPPS_FRQ_LOG("Commit SUCCESS count_try_db_commit=%d",
352                                                           count_try_db_commit);
353                         break;
354                 }
355         }
356
357         DRM_TAPPS_LOG("Finishes successfully..pDBConnection=[0x%x]", pDBConnection);
358
359         return TRUE;
360
361         MCATCH_B
362         DRM_TAPPS_EXCEPTION("Fails.. pDBConnection=[0x%x]", pDBConnection);
363
364         return FALSE;
365 }
366
367 BOOL DTappsDBRollback(const char *CallingFun)
368 {
369         DRM_TAPPS_LOG("Inside %s, Calling function = %s", __func__, CallingFun);
370
371         dtappsThreadID id_curr_thread = drmgettid();
372
373         int count_try_db_rollback = 0, rc = -1;
374
375         DRM_TAPPS_SECURE_LOG("id_curr_thread=[%ld]", id_curr_thread);
376
377         auto it = g_dtapps_sqlite_connection_table.find(id_curr_thread);
378
379         if (it == g_dtapps_sqlite_connection_table.end())
380                 return FALSE;
381
382         auto &pDBConnectionInfo = it->second;
383         DRM_TAPPS_SECURE_LOG("[%s] countOpenConnection=[%d], pDBConnection=[0x%x]",
384                                                  __func__, pDBConnectionInfo->countOpenConnection,
385                                                  pDBConnectionInfo->pDBConnection);
386
387         auto pDBConnection = pDBConnectionInfo->pDBConnection;
388
389         DRM_TAPPS_LOG("Rollback DB operations..pDBConnection=[0x%x]", pDBConnection);
390
391         while (true) {
392                 DRM_TAPPS_FRQ_LOG("START Rollback");
393                 rc = sqlite3_exec(pDBConnection, DTAPPS_SQLITE3_SQL_ROLLBACK, NULL, NULL, NULL);
394                 DRM_TAPPS_FRQ_LOG("START  Rollback rc=%d", rc);
395
396                 if (rc != SQLITE_OK) {
397                         DRM_TAPPS_FRQ_LOG("pDBConnection=0x%x rc=%d ErrMsg:%s", pDBConnection, rc,
398                                                           sqlite3_errmsg(pDBConnection));
399
400                         if (rc == SQLITE_BUSY) {
401                                 dtapps_sleep(2, 0);
402                                 DRM_TAPPS_FRQ_LOG("Tried [%d] times to Rollback", count_try_db_rollback);
403                                 count_try_db_rollback++;
404
405                                 if (count_try_db_rollback >= (int)__DTAPPS_DB_SQLITE_RETRY__) {
406                                         DRM_TAPPS_EXCEPTION("Error pDBConnection=0x%x rc=%d ErrMsg:%s",
407                                                                                 pDBConnection, rc,
408                                                                                 sqlite3_errmsg(pDBConnection));
409                                         MTHROW_BL
410                                 }
411                         } else {
412                                 DRM_TAPPS_EXCEPTION("Error pDBConnection=0x%x rc=%d ErrMsg:%s",
413                                                                         pDBConnection, rc,
414                                                                         sqlite3_errmsg(pDBConnection));
415                                 MTHROW_BL
416                         }
417                 } else {
418                         DRM_TAPPS_FRQ_LOG("Rollback SUCCESS count_try_db_rollback=%d",
419                                                           count_try_db_rollback);
420                         break;
421                 }
422         }
423
424         DRM_TAPPS_LOG("This fn finishes successfully..pDBConnection=[0x%x]",
425                                   pDBConnection);
426
427         return TRUE;
428
429         MCATCH_B
430         DRM_TAPPS_EXCEPTION("This fn fails.. pDBConnection=[0x%x]", pDBConnection);
431
432         return FALSE;
433 }
434
435
436 BOOL DTappsExecuteSQL(void *pDB, const char *query)
437 {
438         int count_try_db_exe = 0, rc = 0;
439         sqlite3 *h_db = (sqlite3 *)pDB;
440
441         TAPPSDbApiLock Dblock;
442
443         while (true) {
444                 rc = sqlite3_exec(h_db, query, NULL, NULL, NULL);
445                 DRM_TAPPS_FRQ_LOG("EXECUTE rc=%d", rc);
446
447                 if (rc != SQLITE_OK) {
448                         if (rc == SQLITE_BUSY) {
449                                 dtapps_sleep(2, 0);
450                                 DRM_TAPPS_FRQ_LOG("Tried [%d] times to execute", count_try_db_exe);
451                                 count_try_db_exe++;
452
453                                 if (count_try_db_exe >= (int)__DTAPPS_DB_SQLITE_RETRY__) {
454                                         DRM_TAPPS_EXCEPTION("h_db=0x%x rc=%d ErrMsg:%s count_try_db_exe=%d",
455                                                                                 h_db, rc, sqlite3_errmsg(h_db), count_try_db_exe);
456                                         DRM_TAPPS_EXCEPTION("query=[%s]", query);
457                                         return FALSE;
458                                 }
459                         } else {
460                                 DRM_TAPPS_EXCEPTION("h_db=0x%x rc=%d ErrMsg:%s", h_db, rc,
461                                                                         sqlite3_errmsg(h_db));
462                                 DRM_TAPPS_EXCEPTION("query=[%s]", query);
463                                 return FALSE;
464                         }
465                 } else {
466                         DRM_TAPPS_FRQ_LOG("EXECUTE SUCCESS count_try_db_exe=%d", count_try_db_exe);
467                         break;
468                 }
469         }
470
471         return TRUE;
472 }
473
474
475 BOOL DTappsSQLGetTable(void *pDB, const char *query,
476                                            TAPPSSqliteSelectTable *select_table)
477 {
478         int rc = 0;
479         sqlite3 *h_db = (sqlite3 *)pDB;
480
481         DRM_TAPPS_FRQ_LOG("h_db=0x%x query=%s", h_db, query);
482         TAPPSDbApiLock Dblock;
483         select_table->handle = h_db;
484
485         DRM_TAPPS_FRQ_LOG("select_table->handle=%x", select_table->handle);
486
487         int count_try_db_select = 0;
488
489         while (true) {
490                 rc = sqlite3_get_table(h_db, query, &select_table->result,
491                                                            &select_table->n_rows, &select_table->n_cols, NULL);
492
493                 DRM_TAPPS_FRQ_LOG("SELECT rc=%d", rc);
494
495                 if (rc != SQLITE_OK) {
496                         if (rc == SQLITE_BUSY) {
497                                 dtapps_sleep(2, 0);
498                                 DRM_TAPPS_FRQ_LOG("SELECT Tried [%d] times to select",
499                                                                   count_try_db_select);
500
501                                 count_try_db_select++;
502
503                                 if (count_try_db_select >= (int)__DTAPPS_DB_SQLITE_RETRY__) {
504                                         DRM_TAPPS_EXCEPTION("SELECT  h_db=0x%x rc=%d ErrMsg:%s "
505                                                                                 "count_try_db_select=%d",
506                                                                                 h_db, rc, sqlite3_errmsg(h_db),
507                                                                                 count_try_db_select);
508                                         DRM_TAPPS_EXCEPTION("query=[%s]", query);
509
510                                         return FALSE;
511                                 }
512                         } else {
513                                 DRM_TAPPS_EXCEPTION("SELECT h_db=0x%x rc=%d ErrMsg:%s", h_db, rc,
514                                                                         sqlite3_errmsg(h_db));
515                                 DRM_TAPPS_EXCEPTION("query=[%s]", query);
516
517                                 return FALSE;
518                         }
519                 } else {
520                         DRM_TAPPS_FRQ_LOG("SELECT SUCCESS count_try_db_select=%d",
521                                                           count_try_db_select);
522                         break;
523                 }
524         }
525
526         DRM_TAPPS_FRQ_LOG("n_rows=%d n_cols=%d", select_table->n_rows,
527                                           select_table->n_cols);
528
529         return TRUE;
530 }
531
532 extern const char *dtappsCreateTableSQLData[];
533
534 char *DTappsGetSQLCreateTable(const char *tableName)
535 {
536         int index = 0;
537
538         if (!tableName)
539                 return NULL;
540
541         DRM_TAPPS_FRQ_LOG("tableName = %s", tableName);
542
543         while (dtappsCreateTableSQLData[index]) {
544                 if (TAPPS_strnicmp(dtappsCreateTableSQLData[index], tableName,
545                                                    TAPPS_STRLEN(tableName)) == 0) {
546                         char *sql = (char *)dtappsCreateTableSQLData[index];
547                         sql = sql + TAPPS_STRLEN(dtappsCreateTableSQLData[index]) + 1;
548
549                         DRM_TAPPS_FRQ_LOG("sql query = %s", sql);
550
551                         return sql;
552                 } else {
553                         index++;
554                 }
555         }
556
557         DRM_TAPPS_EXCEPTION("Specified Table Name is not Valid!!!");
558
559         return NULL;
560 }
561
562 void *DTappsStmtPrepare(void *pDB, const char *query)
563 {
564         int rc = 0;
565         sqlite3 *h_db = (sqlite3 *)pDB;
566         sqlite3_stmt *stmt = 0;
567
568         DRM_TAPPS_FRQ_LOG("h_db=0x%x query=%s", h_db, query);
569
570         TAPPSDbApiLock Dblock;
571
572         if (0 == TAPPS_strnicmp(query, "SELECT", 6)) {
573                 DRM_TAPPS_EXCEPTION("Doesn't support 'Select' query h_db=0x%x query=%s",
574                                                         h_db, query);
575                 return NULL;
576         }
577
578         rc = sqlite3_prepare(h_db, query, -1, &stmt, NULL);
579
580         DRM_TAPPS_FRQ_LOG("%s: rc=%d query=%s stmt=0x%x", __func__, rc, query, stmt);
581
582         if (rc != SQLITE_OK) {
583                 DRM_TAPPS_EXCEPTION("DTappsStmtPrepare: h_db=0x%x err: %s", h_db,
584                                                         sqlite3_errmsg(h_db));
585                 DRM_TAPPS_EXCEPTION("DTappsStmtPrepare: query: %s", query);
586                 return NULL;
587         }
588
589         return stmt;
590 }
591
592
593 int DTappsStmtBindParam(void *pStmt, unsigned int dIdx, unsigned int Type,
594                                                 void *pParam, unsigned int dParamSize)
595 {
596         int rc = 0;
597         sqlite3_stmt *stmt = (sqlite3_stmt *)pStmt;
598
599         DRM_TAPPS_FRQ_LOG("Enter");
600
601         TAPPSDbApiLock Dblock;
602
603         if (stmt == NULL) {
604                 DRM_TAPPS_EXCEPTION("DTappsStmtBindParam: stmt is NULL");
605                 return FALSE;
606         }
607
608         /*
609          * Notice:
610          *  The parameter index in SQL starts from 1 in sqlite3.
611          */
612         switch (Type) {
613         case TAPPSDB_TYPE_NONE:
614                 rc = sqlite3_bind_null(stmt, dIdx + 1);
615
616                 break;
617
618         case TAPPSDB_TYPE_INT:
619                 rc = sqlite3_bind_int(stmt, dIdx + 1, *(int *)pParam);
620                 DRM_TAPPS_FRQ_LOG("rc=%d type=%d pParam=%d", rc, Type, *(int *)pParam);
621
622                 break;
623
624         case TAPPSDB_TYPE_DATETIME:
625         case TAPPSDB_TYPE_CHAR:
626         case TAPPSDB_TYPE_VARCHAR:
627                 rc = sqlite3_bind_text(stmt, dIdx + 1, (char *)pParam, dParamSize,
628                                                            SQLITE_TRANSIENT);
629                 DRM_TAPPS_FRQ_LOG("rc=%d type=%d dParamSize=%d pParam=%s", rc, Type,
630                                                   dParamSize, pParam);
631
632                 break;
633
634         case TAPPSDB_TYPE_BINARY:
635         case TAPPSDB_TYPE_BLOB:
636 #if 0
637                 {
638                         char *packet64 = NULL;
639                         unsigned int packet64_size = 0;
640
641                         if (CMStringUtil::GetBase64Encode((unsigned char *)pParam, dParamSize,
642                                                                                           &packet64) == true) {
643                                 packet64_size = MSTRLEN(packet64);
644                                 rc = sqlite3_bind_blob(stmt, dIdx + 1, packet64, packet64_size,
645                                                                            SQLITE_TRANSIENT);
646                                 DRM_OMA_FRQ_LOG("%s: rc=%d type=%d packet64_size=%d packet64=%s \n", __func__,
647                                                                 rc, Type, packet64_size, packet64);
648
649                                 if (packet64) MDELETES0(packet64);
650                         }
651                 }
652
653 #endif
654                 break;
655
656         case TAPPSDB_TYPE_UNKNOWN:
657         default:
658                 break;
659         }
660
661         if (rc != SQLITE_OK) {
662                 DRM_TAPPS_EXCEPTION("DTappsStmtBindParam: errno: %d", rc);
663                 return FALSE;
664         }
665
666         return TRUE;
667 }
668
669
670 int DTappsStmtExecute(void *pStmt)
671 {
672         int CntTryStmtExe = 0, rc = -1;
673         sqlite3_stmt *stmt = (sqlite3_stmt *)pStmt;
674
675         DRM_TAPPS_FRQ_LOG("%s:stmt=0x%x", __func__, stmt);
676
677         TAPPSDbApiLock Dblock;
678
679         if (stmt == NULL) {
680                 DRM_TAPPS_EXCEPTION("stmt is NULL");
681                 return FALSE;
682         }
683
684         while (true) {
685                 rc = sqlite3_step(stmt);
686
687                 DRM_TAPPS_FRQ_LOG("rc=%d", rc);
688
689                 if (rc != SQLITE_DONE) {
690                         if (rc == SQLITE_BUSY) {
691                                 dtapps_sleep(2, 0);
692                                 DRM_TAPPS_FRQ_LOG("Tried [%d] times to execute stmt", CntTryStmtExe);
693
694                                 CntTryStmtExe++;
695
696                                 if (CntTryStmtExe >= (int)__DTAPPS_DB_SQLITE_RETRY__) {
697                                         DRM_TAPPS_EXCEPTION("stmt=0x%x rc=%d CntTryStmtExe=%d", stmt, rc,
698                                                                                 CntTryStmtExe);
699                                         return FALSE;
700                                 }
701                         } else {
702                                 DRM_TAPPS_EXCEPTION("stmt=0x%x rc=%d", stmt, rc);
703                                 return FALSE;
704                         }
705                 } else {
706                         DRM_TAPPS_FRQ_LOG("STMT EXECUTE SUCCESS CntTryStmtExe=%d", CntTryStmtExe);
707                         return TRUE;
708                 }
709         }
710 }
711
712 int DTappsStmtRelease(void *pStmt)
713 {
714         int rc = 0;
715         sqlite3_stmt *stmt = (sqlite3_stmt *)pStmt;
716         DRM_TAPPS_FRQ_LOG("%s:Enter", __func__);
717         TAPPSDbApiLock Dblock;
718
719         if (!stmt)
720                 return FALSE;
721
722         rc = sqlite3_finalize(stmt);
723
724         DRM_TAPPS_FRQ_LOG("rc=%d", rc);
725
726         if (rc != SQLITE_OK) {
727                 DRM_TAPPS_EXCEPTION("DTappsStmtRelease() Errmsg : %d", rc);
728                 return FALSE;
729         }
730
731         return TRUE;
732 }
733
734
735 BOOL DTapps_DB_Install(const char *sql_query)
736 {
737         void *pDb = NULL;
738         BOOL ret_value = FALSE;
739
740         if (sql_query == NULL) {
741                 DRM_TAPPS_EXCEPTION("Parameter NULL!!!, sql_query = %p", sql_query);
742                 return FALSE;
743         }
744
745         DRM_TAPPS_LOG("Open DB......");
746
747         ret_value = DTappsDBOpen(pDb, __func__);
748
749         if (ret_value != TRUE) {
750                 DRM_TAPPS_EXCEPTION("DB Open Failed!! ret_value = %d", ret_value);
751                 return FALSE;
752         }
753
754         DRM_TAPPS_LOG("Begin Transaction........");
755
756         ret_value = DTappsDBBeginImmedTrans(__func__);
757
758         if (ret_value != TRUE) {
759                 DRM_TAPPS_EXCEPTION("DB Begin Transaction ret_value = %d", ret_value);
760                 goto Error_Exit;
761         }
762
763         DRM_TAPPS_LOG("Execute SQL to Insert Contents into Table........");
764
765         ret_value = DTappsExecuteSQL(pDb, sql_query);
766
767         if (ret_value != TRUE) {
768                 DRM_TAPPS_EXCEPTION("Execute SQL Query Failed!! ret_value = %d", ret_value);
769                 goto Error_Exit;
770         }
771
772         DRM_TAPPS_LOG("Commit DB........");
773
774         ret_value = DTappsDBCommit(__func__);
775
776         if (ret_value != TRUE) {
777                 DRM_TAPPS_EXCEPTION("Commit DB Failed!! ret_value = %d", ret_value);
778                 goto Error_Exit;
779         }
780
781         DRM_TAPPS_LOG("Close DB........");
782
783         ret_value = DTappsDBClose(__func__);
784
785         if (ret_value != TRUE) {
786                 DRM_TAPPS_EXCEPTION("Close DB Failed!! ret_value = %d", ret_value);
787                 goto Error_Exit;
788         }
789
790         DRM_TAPPS_LOG("Install DB Operartion Successful!!!");
791
792         return TRUE;
793
794 Error_Exit:
795
796         ret_value = DTappsDBRollback(__func__);
797
798         if (ret_value != TRUE)
799                 DRM_TAPPS_EXCEPTION("Rollback DB Failed!! ret_value = %d", ret_value);
800
801         ret_value = DTappsDBClose(__func__);
802
803         if (ret_value != TRUE)
804                 DRM_TAPPS_EXCEPTION("Close DB Failed!! ret_value = %d", ret_value);
805
806         return FALSE;
807 }
808
809 BOOL DTapps_Read_DB(const char *sql_query, TAPPSSqliteSelectTable *select_table)
810 {
811         void *pDb = NULL;
812         BOOL ret_value = FALSE;
813
814         if (sql_query == NULL || select_table == NULL) {
815                 DRM_TAPPS_EXCEPTION("Parameters NULL, sql_query = %p, select_table = %p",
816                                                         sql_query, select_table);
817                 return FALSE;
818         }
819
820         DRM_TAPPS_LOG("Open DB......");
821
822         ret_value = DTappsDBOpen(pDb, __func__);
823
824         if (ret_value != TRUE) {
825                 DRM_TAPPS_EXCEPTION("DB Open Failed!! ret_value = %d", ret_value);
826                 return FALSE;
827         }
828
829         DRM_TAPPS_LOG("Begin Transaction........");
830
831         ret_value = DTappsDBBeginImmedTrans(__func__);
832
833         if (ret_value != TRUE) {
834                 DRM_TAPPS_EXCEPTION("DB Begin Transaction Failed!! ret_value = %d", ret_value);
835                 goto Error_Exit;
836         }
837
838         DRM_TAPPS_LOG("Get the Result Table........");
839
840         ret_value = DTappsSQLGetTable(pDb, sql_query, select_table);
841
842         if (ret_value != TRUE) {
843                 DRM_TAPPS_EXCEPTION("DB Get Table failed!! ret_value = %d", ret_value);
844                 goto Error_Exit;
845         }
846
847         DRM_TAPPS_LOG("Close DB........");
848
849         ret_value = DTappsDBClose(__func__);
850
851         if (ret_value != TRUE) {
852                 DRM_TAPPS_EXCEPTION("DB Close failed!! ret_value = %d", ret_value);
853                 goto Error_Exit;
854         }
855
856         DRM_TAPPS_LOG("Reading from DB Successful!!!");
857
858         return TRUE;
859
860 Error_Exit:
861
862         ret_value = DTappsDBRollback(__func__);
863
864         if (ret_value != TRUE)
865                 DRM_TAPPS_EXCEPTION("Rollback DB Failed!! ret_value = %d", ret_value);
866
867         ret_value = DTappsDBClose(__func__);
868
869         if (ret_value != TRUE)
870                 DRM_TAPPS_EXCEPTION("Close DB Failed!! ret_value = %d", ret_value);
871
872         DRM_TAPPS_EXCEPTION("Reading DB function failed!!!");
873
874         return FALSE;
875 }