Implement Multi user changes
[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;
150         mkdir(result, S_IRWXU | S_IRGRP | S_IXGRP | S_IXOTH);
151         if (getuid() == OWNER_ROOT) {
152                 ret = chown(result, uid, ((grpinfo)?grpinfo->gr_gid:0));
153                 SET_SMACK_LABEL(result,uid)
154                 if (ret == -1) {
155                         char buf[BUFSIZE];
156                         strerror_r(errno, buf, sizeof(buf));
157                         _E("FAIL : chown %s %d.%d, because %s", result, uid, ((grpinfo)?grpinfo->gr_gid:0), buf);
158                 }
159         }
160         return result;
161 }
162
163 static char* ail_get_app_DB(uid_t uid)
164 {
165         char *result = NULL;
166         char *journal = NULL;
167         struct group *grpinfo = NULL;
168         char *dir = NULL;
169         struct passwd *userinfo = getpwuid(uid);
170
171         if (uid == 0) {
172                 _E("FAIL : Root is not allowed! switch to DEFAULT_USER");
173                 return NULL;
174         }
175         if (uid != GLOBAL_USER) {
176                 if (userinfo == NULL) {
177                         _E("getpwuid(%d) returns NULL !", uid);
178                         return NULL;
179                 }
180                 grpinfo = getgrnam("users");
181                 if (grpinfo == NULL) {
182                         _E("getgrnam(users) returns NULL !");
183                         return NULL;
184                 }
185                 // Compare git_t type and not group name
186                 if (grpinfo->gr_gid != userinfo->pw_gid) {
187                         _E("UID [%d] does not belong to 'users' group!", uid);
188                         return NULL;
189                 }
190                 asprintf(&result, "%s/.applications/dbspace/.app_info.db", userinfo->pw_dir);
191                 asprintf(&journal, "%s/.applications/dbspace/.app_info.db-journal", userinfo->pw_dir);
192         } else {
193                         result = strdup(APP_INFO_DB_FILE);
194                         journal = strdup(APP_INFO_DB_FILE_JOURNAL);
195         }
196         char *temp = strdup(result);
197         dir = strrchr(temp, '/');
198         if(!dir)
199         {
200                 free(temp);
201                 return result;
202         }
203         *dir = 0;
204         if ((uid != GLOBAL_USER)||((uid == GLOBAL_USER)&& (geteuid() == 0 ))) {
205                 int ret;
206                 mkdir(temp, S_IRWXU | S_IRGRP | S_IXGRP | S_IXOTH);
207                 if (getuid() == OWNER_ROOT) {
208                         ret = chown(temp, uid, ((grpinfo)?grpinfo->gr_gid:0));
209                         SET_SMACK_LABEL(temp,uid)
210                         if (ret == -1) {
211                                 char buf[BUFSIZE];
212                                 strerror_r(errno, buf, sizeof(buf));
213                                 _E("FAIL : chown %s %d.%d, because %s", temp, uid, ((grpinfo)?grpinfo->gr_gid:0), buf);
214                         }
215         }
216         }
217         free(temp);
218         return result;
219 }
220
221 char* al_get_desktop_path(uid_t uid)
222 {
223         char *result = NULL;
224         struct group *grpinfo = NULL;
225         char *dir = NULL;
226         struct passwd *userinfo = getpwuid(uid);
227
228         if (uid == 0) {
229                 _E("FAIL : Root is not allowed user! please fix it replacing with DEFAULT_USER");
230                 return NULL;
231         }
232         if (uid != GLOBAL_USER) {
233                 if (userinfo == NULL) {
234                         _E("getpwuid(%d) returns NULL !", uid);
235                         return NULL;
236                 }
237                 grpinfo = getgrnam("users");
238                 if (grpinfo == NULL) {
239                         _E("getgrnam(users) returns NULL !");
240                         return NULL;
241                 }
242                 // Compare git_t type and not group name
243                 if (grpinfo->gr_gid != userinfo->pw_gid) {
244                         _E("UID [%d] does not belong to 'users' group!", uid);
245                         return NULL;
246                 }
247                 asprintf(&result, "%s/.applications/desktop/", userinfo->pw_dir);
248         } else {
249                 result = tzplatform_mkpath(TZ_SYS_RW_DESKTOP_APP, "/");
250         }
251         if ((uid != GLOBAL_USER)||((uid == GLOBAL_USER)&& (geteuid() == 0 ))) {
252                 int ret;
253                 mkdir(result, S_IRWXU | S_IRGRP | S_IXGRP | S_IXOTH);
254                 ret = chown(result, uid, ((grpinfo)?grpinfo->gr_gid:0));
255                 SET_SMACK_LABEL(result,uid)
256                 if (ret == -1) {
257                         char buf[BUFSIZE];
258                         strerror_r(errno, buf, sizeof(buf));
259                         _E("FAIL : chown %s %d.%d, because %s", result, uid, ((grpinfo)?grpinfo->gr_gid:0), buf);
260                 }
261         }
262         return result;
263 }
264
265
266 static ail_error_e db_do_prepare(sqlite3 *db, const char *query, sqlite3_stmt **stmt)
267 {
268         int ret;
269
270         retv_if(!query, AIL_ERROR_INVALID_PARAMETER);
271         retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
272         retv_if(!db, AIL_ERROR_DB_FAILED);
273
274         ret = sqlite3_prepare_v2(db, query, strlen(query), stmt, NULL);
275         if (ret != SQLITE_OK) {
276                 _E("%s\n", sqlite3_errmsg(db));
277                 return AIL_ERROR_DB_FAILED;
278         } else
279                 return AIL_ERROR_OK;
280 }
281
282 ail_error_e db_open(db_open_mode mode, uid_t uid)
283 {
284         int ret;
285         int changed = 0;
286         int i;
287         const char *tbls[3] = {
288                 "CREATE TABLE app_info "
289                 "(package TEXT PRIMARY KEY, "
290                 "exec TEXT DEFAULT 'No Exec', "
291                 "name TEXT DEFAULT 'No Name', "
292                 "type TEXT DEFAULT 'Application', "
293                 "icon TEXT DEFAULT 'No Icon', "
294                 "categories TEXT, "
295                 "version TEXT, "
296                 "mimetype TEXT, "
297                 "x_slp_service TEXT, "
298                 "x_slp_packagetype TEXT, "
299                 "x_slp_packagecategories TEXT, "
300                 "x_slp_packageid TEXT, "
301                 "x_slp_uri TEXT, "
302                 "x_slp_svc TEXT, "
303                 "x_slp_exe_path TEXT, "
304                 "x_slp_appid TEXT, "
305                 "x_slp_pkgid TEXT, "
306                 "x_slp_domain TEXT, "
307                 "x_slp_submodemainid TEXT, "
308                 "x_slp_installedstorage TEXT, "
309                 "x_slp_baselayoutwidth INTEGER DEFAULT 0, "
310                 "x_slp_installedtime INTEGER DEFAULT 0, "
311                 "nodisplay INTEGER DEFAULT 0, "
312                 "x_slp_taskmanage INTEGER DEFAULT 1, "
313                 "x_slp_multiple INTEGER DEFAULT 0, "
314                 "x_slp_removable INTEGER DEFAULT 1, "
315                 "x_slp_ishorizontalscale INTEGER DEFAULT 0, "
316                 "x_slp_enabled INTEGER DEFAULT 1, "
317                 "x_slp_submode INTEGER DEFAULT 0, "
318                 "desktop TEXT UNIQUE NOT NULL);",
319                 "CREATE TABLE localname (package TEXT NOT NULL, "
320                 "locale TEXT NOT NULL, "
321                 "name TEXT NOT NULL, "
322                 "x_slp_pkgid TEXT NOT NULL, PRIMARY KEY (package, locale));",
323
324                 NULL
325         };
326
327         if (access(ail_get_app_DB(uid), F_OK)) {
328                 if (AIL_ERROR_OK == db_util_open_with_options(ail_get_app_DB(uid), &dbInit, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL))
329                 {
330                         for (i = 0; tbls[i] != NULL; i++) {
331                                 ret = do_db_exec(tbls[i], dbInit);
332                                 retv_if(ret != AIL_ERROR_OK, AIL_ERROR_DB_FAILED);
333                         }
334                         if(AIL_ERROR_OK != ail_db_change_perm(ail_get_app_DB(uid), uid)) {
335                                 _E("Failed to change permission\n");
336                 }
337                 } else {
338                         dbInit = NULL;
339                         _E("Failed to create table %s\n", ail_get_app_DB(uid));
340                 }
341         }
342         if(dbInit) {
343                 ret = sqlite3_close(dbInit);
344                 retv_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
345                 dbInit = NULL;
346         }
347         if(mode & DB_OPEN_RO) {
348                 if(uid != GLOBAL_USER) {
349                         if (!db_info.dbUserro) {
350                                 db_util_open_with_options(ail_get_app_DB(uid), &db_info.dbUserro, SQLITE_OPEN_READONLY, NULL);
351                                 char query_attach[AIL_SQL_QUERY_MAX_LEN];
352                                 char query_view_app[AIL_SQL_QUERY_MAX_LEN];
353                                 char query_view_local[AIL_SQL_QUERY_MAX_LEN];
354                                 snprintf(query_attach, AIL_SQL_QUERY_MAX_LEN, QUERY_ATTACH, ail_get_app_DB(GLOBAL_USER));
355                                 if (db_exec_usr_ro(query_attach) < 0) {
356                                         _D("executing query_attach : %s", query_attach );
357                                         return AIL_ERROR_DB_FAILED;
358                                 }
359                                 snprintf(query_view_app, AIL_SQL_QUERY_MAX_LEN, QUERY_CREATE_VIEW_APP);
360                                 if (db_exec_usr_ro(query_view_app) < 0) {
361                                         _D("executing query_attach : %s", query_view_app );
362                                         return AIL_ERROR_DB_FAILED;
363                                 }
364
365                                 snprintf(query_view_local, AIL_SQL_QUERY_MAX_LEN, QUERY_CREATE_VIEW_LOCAL);
366                                 if (db_exec_usr_ro(query_view_local) < 0) {
367                                         _D("executing query_attach : %s", query_view_local );
368                                         return AIL_ERROR_DB_FAILED;
369                                 }
370                         }
371                 } else {
372                         if (!db_info.dbGlobalro) {
373                                 ret = db_util_open_with_options(ail_get_app_DB(GLOBAL_USER), &db_info.dbGlobalro, SQLITE_OPEN_READONLY, NULL);
374                                 retv_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
375                         }
376                 }
377  }
378         if(mode & DB_OPEN_RW) {
379                 if(uid != GLOBAL_USER) {
380                         if(!db_info.dbUserrw){
381                                 ret = db_util_open(ail_get_app_DB(uid), &db_info.dbUserrw, 0);
382                         }
383                 } else {
384                         if(!db_info.dbGlobalrw){
385                                 ret = db_util_open(ail_get_app_DB(GLOBAL_USER), &db_info.dbGlobalrw, 0);
386                         }
387                 }
388                 retv_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
389         }
390
391         return AIL_ERROR_OK;
392 }
393
394
395 ail_error_e db_prepare(const char *query, sqlite3_stmt **stmt)
396 {
397         return db_do_prepare(db_info.dbUserro, query, stmt);
398 }
399
400 ail_error_e db_prepare_globalro(const char *query, sqlite3_stmt **stmt)
401 {
402         return db_do_prepare(db_info.dbGlobalro, query, stmt);
403 }
404
405 ail_error_e db_prepare_rw(const char *query, sqlite3_stmt **stmt)
406 {
407         return db_do_prepare(db_info.dbUserrw, query, stmt);
408 }
409
410
411 ail_error_e db_prepare_globalrw(const char *query, sqlite3_stmt **stmt)
412 {
413         return db_do_prepare(db_info.dbGlobalrw, query, stmt);
414 }
415
416
417 ail_error_e db_bind_bool(sqlite3_stmt *stmt, int idx, bool value)
418 {
419         int ret;
420
421         retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
422
423         ret = sqlite3_bind_int(stmt, idx, (int) value);
424         retv_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
425
426         return AIL_ERROR_OK;
427 }
428
429
430
431 ail_error_e db_bind_int(sqlite3_stmt *stmt, int idx, int value)
432 {
433         int ret;
434
435         retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
436
437         ret = sqlite3_bind_int(stmt, idx, value);
438         retv_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
439
440         return AIL_ERROR_OK;
441 }
442
443 ail_error_e db_bind_text(sqlite3_stmt *stmt, int idx, char* value)
444 {
445         int ret;
446
447         retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
448
449         ret = sqlite3_bind_text(stmt, idx, value, strlen(value), 0);
450         retv_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
451
452         return AIL_ERROR_OK;
453 }
454
455
456 ail_error_e db_step(sqlite3_stmt *stmt)
457 {
458         int ret;
459
460         retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
461
462         ret = sqlite3_step(stmt);
463         switch (ret) {
464                 case SQLITE_DONE:
465                         return AIL_ERROR_NO_DATA;
466                 case SQLITE_ROW:
467                         return AIL_ERROR_OK;
468         }
469
470         retv_with_dbmsg_if(1, AIL_ERROR_DB_FAILED);
471 }
472
473
474
475 ail_error_e db_column_bool(sqlite3_stmt *stmt, int index, bool *value)
476 {
477         int out_val;
478
479         retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
480         retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
481
482         out_val = sqlite3_column_int(stmt, index);
483         *value = (out_val == 1)? true:false;
484
485         return AIL_ERROR_OK;
486 }
487
488
489
490 ail_error_e db_column_int(sqlite3_stmt *stmt, int index, int *value)
491 {
492         retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
493         retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
494
495         *value = sqlite3_column_int(stmt, index);
496
497         return AIL_ERROR_OK;
498 }
499
500
501
502 ail_error_e db_column_str(sqlite3_stmt *stmt, int index, char **str)
503 {
504         retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
505         retv_if(!str, AIL_ERROR_INVALID_PARAMETER);
506
507         *str = (char *)sqlite3_column_text(stmt, index);
508
509         return AIL_ERROR_OK;
510 }
511
512
513
514 ail_error_e db_reset(sqlite3_stmt *stmt)
515 {
516         int ret;
517
518         retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
519
520         sqlite3_clear_bindings(stmt);
521
522         ret = sqlite3_reset(stmt);
523         retv_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
524
525         return AIL_ERROR_OK;
526 }
527
528
529
530 ail_error_e db_finalize(sqlite3_stmt *stmt)
531 {
532         int ret;
533
534         retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
535
536         ret = sqlite3_finalize(stmt);
537         retv_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
538
539         return AIL_ERROR_OK;
540 }
541
542
543
544 ail_error_e do_db_exec(const char *query, sqlite3 * fileSQL)
545 {
546         int ret;
547         char *errmsg;
548
549         retv_if(!query, AIL_ERROR_INVALID_PARAMETER);
550         retv_if(!fileSQL, AIL_ERROR_DB_FAILED);
551
552         ret = sqlite3_exec(fileSQL, query, NULL, NULL, &errmsg);
553         if (ret != SQLITE_OK) {
554                 _E("Cannot execute this query - %s. because %s",
555                                 query, errmsg? errmsg:"uncatched error");
556                 sqlite3_free(errmsg);
557                 return AIL_ERROR_DB_FAILED;
558         }
559
560         return AIL_ERROR_OK;
561 }
562
563
564
565 ail_error_e db_exec_usr_rw(const char *query)
566 {
567         return do_db_exec(query, db_info.dbUserrw);
568 }
569
570
571 ail_error_e db_exec_usr_ro(const char *query)
572 {
573         return do_db_exec(query, db_info.dbUserro);
574 }
575
576 ail_error_e db_exec_glo_ro(const char *query)
577 {
578         return do_db_exec(query, db_info.dbGlobalro);
579 }
580
581 ail_error_e db_exec_glo_rw(const char *query)
582 {
583         return do_db_exec(query, db_info.dbGlobalrw);
584 }
585
586
587 ail_error_e db_close(void)
588 {
589         int ret;
590
591         if(db_info.dbUserro) {
592                 ret = sqlite3_close(db_info.dbUserro);
593                 retv_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
594
595                 db_info.dbUserro = NULL;
596         }
597         if(db_info.dbGlobalrw) {
598                 ret = sqlite3_close(db_info.dbGlobalrw);
599                 retv_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
600
601                 db_info.dbGlobalrw = NULL;
602         }
603         if(db_info.dbUserrw) {
604                 ret = sqlite3_close(db_info.dbUserrw);
605                 retv_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
606
607                 db_info.dbUserrw = NULL;
608         }
609
610         return AIL_ERROR_OK;
611 }
612
613 EXPORT_API ail_error_e ail_db_close(void)
614 {
615         return db_close();
616 }
617
618 int db_exec_sqlite_query(char *query, sqlite_query_callback callback, void *data)
619 {
620         char *error_message = NULL;
621         if(db_info.dbGlobalro) {
622                 if (SQLITE_OK !=
623                         sqlite3_exec(db_info.dbGlobalro, query, callback, data, &error_message)) {
624                         _E("Don't execute query = %s error message = %s\n", query,
625                                 error_message);
626                         sqlite3_free(error_message);
627                         return -1;
628                 }
629         }
630         if(db_info.dbUserro) {
631                 if (SQLITE_OK !=
632                         sqlite3_exec(db_info.dbUserro, query, callback, data, &error_message)) {
633                         _E("Don't execute query = %s error message = %s\n", query,
634                                 error_message);
635                         sqlite3_free(error_message);
636                         return -1;
637                 }
638         }
639         sqlite3_free(error_message);
640         return 0;
641 }
642
643 // End of file.