Terminate sticker-receiver after sending result
[platform/core/uifw/capi-ui-sticker.git] / server / stickerd_db_manager.c
1 /*
2  * Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (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://www.apache.org/licenses/LICENSE-2.0
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
17 #include <unistd.h>
18 #include <string.h>
19 #include <dlog.h>
20 #include <sqlite3.h>
21
22 #include "stickerd_db_manager.h"
23 #include "stickerd_error.h"
24
25 #ifdef LOG_TAG
26 #undef LOG_TAG
27 #endif
28 #define LOG_TAG "STICKERD_DB_MANAGER"
29
30 /*
31  * Table Information
32  *
33  * sticker_info
34  * +-----------------+--------+------+------+-----------+-------------+------------+------+
35  * | INT             | TEXT   | INT  | TEXT | TEXT      | TEXT        | TEXT       | TEXT |
36  * +-----------------+--------+------+------+-----------+-------------+------------+------+
37  * | sticker_info_id | app_id | type | uri  | thumbnail | description | group_name | date |
38  * +-----------------+--------+------+------+-----------+-------------+------------+------+
39  *
40  * sticker_keyword_info
41  * +------------+-----------------+---------+
42  * | INT        | INT             | TEXT    |
43  * +------------+-----------------+---------+
44  * | keyword_id | sticker_info_id | keyword |
45  * +------------+-----------------+---------+
46  *
47  * sticker_whitelist_info
48  * +--------------+-------------+-------------+
49  * | INT          | TEXT        | TEXT        |
50  * +--------------+-------------+-------------+
51  * | whitelist_id | provider_id | consumer_id |
52  * +------------+---------------+-------------+
53  *
54  */
55
56 #define STICKER_DB_PATH tzplatform_mkpath(TZ_SYS_DB, ".sticker_info.db")
57 #define STICKER_INFO_CREATE_TABLE "CREATE TABLE IF NOT EXISTS sticker_info(sticker_info_id INTEGER PRIMARY KEY AUTOINCREMENT, app_id TEXT NOT NULL, type INTEGER NOT NULL, uri TEXT NOT NULL, thumbnail TEXT, description TEXT, group_name TEXT NOT NULL, date TEXT NOT NULL)"
58 #define STICKER_KEYWORD_INFO_CREATE_TABLE "CREATE TABLE IF NOT EXISTS sticker_keyword_info(keyword_id INTEGER PRIMARY KEY AUTOINCREMENT, sticker_info_id INTEGER, keyword TEXT NOT NULL, FOREIGN KEY (sticker_info_id) REFERENCES sticker_info(sticker_info_id) ON DELETE CASCADE)"
59 #define STICKER_WHITELIST_INFO_CREATE_TABLE "CREATE TABLE IF NOT EXISTS sticker_whitelist_info(whitelist_id INTEGER PRIMARY KEY AUTOINCREMENT, provider_id TEXT NOT NULL, consumer_id TEXT NOT NULL)"
60
61 #define STICKER_DB_INSERT_STICKER_INFO "INSERT INTO sticker_info (app_id, type, uri, thumbnail, description, group_name, date) VALUES (?, ?, ?, ?, ?, ?, DateTime('now','localtime'))"
62 #define STICKER_DB_INSERT_STICKER_KEYWORD_INFO "INSERT INTO sticker_keyword_info (sticker_info_id, keyword) VALUES (?, ?)"
63
64 #define STICKER_DB_DELETE_STICKER_INFO "DELETE FROM sticker_info WHERE sticker_info_id = ?"
65 #define STICKER_DB_DELETE_STICKER_KEYWORD_INFO "DELETE FROM sticker_keyword_info WHERE sticker_info_id = ?"
66
67 #define STICKER_DB_UPDATE_STICKER_TYPE "UPDATE sticker_info SET type = ?, date = DateTime('now','localtime') WHERE sticker_info_id = ?"
68 #define STICKER_DB_UPDATE_STICKER_URI "UPDATE sticker_info SET uri = ?, date = DateTime('now','localtime') WHERE sticker_info_id = ?"
69 #define STICKER_DB_UPDATE_STICKER_THUMBNAIL "UPDATE sticker_info SET thumbnail = ?, date = DateTime('now','localtime') WHERE sticker_info_id = ?"
70 #define STICKER_DB_UPDATE_STICKER_DESCRIPTION "UPDATE sticker_info SET description = ?, date = DateTime('now','localtime') WHERE sticker_info_id = ?"
71 #define STICKER_DB_UPDATE_STICKER_GROUP "UPDATE sticker_info SET group_name = ?, date = DateTime('now','localtime') WHERE sticker_info_id = ?"
72
73 #define STICKER_DB_GET_LATEST_RECORD_ID "SELECT sticker_info_id FROM sticker_info ORDER BY sticker_info_id DESC LIMIT 1"
74 #define STICKER_DB_GET_STICKER_INFO_BY_RECORD_ID "SELECT * FROM sticker_info WHERE sticker_info_id = ?"
75 #define STICKER_DB_GET_KEYWORD_INFO_BY_RECORD_ID "SELECT keyword FROM sticker_keyword_info WHERE sticker_info_id = ?"
76 #define STICKER_DB_GET_ALL_GROUP_LIST "SELECT DISTINCT group_name FROM sticker_info WHERE app_id NOT IN (SELECT DISTINCT provider_id FROM sticker_whitelist_info WHERE provider_id NOT IN (SELECT provider_id FROM sticker_whitelist_info WHERE consumer_id = ?))"
77 #define STICKER_DB_GET_ALL_KEYWORD_LIST "SELECT DISTINCT keyword FROM sticker_keyword_info WHERE sticker_info_id IN (SELECT sticker_info_id from sticker_info WHERE app_id NOT IN (SELECT DISTINCT provider_id FROM sticker_whitelist_info WHERE provider_id NOT IN (SELECT provider_id FROM sticker_whitelist_info WHERE consumer_id = ?)))"
78 #define STICKER_DB_GET_STICKER_COUNT "SELECT count(*) FROM sticker_info WHERE app_id = ?"
79 #define STICKER_DB_GET_ALL_RECORD_ID "SELECT sticker_info_id FROM sticker_info WHERE app_id NOT IN (SELECT DISTINCT provider_id FROM sticker_whitelist_info WHERE provider_id NOT IN (SELECT provider_id FROM sticker_whitelist_info WHERE consumer_id = ?)) LIMIT ?, ?"
80 #define STICKER_DB_GET_RECORD_ID_BY_APP_ID "SELECT sticker_info_id from sticker_info WHERE app_id = ? LIMIT ?, ?"
81 #define STICKER_DB_GET_RECORD_ID_BY_TYPE "SELECT sticker_info_id FROM sticker_info WHERE type = ? AND app_id NOT IN (SELECT DISTINCT provider_id FROM sticker_whitelist_info WHERE provider_id NOT IN (SELECT provider_id FROM sticker_whitelist_info WHERE consumer_id = ?)) LIMIT ?, ?"
82 #define STICKER_DB_GET_RECORD_ID_BY_GROUP "SELECT sticker_info_id from sticker_info WHERE group_name = ? AND app_id NOT IN (SELECT DISTINCT provider_id FROM sticker_whitelist_info WHERE provider_id NOT IN (SELECT provider_id FROM sticker_whitelist_info WHERE consumer_id = ?)) LIMIT ?, ?"
83 #define STICKER_DB_GET_RECORD_ID_BY_KEYWORD "SELECT sticker_info_id FROM sticker_keyword_info WHERE keyword = ? INTERSECT SELECT sticker_info_id from sticker_info WHERE app_id NOT IN (SELECT DISTINCT provider_id FROM sticker_whitelist_info WHERE provider_id NOT IN (SELECT provider_id FROM sticker_whitelist_info WHERE consumer_id = ?)) LIMIT ?, ?"
84
85 typedef enum
86 {
87     CMD_UPDATE,
88     CMD_SELECT,
89 } command_type;
90
91 static gboolean is_corrupted = FALSE;
92
93 static const char *_db_get_query(sticker_info_db_type sticker_type, command_type cmd_type)
94 {
95     static const char* query = NULL;
96
97     if (cmd_type == CMD_UPDATE) {
98         switch(sticker_type) {
99             case STICKER_DB_STICKER_TYPE:
100             query = STICKER_DB_UPDATE_STICKER_TYPE;
101             break;
102             case STICKER_DB_STICKER_URI:
103             query = STICKER_DB_UPDATE_STICKER_URI;
104             break;
105             case STICKER_DB_STICKER_THUMBNAIL:
106             query = STICKER_DB_UPDATE_STICKER_THUMBNAIL;
107             break;
108             case STICKER_DB_STICKER_DESCRIPTION:
109             query = STICKER_DB_UPDATE_STICKER_DESCRIPTION;
110             break;
111             case STICKER_DB_STICKER_GROUP:
112             query = STICKER_DB_UPDATE_STICKER_GROUP;
113             break;
114             case STICKER_DB_STICKER_KEYWORD:
115             query = STICKER_DB_DELETE_STICKER_KEYWORD_INFO;
116             break;
117             default :
118             query = "";
119             break;
120         }
121     } else if (cmd_type == CMD_SELECT) {
122         switch(sticker_type) {
123             case STICKER_DB_STICKER_ALL:
124             query = STICKER_DB_GET_ALL_RECORD_ID;
125             break;
126             case STICKER_DB_STICKER_APPID:
127             query = STICKER_DB_GET_RECORD_ID_BY_APP_ID;
128             break;
129             case STICKER_DB_STICKER_TYPE:
130             query = STICKER_DB_GET_RECORD_ID_BY_TYPE;
131             break;
132             case STICKER_DB_STICKER_GROUP:
133             query = STICKER_DB_GET_RECORD_ID_BY_GROUP;
134             break;
135             case STICKER_DB_STICKER_KEYWORD:
136             query = STICKER_DB_GET_RECORD_ID_BY_KEYWORD;
137             break;
138             default :
139             query = "";
140             break;
141         }
142     }
143
144     return query;
145 }
146
147 static int _recover_db(void)
148 {
149     int ret = STICKERD_SERVER_ERROR_NONE;
150     sqlite3 *db = NULL;
151     char *err = NULL;
152
153     LOGD("Start to recover sticker db");
154     //Remove sticker database file
155     if (unlink(STICKER_DB_PATH) == -1)
156         LOGE("Failed to remove db file");
157
158     ret = sqlite3_open_v2(STICKER_DB_PATH, &db, SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE, NULL);
159     if (ret != SQLITE_OK) {
160         LOGE("Failed to open db : %s", sqlite3_errmsg(db));
161         if (unlink(STICKER_DB_PATH) == -1)
162             LOGE("Failed to remove db file");
163         ret = STICKERD_SERVER_ERROR_DB_FAILED;
164         goto cleanup;
165     }
166
167     ret = sqlite3_exec(db, STICKER_INFO_CREATE_TABLE, NULL, NULL, &err);
168     if (ret != SQLITE_OK) {
169         LOGE("Failed to create sticker_info table : %s" , err);
170         ret = STICKERD_SERVER_ERROR_DB_FAILED;
171         goto cleanup;
172     }
173
174     ret = sqlite3_exec(db, STICKER_KEYWORD_INFO_CREATE_TABLE, NULL, NULL, &err);
175     if (ret != SQLITE_OK) {
176         LOGE("Failed to create sticker_keyword_info table : %s", err);
177         ret = STICKERD_SERVER_ERROR_DB_FAILED;
178     }
179
180     ret = sqlite3_exec(db, STICKER_WHITELIST_INFO_CREATE_TABLE, NULL, NULL, &err);
181     if (ret != SQLITE_OK) {
182         LOGE("Failed to create sticker_whitelist_info table : %s", err);
183         ret = STICKERD_SERVER_ERROR_DB_FAILED;
184     }
185
186     is_corrupted = FALSE;
187
188 cleanup:
189     if (err)
190         sqlite3_free(err);
191
192     if (db)
193         sqlite3_close(db);
194
195     return ret;
196 }
197
198 static int _integrity_check_cb(void *pid, int argc, char **argv, char **notUsed)
199 {
200     if (strcmp(argv[0], "ok") != 0) {
201         LOGE("DB integrity check failed : %s", argv[0]);
202         is_corrupted = TRUE;
203         return -1;
204     }
205
206     LOGD("Result integrity : %s", argv[0]);
207     return 0;
208 }
209
210 int stickerd_db_init(void)
211 {
212     int ret = STICKERD_SERVER_ERROR_NONE;
213     sqlite3 *db = NULL;
214     char *err = NULL;
215
216     ret = sqlite3_open_v2(STICKER_DB_PATH, &db, SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE, NULL);
217     if (ret != SQLITE_OK) {
218         LOGE("Failed to open db : %s", sqlite3_errmsg(db));
219         ret = STICKERD_SERVER_ERROR_DB_FAILED;
220         goto cleanup;
221     }
222
223     ret = sqlite3_exec(db, STICKER_INFO_CREATE_TABLE, NULL, NULL, &err);
224     if (ret != SQLITE_OK) {
225         LOGE("Failed to create sticker_info table : %s" , err);
226         ret = STICKERD_SERVER_ERROR_DB_FAILED;
227         goto cleanup;
228     }
229
230     ret = sqlite3_exec(db, STICKER_KEYWORD_INFO_CREATE_TABLE, NULL, NULL, &err);
231     if (ret != SQLITE_OK) {
232         LOGE("Failed to create sticker_keyword_info table : %s", err);
233         ret = STICKERD_SERVER_ERROR_DB_FAILED;
234         goto cleanup;
235     }
236
237     ret = sqlite3_exec(db, STICKER_WHITELIST_INFO_CREATE_TABLE, NULL, NULL, &err);
238     if (ret != SQLITE_OK) {
239         LOGE("Failed to create sticker_whitelist_info table : %s", err);
240         ret = STICKERD_SERVER_ERROR_DB_FAILED;
241     }
242
243     ret = sqlite3_exec(db, "PRAGMA journal_mode = WAL", NULL, NULL, &err);
244     if (ret != SQLITE_OK) {
245         LOGE("Failed to set journal_mode : %s", err);
246         ret = STICKERD_SERVER_ERROR_DB_FAILED;
247         goto cleanup;
248     }
249
250     ret = sqlite3_exec(db, "PRAGMA integrity_check", _integrity_check_cb, NULL, &err);
251     if (ret != SQLITE_OK) {
252         LOGE("Failed to check integrity : %s", err);
253         ret = STICKERD_SERVER_ERROR_DB_FAILED;
254     }
255
256 cleanup:
257     if (err)
258         sqlite3_free(err);
259
260     if (db)
261         sqlite3_close(db);
262
263     if (ret == SQLITE_CORRUPT || ret == SQLITE_NOTADB || is_corrupted)
264         ret = _recover_db();
265
266     return ret;
267 }
268
269 static sqlite3 *_db_open(void)
270 {
271     int ret;
272     sqlite3 *db = NULL;
273     char *err = NULL;
274
275     ret = sqlite3_open(STICKER_DB_PATH, &db);
276     if (ret != SQLITE_OK) {
277         LOGE("Failed to open db : %s", sqlite3_errmsg(db));
278         return NULL;
279     }
280
281     ret = sqlite3_exec(db, "PRAGMA foreign_keys = ON", NULL, NULL, &err);
282     if (ret != SQLITE_OK) {
283         LOGE("Failed to turn on foreign keys : %s", err);
284     }
285
286     if (err)
287         sqlite3_free(err);
288
289     return db;
290 }
291
292 int stickerd_db_insert_sticker_info(int *record_id, sticker_info_db *sticker_info)
293 {
294     int ret;
295     sqlite3 *db = NULL;
296     sqlite3_stmt *stmt = NULL;
297
298     db = _db_open();
299     if (!db)
300         return STICKERD_SERVER_ERROR_DB_FAILED;
301
302     ret = sqlite3_prepare_v2(db, STICKER_DB_INSERT_STICKER_INFO, -1, &stmt, NULL);
303     if (ret != SQLITE_OK) {
304         LOGE("fail to insert sticker information : %s", sqlite3_errmsg(db));
305         goto cleanup;
306     }
307
308     sqlite3_bind_text(stmt, 1, sticker_info->app_id, -1, SQLITE_TRANSIENT);
309     sqlite3_bind_int(stmt, 2, sticker_info->type);
310     sqlite3_bind_text(stmt, 3, sticker_info->uri, -1, SQLITE_TRANSIENT);
311     sqlite3_bind_text(stmt, 4, sticker_info->thumbnail, -1, SQLITE_TRANSIENT);
312     sqlite3_bind_text(stmt, 5, sticker_info->description, -1, SQLITE_TRANSIENT);
313     sqlite3_bind_text(stmt, 6, sticker_info->group, -1, SQLITE_TRANSIENT);
314
315     ret = sqlite3_step(stmt);
316     if (ret != SQLITE_OK && ret != SQLITE_DONE) {
317         LOGE("sqlite3_step() failed : ret(%d)", ret);
318         goto cleanup;
319     } else if (sqlite3_changes(db) == 0) {
320         LOGE("No changes to DB");
321         goto cleanup;
322     }
323
324     sqlite3_finalize(stmt);
325     stmt = NULL;
326
327     ret = sqlite3_prepare_v2(db, STICKER_DB_GET_LATEST_RECORD_ID, -1, &stmt, NULL);
328     if (ret != SQLITE_OK) {
329         LOGE("fail to get sticker id : %s", sqlite3_errmsg(db));
330         goto cleanup;
331     }
332
333     ret = sqlite3_step(stmt);
334     if (ret == SQLITE_ERROR) {
335         LOGE("sqlite3_step() failed : ret(%d)", ret);
336         *record_id = 0;
337         goto cleanup;
338     } else {
339         *record_id = sqlite3_column_int(stmt, 0);
340         LOGD("record_id : %d", *record_id);
341     }
342
343     GList *list;
344     for(list = sticker_info->keyword; list != NULL; list=list->next) {
345         sqlite3_finalize(stmt);
346         stmt = NULL;
347
348         ret = sqlite3_prepare_v2(db, STICKER_DB_INSERT_STICKER_KEYWORD_INFO, -1, &stmt, NULL);
349         if (ret != SQLITE_OK) {
350             LOGE("fail to insert sticker keyword : %s", sqlite3_errmsg(db));
351             goto cleanup;
352         }
353
354         sqlite3_bind_int(stmt, 1, *record_id);
355         sqlite3_bind_text(stmt, 2, (char *)list->data, -1, SQLITE_TRANSIENT);
356
357         ret = sqlite3_step(stmt);
358         if (ret != SQLITE_OK && ret != SQLITE_DONE) {
359             LOGE("sqlite3_step() failed : ret(%d)", ret);
360             goto cleanup;
361         } else if (sqlite3_changes(db) == 0) {
362             LOGE("No changes to DB");
363             goto cleanup;
364         }
365     }
366
367     sqlite3_finalize(stmt);
368     sqlite3_close(db);
369
370     return STICKERD_SERVER_ERROR_NONE;
371
372 cleanup:
373     sqlite3_finalize(stmt);
374     sqlite3_close(db);
375
376     return STICKERD_SERVER_ERROR_DB_FAILED;
377 }
378
379 int stickerd_db_delete_sticker_info(int record_id)
380 {
381     int ret;
382     sqlite3 *db = NULL;
383     sqlite3_stmt *stmt = NULL;
384
385     db = _db_open();
386     if (!db)
387         return STICKERD_SERVER_ERROR_DB_FAILED;
388
389     ret = sqlite3_prepare_v2(db, STICKER_DB_DELETE_STICKER_INFO, -1, &stmt, NULL);
390     if (ret != SQLITE_OK) {
391         LOGE("fail to delete sticker information : %s", sqlite3_errmsg(db));
392         goto cleanup;
393     }
394
395     sqlite3_bind_int(stmt, 1, record_id);
396
397     ret = sqlite3_step(stmt);
398     if (ret != SQLITE_OK && ret != SQLITE_DONE) {
399         LOGE("sqlite3_step() failed : ret(%d)", ret);
400         goto cleanup;
401     } else if (sqlite3_changes(db) == 0) {
402         LOGE("No changes to DB");
403         goto cleanup;
404     }
405
406     sqlite3_finalize(stmt);
407     sqlite3_close(db);
408
409     return STICKERD_SERVER_ERROR_NONE;
410
411 cleanup:
412     sqlite3_finalize(stmt);
413     sqlite3_close(db);
414
415     return STICKERD_SERVER_ERROR_DB_FAILED;
416 }
417
418 int stickerd_db_update_sticker_info(int record_id, sticker_info_db_type type, void *data)
419 {
420     int ret;
421     sqlite3 *db = NULL;
422     sqlite3_stmt *stmt = NULL;
423
424     db = _db_open();
425     if (!db)
426         return STICKERD_SERVER_ERROR_DB_FAILED;
427
428     const char* query = _db_get_query(type, CMD_UPDATE);
429     ret = sqlite3_prepare_v2(db, query, -1, &stmt, NULL);
430     if (ret != SQLITE_OK) {
431         LOGE("fail to update sticker information : %s", sqlite3_errmsg(db));
432         goto cleanup;
433     }
434
435     if (type == STICKER_DB_STICKER_TYPE) {
436         sqlite3_bind_int(stmt, 1, *(int *)data);
437     } else if (type == STICKER_DB_STICKER_KEYWORD) {
438         sqlite3_bind_int(stmt, 1, record_id);
439     } else {
440         sqlite3_bind_text(stmt, 1, (char *)data, -1, SQLITE_TRANSIENT);
441     }
442
443     if (type != STICKER_DB_STICKER_KEYWORD)
444         sqlite3_bind_int(stmt, 2, record_id);
445
446     ret = sqlite3_step(stmt);
447     if (ret != SQLITE_OK && ret != SQLITE_DONE) {
448         LOGE("sqlite3_step() failed : ret(%d)", ret);
449         goto cleanup;
450     }
451
452     if (type == STICKER_DB_STICKER_KEYWORD) {
453         GList *list;
454         for(list = (GList *)data; list != NULL; list=list->next) {
455             sqlite3_finalize(stmt);
456             stmt = NULL;
457
458             ret = sqlite3_prepare_v2(db, STICKER_DB_INSERT_STICKER_KEYWORD_INFO, -1, &stmt, NULL);
459             if (ret != SQLITE_OK) {
460                 LOGE("fail to insert sticker information : %s", sqlite3_errmsg(db));
461                 goto cleanup;
462             }
463
464             sqlite3_bind_int(stmt, 1, record_id);
465             sqlite3_bind_text(stmt, 2, (char *)list->data, -1, SQLITE_TRANSIENT);
466
467             ret = sqlite3_step(stmt);
468             if (ret != SQLITE_OK && ret != SQLITE_DONE) {
469                 LOGE("sqlite3_step() failed : ret(%d)", ret);
470                 goto cleanup;
471             } else if (sqlite3_changes(db) == 0) {
472                 LOGE("No changes to DB");
473                 goto cleanup;
474             }
475         }
476     }
477
478     sqlite3_finalize(stmt);
479     sqlite3_close(db);
480
481     return STICKERD_SERVER_ERROR_NONE;
482
483 cleanup:
484     sqlite3_finalize(stmt);
485     sqlite3_close(db);
486
487     return STICKERD_SERVER_ERROR_DB_FAILED;
488 }
489
490 int stickerd_db_get_sticker_info_by_record_id(int record_id, sticker_info_db *sticker_info)
491 {
492     int ret;
493     sqlite3 *db = NULL;
494     sqlite3_stmt *stmt = NULL;
495
496     db = _db_open();
497     if (!db)
498         return STICKERD_SERVER_ERROR_DB_FAILED;
499
500     ret = sqlite3_prepare_v2(db, STICKER_DB_GET_STICKER_INFO_BY_RECORD_ID, -1, &stmt, NULL);
501     if (ret != SQLITE_OK) {
502         LOGE("fail to get sticker information : %s", sqlite3_errmsg(db));
503         goto cleanup;
504     }
505
506     sqlite3_bind_int(stmt, 1, record_id);
507
508     ret = sqlite3_step(stmt);
509     if (ret == SQLITE_ERROR) {
510         LOGE("sqlite3_step() failed : ret(%d)", ret);
511         goto cleanup;
512     }
513
514     const unsigned char *tmp_app_id = sqlite3_column_text(stmt, 1);
515     if (tmp_app_id) {
516         sticker_info->app_id = strdup((const char *)tmp_app_id);
517     } else {
518         LOGW("invalid record_id : %d", record_id);
519         goto cleanup;
520     }
521
522     sticker_info->type = sqlite3_column_int(stmt, 2);
523
524     const unsigned char *tmp_uri = sqlite3_column_text(stmt, 3);
525     if (tmp_uri)
526         sticker_info->uri = strdup((const char *)tmp_uri);
527
528     const unsigned char *tmp_thumbnail = sqlite3_column_text(stmt, 4);
529     if (tmp_thumbnail)
530         sticker_info->thumbnail = strdup((const char *)tmp_thumbnail);
531
532     const unsigned char *tmp_description = sqlite3_column_text(stmt, 5);
533     if (tmp_description)
534         sticker_info->description = strdup((const char *)tmp_description);
535
536     const unsigned char *tmp_group = sqlite3_column_text(stmt, 6);
537     if (tmp_group)
538         sticker_info->group = strdup((const char *)tmp_group);
539
540     const unsigned char *tmp_date = sqlite3_column_text(stmt, 7);
541     if (tmp_date)
542         sticker_info->date = strdup((const char *)tmp_date);
543
544     sqlite3_finalize(stmt);
545     stmt = NULL;
546
547     ret = sqlite3_prepare_v2(db, STICKER_DB_GET_KEYWORD_INFO_BY_RECORD_ID, -1, &stmt, NULL);
548     if (ret != SQLITE_OK) {
549         LOGE("fail to get sticker keyword : %s", sqlite3_errmsg(db));
550         goto cleanup;
551     }
552
553     sqlite3_bind_int(stmt, 1, record_id);
554
555     while (sqlite3_step(stmt) == SQLITE_ROW) {
556         const unsigned char *keyword = sqlite3_column_text(stmt, 0);
557         if (keyword)
558             sticker_info->keyword = g_list_append(sticker_info->keyword, strdup((const char *)keyword));
559     }
560
561     sqlite3_finalize(stmt);
562     sqlite3_close(db);
563
564     return STICKERD_SERVER_ERROR_NONE;
565
566 cleanup:
567     sqlite3_finalize(stmt);
568     sqlite3_close(db);
569
570     return STICKERD_SERVER_ERROR_DB_FAILED;
571 }
572
573 int stickerd_db_get_group_list(GVariantBuilder *builder, char *app_id)
574 {
575     int ret;
576     sqlite3 *db = NULL;
577     sqlite3_stmt *stmt = NULL;
578
579     db = _db_open();
580     if (!db)
581         return STICKERD_SERVER_ERROR_DB_FAILED;
582
583     ret = sqlite3_prepare_v2(db, STICKER_DB_GET_ALL_GROUP_LIST, -1, &stmt, NULL);
584     if (ret != SQLITE_OK) {
585         LOGE("fail to get group list : %s", sqlite3_errmsg(db));
586         goto cleanup;
587     }
588
589     sqlite3_bind_text(stmt, 1, app_id, -1, SQLITE_TRANSIENT);
590
591     while (sqlite3_step(stmt) == SQLITE_ROW) {
592         const unsigned char *group = sqlite3_column_text(stmt, 0);
593         if (group)
594             g_variant_builder_add(builder, "(s)", strdup((const char *)group));
595     }
596
597     sqlite3_finalize(stmt);
598     sqlite3_close(db);
599
600     return STICKERD_SERVER_ERROR_NONE;
601
602 cleanup:
603     sqlite3_finalize(stmt);
604     sqlite3_close(db);
605
606     return STICKERD_SERVER_ERROR_DB_FAILED;
607 }
608
609 int stickerd_db_get_keyword_list(GVariantBuilder *builder, char *app_id)
610 {
611     int ret;
612     sqlite3 *db = NULL;
613     sqlite3_stmt *stmt = NULL;
614
615     db = _db_open();
616     if (!db)
617         return STICKERD_SERVER_ERROR_DB_FAILED;
618
619     ret = sqlite3_prepare_v2(db, STICKER_DB_GET_ALL_KEYWORD_LIST, -1, &stmt, NULL);
620     if (ret != SQLITE_OK) {
621         LOGE("fail to get keyword list : %s", sqlite3_errmsg(db));
622         goto cleanup;
623     }
624
625     sqlite3_bind_text(stmt, 1, app_id, -1, SQLITE_TRANSIENT);
626
627     while (sqlite3_step(stmt) == SQLITE_ROW) {
628         const unsigned char *keyword = sqlite3_column_text(stmt, 0);
629         if (keyword)
630             g_variant_builder_add(builder, "(s)", strdup((const char *)keyword));
631     }
632
633     sqlite3_finalize(stmt);
634     sqlite3_close(db);
635
636     return STICKERD_SERVER_ERROR_NONE;
637
638 cleanup:
639     sqlite3_finalize(stmt);
640     sqlite3_close(db);
641
642     return STICKERD_SERVER_ERROR_DB_FAILED;
643 }
644
645 int stickerd_db_get_sticker_count(int *count, char *app_id)
646 {
647     int ret;
648     sqlite3 *db = NULL;
649     sqlite3_stmt *stmt = NULL;
650
651     db = _db_open();
652     if (!db)
653         return STICKERD_SERVER_ERROR_DB_FAILED;
654
655     ret = sqlite3_prepare_v2(db, STICKER_DB_GET_STICKER_COUNT, -1, &stmt, NULL);
656     if (ret != SQLITE_OK) {
657         LOGE("fail to get sticker count : %s", sqlite3_errmsg(db));
658         goto cleanup;
659     }
660
661     sqlite3_bind_text(stmt, 1, app_id, -1, SQLITE_TRANSIENT);
662
663     ret = sqlite3_step(stmt);
664     if (ret == SQLITE_ERROR) {
665         LOGE("sqlite3_step() failed : ret(%d)", ret);
666         goto cleanup;
667     }
668
669     *count = sqlite3_column_int(stmt, 0);
670
671     sqlite3_finalize(stmt);
672     sqlite3_close(db);
673
674     return STICKERD_SERVER_ERROR_NONE;
675
676 cleanup:
677     sqlite3_finalize(stmt);
678     sqlite3_close(db);
679
680     return STICKERD_SERVER_ERROR_DB_FAILED;
681 }
682
683 int stickerd_db_get_record_id(sticker_info_db_type type, GList **id_list, void *data, char *app_id, int offset, int count)
684 {
685     int ret;
686     sqlite3 *db = NULL;
687     sqlite3_stmt *stmt = NULL;
688
689     db = _db_open();
690     if (!db)
691         return STICKERD_SERVER_ERROR_DB_FAILED;
692
693     const char* query = _db_get_query(type, CMD_SELECT);
694     ret = sqlite3_prepare_v2(db, query, -1, &stmt, NULL);
695     if (ret != SQLITE_OK) {
696         LOGE("fail to get record id : %s", sqlite3_errmsg(db));
697         goto cleanup;
698     }
699
700     if (type == STICKER_DB_STICKER_ALL || type == STICKER_DB_STICKER_APPID) {
701         sqlite3_bind_text(stmt, 1, app_id, -1, SQLITE_TRANSIENT);
702         sqlite3_bind_int(stmt, 2, offset);
703         sqlite3_bind_int(stmt, 3, count);
704     } else {
705         if (type == STICKER_DB_STICKER_TYPE)
706             sqlite3_bind_int(stmt, 1, *(int *)data);
707         else
708             sqlite3_bind_text(stmt, 1, (char *)data, -1, SQLITE_TRANSIENT);
709
710         sqlite3_bind_text(stmt, 2, app_id, -1, SQLITE_TRANSIENT);
711         sqlite3_bind_int(stmt, 3, offset);
712         sqlite3_bind_int(stmt, 4, count);
713     }
714
715     while (sqlite3_step(stmt) == SQLITE_ROW) {
716         const unsigned char *tmp_id = sqlite3_column_text(stmt, 0);
717         if (tmp_id)
718             *id_list = g_list_append(*id_list, strdup((const char *)tmp_id));
719     }
720
721     sqlite3_finalize(stmt);
722     sqlite3_close(db);
723
724     return STICKERD_SERVER_ERROR_NONE;
725
726 cleanup:
727     sqlite3_finalize(stmt);
728     sqlite3_close(db);
729
730     return STICKERD_SERVER_ERROR_DB_FAILED;
731 }