Merge "check src before doing g_strlcpy and g_strlcat" into tizen
[platform/core/multimedia/libmedia-service.git] / src / common / media-svc-db-utils.c
1 /*
2  * libmedia-service
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Hyunjun Ko <zzoon.ko@samsung.com>, Haejeong Kim <backto.kim@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 #include <unistd.h>
23 #include <media-util.h>
24 #include <errno.h>
25 #include "media-svc-env.h"
26 #include "media-svc-debug.h"
27 #include "media-svc-util.h"
28 #include "media-svc-db-utils.h"
29 #include "media-util-err.h"
30 #include "media-util-db.h"
31 #include "media-svc-media.h"
32
33 static GHashTable *table;
34 static GSList *column_list[MEDIA_SVC_DB_LIST_MAX];
35
36 static int __media_svc_add_table_info(const char *name, const char *trigger_name, const char *event_table, const char *action_table, const char *view_name)
37 {
38         table_info_s *tbl = NULL;
39
40         media_svc_retvm_if(!STRING_VALID(name), MS_MEDIA_ERR_INVALID_PARAMETER, "name is NULL");
41
42         if (STRING_VALID(trigger_name)) {
43                 media_svc_retvm_if(!STRING_VALID(event_table), MS_MEDIA_ERR_INVALID_PARAMETER, "event_table is NULL");
44                 media_svc_retvm_if(!STRING_VALID(action_table), MS_MEDIA_ERR_INVALID_PARAMETER, "action_table is NULL");
45         }
46
47         tbl = calloc(1, sizeof(table_info_s));
48         media_svc_retvm_if(!tbl, MS_MEDIA_ERR_OUT_OF_MEMORY, "Failed to allocation");
49
50         if (STRING_VALID(trigger_name)) {
51                 tbl->trigger_name = g_strdup(trigger_name);
52                 tbl->event_table = g_strdup(event_table);
53                 tbl->action_table = g_strdup(action_table);
54         }
55
56         if (STRING_VALID(view_name))
57                 tbl->view_name = g_strdup(view_name);
58
59         g_hash_table_insert(table, (gpointer)name, (gpointer)tbl);
60
61         return MS_MEDIA_ERR_NONE;
62 }
63
64 int __media_svc_add_column_info(GSList **slist, const char *name, const char *type, const char *option, int version, const char *index_name, bool is_unique, bool is_trigger, bool is_view)
65 {
66         column_info_s *col = NULL;
67         col = calloc(1, sizeof(column_info_s));
68         media_svc_retvm_if(!col, MS_MEDIA_ERR_OUT_OF_MEMORY, "Failed to allocation");
69
70         col->name = g_strdup(name);
71         col->type = g_strdup(type);
72         col->option = g_strdup(option);
73         col->version = version;
74         col->index_name = g_strdup(index_name);
75
76         col->is_unique = is_unique;
77         col->is_trigger = is_trigger;
78         col->is_view = is_view;
79
80         *slist = g_slist_append(*slist, col);
81
82         return MS_MEDIA_ERR_NONE;
83 }
84
85 static int __create_playlist_view(uid_t uid)
86 {
87         int ret = MS_MEDIA_ERR_NONE;
88         GSList *iter = NULL;
89         column_info_s *col_ptr = NULL;
90         char *sql = NULL;
91         GString *table_query = g_string_new(NULL);
92         media_svc_retvm_if(!table_query, MS_MEDIA_ERR_INTERNAL, "g_string_new failed");
93
94         for (iter = column_list[MEDIA_SVC_DB_LIST_PLAYLIST]; iter; iter = g_slist_next(iter)) {
95                 col_ptr = iter->data;
96
97                 if (!col_ptr)
98                         continue;
99
100                 if (col_ptr->is_view) {
101                         if (table_query->len != 0) {
102                                 if (strncmp(col_ptr->name, MEDIA_SVC_DB_COLUMN_THUMBNAIL, strlen(MEDIA_SVC_DB_COLUMN_THUMBNAIL)) == 0)
103                                         g_string_append_printf(table_query, ", playlist.%s AS p_thumbnail_path", col_ptr->name);
104                                 else
105                                         g_string_append_printf(table_query, ", playlist.%s", col_ptr->name);
106                         } else {
107                                 g_string_append_printf(table_query, "playlist.%s", col_ptr->name);
108                         }
109                 }
110         }
111
112         for (iter = column_list[MEDIA_SVC_DB_LIST_PLAYLIST_MAP]; iter; iter = g_slist_next(iter)) {
113                 col_ptr = iter->data;
114
115                 if (!col_ptr)
116                         continue;
117
118                 if (col_ptr->is_view) {
119                         if (strncmp(col_ptr->name, MEDIA_SVC_DB_COLUMN_MAP_ID, strlen(MEDIA_SVC_DB_COLUMN_MAP_ID)) == 0)
120                                 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);
121                         else
122                                 g_string_append_printf(table_query, ", playlist_map.%s", col_ptr->name);
123                 }
124         }
125
126         for (iter = column_list[MEDIA_SVC_DB_LIST_MEDIA]; iter; iter = g_slist_next(iter)) {
127                 col_ptr = iter->data;
128
129                 if (!col_ptr)
130                         continue;
131
132                 if (col_ptr->is_view)
133                         g_string_append_printf(table_query, ", media.%s", col_ptr->name);
134         }
135
136         sql = sqlite3_mprintf(MEDIA_SVC_DB_QUERY_VIEW_PLAYLIST, MEDIA_SVC_DB_VIEW_PLAYLIST, table_query->str);
137         g_string_free(table_query, TRUE);
138         ret = _media_svc_sql_query(sql, uid);
139         SQLITE3_SAFE_FREE(sql);
140
141         return ret;
142 }
143
144 static int __create_tag_view(uid_t uid)
145 {
146         int ret = MS_MEDIA_ERR_NONE;
147         GSList *iter = NULL;
148         column_info_s *col_ptr = NULL;
149         char *sql = NULL;
150         GString *table_query = g_string_new(NULL);
151         media_svc_retvm_if(!table_query, MS_MEDIA_ERR_INTERNAL, "g_string_new failed");
152
153         for (iter = column_list[MEDIA_SVC_DB_LIST_TAG]; iter; iter = g_slist_next(iter)) {
154                 col_ptr = iter->data;
155
156                 if (!col_ptr)
157                         continue;
158
159                 if (col_ptr->is_view) {
160                         if (table_query->len != 0)
161                                 g_string_append_printf(table_query, ", tag.%s", col_ptr->name);
162                         else
163                                 g_string_append_printf(table_query, "tag.%s", col_ptr->name);
164                 }
165         }
166
167         for (iter = column_list[MEDIA_SVC_DB_LIST_TAG_MAP]; iter; iter = g_slist_next(iter)) {
168                 col_ptr = iter->data;
169
170                 if (!col_ptr)
171                         continue;
172
173                 if (col_ptr->is_view) {
174                         if (strncmp(col_ptr->name, MEDIA_SVC_DB_COLUMN_MAP_ID, strlen(MEDIA_SVC_DB_COLUMN_MAP_ID)) == 0)
175                                 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);
176                         else
177                                 g_string_append_printf(table_query, ", tag_map.%s", col_ptr->name);
178                 }
179         }
180
181         for (iter = column_list[MEDIA_SVC_DB_LIST_MEDIA]; iter; iter = g_slist_next(iter)) {
182                 col_ptr = iter->data;
183
184                 if (!col_ptr)
185                         continue;
186
187                 if (col_ptr->is_view)
188                         g_string_append_printf(table_query, ", media.%s", col_ptr->name);
189         }
190
191         sql = sqlite3_mprintf(MEDIA_SVC_DB_QUERY_VIEW_TAG, MEDIA_SVC_DB_VIEW_TAG, table_query->str);
192         g_string_free(table_query, TRUE);
193         ret = _media_svc_sql_query(sql, uid);
194         SQLITE3_SAFE_FREE(sql);
195
196         return ret;
197 }
198
199 static int __drop_views(uid_t uid)
200 {
201         int ret = MS_MEDIA_ERR_NONE;
202         char *sql = NULL;
203
204         sql = sqlite3_mprintf("DROP VIEW IF EXISTS %q;DROP VIEW IF EXISTS %q;DROP VIEW IF EXISTS %q", MEDIA_SVC_DB_VIEW_PLAYLIST, MEDIA_SVC_DB_VIEW_TAG, MEDIA_SVC_DB_VIEW_MEDIA);
205
206         ret = _media_svc_sql_query(sql, uid);
207         SQLITE3_SAFE_FREE(sql);
208
209         return ret;
210 }
211
212 static int __media_svc_rebuild_view_query(sqlite3 *db_handle, uid_t uid)
213 {
214         int ret = MS_MEDIA_ERR_NONE;
215
216         /*create playlist_view */
217         ret = __create_playlist_view(uid);
218         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
219
220         /*create tag_view */
221         ret = __create_tag_view(uid);
222         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
223
224         return MS_MEDIA_ERR_NONE;
225 }
226
227 int _media_svc_make_table_query(const char *table_name, media_svc_table_slist_e list, uid_t uid)
228 {
229         int ret = MS_MEDIA_ERR_NONE;
230         GSList *iter = NULL;
231         table_info_s *tb = NULL;
232         column_info_s *col_ptr = NULL;
233         char *sql = NULL;
234         GString *table_query = g_string_new(NULL);
235         GString *index_query = g_string_new(NULL);
236         GString *trigger_query = g_string_new(NULL);
237         GString *unique_query = g_string_new(NULL);
238
239         if (!table_query || !index_query || !trigger_query || !unique_query) {
240                 media_svc_error("g_string_new failed");
241                 ret = MS_MEDIA_ERR_INTERNAL;
242                 goto ERROR;
243         }
244
245         tb = g_hash_table_lookup(table, table_name);
246         if (tb == NULL) {
247                 media_svc_debug("lookup fail.. table name [%s] ", table_name);
248                 ret = MS_MEDIA_ERR_INTERNAL;
249                 goto ERROR;
250         }
251
252         for (iter = column_list[list]; iter; iter = g_slist_next(iter)) {
253                 col_ptr = iter->data;
254                 if (!col_ptr)
255                         continue;
256
257                 /*create table */
258                 if (col_ptr->option) {
259                         if (table_query->len != 0)
260                                 g_string_append_printf(table_query, ", %s %s %s", col_ptr->name, col_ptr->type, col_ptr->option);
261                         else
262                                 g_string_append_printf(table_query, "%s %s %s", col_ptr->name, col_ptr->type, col_ptr->option);
263                 } else {
264                         if (table_query->len != 0)
265                                 g_string_append_printf(table_query, ", %s %s", col_ptr->name, col_ptr->type);
266                         else
267                                 g_string_append_printf(table_query, "%s %s", col_ptr->name, col_ptr->type);
268                 }
269
270                 /*unique */
271                 if (col_ptr->is_unique) {
272                         if (unique_query->len != 0)
273                                 g_string_append_printf(unique_query, ", %s", col_ptr->name);
274                         else
275                                 g_string_append_printf(unique_query, "%s", col_ptr->name);
276                 }
277
278                 /*create index */
279                 if (col_ptr->index_name)
280                         g_string_append_printf(index_query, MEDIA_SVC_DB_QUERY_INDEX, col_ptr->index_name, table_name, col_ptr->name);
281
282                 /*create trigger */
283                 if (col_ptr->is_trigger) {
284                         if (STRING_VALID(tb->trigger_name)) {
285                                 if (strncmp(table_name, MEDIA_SVC_DB_TABLE_ALBUM, strlen(MEDIA_SVC_DB_TABLE_ALBUM)) == 0)
286                                         g_string_append_printf(trigger_query, MEDIA_SVC_DB_QUERY_TRIGGER_WITH_COUNT, tb->trigger_name, tb->event_table, tb->action_table, tb->event_table, col_ptr->name, col_ptr->name, col_ptr->name, col_ptr->name);
287                                 else
288                                         g_string_append_printf(trigger_query, MEDIA_SVC_DB_QUERY_TRIGGER, tb->trigger_name, tb->event_table, tb->action_table, col_ptr->name, col_ptr->name);
289                         } else {
290                                 media_svc_error("invalid trigger name");
291                         }
292                 }
293         }
294
295         /*send queries */
296         if (unique_query->len > 0)
297                 sql = sqlite3_mprintf(MEDIA_SVC_DB_QUERY_TABLE_WITH_UNIQUE, table_name, table_query->str, unique_query->str);
298         else
299                 sql = sqlite3_mprintf(MEDIA_SVC_DB_QUERY_TABLE, table_name, table_query->str);
300
301         ret = _media_svc_sql_query(sql, uid);
302         SQLITE3_SAFE_FREE(sql);
303         if (ret != MS_MEDIA_ERR_NONE)
304                 goto ERROR;
305
306         if (index_query->len > 0) {
307                 ret = _media_svc_sql_query(index_query->str, uid);
308                 if (ret != MS_MEDIA_ERR_NONE)
309                         goto ERROR;
310         }
311
312         if (trigger_query->len > 0) {
313                 ret = _media_svc_sql_query(trigger_query->str, uid);
314                 if (ret != MS_MEDIA_ERR_NONE)
315                         goto ERROR;
316         }
317
318         /*create view */
319         if (strncmp(table_name, MEDIA_SVC_DB_TABLE_PLAYLIST, strlen(MEDIA_SVC_DB_TABLE_PLAYLIST)) == 0)
320                 ret = __create_playlist_view(uid);
321         else if (strncmp(table_name, MEDIA_SVC_DB_TABLE_TAG, strlen(MEDIA_SVC_DB_TABLE_TAG)) == 0)
322                 ret = __create_tag_view(uid);
323
324 ERROR:
325         if (index_query)
326                 g_string_free(index_query, TRUE);
327         if (trigger_query)
328                 g_string_free(trigger_query, TRUE);
329         if (unique_query)
330                 g_string_free(unique_query, TRUE);
331         if (table_query)
332                 g_string_free(table_query, TRUE);
333
334         return ret;
335 }
336
337 /* NOTICE : This function will be used someday.. Do not remove.
338 static int __media_svc_upgrade_table_query(sqlite3 *db_handle, const char *table_name, media_svc_table_slist_e list, uid_t uid)
339 {
340         int ret = MS_MEDIA_ERR_NONE;
341         GSList *iter = NULL;
342         column_info_s *col_ptr = NULL;
343         char *sql = NULL;
344         char temp[1024] = {0, };
345         int cur_version = 0;
346         sqlite3_stmt *sql_stmt = NULL;
347
348         sql = sqlite3_mprintf("PRAGMA user_version");
349         ret = _media_svc_sql_prepare_to_step(db_handle, sql, &sql_stmt);
350
351         if (ret != MS_MEDIA_ERR_NONE) {
352                 media_svc_error("error when get user_version. err = [%d]", ret);
353                 return ret;
354         }
355         cur_version = sqlite3_column_int(sql_stmt, 0);
356         SQLITE3_FINALIZE(sql_stmt);
357
358         for (iter = column_list[list]; iter; iter = g_slist_next(iter)) {
359                 col_ptr = iter->data;
360
361                 if (!col_ptr)
362                         continue;
363
364                 if (col_ptr->version > cur_version) {
365                         // alter table
366                         memset(temp, 0, sizeof(temp));
367                         if (col_ptr->option)
368                                 snprintf(temp, sizeof(temp), "%s %s %s", col_ptr->name, col_ptr->type, col_ptr->option);
369                         else
370                                 snprintf(temp, sizeof(temp), "%s %s", col_ptr->name, col_ptr->type);
371                         sql = sqlite3_mprintf(MEDIA_SVC_DB_QUERY_ALTER_TABLE, table_name, temp);
372                         ret = _media_svc_sql_query(sql, uid);
373                         SQLITE3_SAFE_FREE(sql);
374                         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
375                         //create index
376                         if (col_ptr->index_name) {
377                                 sql = sqlite3_mprintf(MEDIA_SVC_DB_QUERY_INDEX, col_ptr->index_name, table_name, col_ptr->name);
378                                 ret = _media_svc_sql_query(sql, uid);
379                                 SQLITE3_SAFE_FREE(sql);
380                                 media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
381                         }
382                 }
383         }
384
385         return MS_MEDIA_ERR_NONE;
386 }
387 */
388 static void __media_svc_table_free(gpointer data)
389 {
390         table_info_s *tb = (table_info_s *) data;
391
392         SAFE_FREE(tb->trigger_name);
393         SAFE_FREE(tb->view_name);
394         SAFE_FREE(tb->event_table);
395         SAFE_FREE(tb->action_table);
396         SAFE_FREE(tb);
397 }
398
399 static void __media_svc_column_free(gpointer data)
400 {
401         column_info_s *col = (column_info_s *) data;
402
403         SAFE_FREE(col->name);
404         SAFE_FREE(col->type);
405         SAFE_FREE(col->option);
406         SAFE_FREE(col->index_name);
407         SAFE_FREE(col);
408 }
409
410 int _media_svc_init_table_query(const char *event_table_name)
411 {
412         int ret = MS_MEDIA_ERR_NONE;
413
414         /*variable initialize.. */
415         table = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, __media_svc_table_free);
416
417         /*table specification.. (table_name, index, unique set, trigger, view, trigger name, event table, action table, view name) */
418         ret = __media_svc_add_table_info(MEDIA_SVC_DB_TABLE_MEDIA, NULL, NULL, NULL, NULL);
419         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
420         ret = __media_svc_add_table_info(MEDIA_SVC_DB_TABLE_FOLDER, NULL, NULL, NULL, NULL);
421         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
422         ret = __media_svc_add_table_info(MEDIA_SVC_DB_TABLE_PLAYLIST_MAP, MEDIA_SVC_DB_TRIGGER_PLAYLIST_MAP, event_table_name, MEDIA_SVC_DB_TABLE_PLAYLIST_MAP, NULL);
423         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
424         ret = __media_svc_add_table_info(MEDIA_SVC_DB_TABLE_PLAYLIST, MEDIA_SVC_DB_TRIGGER_PLAYLIST_MAP1, MEDIA_SVC_DB_TABLE_PLAYLIST, MEDIA_SVC_DB_TABLE_PLAYLIST_MAP, MEDIA_SVC_DB_VIEW_PLAYLIST);
425         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
426         ret = __media_svc_add_table_info(MEDIA_SVC_DB_TABLE_ALBUM, MEDIA_SVC_DB_TRIGGER_ALBUM, event_table_name, MEDIA_SVC_DB_TABLE_ALBUM, NULL);
427         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
428         ret = __media_svc_add_table_info(MEDIA_SVC_DB_TABLE_TAG_MAP, MEDIA_SVC_DB_TRIGGER_TAG_MAP, event_table_name, MEDIA_SVC_DB_TABLE_TAG_MAP, NULL);
429         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
430         ret = __media_svc_add_table_info(MEDIA_SVC_DB_TABLE_TAG, MEDIA_SVC_DB_TRIGGER_TAG_MAP1, MEDIA_SVC_DB_TABLE_TAG, MEDIA_SVC_DB_TABLE_TAG_MAP, MEDIA_SVC_DB_VIEW_TAG);
431         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
432         ret = __media_svc_add_table_info(MEDIA_SVC_DB_TABLE_BOOKMARK, MEDIA_SVC_DB_TRIGGER_BOOKMARK, event_table_name, MEDIA_SVC_DB_TABLE_BOOKMARK, NULL);
433         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
434         ret = __media_svc_add_table_info(MEDIA_SVC_DB_TABLE_STORAGE, NULL, NULL, NULL, NULL);
435         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
436         ret = __media_svc_add_table_info(MEDIA_SVC_DB_TABLE_FACE_SCAN_LIST, MEDIA_SVC_DB_TRIGGER_FACE_SCAN_LIST, MEDIA_SVC_DB_TABLE_MEDIA, MEDIA_SVC_DB_TABLE_FACE_SCAN_LIST, NULL);
437         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
438         ret = __media_svc_add_table_info(MEDIA_SVC_DB_TABLE_FACE, MEDIA_SVC_DB_TRIGGER_FACE, MEDIA_SVC_DB_TABLE_FACE_SCAN_LIST, MEDIA_SVC_DB_TABLE_FACE, NULL);
439         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
440
441         /*insert column info.. */
442         /*media*/
443         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "media_id", MEDIA_SVC_DB_TYPE_TEXT, "PRIMARY KEY", USER_V2, NULL, false, false, true);
444         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
445         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "media_path", MEDIA_SVC_DB_TYPE_TEXT, "NOT NULL UNIQUE", USER_V2, NULL, false, false, true);
446         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
447         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "media_display_name", MEDIA_SVC_DB_TYPE_TEXT, "NOT NULL", USER_V2, NULL, false, false, true);
448         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
449         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "media_type", MEDIA_SVC_DB_TYPE_INT, NULL, USER_V2, NULL, false, false, true);
450         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
451         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "media_mime_type", MEDIA_SVC_DB_TYPE_TEXT, NULL, USER_V2, NULL, false, false, true);
452         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
453         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "media_size", MEDIA_SVC_DB_TYPE_INT, "DEFAULT 0", USER_V2, NULL, false, false, true);
454         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
455         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "media_added_time", MEDIA_SVC_DB_TYPE_INT, "DEFAULT 0", USER_V2, NULL, false, false, true);
456         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
457         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "media_modified_time", MEDIA_SVC_DB_TYPE_INT, "DEFAULT 0", USER_V2, NULL, false, false, true);
458         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
459         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "folder_id", MEDIA_SVC_DB_TYPE_TEXT, "NOT NULL", USER_V2, NULL, false, false, false);
460         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
461         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "media_thumbnail_path", MEDIA_SVC_DB_TYPE_TEXT, NULL, USER_V2, NULL, false, false, true);
462         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
463         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "media_title", MEDIA_SVC_DB_TYPE_TEXT, NULL, USER_V2, NULL, false, false, true);
464         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
465         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "album_id", MEDIA_SVC_DB_TYPE_INT, "DEFAULT 0", USER_V2, NULL, false, false, false);
466         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
467         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "media_album", MEDIA_SVC_DB_TYPE_TEXT, NULL, USER_V2, NULL, false, false, true);
468         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
469         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "media_artist", MEDIA_SVC_DB_TYPE_TEXT, NULL, USER_V2, NULL, false, false, true);
470         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
471         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "media_album_artist", MEDIA_SVC_DB_TYPE_TEXT, NULL, USER_V2, NULL, false, false, true);
472         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
473         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "media_genre", MEDIA_SVC_DB_TYPE_TEXT, NULL, USER_V2, NULL, false, false, true);
474         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
475         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "media_composer", MEDIA_SVC_DB_TYPE_TEXT, NULL, USER_V2, NULL, false, false, true);
476         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
477         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "media_year", MEDIA_SVC_DB_TYPE_TEXT, NULL, USER_V2, NULL, false, false, true);
478         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
479         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "media_recorded_date", MEDIA_SVC_DB_TYPE_TEXT, NULL, USER_V2, NULL, false, false, true);
480         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
481         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "media_copyright", MEDIA_SVC_DB_TYPE_TEXT, NULL, USER_V2, NULL, false, false, true);
482         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
483         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "media_track_num", MEDIA_SVC_DB_TYPE_TEXT, NULL, USER_V2, NULL, false, false, true);
484         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
485         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "media_description", MEDIA_SVC_DB_TYPE_TEXT, NULL, USER_V2, NULL, false, false, true);
486         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
487         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "media_bitrate", MEDIA_SVC_DB_TYPE_INT, "DEFAULT -1", USER_V2, NULL, false, false, true);
488         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
489         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "media_bitpersample", MEDIA_SVC_DB_TYPE_INT, "DEFAULT 0", USER_V3, NULL, false, false, true);
490         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
491         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "media_samplerate", MEDIA_SVC_DB_TYPE_INT, "DEFAULT -1", USER_V2, NULL, false, false, true);
492         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
493         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "media_channel", MEDIA_SVC_DB_TYPE_INT, "DEFAULT -1", USER_V2, NULL, false, false, true);
494         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
495         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "media_duration", MEDIA_SVC_DB_TYPE_INT, "DEFAULT -1", USER_V2, NULL, false, false, true);
496         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
497         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "media_longitude", MEDIA_SVC_DB_TYPE_DOUBLE, "DEFAULT 0", USER_V2, NULL, false, false, true);
498         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
499         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "media_latitude", MEDIA_SVC_DB_TYPE_DOUBLE, "DEFAULT 0", USER_V2, NULL, false, false, true);
500         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
501         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "media_altitude", MEDIA_SVC_DB_TYPE_DOUBLE, "DEFAULT 0", USER_V2, NULL, false, false, true);
502         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
503         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "exposure_time", MEDIA_SVC_DB_TYPE_TEXT, NULL, USER_V4, NULL, false, false, true);
504         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
505         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "fnumber", MEDIA_SVC_DB_TYPE_DOUBLE, "DEFAULT 0", USER_V4, NULL, false, false, true);
506         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
507         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "iso", MEDIA_SVC_DB_TYPE_INT, "DEFAULT -1", USER_V4, NULL, false, false, true);
508         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
509         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "model", MEDIA_SVC_DB_TYPE_TEXT, NULL, USER_V4, NULL, false, false, true);
510         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
511         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "media_width", MEDIA_SVC_DB_TYPE_INT, "DEFAULT -1", USER_V2, NULL, false, false, true);
512         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
513         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "media_height", MEDIA_SVC_DB_TYPE_INT, "DEFAULT -1", USER_V2, NULL, false, false, true);
514         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
515         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "media_datetaken", MEDIA_SVC_DB_TYPE_TEXT, NULL, USER_V2, NULL, false, false, true);
516         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
517         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "media_orientation", MEDIA_SVC_DB_TYPE_INT, "DEFAULT -1", USER_V2, NULL, false, false, true);
518         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
519         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "media_rating", MEDIA_SVC_DB_TYPE_INT, "DEFAULT 0", USER_V2, NULL, false, false, true);
520         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
521         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "media_favourite", MEDIA_SVC_DB_TYPE_INT, "DEFAULT 0", USER_V2, NULL, false, false, true);
522         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
523         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "media_is_drm", MEDIA_SVC_DB_TYPE_INT, "DEFAULT 0", USER_V2, NULL, false, false, true);
524         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
525         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "media_storage_type", MEDIA_SVC_DB_TYPE_INT, NULL, USER_V2, NULL, false, false, true);
526         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
527         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "media_timeline", MEDIA_SVC_DB_TYPE_INT, "DEFAULT 0", USER_V2, NULL, false, false, true);
528         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
529         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "media_file_name_pinyin", MEDIA_SVC_DB_TYPE_TEXT, NULL, USER_V2, NULL, false, false, false);
530         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
531         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "media_title_pinyin", MEDIA_SVC_DB_TYPE_TEXT, NULL, USER_V2, NULL, false, false, false);
532         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
533         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "media_album_pinyin", MEDIA_SVC_DB_TYPE_TEXT, NULL, USER_V2, NULL, false, false, false);
534         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
535         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "media_artist_pinyin", MEDIA_SVC_DB_TYPE_TEXT, NULL, USER_V2, NULL, false, false, false);
536         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
537         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "media_album_artist_pinyin", MEDIA_SVC_DB_TYPE_TEXT, NULL, USER_V2, NULL, false, false, false);
538         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
539         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "media_genre_pinyin", MEDIA_SVC_DB_TYPE_TEXT, NULL, USER_V2, NULL, false, false, false);
540         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
541         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "media_composer_pinyin", MEDIA_SVC_DB_TYPE_TEXT, NULL, USER_V2, NULL, false, false, false);
542         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
543         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "media_copyright_pinyin", MEDIA_SVC_DB_TYPE_TEXT, NULL, USER_V2, NULL, false, false, false);
544         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
545         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "media_description_pinyin", MEDIA_SVC_DB_TYPE_TEXT, NULL, USER_V2, NULL, false, false, false);
546         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
547         /* storage_uuid column is added in DB v4. When doing DB upgrade to v4, if storage_uuid is NOT NULL, alter table failed. */
548         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "storage_uuid", MEDIA_SVC_DB_TYPE_TEXT, NULL, USER_V4, NULL, false, false, true);
549         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
550         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "validity", MEDIA_SVC_DB_TYPE_INT, "DEFAULT 1", USER_V2, NULL, false, false, false);
551         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
552         /* color column is added with dcm. (DB v5) */
553         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "media_360", MEDIA_SVC_DB_TYPE_INT, "DEFAULT 0", USER_V5, NULL, false, false, true);
554         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
555
556         /*folder*/
557         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_FOLDER], "folder_id", MEDIA_SVC_DB_TYPE_TEXT, "PRIMARY KEY", USER_V2, NULL, false, false, false);
558         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
559         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_FOLDER], "folder_path", MEDIA_SVC_DB_TYPE_TEXT, "NOT NULL", USER_V2, NULL, true, false, false);
560         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
561         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_FOLDER], "folder_name", MEDIA_SVC_DB_TYPE_TEXT, "NOT NULL", USER_V2, NULL, false, false, false);
562         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
563         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_FOLDER], "folder_modified_time", MEDIA_SVC_DB_TYPE_INT, "DEFAULT 0", USER_V2, NULL, false, false, false);
564         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
565         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_FOLDER], "folder_name_pinyin", MEDIA_SVC_DB_TYPE_TEXT, NULL, USER_V2, NULL, false, false, false);
566         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
567         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_FOLDER], "folder_storage_type", MEDIA_SVC_DB_TYPE_INT, NULL, USER_V2, NULL, false, false, false);
568         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
569         /* storage_uuid column is added in DB v4. When doing DB upgrade to v4, if storage_uuid is NOT NULL, alter table failed. */
570         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_FOLDER], "storage_uuid", MEDIA_SVC_DB_TYPE_TEXT, NULL, USER_V4, NULL, true, false, false);
571         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
572         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_FOLDER], "validity", MEDIA_SVC_DB_TYPE_INT, "DEFAULT 1", USER_V4, NULL, false, false, false);
573         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
574
575         /*playlist_map*/
576         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_PLAYLIST_MAP], "_id", MEDIA_SVC_DB_TYPE_INT, "PRIMARY KEY AUTOINCREMENT", USER_V2, NULL, false, false, true);
577         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
578         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_PLAYLIST_MAP], "playlist_id", MEDIA_SVC_DB_TYPE_INT, "NOT NULL", USER_V2, NULL, false, false, false);
579         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
580         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_PLAYLIST_MAP], "media_id", MEDIA_SVC_DB_TYPE_TEXT, "NOT NULL", USER_V2, NULL, false, true, false);
581         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
582         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_PLAYLIST_MAP], "playlist_member_order", MEDIA_SVC_DB_TYPE_INT, "NOT NULL", USER_V2, NULL, false, false, true);
583         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
584
585         /*playlist*/
586         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_PLAYLIST], "playlist_id", MEDIA_SVC_DB_TYPE_INT, "PRIMARY KEY AUTOINCREMENT", USER_V2, NULL, false, true, true);
587         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
588         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_PLAYLIST], "playlist_name", MEDIA_SVC_DB_TYPE_TEXT, "NOT NULL UNIQUE", USER_V2, NULL, false, false, true);
589         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
590         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_PLAYLIST], "thumbnail_path", MEDIA_SVC_DB_TYPE_TEXT, NULL, USER_V2, NULL, false, false, true);
591         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
592
593         /*album*/
594         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_ALBUM], "album_id", MEDIA_SVC_DB_TYPE_INT, "PRIMARY KEY AUTOINCREMENT", USER_V2, NULL, false, true, false);
595         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
596         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_ALBUM], "name", MEDIA_SVC_DB_TYPE_TEXT, "NOT NULL", USER_V2, NULL, false, false, false);
597         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
598         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_ALBUM], "artist", MEDIA_SVC_DB_TYPE_TEXT, NULL, USER_V2, NULL, false, false, false);
599         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
600         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_ALBUM], "album_art", MEDIA_SVC_DB_TYPE_TEXT, NULL, USER_V2, NULL, false, false, false);
601         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
602
603         /*tag_map*/
604         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_TAG_MAP], "_id", MEDIA_SVC_DB_TYPE_INT, "PRIMARY KEY AUTOINCREMENT", USER_V2, NULL, false, false, true);
605         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
606         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_TAG_MAP], "tag_id", MEDIA_SVC_DB_TYPE_INT, "NOT NULL", USER_V2, NULL, true, false, false);
607         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
608         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_TAG_MAP], "media_id", MEDIA_SVC_DB_TYPE_TEXT, "NOT NULL", USER_V2, NULL, true, true, false);
609         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
610
611         /*tag*/
612         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_TAG], "tag_id ", MEDIA_SVC_DB_TYPE_INT, "PRIMARY KEY AUTOINCREMENT", USER_V2, NULL, false, true, true);
613         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
614         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_TAG], "tag_name", MEDIA_SVC_DB_TYPE_TEXT, "NOT NULL UNIQUE", USER_V2, NULL, false, false, true);
615         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
616
617         /*bookmark*/
618         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_BOOKMARK], "bookmark_id", MEDIA_SVC_DB_TYPE_INT, "PRIMARY KEY AUTOINCREMENT", USER_V2, NULL, false, false, false);
619         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
620         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_BOOKMARK], "media_id", MEDIA_SVC_DB_TYPE_TEXT, "NOT NULL", USER_V2, NULL, true, true, false);
621         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
622         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_BOOKMARK], "bookmark_marked_time", MEDIA_SVC_DB_TYPE_INT, "DEFAULT 0", USER_V2, NULL, true, false, false);
623         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
624         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_BOOKMARK], "bookmark_thumbnail_path", MEDIA_SVC_DB_TYPE_TEXT, NULL, USER_V2, NULL, false, false, false);
625         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
626         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_BOOKMARK], "bookmark_name", MEDIA_SVC_DB_TYPE_TEXT, NULL, USER_V6, NULL, false, false, false);
627         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
628
629         /*storage*/
630         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_STORAGE], "storage_id", MEDIA_SVC_DB_TYPE_TEXT, "PRIMARY KEY", USER_V3, NULL, false, false, false);
631         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
632         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_STORAGE], "storage_path", MEDIA_SVC_DB_TYPE_TEXT, "NOT NULL", USER_V3, NULL, false, false, false);
633         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
634         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_STORAGE], "storage_type", MEDIA_SVC_DB_TYPE_INT, "DEFAULT 0", USER_V3, NULL, false, false, false);
635         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
636         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_STORAGE], "validity", MEDIA_SVC_DB_TYPE_INT, "DEFAULT 1", USER_V3, NULL, false, false, false);
637         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
638
639         /*face scan list*/
640         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_FACE_SCAN_LIST], "media_id", MEDIA_SVC_DB_TYPE_TEXT, "NOT NULL UNIQUE", USER_V4, NULL, false, true, false);
641         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
642         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_FACE_SCAN_LIST], "modified_time", MEDIA_SVC_DB_TYPE_INT, "DEFAULT 0", USER_V6, NULL, false, false, false);
643         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
644
645         /*face*/
646         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_FACE], "media_face_id", MEDIA_SVC_DB_TYPE_INT, "PRIMARY KEY AUTOINCREMENT", USER_V4, NULL, false, false, false);
647         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
648         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_FACE], "media_id", MEDIA_SVC_DB_TYPE_TEXT, "NOT NULL", USER_V4, NULL, true, true, false);
649         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
650         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_FACE], "face_rect_x", MEDIA_SVC_DB_TYPE_INT, "DEFAULT 0", USER_V4, NULL, true, false, false);
651         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
652         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_FACE], "face_rect_y", MEDIA_SVC_DB_TYPE_INT, "DEFAULT 0", USER_V4, NULL, true, false, false);
653         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
654         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_FACE], "face_rect_w", MEDIA_SVC_DB_TYPE_INT, "DEFAULT 0", USER_V4, NULL, true, false, false);
655         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
656         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_FACE], "face_rect_h", MEDIA_SVC_DB_TYPE_INT, "DEFAULT 0", USER_V4, NULL, true, false, false);
657         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
658         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_FACE], "face_orientation", MEDIA_SVC_DB_TYPE_INT, "DEFAULT 0", USER_V4, NULL, false, false, false);
659         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
660         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_FACE], "media_face_tag", MEDIA_SVC_DB_TYPE_TEXT, NULL, USER_V4, NULL, false, false, false);
661         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
662
663         return ret;
664 }
665
666 void _media_svc_destroy_table_query()
667 {
668         int i = 0;
669
670         /* Table Free */
671         g_hash_table_destroy(table);
672
673         /* Column Free */
674         for (i = 0; i < MEDIA_SVC_DB_LIST_MAX; i++)
675                 g_slist_free_full(column_list[i], __media_svc_column_free);
676 }
677 /* NOTICE : This function will be used someday.. Do not remove.
678 static int __alter_table(sqlite3 *db_handle, uid_t uid)
679 {
680         int ret = MS_MEDIA_ERR_NONE;
681
682         ret = __media_svc_upgrade_table_query(db_handle, MEDIA_SVC_DB_TABLE_MEDIA, MEDIA_SVC_DB_LIST_MEDIA, uid);
683         media_svc_retvm_if(ret != MS_MEDIA_ERR_NONE, ret, "fail to __media_svc_upgrade_table_query [%d]", ret);
684
685         ret = __media_svc_upgrade_table_query(db_handle, MEDIA_SVC_DB_TABLE_PLAYLIST_MAP, MEDIA_SVC_DB_LIST_PLAYLIST_MAP, uid);
686         media_svc_retvm_if(ret != MS_MEDIA_ERR_NONE, ret, "fail to __media_svc_upgrade_table_query [%d]", ret);
687
688         ret = __media_svc_upgrade_table_query(db_handle, MEDIA_SVC_DB_TABLE_PLAYLIST, MEDIA_SVC_DB_LIST_PLAYLIST, uid);
689         media_svc_retvm_if(ret != MS_MEDIA_ERR_NONE, ret, "fail to __media_svc_upgrade_table_query [%d]", ret);
690
691         ret = __media_svc_upgrade_table_query(db_handle, MEDIA_SVC_DB_TABLE_ALBUM, MEDIA_SVC_DB_LIST_ALBUM, uid);
692         media_svc_retvm_if(ret != MS_MEDIA_ERR_NONE, ret, "fail to __media_svc_upgrade_table_query [%d]", ret);
693
694         ret = __media_svc_upgrade_table_query(db_handle, MEDIA_SVC_DB_TABLE_TAG_MAP, MEDIA_SVC_DB_LIST_TAG_MAP, uid);
695         media_svc_retvm_if(ret != MS_MEDIA_ERR_NONE, ret, "fail to __media_svc_upgrade_table_query [%d]", ret);
696
697         ret = __media_svc_upgrade_table_query(db_handle, MEDIA_SVC_DB_TABLE_TAG, MEDIA_SVC_DB_LIST_TAG, uid);
698         media_svc_retvm_if(ret != MS_MEDIA_ERR_NONE, ret, "fail to __media_svc_upgrade_table_query [%d]", ret);
699
700         ret = __media_svc_upgrade_table_query(db_handle, MEDIA_SVC_DB_TABLE_BOOKMARK, MEDIA_SVC_DB_LIST_BOOKMARK, uid);
701         media_svc_retvm_if(ret != MS_MEDIA_ERR_NONE, ret, "fail to __media_svc_upgrade_table_query [%d]", ret);
702
703         ret = __media_svc_upgrade_table_query(db_handle, MEDIA_SVC_DB_TABLE_STORAGE, MEDIA_SVC_DB_LIST_STORAGE, uid);
704         media_svc_retvm_if(ret != MS_MEDIA_ERR_NONE, ret, "fail to __media_svc_upgrade_table_query [%d]", ret);
705
706         return ret;
707 }
708 */
709 static void __media_svc_merge_table(gpointer data, gpointer user_data)
710 {
711         int ret = MS_MEDIA_ERR_NONE;
712         uid_t uid = GPOINTER_TO_INT(user_data);
713         char *storage_id = (char *)data;
714         char *sql = sqlite3_mprintf("INSERT INTO %q SELECT * FROM %Q;DROP TABLE %Q;", MEDIA_SVC_DB_TABLE_MEDIA, storage_id, storage_id);
715
716         ret = _media_svc_sql_query(sql, uid);
717         SQLITE3_SAFE_FREE(sql);
718         if (ret != MS_MEDIA_ERR_NONE)
719                 media_svc_error("Merge failed[%s]", storage_id);
720 }
721
722 static int __media_svc_db_upgrade(sqlite3 *db_handle, int cur_version, uid_t uid)
723 {
724         int ret = MS_MEDIA_ERR_NONE;
725         char *sql = NULL;
726         char *storage_id = NULL;
727         sqlite3_stmt *stmt = NULL;
728         GPtrArray *storage_list = NULL;
729
730         /* Basic upgrade routine
731                 1. Drop views (No need if media, playlist, playlist_map, tag, tag_map tables are not changed.)
732                 2. Alter table(add columns, remove columns, change naming, and etc.)
733                 3. Rebuild views (If views are dropped)
734         */
735         media_svc_debug_fenter();
736
737         /* drop view */
738         ret = __drop_views(uid);
739         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
740
741         /* Insert items in external tables into media table, and drop external tables (5.5 to 6.0)*/
742         sql = sqlite3_mprintf("SELECT storage_id FROM %q", MEDIA_SVC_DB_TABLE_STORAGE);
743
744         ret = media_db_get_result(db_handle, sql, &stmt);
745         media_svc_retvm_if(ret != MS_MEDIA_ERR_NONE, ret, "Query failed. err[%d]", ret);
746
747         while (sqlite3_step(stmt) == SQLITE_ROW) {
748                 if (!storage_list)
749                         storage_list = g_ptr_array_new_with_free_func(g_free);
750
751                 storage_id = g_strdup((const char *)sqlite3_column_text(stmt, 0));
752                 g_ptr_array_add(storage_list, storage_id);
753         }
754
755         SQLITE3_FINALIZE(stmt);
756
757         if (storage_list) {
758                 g_ptr_array_foreach(storage_list, __media_svc_merge_table, GINT_TO_POINTER(uid));
759                 g_ptr_array_free(storage_list, TRUE);
760         }
761
762         /* Rebuilding view */
763         ret = _media_svc_init_table_query(MEDIA_SVC_DB_TABLE_MEDIA);
764         media_svc_retvm_if(ret != MS_MEDIA_ERR_NONE, ret, "_media_svc_init_table_query failed");
765         ret = __media_svc_rebuild_view_query(db_handle, uid);
766         _media_svc_destroy_table_query();
767         media_svc_retvm_if(ret != MS_MEDIA_ERR_NONE, ret, "__media_svc_rebuild_view_query failed");
768
769         /* Update user version */
770         sql = sqlite3_mprintf("PRAGMA user_version=%d;", LATEST_DB_VERSION);
771         media_svc_retvm_if(ret != MS_MEDIA_ERR_NONE, ret, "Query failed. err[%d]", ret);
772         ret = _media_svc_sql_query(sql, uid);
773         SQLITE3_SAFE_FREE(sql);
774
775         media_svc_debug_fleave();
776
777         return ret;
778 }
779
780 int _media_svc_sql_query(const char *sql_str, uid_t uid)
781 {
782         return media_db_request_update_db(sql_str, uid);
783 }
784
785 #define MAX_RETRY 9
786 #define SLEEP_TIME 1000 * 1000
787 static int __media_svc_query_direct(sqlite3 *handle, const char *query, uid_t uid)
788 {
789         int ret = MS_MEDIA_ERR_NONE;
790         char *zErrMsg = NULL;
791         int retry_count = 0;
792
793 EXEC_RETRY:
794         ret = sqlite3_exec(handle, query, NULL, NULL, &zErrMsg);
795         if (SQLITE_OK != ret) {
796                 media_svc_sec_error("Error[%s],Query[%s]", zErrMsg, query);
797                 SQLITE3_SAFE_FREE(zErrMsg);
798                 if (ret == SQLITE_BUSY) {
799                         ret = MS_MEDIA_ERR_DB_BUSY_FAIL;
800                 } else if (ret == SQLITE_CONSTRAINT) {
801                         ret = MS_MEDIA_ERR_DB_CONSTRAINT_FAIL;
802                 } else if (ret == SQLITE_FULL) {
803                         ret = MS_MEDIA_ERR_DB_FULL_FAIL;
804                 } else if (ret == SQLITE_LOCKED) {
805                         if (retry_count < MAX_RETRY) {
806                                 media_svc_error("Locked retry[%d]", retry_count);
807                                 retry_count++;
808                                 usleep(SLEEP_TIME);
809                                 goto EXEC_RETRY;
810                         }
811                         ret = MS_MEDIA_ERR_DB_INTERNAL;
812                 } else {
813                         ret = MS_MEDIA_ERR_DB_INTERNAL;
814                 }
815         }
816
817         return ret;
818 }
819
820 int _media_svc_sql_query_direct(const char *sql_str, uid_t uid)
821 {
822         int ret = MS_MEDIA_ERR_NONE;
823         sqlite3 *handle = NULL;
824
825         ret = media_db_connect(&handle, uid, true);
826         media_svc_retvm_if(ret != MS_MEDIA_ERR_NONE, ret, "DB connection failed");
827         ret = __media_svc_query_direct(handle, sql_str, uid);
828         media_db_disconnect(handle);
829
830         return ret;
831 }
832
833 int _media_svc_get_user_version(sqlite3 *db_handle, int *user_version)
834 {
835         int ret = MS_MEDIA_ERR_NONE;
836         sqlite3_stmt *sql_stmt = NULL;
837         char *sql = sqlite3_mprintf("PRAGMA user_version;");
838
839         ret = _media_svc_sql_prepare_to_step(db_handle, sql, &sql_stmt);
840         if (ret != MS_MEDIA_ERR_NONE) {
841                 media_svc_error("error when get user_version.");
842                 return ret;
843         }
844
845         *user_version = sqlite3_column_int(sql_stmt, 0);
846         SQLITE3_FINALIZE(sql_stmt);
847
848         return MS_MEDIA_ERR_NONE;
849 }
850
851 int _media_svc_sql_prepare_to_step(sqlite3 *handle, const char *sql_str, sqlite3_stmt **stmt)
852 {
853         int err = -1;
854
855         media_svc_retvm_if(sql_str == NULL, MS_MEDIA_ERR_INVALID_PARAMETER, "invalid query");
856
857         if (handle == NULL) {
858                 media_svc_error("handle is NULL");
859                 sqlite3_free((char *)sql_str);
860                 return MS_MEDIA_ERR_INVALID_PARAMETER;
861         }
862
863         media_svc_sec_debug("Query[%s]", sql_str);
864
865         err = sqlite3_prepare_v2(handle, sql_str, -1, stmt, NULL);
866         sqlite3_free((char *)sql_str);
867
868         if (err != SQLITE_OK) {
869                 media_svc_error("prepare error %d[%s]", err, sqlite3_errmsg(handle));
870                 if (err == SQLITE_CORRUPT)
871                         return MS_MEDIA_ERR_DB_CORRUPT;
872
873                 return MS_MEDIA_ERR_DB_INTERNAL;
874         }
875
876         err = sqlite3_step(*stmt);
877         if (err != SQLITE_ROW) {
878                 media_svc_debug("No record");
879                 SQLITE3_FINALIZE(*stmt);
880                 return MS_MEDIA_ERR_DB_NO_RECORD;
881         }
882
883         return MS_MEDIA_ERR_NONE;
884 }
885
886 int _media_svc_sql_prepare_to_step_simple(sqlite3 *handle, const char *sql_str, sqlite3_stmt **stmt)
887 {
888         int err = -1;
889
890         media_svc_retvm_if(handle == NULL, MS_MEDIA_ERR_INVALID_PARAMETER, "handle is NULL");
891
892         media_svc_sec_debug("Query[%s]", sql_str);
893
894         if (!STRING_VALID(sql_str)) {
895                 media_svc_error("invalid query");
896                 return MS_MEDIA_ERR_INVALID_PARAMETER;
897         }
898
899         err = sqlite3_prepare_v2(handle, sql_str, -1, stmt, NULL);
900         sqlite3_free((char *)sql_str);
901
902         if (err != SQLITE_OK) {
903                 media_svc_error("prepare error %d[%s]", err, sqlite3_errmsg(handle));
904                 if (err == SQLITE_CORRUPT)
905                         return MS_MEDIA_ERR_DB_CORRUPT;
906
907                 return MS_MEDIA_ERR_DB_INTERNAL;
908         }
909
910         return MS_MEDIA_ERR_NONE;
911 }
912
913 int _media_svc_sql_query_list(GList **query_list, uid_t uid)
914 {
915         int ret = MS_MEDIA_ERR_NONE;
916         int idx = 0;
917         int length = g_list_length(*query_list);
918         char *sql = NULL;
919         char query_bundle[MEDIA_SVC_QUERY_LEN_MAX] = {0, };
920         int query_len = 0;
921         int total_len = 0;
922
923         media_svc_debug("query list length : [%d]", length);
924
925         memset(query_bundle, 0, sizeof(query_bundle));
926
927         for (idx = 0; idx < length; idx++) {
928                 sql = (char *)g_list_nth_data(*query_list, idx);
929                 if (STRING_VALID(sql)) {
930                         query_len = strlen(sql);
931
932                         if (query_len >= (sizeof(query_bundle) - 1)) {
933                                 media_svc_error("NEED TO CHECK FILE : A single query size exceeds 8k [%d]", query_len);
934                                 SQLITE3_SAFE_FREE(sql);
935                                 continue;
936                         }
937
938                         if ((total_len + query_len) >= (sizeof(query_bundle) - 1)) {
939                                 ret = media_db_request_update_db(query_bundle, uid);
940                                 if (ret != MS_MEDIA_ERR_NONE)
941                                         media_svc_error("media_db_request_update_db failed : %d", ret);
942
943                                 memset(query_bundle, 0, sizeof(query_bundle));
944                                 total_len = 0;
945                                 /* NEED TO CHECK : If a single query size is over 8K, drop it. */
946                                 /*                              Consider inserting the basic information without metadata */
947                                 /* Refer : SQLITE3 spec In Tizen 3.0 */
948                                 /* Single query limit size = 1 billion bytes(1GiB) */
949                                 /* DB limit size = 1 billion bytes(1GiB) */
950                                 /* column limit = 2000 */
951                         }
952
953                         SAFE_STRLCAT(query_bundle, sql, sizeof(query_bundle));
954                         total_len += query_len;
955
956                         SQLITE3_SAFE_FREE(sql);
957                 }
958         }
959
960         if (total_len > 0) {
961                 ret = media_db_request_update_db(query_bundle, uid);
962                 if (ret != MS_MEDIA_ERR_NONE)
963                         media_svc_error("media_db_request_update_db failed : %d", ret);
964
965                 memset(query_bundle, 0, sizeof(query_bundle));
966                 total_len = 0;
967         }
968
969         _media_svc_sql_query_release(query_list);
970
971         return MS_MEDIA_ERR_NONE;
972 }
973
974 int _media_svc_sql_query_list_direct(GList **query_list, uid_t uid)
975 {
976         int ret = MS_MEDIA_ERR_NONE;
977         int idx = 0;
978         int length = g_list_length(*query_list);
979         char *sql = NULL;
980         char *zErrMsg = NULL;
981         sqlite3 *handle = NULL;
982         bool with_transaction = true;
983
984         media_svc_debug("query list length[%d]", length);
985         if (length == 0)
986                 goto ZERO_LEN;
987
988         ret = media_db_connect(&handle, uid, true);
989         media_svc_retvm_if(ret != MS_MEDIA_ERR_NONE, ret, "DB connection failed");
990
991         ret = sqlite3_exec(handle, "BEGIN;", NULL, NULL, &zErrMsg);
992         if (SQLITE_OK != ret) {
993                 media_svc_sec_error("Transaction failed[%s]. Try an individual insert.", zErrMsg);
994                 SQLITE3_SAFE_FREE(zErrMsg);
995                 with_transaction = false;
996         }
997
998         for (idx = 0; idx < length; idx++) {
999                 sql = (char *)g_list_nth_data(*query_list, idx);
1000                 if (STRING_VALID(sql)) {
1001                         ret = __media_svc_query_direct(handle, sql, uid);
1002                         if (ret != MS_MEDIA_ERR_NONE)
1003                                 media_svc_debug("_media_svc_query_direct failed[%s]", sql);
1004
1005                         SQLITE3_SAFE_FREE(sql);
1006                 }
1007         }
1008
1009         if (with_transaction) {
1010                 ret = sqlite3_exec(handle, "COMMIT;", NULL, NULL, &zErrMsg);
1011                 if (SQLITE_OK != ret) {
1012                         media_svc_sec_error("Commit failed[%s]", zErrMsg);
1013                         SQLITE3_SAFE_FREE(zErrMsg);
1014                         media_db_disconnect(handle);
1015                         _media_svc_sql_query_release(query_list);
1016                         return MS_MEDIA_ERR_DB_INTERNAL;
1017                 }
1018         }
1019
1020         media_db_disconnect(handle);
1021
1022 ZERO_LEN:
1023         _media_svc_sql_query_release(query_list);
1024
1025         return MS_MEDIA_ERR_NONE;
1026 }
1027
1028 void _media_svc_sql_query_add(GList **query_list, char **query)
1029 {
1030         *query_list = g_list_append(*query_list, *query);
1031 }
1032
1033 void _media_svc_sql_query_release(GList **query_list)
1034 {
1035         if (*query_list) {
1036                 g_list_free(*query_list);
1037                 *query_list = NULL;
1038         }
1039 }
1040
1041 int _media_svc_check_db_upgrade(sqlite3 *db_handle, int user_version, uid_t uid)
1042 {
1043         if (user_version < LATEST_DB_VERSION) {
1044                 media_svc_error("Current DB is out of date(%d).. So start to upgrade DB(%d)", user_version, LATEST_DB_VERSION);
1045                 return __media_svc_db_upgrade(db_handle, user_version, uid);
1046         } else {
1047                 return MS_MEDIA_ERR_NONE;
1048         }
1049 }