Using gdbus for IPC instead of com-core package
[platform/core/appfw/shortcut.git] / lib / src / shortcut_db.c
1 #include <dlog.h>
2 #include <glib.h>
3 #include <db-util.h>
4 #include <shortcut_private.h>
5 #include <shortcut_db.h>
6 #include <vconf.h>
7 #include <vconf-keys.h>
8
9
10
11 static sqlite3 * _open_db(void)
12 {
13         int ret;
14         const char *dbfile = DB_PATH;
15         sqlite3 *db = NULL;
16
17         ret = db_util_open(dbfile, &db, 0);
18         if (ret != SQLITE_OK) {
19                 DbgPrint("Failed to open a %s\n", dbfile);
20                 return NULL;
21         }
22
23         return db;
24 }
25
26 static int _close_db(sqlite3 ** db)
27 {
28         int ret = 0;
29
30         if (db == NULL || *db == NULL)
31                 return SHORTCUT_ERROR_INVALID_PARAMETER;
32
33         ret = db_util_close(*db);
34         if (ret != SQLITE_OK) {
35                 DbgPrint("DB close error(%d)", ret);
36                 return SHORTCUT_ERROR_IO_ERROR;
37         }
38
39         *db = NULL;
40
41         return SHORTCUT_ERROR_NONE;
42 }
43
44
45 /*!
46  * \note this function will returns allocated(heap) string
47  */
48 static inline int _get_i18n_name(sqlite3 *handle, const char *lang, int id, char **name, char **icon)
49 {
50         sqlite3_stmt *stmt;
51         static const char *query = "SELECT name, icon FROM shortcut_name WHERE id = ? AND lang = ? COLLATE NOCASE";
52         const unsigned char *_name;
53         const unsigned char *_icon;
54         int ret = 0;
55         int status;
56
57         status = sqlite3_prepare_v2(handle, query, -1, &stmt, NULL);
58         if (status != SQLITE_OK) {
59                 ErrPrint("Failed to prepare stmt: %s\n", sqlite3_errmsg(handle));
60                 return -EFAULT;
61         }
62
63         status = sqlite3_bind_int(stmt, 1, id);
64         if (status != SQLITE_OK) {
65                 ErrPrint("Failed to bind id: %s\n", sqlite3_errmsg(handle));
66                 ret = -EFAULT;
67                 goto out;
68         }
69
70         status = sqlite3_bind_text(stmt, 2, lang, -1, SQLITE_TRANSIENT);
71         if (status != SQLITE_OK) {
72                 ErrPrint("Failed to bind lang: %s\n", sqlite3_errmsg(handle));
73                 ret = -EFAULT;
74                 goto out;
75         }
76
77         DbgPrint("id: %d, lang: %s\n", id, lang);
78         if (SQLITE_ROW != sqlite3_step(stmt)) {
79                 ErrPrint("Failed to do step: %s\n", sqlite3_errmsg(handle));
80                 ret = -ENOENT;
81                 goto out;
82         }
83
84         _name = sqlite3_column_text(stmt, 0);
85         if (name) {
86                 if (_name && strlen((const char *)_name)) {
87                         *name = strdup((const char *)_name);
88                         if (!*name) {
89                                 ErrPrint("strdup: %d\n", errno);
90                                 ret = -ENOMEM;
91                                 goto out;
92                         }
93                 } else {
94                         *name = NULL;
95                 }
96         }
97
98         _icon = sqlite3_column_text(stmt, 1);
99         if (icon) {
100                 if (_icon && strlen((const char *)_icon)) {
101                         *icon = strdup((const char *)_icon);
102                         if (!*icon) {
103                                 ErrPrint("strdup: %d\n", errno);
104                                 ret = -ENOMEM;
105                                 if (name && *name)
106                                         free(*name);
107
108                                 goto out;
109                         }
110                 } else {
111                         *icon = NULL;
112                 }
113         }
114
115 out:
116         sqlite3_reset(stmt);
117         sqlite3_clear_bindings(stmt);
118         sqlite3_finalize(stmt);
119         return ret;
120 }
121
122 static inline char *_cur_locale(void)
123 {
124         char *language;
125         char *ptr;
126
127         language = vconf_get_str(VCONFKEY_LANGSET);
128         if (language) {
129                 ptr = language;
130                 while (*ptr) {
131                         if (*ptr == '.') {
132                                 *ptr = '\0';
133                                 break;
134                         }
135
136                         if (*ptr == '_')
137                                 *ptr = '-';
138
139                         ptr++;
140                 }
141         } else {
142                 language = strdup("en-us");
143                 if (!language)
144                         ErrPrint("Heap: %d\n", errno);
145         }
146
147         return language;
148 }
149
150 EAPI int shortcut_db_get_list(const char *package_name, GList **shortcut_list)
151 {
152         sqlite3_stmt *stmt;
153         sqlite3 *handle = NULL;
154         const char *query;
155         const unsigned char *name;
156         char *i18n_name = NULL;
157         char *i18n_icon = NULL;
158         const unsigned char *extra_data;
159         const unsigned char *extra_key;
160         const unsigned char *icon;
161         shortcut_info_s *shortcut;
162         int id;
163         int ret;
164         int cnt;
165         char *language;
166
167         handle = _open_db();
168         if (!handle) {
169                 ErrPrint("Failed to open a DB\n");
170                 return SHORTCUT_ERROR_IO_ERROR;
171         }
172
173         language = _cur_locale();
174         if (!language) {
175                 ErrPrint("Locale is not valid\n");
176                 _close_db(&handle);
177                 return SHORTCUT_ERROR_FAULT;
178         }
179
180         if (package_name) {
181                 query = "SELECT id, appid, name, extra_key, extra_data, icon FROM shortcut_service WHERE appid = ?";
182                 ret = sqlite3_prepare_v2(handle, query, -1, &stmt, NULL);
183                 if (ret != SQLITE_OK) {
184                         ErrPrint("prepare: %s\n", sqlite3_errmsg(handle));
185                         free(language);
186                         _close_db(&handle);
187                         return SHORTCUT_ERROR_IO_ERROR;
188                 }
189
190                 ret = sqlite3_bind_text(stmt, 1, package_name, -1, SQLITE_TRANSIENT);
191                 if (ret != SQLITE_OK) {
192                         ErrPrint("bind text: %s\n", sqlite3_errmsg(handle));
193                         sqlite3_finalize(stmt);
194                         free(language);
195                         _close_db(&handle);
196                         return SHORTCUT_ERROR_IO_ERROR;
197                 }
198         } else {
199                 query = "SELECT id, appid, name, extra_key, extra_data, icon FROM shortcut_service";
200                 ret = sqlite3_prepare_v2(handle, query, -1, &stmt, NULL);
201                 if (ret != SQLITE_OK) {
202                         ErrPrint("prepare: %s\n", sqlite3_errmsg(handle));
203                         free(language);
204                         _close_db(&handle);
205                         return SHORTCUT_ERROR_IO_ERROR;
206                 }
207         }
208
209         cnt = 0;
210         *shortcut_list = NULL;
211         while (SQLITE_ROW == sqlite3_step(stmt)) {
212                 id = sqlite3_column_int(stmt, 0);
213
214                 package_name = (const char *)sqlite3_column_text(stmt, 1);
215                 if (!package_name) {
216                         LOGE("Failed to get package name\n");
217                         continue;
218                 }
219
220                 name = sqlite3_column_text(stmt, 2);
221                 if (!name) {
222                         LOGE("Failed to get name\n");
223                         continue;
224                 }
225
226                 extra_key = sqlite3_column_text(stmt, 3);
227                 if (!extra_key) {
228                         LOGE("Failed to get service\n");
229                         continue;
230                 }
231
232                 extra_data = sqlite3_column_text(stmt, 4);
233                 if (!extra_data) {
234                         LOGE("Failed to get service\n");
235                         continue;
236                 }
237
238                 icon = sqlite3_column_text(stmt, 5);
239                 if (!icon) {
240                         LOGE("Failed to get icon\n");
241                         continue;
242                 }
243
244                 /*!
245                  * \todo
246                  * Implement the "GET LOCALE" code
247                  */
248                 /* if (get_i18n_name(language, id, &i18n_name, &i18n_icon) < 0) { */
249                         /* Okay, we can't manage this. just use the fallback string */
250                 /* } */
251                 _get_i18n_name(handle, language, id, &i18n_name, &i18n_icon);
252
253                 cnt++;
254                 shortcut = (shortcut_info_s *)calloc(sizeof(shortcut_info_s), 1);
255                 if (shortcut == NULL) {
256                         free(i18n_name);
257                         break;
258                 }
259                 shortcut->package_name = strdup(package_name);
260                 shortcut->icon = strdup((i18n_icon != NULL ? i18n_icon : (char *)icon));
261                 shortcut->name = strdup((i18n_name != NULL ? i18n_name : (char *)name));
262                 shortcut->extra_key = strdup((char *)extra_key);
263                 shortcut->extra_data = strdup((char *)extra_key);
264                 *shortcut_list = g_list_append(*shortcut_list, shortcut);
265
266                 free(i18n_name);
267                 i18n_name = NULL;
268
269                 free(i18n_icon);
270                 i18n_icon = NULL;
271         }
272
273         sqlite3_reset(stmt);
274         sqlite3_clear_bindings(stmt);
275         sqlite3_finalize(stmt);
276         free(language);
277         _close_db(&handle);
278
279         return cnt;
280 }