14a99faa331936e41a3f8d26f745debe2e156ec8
[platform/core/multimedia/libmedia-service.git] / src / media-svc-db-utils.c
1 /*
2  * libmedia-service
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  */
19
20 #include <unistd.h>
21 #include <media-util-db.h>
22 #include <errno.h>
23
24 #include "media-svc-env.h"
25 #include "media-svc-debug.h"
26 #include "media-svc-util.h"
27 #include "media-svc-db-utils.h"
28 #include "media-svc-media.h"
29
30 typedef enum {
31         DB_LIST_MEDIA = 0,
32         DB_LIST_FOLDER,
33         DB_LIST_PLAYLIST_MAP,
34         DB_LIST_PLAYLIST,
35         DB_LIST_ALBUM,
36         DB_LIST_TAG_MAP,
37         DB_LIST_TAG,
38         DB_LIST_BOOKMARK,
39         DB_LIST_STORAGE,
40         DB_LIST_FACE_SCAN_LIST,
41         DB_LIST_FACE,
42         DB_LIST_MAX,
43 } media_svc_table_slist_e;
44
45 static GHashTable *table;
46 static GSList *column_list[DB_LIST_MAX];
47
48 typedef struct {
49         char *trigger_name;
50         char *view_name;
51         char *event_table;
52         char *action_table;
53 } table_info_s;
54
55 typedef struct {
56         char *name;
57         char *type;
58         char *option;
59         bool is_unique;
60         bool is_trigger;
61         bool is_view;
62 } column_info_s;
63
64 static void __add_table_info(const char *name,
65                                                         const char *trigger_name,
66                                                         const char *event_table,
67                                                         const char *action_table,
68                                                         const char *view_name)
69 {
70         table_info_s *tbl = NULL;
71
72         if (!name)
73                 return;
74
75         if (trigger_name) {
76                 if(!event_table || !action_table)
77                         return;
78         }
79
80         tbl = g_new0(table_info_s, 1);
81
82         if (trigger_name) {
83                 tbl->trigger_name = g_strdup(trigger_name);
84                 tbl->event_table = g_strdup(event_table);
85                 tbl->action_table = g_strdup(action_table);
86         }
87
88         if (view_name)
89                 tbl->view_name = g_strdup(view_name);
90
91         g_hash_table_insert(table, (gpointer)name, (gpointer)tbl);
92 }
93
94 static void __add_column_info(GSList **slist,
95                                                                 const char *name,
96                                                                 const char *type,
97                                                                 const char *option,
98                                                                 bool is_unique,
99                                                                 bool is_trigger,
100                                                                 bool is_view)
101 {
102         column_info_s *col = g_new0(column_info_s, 1);
103
104         col->name = g_strdup(name);
105         col->type = g_strdup(type);
106         col->option = g_strdup(option);
107
108         col->is_unique = is_unique;
109         col->is_trigger = is_trigger;
110         col->is_view = is_view;
111
112         *slist = g_slist_append(*slist, col);
113 }
114
115 static int __create_playlist_view(uid_t uid)
116 {
117         GSList *iter = NULL;
118         column_info_s *col_ptr = NULL;
119         sql_autoptr q = NULL;
120         GString *table_query = g_string_new(NULL);
121         media_svc_retvm_if(!table_query, MS_MEDIA_ERR_INTERNAL, "g_string_new failed");
122
123         for (iter = column_list[DB_LIST_PLAYLIST]; iter; iter = g_slist_next(iter)) {
124                 col_ptr = iter->data;
125
126                 if (!col_ptr)
127                         continue;
128
129                 if (col_ptr->is_view) {
130                         if (table_query->len != 0) {
131                                 if (strncmp(col_ptr->name, DB_COLUMN_THUMBNAIL, strlen(DB_COLUMN_THUMBNAIL)) == 0)
132                                         g_string_append_printf(table_query, ", playlist.%s AS p_thumbnail_path", col_ptr->name);
133                                 else
134                                         g_string_append_printf(table_query, ", playlist.%s", col_ptr->name);
135                         } else {
136                                 g_string_append_printf(table_query, "playlist.%s", col_ptr->name);
137                         }
138                 }
139         }
140
141         for (iter = column_list[DB_LIST_PLAYLIST_MAP]; iter; iter = g_slist_next(iter)) {
142                 col_ptr = iter->data;
143
144                 if (!col_ptr)
145                         continue;
146
147                 if (col_ptr->is_view) {
148                         if (strncmp(col_ptr->name, DB_COLUMN_MAP_ID, strlen(DB_COLUMN_MAP_ID)) == 0)
149                                 g_string_append_printf(table_query, ", playlist_media_count IS NOT NULL AS playlist_media_count, playlist_map.%s AS pm_id", col_ptr->name);
150                         else
151                                 g_string_append_printf(table_query, ", playlist_map.%s", col_ptr->name);
152                 }
153         }
154
155         for (iter = column_list[DB_LIST_MEDIA]; iter; iter = g_slist_next(iter)) {
156                 col_ptr = iter->data;
157
158                 if (!col_ptr)
159                         continue;
160
161                 if (col_ptr->is_view)
162                         g_string_append_printf(table_query, ", media.%s", col_ptr->name);
163         }
164
165         q = sqlite3_mprintf(DB_QUERY_VIEW_PLAYLIST, DB_VIEW_PLAYLIST, table_query->str);
166         g_string_free(table_query, TRUE);
167
168         return _media_svc_sql_query(q, uid);
169 }
170
171 static int __create_tag_view(uid_t uid)
172 {
173         GSList *iter = NULL;
174         column_info_s *col_ptr = NULL;
175         sql_autoptr q = NULL;
176         GString *table_query = g_string_new(NULL);
177         media_svc_retvm_if(!table_query, MS_MEDIA_ERR_INTERNAL, "g_string_new failed");
178
179         for (iter = column_list[DB_LIST_TAG]; iter; iter = g_slist_next(iter)) {
180                 col_ptr = iter->data;
181
182                 if (!col_ptr)
183                         continue;
184
185                 if (col_ptr->is_view) {
186                         if (table_query->len != 0)
187                                 g_string_append_printf(table_query, ", tag.%s", col_ptr->name);
188                         else
189                                 g_string_append_printf(table_query, "tag.%s", col_ptr->name);
190                 }
191         }
192
193         for (iter = column_list[DB_LIST_TAG_MAP]; iter; iter = g_slist_next(iter)) {
194                 col_ptr = iter->data;
195
196                 if (!col_ptr)
197                         continue;
198
199                 if (col_ptr->is_view) {
200                         if (strncmp(col_ptr->name, DB_COLUMN_MAP_ID, strlen(DB_COLUMN_MAP_ID)) == 0)
201                                 g_string_append_printf(table_query, ", tag_media_count IS NOT NULL AS tag_media_count, tag_map.%s AS tm_id", col_ptr->name);
202                         else
203                                 g_string_append_printf(table_query, ", tag_map.%s", col_ptr->name);
204                 }
205         }
206
207         for (iter = column_list[DB_LIST_MEDIA]; iter; iter = g_slist_next(iter)) {
208                 col_ptr = iter->data;
209
210                 if (!col_ptr)
211                         continue;
212
213                 if (col_ptr->is_view)
214                         g_string_append_printf(table_query, ", media.%s", col_ptr->name);
215         }
216
217         q = sqlite3_mprintf(DB_QUERY_VIEW_TAG, DB_VIEW_TAG, table_query->str);
218         g_string_free(table_query, TRUE);
219
220         return _media_svc_sql_query(q, uid);
221 }
222
223 static int __media_svc_make_table_query(const char *table_name, media_svc_table_slist_e list, uid_t uid)
224 {
225         int ret = MS_MEDIA_ERR_NONE;
226         GSList *iter = NULL;
227         table_info_s *tb = NULL;
228         column_info_s *col_ptr = NULL;
229         sql_autoptr q = NULL;
230         GString *table_query = g_string_new(NULL);
231         GString *trigger_query = g_string_new(NULL);
232         GString *unique_query = g_string_new(NULL);
233
234         if (!table_query || !trigger_query || !unique_query) {
235                 media_svc_error("g_string_new failed");
236                 ret = MS_MEDIA_ERR_INTERNAL;
237                 goto ERROR;
238         }
239
240         tb = g_hash_table_lookup(table, table_name);
241         if (tb == NULL) {
242                 media_svc_debug("lookup fail.. table name [%s] ", table_name);
243                 ret = MS_MEDIA_ERR_INTERNAL;
244                 goto ERROR;
245         }
246
247         for (iter = column_list[list]; iter; iter = g_slist_next(iter)) {
248                 col_ptr = iter->data;
249                 if (!col_ptr)
250                         continue;
251
252                 /*create table */
253                 if (col_ptr->option) {
254                         if (table_query->len != 0)
255                                 g_string_append_printf(table_query, ", %s %s %s", col_ptr->name, col_ptr->type, col_ptr->option);
256                         else
257                                 g_string_append_printf(table_query, "%s %s %s", col_ptr->name, col_ptr->type, col_ptr->option);
258                 } else {
259                         if (table_query->len != 0)
260                                 g_string_append_printf(table_query, ", %s %s", col_ptr->name, col_ptr->type);
261                         else
262                                 g_string_append_printf(table_query, "%s %s", col_ptr->name, col_ptr->type);
263                 }
264
265                 /*unique */
266                 if (col_ptr->is_unique) {
267                         if (unique_query->len != 0)
268                                 g_string_append_printf(unique_query, ", %s", col_ptr->name);
269                         else
270                                 g_string_append_printf(unique_query, "%s", col_ptr->name);
271                 }
272
273                 /*create trigger */
274                 if (col_ptr->is_trigger) {
275                         if (tb->trigger_name) {
276                                 if (strncmp(table_name, DB_TABLE_ALBUM, strlen(DB_TABLE_ALBUM)) == 0) {
277                                         g_string_append_printf(trigger_query, DB_QUERY_TRIGGER_WITH_COUNT,
278                                                                                         tb->trigger_name, tb->event_table, tb->action_table, tb->event_table,
279                                                                                         col_ptr->name, col_ptr->name, col_ptr->name, col_ptr->name);
280                                 } else {
281                                         g_string_append_printf(trigger_query, DB_QUERY_TRIGGER,
282                                                                                         tb->trigger_name, tb->event_table, tb->action_table,
283                                                                                         col_ptr->name, col_ptr->name);
284                                 }
285                         } else {
286                                 media_svc_error("invalid trigger name");
287                         }
288                 }
289         }
290
291         /*send queries */
292         if (unique_query->len > 0)
293                 q = sqlite3_mprintf(DB_QUERY_TABLE_WITH_UNIQUE, table_name, table_query->str, unique_query->str);
294         else
295                 q = sqlite3_mprintf(DB_QUERY_TABLE, table_name, table_query->str);
296
297         ret = _media_svc_sql_query(q, uid);
298         if (ret != MS_MEDIA_ERR_NONE)
299                 goto ERROR;
300
301         if (trigger_query->len > 0) {
302                 ret = _media_svc_sql_query(trigger_query->str, uid);
303                 if (ret != MS_MEDIA_ERR_NONE)
304                         goto ERROR;
305         }
306
307         /*create view */
308         if (strncmp(table_name, DB_TABLE_PLAYLIST, strlen(DB_TABLE_PLAYLIST)) == 0)
309                 ret = __create_playlist_view(uid);
310         else if (strncmp(table_name, DB_TABLE_TAG, strlen(DB_TABLE_TAG)) == 0)
311                 ret = __create_tag_view(uid);
312
313 ERROR:
314         if (trigger_query)
315                 g_string_free(trigger_query, TRUE);
316         if (unique_query)
317                 g_string_free(unique_query, TRUE);
318         if (table_query)
319                 g_string_free(table_query, TRUE);
320
321         return ret;
322 }
323
324 static void __media_svc_table_free(gpointer data)
325 {
326         table_info_s *tb = (table_info_s *) data;
327
328         g_free(tb->trigger_name);
329         g_free(tb->view_name);
330         g_free(tb->event_table);
331         g_free(tb->action_table);
332         g_free(tb);
333 }
334
335 static void __media_svc_column_free(gpointer data)
336 {
337         column_info_s *col = (column_info_s *) data;
338
339         g_free(col->name);
340         g_free(col->type);
341         g_free(col->option);
342         g_free(col);
343 }
344
345 static void __media_svc_init_table_query(void)
346 {
347         /*variable initialize.. */
348         table = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, __media_svc_table_free);
349
350         /*table specification.. (table_name, trigger name, event table, action table, view name) */
351         __add_table_info(DB_TABLE_MEDIA, NULL, NULL, NULL, NULL);
352         __add_table_info(DB_TABLE_FOLDER, NULL, NULL, NULL, NULL);
353         __add_table_info(DB_TABLE_PLAYLIST_MAP, DB_TRIGGER_PLAYLIST_MAP, DB_TABLE_MEDIA, DB_TABLE_PLAYLIST_MAP, NULL);
354         __add_table_info(DB_TABLE_PLAYLIST, DB_TRIGGER_PLAYLIST_MAP1, DB_TABLE_PLAYLIST, DB_TABLE_PLAYLIST_MAP, DB_VIEW_PLAYLIST);
355         __add_table_info(DB_TABLE_ALBUM, DB_TRIGGER_ALBUM, DB_TABLE_MEDIA, DB_TABLE_ALBUM, NULL);
356         __add_table_info(DB_TABLE_TAG_MAP, DB_TRIGGER_TAG_MAP, DB_TABLE_MEDIA, DB_TABLE_TAG_MAP, NULL);
357         __add_table_info(DB_TABLE_TAG, DB_TRIGGER_TAG_MAP1, DB_TABLE_TAG, DB_TABLE_TAG_MAP, DB_VIEW_TAG);
358         __add_table_info(DB_TABLE_BOOKMARK, DB_TRIGGER_BOOKMARK, DB_TABLE_MEDIA, DB_TABLE_BOOKMARK, NULL);
359         __add_table_info(DB_TABLE_STORAGE, NULL, NULL, NULL, NULL);
360         __add_table_info(DB_TABLE_FACE_SCAN_LIST, DB_TRIGGER_FACE_SCAN_LIST, DB_TABLE_MEDIA, DB_TABLE_FACE_SCAN_LIST, NULL);
361         __add_table_info(DB_TABLE_FACE, DB_TRIGGER_FACE, DB_TABLE_FACE_SCAN_LIST, DB_TABLE_FACE, NULL);
362
363         /*insert column info.. */
364         /*media*/
365         __add_column_info(&column_list[DB_LIST_MEDIA], "media_id", DB_TYPE_TEXT, "PRIMARY KEY", false, false, true);
366         __add_column_info(&column_list[DB_LIST_MEDIA], "media_path", DB_TYPE_TEXT, "NOT NULL UNIQUE", false, false, true);
367         __add_column_info(&column_list[DB_LIST_MEDIA], "media_display_name", DB_TYPE_TEXT, "NOT NULL", false, false, true);
368         __add_column_info(&column_list[DB_LIST_MEDIA], "media_type", DB_TYPE_INT, NULL, false, false, true);
369         __add_column_info(&column_list[DB_LIST_MEDIA], "media_mime_type", DB_TYPE_TEXT, NULL, false, false, true);
370         __add_column_info(&column_list[DB_LIST_MEDIA], "media_size", DB_TYPE_INT, "DEFAULT 0", false, false, true);
371         __add_column_info(&column_list[DB_LIST_MEDIA], "media_added_time", DB_TYPE_INT, "DEFAULT (unixepoch())", false, false, true);
372         __add_column_info(&column_list[DB_LIST_MEDIA], "media_modified_time", DB_TYPE_INT, "DEFAULT 0", false, false, true);
373         __add_column_info(&column_list[DB_LIST_MEDIA], "folder_id", DB_TYPE_INT, "DEFAULT 0", false, false, false);
374         __add_column_info(&column_list[DB_LIST_MEDIA], "media_thumbnail_path", DB_TYPE_TEXT, NULL, false, false, true);
375         __add_column_info(&column_list[DB_LIST_MEDIA], "media_title", DB_TYPE_TEXT, NULL, false, false, true);
376         __add_column_info(&column_list[DB_LIST_MEDIA], "album_id", DB_TYPE_INT, "DEFAULT 0", false, false, false);
377         __add_column_info(&column_list[DB_LIST_MEDIA], "media_album", DB_TYPE_TEXT, NULL, false, false, true);
378         __add_column_info(&column_list[DB_LIST_MEDIA], "media_artist", DB_TYPE_TEXT, NULL, false, false, true);
379         __add_column_info(&column_list[DB_LIST_MEDIA], "media_album_artist", DB_TYPE_TEXT, NULL, false, false, true);
380         __add_column_info(&column_list[DB_LIST_MEDIA], "media_genre", DB_TYPE_TEXT, NULL, false, false, true);
381         __add_column_info(&column_list[DB_LIST_MEDIA], "media_composer", DB_TYPE_TEXT, "DEFAULT ''", false, false, true);
382         __add_column_info(&column_list[DB_LIST_MEDIA], "media_year", DB_TYPE_TEXT, NULL, false, false, true);
383         __add_column_info(&column_list[DB_LIST_MEDIA], "media_recorded_date", DB_TYPE_TEXT, "DEFAULT ''", false, false, true);
384         __add_column_info(&column_list[DB_LIST_MEDIA], "media_copyright", DB_TYPE_TEXT, "DEFAULT ''", false, false, true);
385         __add_column_info(&column_list[DB_LIST_MEDIA], "media_track_num", DB_TYPE_TEXT, NULL, false, false, true);
386         __add_column_info(&column_list[DB_LIST_MEDIA], "media_description", DB_TYPE_TEXT, "DEFAULT ''", false, false, true);
387         __add_column_info(&column_list[DB_LIST_MEDIA], "media_bitrate", DB_TYPE_INT, "DEFAULT -1", false, false, true);
388         __add_column_info(&column_list[DB_LIST_MEDIA], "media_bitpersample", DB_TYPE_INT, "DEFAULT 0", false, false, true);
389         __add_column_info(&column_list[DB_LIST_MEDIA], "media_samplerate", DB_TYPE_INT, "DEFAULT -1", false, false, true);
390         __add_column_info(&column_list[DB_LIST_MEDIA], "media_channel", DB_TYPE_INT, "DEFAULT -1", false, false, true);
391         __add_column_info(&column_list[DB_LIST_MEDIA], "media_duration", DB_TYPE_INT, "DEFAULT -1", false, false, true);
392         __add_column_info(&column_list[DB_LIST_MEDIA], "media_longitude", DB_TYPE_DOUBLE, "DEFAULT -200", false, false, true);
393         __add_column_info(&column_list[DB_LIST_MEDIA], "media_latitude", DB_TYPE_DOUBLE, "DEFAULT -200", false, false, true);
394         __add_column_info(&column_list[DB_LIST_MEDIA], "media_altitude", DB_TYPE_DOUBLE, "DEFAULT 0", false, false, true);
395         __add_column_info(&column_list[DB_LIST_MEDIA], "exposure_time", DB_TYPE_TEXT, NULL, false, false, true);
396         __add_column_info(&column_list[DB_LIST_MEDIA], "fnumber", DB_TYPE_DOUBLE, "DEFAULT 0", false, false, true);
397         __add_column_info(&column_list[DB_LIST_MEDIA], "iso", DB_TYPE_INT, "DEFAULT -1", false, false, true);
398         __add_column_info(&column_list[DB_LIST_MEDIA], "model", DB_TYPE_TEXT, NULL, false, false, true);
399         __add_column_info(&column_list[DB_LIST_MEDIA], "media_width", DB_TYPE_INT, "DEFAULT -1", false, false, true);
400         __add_column_info(&column_list[DB_LIST_MEDIA], "media_height", DB_TYPE_INT, "DEFAULT -1", false, false, true);
401         __add_column_info(&column_list[DB_LIST_MEDIA], "media_datetaken", DB_TYPE_TEXT, NULL, false, false, true);
402         __add_column_info(&column_list[DB_LIST_MEDIA], "orientation", DB_TYPE_INT, "DEFAULT -1", false, false, true);
403         __add_column_info(&column_list[DB_LIST_MEDIA], "media_rating", DB_TYPE_INT, "DEFAULT 0", false, false, true);
404         __add_column_info(&column_list[DB_LIST_MEDIA], "media_favourite", DB_TYPE_INT, "DEFAULT 0", false, false, true);
405         __add_column_info(&column_list[DB_LIST_MEDIA], "media_is_drm", DB_TYPE_INT, "DEFAULT 0", false, false, true);
406         __add_column_info(&column_list[DB_LIST_MEDIA], "media_timeline", DB_TYPE_INT, "DEFAULT 0", false, false, true);
407         __add_column_info(&column_list[DB_LIST_MEDIA], "storage_uuid", DB_TYPE_TEXT, NULL, false, false, true);
408         __add_column_info(&column_list[DB_LIST_MEDIA], "validity", DB_TYPE_INT, "DEFAULT 1", false, false, false);
409         __add_column_info(&column_list[DB_LIST_MEDIA], "media_360", DB_TYPE_INT, "DEFAULT 0", false, false, true);
410
411         /*folder*/
412         __add_column_info(&column_list[DB_LIST_FOLDER], "folder_id", DB_TYPE_INT, "PRIMARY KEY AUTOINCREMENT", false, false, false);
413         __add_column_info(&column_list[DB_LIST_FOLDER], "folder_path", DB_TYPE_TEXT, "NOT NULL", true, false, false);
414         __add_column_info(&column_list[DB_LIST_FOLDER], "folder_name", DB_TYPE_TEXT, "NOT NULL", false, false, false);
415         __add_column_info(&column_list[DB_LIST_FOLDER], "storage_uuid", DB_TYPE_TEXT, NULL, true, false, false);
416         __add_column_info(&column_list[DB_LIST_FOLDER], "validity", DB_TYPE_INT, "DEFAULT 1", false, false, false);
417
418         /*playlist_map*/
419         __add_column_info(&column_list[DB_LIST_PLAYLIST_MAP], "_id", DB_TYPE_INT, "PRIMARY KEY AUTOINCREMENT", false, false, true);
420         __add_column_info(&column_list[DB_LIST_PLAYLIST_MAP], "playlist_id", DB_TYPE_INT, "NOT NULL", false, false, false);
421         __add_column_info(&column_list[DB_LIST_PLAYLIST_MAP], "media_id", DB_TYPE_TEXT, "NOT NULL", false, true, false);
422         __add_column_info(&column_list[DB_LIST_PLAYLIST_MAP], "playlist_member_order", DB_TYPE_INT, "NOT NULL", false, false, true);
423
424         /*playlist*/
425         __add_column_info(&column_list[DB_LIST_PLAYLIST], "playlist_id", DB_TYPE_INT, "PRIMARY KEY AUTOINCREMENT", false, true, true);
426         __add_column_info(&column_list[DB_LIST_PLAYLIST], "playlist_name", DB_TYPE_TEXT, "NOT NULL UNIQUE", false, false, true);
427         __add_column_info(&column_list[DB_LIST_PLAYLIST], "thumbnail_path", DB_TYPE_TEXT, NULL, false, false, true);
428
429         /*album*/
430         __add_column_info(&column_list[DB_LIST_ALBUM], "album_id", DB_TYPE_INT, "PRIMARY KEY AUTOINCREMENT", false, true, false);
431         __add_column_info(&column_list[DB_LIST_ALBUM], "name", DB_TYPE_TEXT, "NOT NULL", false, false, false);
432         __add_column_info(&column_list[DB_LIST_ALBUM], "artist", DB_TYPE_TEXT, NULL, false, false, false);
433         __add_column_info(&column_list[DB_LIST_ALBUM], "album_art", DB_TYPE_TEXT, NULL, false, false, false);
434
435         /*tag_map*/
436         __add_column_info(&column_list[DB_LIST_TAG_MAP], "_id", DB_TYPE_INT, "PRIMARY KEY AUTOINCREMENT", false, false, true);
437         __add_column_info(&column_list[DB_LIST_TAG_MAP], "tag_id", DB_TYPE_INT, "NOT NULL", true, false, false);
438         __add_column_info(&column_list[DB_LIST_TAG_MAP], "media_id", DB_TYPE_TEXT, "NOT NULL", true, true, false);
439
440         /*tag*/
441         __add_column_info(&column_list[DB_LIST_TAG], "tag_id ", DB_TYPE_INT, "PRIMARY KEY AUTOINCREMENT", false, true, true);
442         __add_column_info(&column_list[DB_LIST_TAG], "tag_name", DB_TYPE_TEXT, "NOT NULL UNIQUE", false, false, true);
443
444         /*bookmark*/
445         __add_column_info(&column_list[DB_LIST_BOOKMARK], "bookmark_id", DB_TYPE_INT, "PRIMARY KEY AUTOINCREMENT", false, false, false);
446         __add_column_info(&column_list[DB_LIST_BOOKMARK], "media_id", DB_TYPE_TEXT, "NOT NULL", true, true, false);
447         __add_column_info(&column_list[DB_LIST_BOOKMARK], "bookmark_marked_time", DB_TYPE_INT, "DEFAULT 0", true, false, false);
448         __add_column_info(&column_list[DB_LIST_BOOKMARK], "bookmark_thumbnail_path", DB_TYPE_TEXT, NULL, false, false, false);
449         __add_column_info(&column_list[DB_LIST_BOOKMARK], "bookmark_name", DB_TYPE_TEXT, NULL, false, false, false);
450
451         /*storage*/
452         __add_column_info(&column_list[DB_LIST_STORAGE], "storage_id", DB_TYPE_TEXT, "PRIMARY KEY", false, false, false);
453         __add_column_info(&column_list[DB_LIST_STORAGE], "storage_path", DB_TYPE_TEXT, "NOT NULL", false, false, false);
454         __add_column_info(&column_list[DB_LIST_STORAGE], "validity", DB_TYPE_INT, "DEFAULT 1", false, false, false);
455
456         /*face scan list*/
457         __add_column_info(&column_list[DB_LIST_FACE_SCAN_LIST], "media_id", DB_TYPE_TEXT, "NOT NULL UNIQUE", false, true, false);
458         __add_column_info(&column_list[DB_LIST_FACE_SCAN_LIST], "modified_time", DB_TYPE_INT, "DEFAULT 0", false, false, false);
459
460         /*face*/
461         __add_column_info(&column_list[DB_LIST_FACE], "media_face_id", DB_TYPE_INT, "PRIMARY KEY AUTOINCREMENT", false, false, false);
462         __add_column_info(&column_list[DB_LIST_FACE], "media_id", DB_TYPE_TEXT, "NOT NULL", true, true, false);
463         __add_column_info(&column_list[DB_LIST_FACE], "face_rect_x", DB_TYPE_INT, "DEFAULT 0", true, false, false);
464         __add_column_info(&column_list[DB_LIST_FACE], "face_rect_y", DB_TYPE_INT, "DEFAULT 0", true, false, false);
465         __add_column_info(&column_list[DB_LIST_FACE], "face_rect_w", DB_TYPE_INT, "DEFAULT 0", true, false, false);
466         __add_column_info(&column_list[DB_LIST_FACE], "face_rect_h", DB_TYPE_INT, "DEFAULT 0", true, false, false);
467         __add_column_info(&column_list[DB_LIST_FACE], "face_orientation", DB_TYPE_INT, "DEFAULT 0", false, false, false);
468         __add_column_info(&column_list[DB_LIST_FACE], "media_face_tag", DB_TYPE_TEXT, NULL, false, false, false);
469 }
470
471 static void __media_svc_destroy_table_query(void)
472 {
473         int i = 0;
474
475         /* Table Free */
476         g_hash_table_destroy(table);
477         table = NULL;
478
479         /* Column Free */
480         for (i = 0; i < DB_LIST_MAX; i++) {
481                 g_slist_free_full(column_list[i], __media_svc_column_free);
482                 column_list[i] = NULL;
483         }
484 }
485
486 int _media_svc_create_table(uid_t uid)
487 {
488         int ret = MS_MEDIA_ERR_NONE;
489         media_svc_debug_fenter();
490         __media_svc_init_table_query();
491
492         /*create media table*/
493         ret = __media_svc_make_table_query(DB_TABLE_MEDIA, DB_LIST_MEDIA, uid);
494         if (ret != MS_MEDIA_ERR_NONE) {
495                 media_svc_error("failed to create media table");
496                 goto ERROR;
497         }
498
499         /*create folder table*/
500         ret = __media_svc_make_table_query(DB_TABLE_FOLDER, DB_LIST_FOLDER, uid);
501         if (ret != MS_MEDIA_ERR_NONE) {
502                 media_svc_error("failed to create folder table");
503                 goto ERROR;
504         }
505
506         /*create playlist_map table*/
507         ret = __media_svc_make_table_query(DB_TABLE_PLAYLIST_MAP, DB_LIST_PLAYLIST_MAP, uid);
508         if (ret != MS_MEDIA_ERR_NONE) {
509                 media_svc_error("failed to create playlist_map table");
510                 goto ERROR;
511         }
512
513         /*create playlist table*/
514         ret = __media_svc_make_table_query(DB_TABLE_PLAYLIST, DB_LIST_PLAYLIST, uid);
515         if (ret != MS_MEDIA_ERR_NONE) {
516                 media_svc_error("failed to create playlist table");
517                 goto ERROR;
518         }
519
520         /* create album table*/
521         ret = __media_svc_make_table_query(DB_TABLE_ALBUM, DB_LIST_ALBUM, uid);
522         if (ret != MS_MEDIA_ERR_NONE) {
523                 media_svc_error("failed to create album table");
524                 goto ERROR;
525         }
526
527         /*create tag_map table*/
528         ret = __media_svc_make_table_query(DB_TABLE_TAG_MAP, DB_LIST_TAG_MAP, uid);
529         if (ret != MS_MEDIA_ERR_NONE) {
530                 media_svc_error("failed to create tag_map table");
531                 goto ERROR;
532         }
533
534         /*create tag table*/
535         ret = __media_svc_make_table_query(DB_TABLE_TAG, DB_LIST_TAG, uid);
536         if (ret != MS_MEDIA_ERR_NONE) {
537                 media_svc_error("failed to create tag table");
538                 goto ERROR;
539         }
540
541         /*create bookmark table*/
542         ret = __media_svc_make_table_query(DB_TABLE_BOOKMARK, DB_LIST_BOOKMARK, uid);
543         if (ret != MS_MEDIA_ERR_NONE) {
544                 media_svc_error("failed to create bookmark table");
545                 goto ERROR;
546         }
547
548         /*create storage table from tizen 2.4 */
549         ret = __media_svc_make_table_query(DB_TABLE_STORAGE, DB_LIST_STORAGE, uid);
550         if (ret != MS_MEDIA_ERR_NONE) {
551                 media_svc_error("failed to create storage table");
552                 goto ERROR;
553         }
554
555         /*create face table. from tizen 3.0*/
556         ret = __media_svc_make_table_query(DB_TABLE_FACE_SCAN_LIST, DB_LIST_FACE_SCAN_LIST, uid);
557         if (ret != MS_MEDIA_ERR_NONE) {
558                 media_svc_error("failed to create face_scan_list table");
559                 goto ERROR;
560         }
561
562         ret = __media_svc_make_table_query(DB_TABLE_FACE, DB_LIST_FACE, uid);
563         if (ret != MS_MEDIA_ERR_NONE) {
564                 media_svc_error("failed to create face table");
565                 goto ERROR;
566         }
567 ERROR:
568         __media_svc_destroy_table_query();
569         media_svc_debug_fleave();
570
571         return ret;
572 }
573
574 int _media_svc_sql_query(const char *sql_str, uid_t uid)
575 {
576         return media_db_request_update_db(sql_str, uid);
577 }
578
579 int _media_svc_sql_query_direct(const char *sql_str, uid_t uid)
580 {
581         return media_db_update_db_direct(sql_str, uid);
582 }
583
584 int _media_svc_check_table_exist(sqlite3 *db_handle, bool *exist)
585 {
586         int ret = MS_MEDIA_ERR_NONE;
587         sqlite3_stmt *stmt = NULL;
588         const char *q = "SELECT name FROM sqlite_master WHERE type='table' AND name='media';";
589
590         ret = _media_svc_get_result(db_handle, q, &stmt);
591         media_svc_retvm_if(ret != MS_MEDIA_ERR_NONE, ret, "_media_svc_get_result failed");
592         if (sqlite3_step(stmt) != SQLITE_ROW) {
593                 media_svc_debug("Need to create table");
594                 *exist = false;
595         } else {
596                 media_svc_debug("Already exists");
597                 *exist = true;
598         }
599
600         sqlite3_finalize(stmt);
601
602         return MS_MEDIA_ERR_NONE;
603 }
604
605 static int __media_svc_check_record(sqlite3_stmt **stmt)
606 {
607         media_svc_retvm_if(!stmt, MS_MEDIA_ERR_INVALID_PARAMETER, "invalid statement");
608
609         if (sqlite3_step(*stmt) != SQLITE_ROW) {
610                 media_svc_debug("No record");
611                 sqlite3_finalize(*stmt);
612                 return MS_MEDIA_ERR_DB_NO_RECORD;
613         }
614
615         return MS_MEDIA_ERR_NONE;
616 }
617
618 int _media_svc_get_result_with_check_record(sqlite3 *handle, const char *sql_str, sqlite3_stmt **stmt)
619 {
620         int ret = media_db_get_result(handle, sql_str, stmt);
621         media_svc_retvm_if(ret != MS_MEDIA_ERR_NONE, ret, "failed to get result");
622
623         return __media_svc_check_record(stmt);
624 }
625
626 int _media_svc_get_result(sqlite3 *handle, const char *sql_str, sqlite3_stmt **stmt)
627 {
628         return media_db_get_result(handle, sql_str, stmt);
629 }
630
631 static void __media_svc_sql_query_release(GList **query_list)
632 {
633         if (*query_list) {
634                 g_list_free(*query_list);
635                 *query_list = NULL;
636         }
637 }
638
639 int _media_svc_sql_query_list(GList **query_list, uid_t uid)
640 {
641         int ret = MS_MEDIA_ERR_NONE;
642         int idx = 0;
643         int length = g_list_length(*query_list);
644         char *q = NULL;
645
646         media_svc_debug("query list length : [%d]", length);
647
648         for (idx = 0; idx < length; idx++) {
649                 q = (char *)g_list_nth_data(*query_list, idx);
650                 if (STRING_VALID(q)) {
651                         ret = media_db_request_update_db(q, uid);
652                         if (ret != MS_MEDIA_ERR_NONE)
653                                 media_svc_error("media_db_request_update_db failed : %d", ret);
654                 }
655
656                 sqlite3_free(q);
657         }
658
659         __media_svc_sql_query_release(query_list);
660
661         return MS_MEDIA_ERR_NONE;
662 }
663
664 int _media_svc_sql_query_list_direct(GList **query_list, uid_t uid)
665 {
666         int ret = MS_MEDIA_ERR_NONE;
667         int idx = 0;
668         int length = g_list_length(*query_list);
669         char *q = NULL;
670         sqlite3 *handle = NULL;
671         bool with_transaction = true;
672
673         media_svc_debug("query list length[%d]", length);
674         if (length == 0)
675                 goto ZERO_LEN;
676
677         ret = media_db_connect(&handle, uid, true);
678         media_svc_retvm_if(ret != MS_MEDIA_ERR_NONE, ret, "DB connection failed");
679
680         if (sqlite3_exec(handle, "BEGIN;", NULL, NULL, NULL) != SQLITE_OK) {
681                 media_svc_error("transaction failed. try an individual insert.");
682                 with_transaction = false;
683         }
684
685         for (idx = 0; idx < length; idx++) {
686                 q = (char *)g_list_nth_data(*query_list, idx);
687                 if (STRING_VALID(q)) {
688                         if (sqlite3_exec(handle, q, NULL, NULL, NULL) != SQLITE_OK)
689                                 media_svc_debug("query failed[%s]", sqlite3_errmsg(handle));
690
691                         sqlite3_free(q);
692                 }
693         }
694
695         if (with_transaction) {
696                 if (sqlite3_exec(handle, "COMMIT;", NULL, NULL, NULL) != SQLITE_OK) {
697                         media_svc_error("Commit failed");
698                         ret = MS_MEDIA_ERR_DB_INTERNAL;
699                 }
700         }
701
702         media_db_disconnect(handle);
703
704 ZERO_LEN:
705         __media_svc_sql_query_release(query_list);
706
707         return ret;
708 }
709
710 void _media_svc_sql_query_add(GList **query_list, char **query)
711 {
712         *query_list = g_list_append(*query_list, *query);
713 }