060d0cab1e85f166cc946059153eeb5e892c1f81
[platform/core/appfw/ail.git] / src / ail_db.c
1 /*
2  * ail
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>, Jaeho Lee <jaeho81.lee@samsung.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21
22
23
24
25 #include <stdlib.h>
26 #include <string.h>
27 #include <db-util.h>
28 #include <errno.h>
29 #include <glib.h>
30 #include <grp.h>
31 #include <pwd.h>
32 #include <sys/smack.h>
33 #include <sys/stat.h>
34 #include <tzplatform_config.h>
35 #include "ail_private.h"
36 #include "ail_db.h"
37
38 #define GLOBAL_USER tzplatform_getuid(TZ_SYS_GLOBALAPP_USER)
39 #define BUFSIZE 4096
40 #define QUERY_ATTACH "attach database '%s' as Global"
41 #define QUERY_CREATE_VIEW_APP "CREATE temp VIEW app_info as select distinct * from (select  * from main.app_info m union select * from Global.app_info g)"
42
43 #define QUERY_CREATE_VIEW_LOCAL "CREATE temp VIEW localname as select distinct * from (select  * from main.localname m union select * from Global.localname g)"
44
45 #define SET_SMACK_LABEL(x,uid) \
46         if(smack_setlabel((x), (((uid) == GLOBAL_USER)?"*":"User"), SMACK_LABEL_ACCESS)) _E("failed chsmack -a \"User/*\" %s", x); \
47         else _D("chsmack -a \"User/*\" %s", x);
48         
49         
50 #define retv_with_dbmsg_if(expr, val) do { \
51         if (expr) { \
52                 _E("db_info.dbUserro: %s", sqlite3_errmsg(db_info.dbUserro)); \
53                 _E("db_info.dbGlobalro: %s", sqlite3_errmsg(db_info.dbGlobalro)); \
54                 _E("db_info.dbUserrw: %s", sqlite3_errmsg(db_info.dbUserrw)); \
55                 _E("db_info.dbGlobalrw: %s", sqlite3_errmsg(db_info.dbGlobalrw)); \
56                 _E("db_info.dbUserro errcode: %d", sqlite3_extended_errcode(db_info.dbUserro)); \
57                 _E("db_info.dbGlobalro errcode: %d", sqlite3_extended_errcode(db_info.dbGlobalro)); \
58                 _E("db_info.dbUserrw errcode: %d", sqlite3_extended_errcode(db_info.dbUserrw)); \
59                 _E("db_info.dbGlobalrw errcode: %d", sqlite3_extended_errcode(db_info.dbGlobalrw)); \
60                 return (val); \
61         } \
62 } while (0)
63
64 static __thread struct {
65         sqlite3         *dbUserro;
66         sqlite3         *dbGlobalro;
67         sqlite3         *dbUserrw;
68         sqlite3         *dbGlobalrw;
69 } db_info = {
70         .dbUserro = NULL,
71         .dbGlobalro = NULL,
72         .dbUserrw = NULL,
73         .dbGlobalrw = NULL
74 };
75   static __thread      sqlite3         *dbInit = NULL;
76
77 static int ail_db_change_perm(const char *db_file, uid_t uid)
78 {
79         char buf[BUFSIZE];
80         char journal_file[BUFSIZE];
81         char *files[3];
82         int ret, i;
83         struct passwd *userinfo = NULL;
84         files[0] = (char *)db_file;
85         files[1] = journal_file;
86         files[2] = NULL;
87
88         retv_if(!db_file, AIL_ERROR_FAIL);
89         if(getuid() != OWNER_ROOT) //At this time we should be root to apply this
90                         return AIL_ERROR_OK;
91     userinfo = getpwuid(uid);
92     if (!userinfo) {
93                 _E("FAIL: user %d doesn't exist", uid);
94                 return AIL_ERROR_FAIL;
95         }
96         snprintf(journal_file, sizeof(journal_file), "%s%s", db_file, "-journal");
97
98         for (i = 0; files[i]; i++) {
99                 // Compare git_t type and not group name
100                 ret = chown(files[i], uid, userinfo->pw_gid);
101                 SET_SMACK_LABEL(files[i],uid)
102                 if (ret == -1) {
103                         strerror_r(errno, buf, sizeof(buf));
104                         _E("FAIL : chown %s %d.%d, because %s", db_file, uid, userinfo->pw_gid, buf);
105                         return AIL_ERROR_FAIL;
106                 }
107
108                 ret = chmod(files[i], S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
109                 if (ret == -1) {
110                         strerror_r(errno, buf, sizeof(buf));
111                         _E("FAIL : chmod %s 0664, because %s", db_file, buf);
112                         return AIL_ERROR_FAIL;
113                 }
114         }
115
116         return AIL_ERROR_OK;
117 }
118
119 char* ail_get_icon_path(uid_t uid)
120 {
121         char *result = NULL;
122         struct group *grpinfo = NULL;
123         char *dir = NULL;
124         struct passwd *userinfo = getpwuid(uid);
125
126         if (uid == 0) {
127                 _E("FAIL : Root is not allowed user! please fix it replacing with DEFAULT_USER");
128                 return NULL;
129         }
130         if (uid != GLOBAL_USER) {
131                 if (userinfo == NULL) {
132                         _E("getpwuid(%d) returns NULL !", uid);
133                         return NULL;
134                 }
135                 grpinfo = getgrnam("users");
136                 if (grpinfo == NULL) {
137                         _E("getgrnam(users) returns NULL !");
138                         return NULL;
139                 }
140                 // Compare git_t type and not group name
141                 if (grpinfo->gr_gid != userinfo->pw_gid) {
142                         _E("UID [%d] does not belong to 'users' group!", uid);
143                         return NULL;
144                 }
145                 asprintf(&result, "%s/.applications/icons/", userinfo->pw_dir);
146         } else {
147                 result = tzplatform_mkpath(TZ_SYS_RW_ICONS, "/");
148         }
149         int ret = mkdir(result, S_IRWXU | S_IRGRP | S_IXGRP | S_IXOTH);
150         if (ret == -1 && errno != EEXIST) {
151                 _E("FAIL : to create directory %s %d", result, errno);
152         } else if (getuid() == OWNER_ROOT) {
153                 ret = chown(result, uid, ((grpinfo)?grpinfo->gr_gid:0));
154                 SET_SMACK_LABEL(result,uid)
155                 if (ret == -1) {
156                         char buf[BUFSIZE];
157                         strerror_r(errno, buf, sizeof(buf));
158                         _E("FAIL : chown %s %d.%d, because %s", result, uid, ((grpinfo)?grpinfo->gr_gid:0), buf);
159                 }
160         }
161         return result;
162 }
163
164 char* ail_get_app_DB_journal(uid_t uid)
165 {
166
167         char *app_path = ail_get_app_DB(uid);
168         char* result = NULL;
169
170         asprintf(&result, "%s-journal", app_path);
171         return  result;
172 }
173
174 char* ail_get_app_DB(uid_t uid)
175 {
176         char *result = NULL;
177         struct group *grpinfo = NULL;
178         char *dir = NULL;
179         struct passwd *userinfo = getpwuid(uid);
180
181         if (uid == 0) {
182                 _E("FAIL : Root is not allowed! switch to DEFAULT_USER");
183                 return NULL;
184         }
185         if (uid != GLOBAL_USER) {
186                 if (userinfo == NULL) {
187                         _E("getpwuid(%d) returns NULL !", uid);
188                         return NULL;
189                 }
190                 grpinfo = getgrnam("users");
191                 if (grpinfo == NULL) {
192                         _E("getgrnam(users) returns NULL !");
193                         return NULL;
194                 }
195                 // Compare git_t type and not group name
196                 if (grpinfo->gr_gid != userinfo->pw_gid) {
197                         _E("UID [%d] does not belong to 'users' group!", uid);
198                         return NULL;
199                 }
200                 asprintf(&result, "%s/.applications/dbspace/.app_info.db", userinfo->pw_dir);
201         } else {
202                         result = strdup(APP_INFO_DB_FILE);
203         }
204         char *temp = strdup(result);
205         dir = strrchr(temp, '/');
206         if(!dir)
207         {
208                 free(temp);
209                 return result;
210         }
211         *dir = 0;
212                 int ret = mkdir(temp, S_IRWXU | S_IRGRP | S_IXGRP | S_IXOTH);
213                 if (ret == -1 && errno != EEXIST) {
214                         _E("FAIL : to create directory %s %d", temp, errno);
215                 } else if (getuid() == OWNER_ROOT) {
216                         ret = chown(temp, uid, ((grpinfo)?grpinfo->gr_gid:0));
217                         SET_SMACK_LABEL(temp,uid)
218                         if (ret == -1) {
219                                 char buf[BUFSIZE];
220                                 strerror_r(errno, buf, sizeof(buf));
221                                 _E("FAIL : chown %s %d.%d, because %s", temp, uid, ((grpinfo)?grpinfo->gr_gid:0), buf);
222                         }
223                 }
224         free(temp);
225         return result;
226 }
227
228 char* al_get_desktop_path(uid_t uid)
229 {
230         char *result = NULL;
231         struct group *grpinfo = NULL;
232         char *dir = NULL;
233         struct passwd *userinfo = getpwuid(uid);
234
235         if (uid == 0) {
236                 _E("FAIL : Root is not allowed user! please fix it replacing with DEFAULT_USER");
237                 return NULL;
238         }
239         if (uid != GLOBAL_USER) {
240                 if (userinfo == NULL) {
241                         _E("getpwuid(%d) returns NULL !", uid);
242                         return NULL;
243                 }
244                 grpinfo = getgrnam("users");
245                 if (grpinfo == NULL) {
246                         _E("getgrnam(users) returns NULL !");
247                         return NULL;
248                 }
249                 // Compare git_t type and not group name
250                 if (grpinfo->gr_gid != userinfo->pw_gid) {
251                         _E("UID [%d] does not belong to 'users' group!", uid);
252                         return NULL;
253                 }
254                 asprintf(&result, "%s/.applications/desktop/", userinfo->pw_dir);
255         } else {
256                 result = tzplatform_mkpath(TZ_SYS_RW_DESKTOP_APP, "/");
257         }
258                 int ret = mkdir(result, S_IRWXU | S_IRGRP | S_IXGRP | S_IXOTH);
259                 if (ret == -1 && errno != EEXIST) {
260                         _E("FAIL : to create directory %s %d", result, errno);
261                 } else if (getuid() == OWNER_ROOT) {
262                         ret = chown(result, uid, ((grpinfo)?grpinfo->gr_gid:0));
263                         SET_SMACK_LABEL(result,uid)
264                         if (ret == -1) {
265                                 char buf[BUFSIZE];
266                                 strerror_r(errno, buf, sizeof(buf));
267                                 _E("FAIL : chown %s %d.%d, because %s", result, uid, ((grpinfo)?grpinfo->gr_gid:0), buf);
268                         }
269                 }
270         return result;
271 }
272
273
274 static ail_error_e db_do_prepare(sqlite3 *db, const char *query, sqlite3_stmt **stmt)
275 {
276         int ret;
277
278         retv_if(!query, AIL_ERROR_INVALID_PARAMETER);
279         retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
280         retv_if(!db, AIL_ERROR_DB_FAILED);
281
282         ret = sqlite3_prepare_v2(db, query, strlen(query), stmt, NULL);
283         if (ret != SQLITE_OK) {
284                 _E("%s\n", sqlite3_errmsg(db));
285                 return AIL_ERROR_DB_FAILED;
286         } else
287                 return AIL_ERROR_OK;
288 }
289
290 ail_error_e db_open(db_open_mode mode, uid_t uid)
291 {
292         int ret;
293         int changed = 0;
294         int i;
295         const char *tbls[3] = {
296                 "CREATE TABLE app_info "
297                 "(package TEXT PRIMARY KEY, "
298                 "exec TEXT DEFAULT 'No Exec', "
299                 "name TEXT DEFAULT 'No Name', "
300                 "type TEXT DEFAULT 'Application', "
301                 "icon TEXT DEFAULT 'No Icon', "
302                 "categories TEXT, "
303                 "version TEXT, "
304                 "mimetype TEXT, "
305                 "x_slp_service TEXT, "
306                 "x_slp_packagetype TEXT, "
307                 "x_slp_packagecategories TEXT, "
308                 "x_slp_packageid TEXT, "
309                 "x_slp_uri TEXT, "
310                 "x_slp_svc TEXT, "
311                 "x_slp_exe_path TEXT, "
312                 "x_slp_appid TEXT, "
313                 "x_slp_pkgid TEXT, "
314                 "x_slp_domain TEXT, "
315                 "x_slp_submodemainid TEXT, "
316                 "x_slp_installedstorage TEXT, "
317                 "x_slp_baselayoutwidth INTEGER DEFAULT 0, "
318                 "x_slp_installedtime INTEGER DEFAULT 0, "
319                 "nodisplay INTEGER DEFAULT 0, "
320                 "x_slp_taskmanage INTEGER DEFAULT 1, "
321                 "x_slp_multiple INTEGER DEFAULT 0, "
322                 "x_slp_removable INTEGER DEFAULT 1, "
323                 "x_slp_ishorizontalscale INTEGER DEFAULT 0, "
324                 "x_slp_enabled INTEGER DEFAULT 1, "
325                 "x_slp_submode INTEGER DEFAULT 0, "
326                 "desktop TEXT UNIQUE NOT NULL);",
327                 "CREATE TABLE localname (package TEXT NOT NULL, "
328                 "locale TEXT NOT NULL, "
329                 "name TEXT NOT NULL, "
330                 "x_slp_pkgid TEXT NOT NULL, PRIMARY KEY (package, locale));",
331
332                 NULL
333         };
334
335         char *db = ail_get_app_DB(uid);
336         char *global_db = ail_get_app_DB(GLOBAL_USER);
337
338         if (access(db, F_OK)) {
339                 if (AIL_ERROR_OK == db_util_open_with_options(db, &dbInit, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL))
340                 {
341                         for (i = 0; tbls[i] != NULL; i++) {
342                                 ret = do_db_exec(tbls[i], dbInit);
343                                 retv_if(ret != AIL_ERROR_OK, AIL_ERROR_DB_FAILED);
344                         }
345                         if(getuid() == OWNER_ROOT && AIL_ERROR_OK != ail_db_change_perm(db, uid)) {
346                                 _E("Failed to change permission\n");
347                         }
348                 } else {
349                         dbInit = NULL;
350                         _E("Failed to create table %s\n", db);
351                 }
352         }
353         if(dbInit) {
354                 ret = sqlite3_close(dbInit);
355                 retv_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
356                 dbInit = NULL;
357         }
358         if(mode & DB_OPEN_RO) {
359                 if(uid != GLOBAL_USER) {
360                         if (!db_info.dbUserro) {
361                                 db_util_open_with_options(db, &db_info.dbUserro, SQLITE_OPEN_READONLY, NULL);
362                                 char query_attach[AIL_SQL_QUERY_MAX_LEN];
363                                 char query_view_app[AIL_SQL_QUERY_MAX_LEN];
364                                 char query_view_local[AIL_SQL_QUERY_MAX_LEN];
365                                 snprintf(query_attach, AIL_SQL_QUERY_MAX_LEN, QUERY_ATTACH, global_db);
366                                 if (db_exec_usr_ro(query_attach) < 0) {
367                                         _D("executing query_attach : %s", query_attach );
368                                         goto error;
369                                 }
370                                 snprintf(query_view_app, AIL_SQL_QUERY_MAX_LEN, QUERY_CREATE_VIEW_APP);
371                                 if (db_exec_usr_ro(query_view_app) < 0) {
372                                         _D("executing query_attach : %s", query_view_app );
373                                         goto error;
374                                 }
375
376                                 snprintf(query_view_local, AIL_SQL_QUERY_MAX_LEN, QUERY_CREATE_VIEW_LOCAL);
377                                 if (db_exec_usr_ro(query_view_local) < 0) {
378                                         _D("executing query_attach : %s", query_view_local );
379                                         goto error;
380                                 }
381                         }
382                 } else {
383                         if (!db_info.dbGlobalro) {
384                                 ret = db_util_open_with_options(global_db, &db_info.dbGlobalro, SQLITE_OPEN_READONLY, NULL);
385                                 retv_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
386                         }
387                 }
388         }
389         if(mode & DB_OPEN_RW) {
390                 if(uid != GLOBAL_USER) {
391                         if(!db_info.dbUserrw){
392                                 ret = db_util_open(db, &db_info.dbUserrw, 0);
393                         }
394                 } else {
395                         if(!db_info.dbGlobalrw){
396                                 ret = db_util_open(global_db, &db_info.dbGlobalrw, 0);
397                         }
398                 }
399                 retv_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
400         }
401
402         free(global_db);
403         free(db);
404
405         return AIL_ERROR_OK;
406
407 error:
408         free(global_db);
409         free(db);
410
411         return AIL_ERROR_DB_FAILED;
412 }
413
414
415 ail_error_e db_prepare(const char *query, sqlite3_stmt **stmt)
416 {
417         return db_do_prepare(db_info.dbUserro, query, stmt);
418 }
419
420 ail_error_e db_prepare_globalro(const char *query, sqlite3_stmt **stmt)
421 {
422         return db_do_prepare(db_info.dbGlobalro, query, stmt);
423 }
424
425 ail_error_e db_prepare_rw(const char *query, sqlite3_stmt **stmt)
426 {
427         return db_do_prepare(db_info.dbUserrw, query, stmt);
428 }
429
430
431 ail_error_e db_prepare_globalrw(const char *query, sqlite3_stmt **stmt)
432 {
433         return db_do_prepare(db_info.dbGlobalrw, query, stmt);
434 }
435
436
437 ail_error_e db_bind_bool(sqlite3_stmt *stmt, int idx, bool value)
438 {
439         int ret;
440
441         retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
442
443         ret = sqlite3_bind_int(stmt, idx, (int) value);
444         retv_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
445
446         return AIL_ERROR_OK;
447 }
448
449
450
451 ail_error_e db_bind_int(sqlite3_stmt *stmt, int idx, int value)
452 {
453         int ret;
454
455         retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
456
457         ret = sqlite3_bind_int(stmt, idx, value);
458         retv_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
459
460         return AIL_ERROR_OK;
461 }
462
463 ail_error_e db_bind_text(sqlite3_stmt *stmt, int idx, char* value)
464 {
465         int ret;
466
467         retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
468
469         ret = sqlite3_bind_text(stmt, idx, value, strlen(value), 0);
470         retv_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
471
472         return AIL_ERROR_OK;
473 }
474
475
476 ail_error_e db_step(sqlite3_stmt *stmt)
477 {
478         int ret;
479
480         retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
481
482         ret = sqlite3_step(stmt);
483         switch (ret) {
484                 case SQLITE_DONE:
485                         return AIL_ERROR_NO_DATA;
486                 case SQLITE_ROW:
487                         return AIL_ERROR_OK;
488         }
489
490         retv_with_dbmsg_if(1, AIL_ERROR_DB_FAILED);
491 }
492
493
494
495 ail_error_e db_column_bool(sqlite3_stmt *stmt, int index, bool *value)
496 {
497         int out_val;
498
499         retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
500         retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
501
502         out_val = sqlite3_column_int(stmt, index);
503         *value = (out_val == 1)? true:false;
504
505         return AIL_ERROR_OK;
506 }
507
508
509
510 ail_error_e db_column_int(sqlite3_stmt *stmt, int index, int *value)
511 {
512         retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
513         retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
514
515         *value = sqlite3_column_int(stmt, index);
516
517         return AIL_ERROR_OK;
518 }
519
520
521
522 ail_error_e db_column_str(sqlite3_stmt *stmt, int index, char **str)
523 {
524         retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
525         retv_if(!str, AIL_ERROR_INVALID_PARAMETER);
526
527         *str = (char *)sqlite3_column_text(stmt, index);
528
529         return AIL_ERROR_OK;
530 }
531
532
533
534 ail_error_e db_reset(sqlite3_stmt *stmt)
535 {
536         int ret;
537
538         retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
539
540         sqlite3_clear_bindings(stmt);
541
542         ret = sqlite3_reset(stmt);
543         retv_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
544
545         return AIL_ERROR_OK;
546 }
547
548
549
550 ail_error_e db_finalize(sqlite3_stmt *stmt)
551 {
552         int ret;
553
554         retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
555
556         ret = sqlite3_finalize(stmt);
557         retv_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
558
559         return AIL_ERROR_OK;
560 }
561
562
563
564 ail_error_e do_db_exec(const char *query, sqlite3 * fileSQL)
565 {
566         int ret;
567         char *errmsg = NULL;
568
569         retv_if(!query, AIL_ERROR_INVALID_PARAMETER);
570         retv_if(!fileSQL, AIL_ERROR_DB_FAILED);
571
572         ret = sqlite3_exec(fileSQL, query, NULL, NULL, &errmsg);
573         if (ret != SQLITE_OK) {
574                 _E("Cannot execute this query - %s. because %s",
575                                 query, errmsg? errmsg:"uncatched error");
576                 if(errmsg)
577                         sqlite3_free(errmsg);
578                 return AIL_ERROR_DB_FAILED;
579         }
580
581         return AIL_ERROR_OK;
582 }
583
584
585
586 ail_error_e db_exec_usr_rw(const char *query)
587 {
588         return do_db_exec(query, db_info.dbUserrw);
589 }
590
591
592 ail_error_e db_exec_usr_ro(const char *query)
593 {
594         return do_db_exec(query, db_info.dbUserro);
595 }
596
597 ail_error_e db_exec_glo_ro(const char *query)
598 {
599         return do_db_exec(query, db_info.dbGlobalro);
600 }
601
602 ail_error_e db_exec_glo_rw(const char *query)
603 {
604         return do_db_exec(query, db_info.dbGlobalrw);
605 }
606
607
608 ail_error_e db_close(void)
609 {
610         int ret;
611
612         if(db_info.dbUserro) {
613                 ret = sqlite3_close(db_info.dbUserro);
614                 retv_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
615
616                 db_info.dbUserro = NULL;
617         }
618         if(db_info.dbGlobalrw) {
619                 ret = sqlite3_close(db_info.dbGlobalrw);
620                 retv_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
621
622                 db_info.dbGlobalrw = NULL;
623         }
624         if(db_info.dbUserrw) {
625                 ret = sqlite3_close(db_info.dbUserrw);
626                 retv_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
627
628                 db_info.dbUserrw = NULL;
629         }
630
631         return AIL_ERROR_OK;
632 }
633
634 EXPORT_API ail_error_e ail_db_close(void)
635 {
636         return db_close();
637 }
638
639 int db_exec_sqlite_query(char *query, sqlite_query_callback callback, void *data)
640 {
641         char *error_message = NULL;
642         if(db_info.dbGlobalro) {
643                 if (SQLITE_OK !=
644                         sqlite3_exec(db_info.dbGlobalro, query, callback, data, &error_message)) {
645                         _E("Don't execute query = %s error message = %s\n", query,
646                                 error_message);
647                         sqlite3_free(error_message);
648                         return -1;
649                 }
650         }
651         if(db_info.dbUserro) {
652                 if (SQLITE_OK !=
653                         sqlite3_exec(db_info.dbUserro, query, callback, data, &error_message)) {
654                         _E("Don't execute query = %s error message = %s\n", query,
655                                 error_message);
656                         sqlite3_free(error_message);
657                         return -1;
658                 }
659         }
660         sqlite3_free(error_message);
661         return 0;
662 }
663
664 // End of file.