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