Apply tizen coding rule
[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 <sys/stat.h>
24 #include <db-util.h>
25 #include <media-util.h>
26 #include <errno.h>
27 #include <grp.h>
28 #include <pwd.h>
29 #include "media-svc-env.h"
30 #include "media-svc-debug.h"
31 #include "media-svc-util.h"
32 #include "media-svc-db-utils.h"
33 #include "media-util-err.h"
34 #include "media-util-db.h"
35 #include "media-svc-media.h"
36
37 static int __media_svc_db_upgrade(sqlite3 *db_handle, int cur_version, uid_t uid);
38 static int __media_svc_rebuild_view_query(sqlite3 *db_handle, uid_t uid);
39
40
41 static GHashTable *table;
42 static GSList *column_list[MEDIA_SVC_DB_LIST_MAX];
43
44 char *_media_svc_get_path(uid_t uid)
45 {
46         char *result_passwd = NULL;
47         struct group *grpinfo = NULL;
48         if (uid == getuid()) {
49                 grpinfo = getgrnam("users");
50                 if (grpinfo == NULL) {
51                         media_svc_error("getgrnam(users) returns NULL !");
52                         return NULL;
53                 }
54                 result_passwd = g_strdup(MEDIA_ROOT_PATH_INTERNAL);
55         } else {
56                 char passwd_str[MEDIA_SVC_PATHNAME_SIZE] = {0, };
57                 struct passwd *userinfo = getpwuid(uid);
58                 if (userinfo == NULL) {
59                         media_svc_error("getpwuid(%d) returns NULL !", uid);
60                         return NULL;
61                 }
62                 grpinfo = getgrnam("users");
63                 if (grpinfo == NULL) {
64                         media_svc_error("getgrnam(users) returns NULL !");
65                         return NULL;
66                 }
67                 /* Compare git_t type and not group name */
68                 if (grpinfo->gr_gid != userinfo->pw_gid) {
69                         media_svc_error("UID [%d] does not belong to 'users' group!", uid);
70                         return NULL;
71                 }
72                 sprintf(passwd_str, "%s/%s", userinfo->pw_dir, MEDIA_CONTENT_PATH);
73                 result_passwd = g_strdup(passwd_str);
74         }
75
76         return result_passwd;
77 }
78
79 int __media_svc_add_table_info(const char *name, const char *triggerName, const char *eventTable, const char *actionTable, const char *viewName)
80 {
81         table_info *tbl = NULL;
82
83         media_svc_retvm_if(!STRING_VALID(name), MS_MEDIA_ERR_INVALID_PARAMETER, "name is NULL");
84
85         if (STRING_VALID(triggerName)) {
86                 media_svc_retvm_if(!STRING_VALID(eventTable), MS_MEDIA_ERR_INVALID_PARAMETER, "eventTable is NULL");
87                 media_svc_retvm_if(!STRING_VALID(actionTable), MS_MEDIA_ERR_INVALID_PARAMETER, "actionTable is NULL");
88         }
89
90         tbl = malloc(sizeof(table_info));
91         if (tbl == NULL) {
92                 media_svc_error("MS_MEDIA_ERR_OUT_OF_MEMORY");
93                 return MS_MEDIA_ERR_OUT_OF_MEMORY;
94         }
95
96         memset(tbl, 0x00, sizeof(table_info));
97
98         if (STRING_VALID(triggerName)) {
99                 tbl->triggerName = malloc(MEDIA_SVC_PATHNAME_SIZE);
100                 if (tbl->triggerName == NULL) {
101                         media_svc_error("MS_MEDIA_ERR_OUT_OF_MEMORY");
102                         SAFE_FREE(tbl);
103                         return MS_MEDIA_ERR_OUT_OF_MEMORY;
104                 }
105
106                 memset(tbl->triggerName, 0x00, MEDIA_SVC_PATHNAME_SIZE);
107                 snprintf(tbl->triggerName, MEDIA_SVC_PATHNAME_SIZE, "%s_%s", triggerName, eventTable);
108
109                 tbl->eventTable = strndup(eventTable, strlen(eventTable));
110                 tbl->actionTable = strndup(actionTable, strlen(actionTable));
111         }
112
113         if (STRING_VALID(viewName)) {
114                 tbl->viewName = strndup(viewName, strlen(viewName));
115         }
116
117         g_hash_table_insert(table, (gpointer)name, (gpointer)tbl);
118
119         return MS_MEDIA_ERR_NONE;
120 }
121
122 int __media_svc_add_column_info(GSList **slist, const char *name, const char *type, const char *option, int version, const char *indexName, bool isUnique, bool isTrigger, bool isView)
123 {
124         column_info *col = NULL;
125         col = malloc(sizeof(column_info));
126         if (col == NULL) {
127                 media_svc_error("MS_MEDIA_ERR_OUT_OF_MEMORY");
128                 return MS_MEDIA_ERR_OUT_OF_MEMORY;
129         }
130         memset(col, 0, sizeof(column_info));
131
132         col->name = strndup(name, strlen(name));
133         col->type = strndup(type, strlen(type));
134         if (option != NULL) {
135                 col->hasOption = true;
136                 col->option = strndup(option, strlen(option));
137         } else {
138                 col->hasOption = false;
139         }
140         col->version = version;
141         if (indexName != NULL) {
142                 col->isIndex = true;
143                 col->indexName = strndup(indexName, strlen(indexName));
144         } else {
145                 col->isIndex = false;
146         }
147         col->isUnique = isUnique;
148         col->isTrigger = isTrigger;
149         col->isView = isView;
150         *slist = g_slist_append(*slist, col);
151
152         return MS_MEDIA_ERR_NONE;
153 }
154
155 static int __media_svc_rebuild_view_query(sqlite3 *db_handle, uid_t uid)
156 {
157         int ret = MS_MEDIA_ERR_NONE;
158         column_info *col_ptr = NULL;
159         char *sql = NULL;
160         char table_query[4096] = {0, };
161         char temp[1024] = {0, };
162         bool sflag = false;
163         int i, len;
164         /*media */
165         _media_svc_update_media_view(db_handle, uid);
166
167         /*drop playlist_view, tag_view */
168         sql = sqlite3_mprintf(MEDIA_SVC_DB_QUERY_DROP_VIEW, MEDIA_SVC_DB_VIEW_PLAYLIST);
169         ret = _media_svc_sql_query(db_handle, sql, uid);
170         sqlite3_free(sql);
171         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
172
173         sql = sqlite3_mprintf(MEDIA_SVC_DB_QUERY_DROP_VIEW, MEDIA_SVC_DB_VIEW_TAG);
174         ret = _media_svc_sql_query(db_handle, sql, uid);
175         sqlite3_free(sql);
176         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
177
178         /*create playlist_view */
179         len = g_slist_length(column_list[MEDIA_SVC_DB_LIST_PLAYLIST]);
180         for (i = 1; i < len; i++) {
181                 col_ptr = g_slist_nth_data(column_list[MEDIA_SVC_DB_LIST_PLAYLIST], i);
182                 if (col_ptr->isView) {
183                         if (sflag == true) {
184                                 if (strncmp(col_ptr->name, MEDIA_SVC_DB_COLUMN_THUMBNAIL, strlen(MEDIA_SVC_DB_COLUMN_THUMBNAIL)) == 0)
185                                         snprintf(temp, sizeof(temp), ", playlist.%s AS p_thumbnail_path", col_ptr->name);
186                                 else
187                                         snprintf(temp, sizeof(temp), ", playlist.%s", col_ptr->name);
188                                 strncat(table_query, temp, strlen(temp));
189                         } else {
190                                 snprintf(temp, sizeof(temp), "playlist.%s", col_ptr->name);
191                                 strncpy(table_query, temp, strlen(temp));
192                                 sflag = true;
193                         }
194                 }
195                 memset(temp, 0, sizeof(temp));
196         }
197         len = g_slist_length(column_list[MEDIA_SVC_DB_LIST_PLAYLIST_MAP]);
198         for (i = 1; i < len; i++) {
199                 col_ptr = g_slist_nth_data(column_list[MEDIA_SVC_DB_LIST_PLAYLIST_MAP], i);
200                 if (col_ptr->isView) {
201                         if (strncmp(col_ptr->name, MEDIA_SVC_DB_COLUMN_MAP_ID, strlen(MEDIA_SVC_DB_COLUMN_MAP_ID)) == 0)
202                                 snprintf(temp, sizeof(temp), ", media_count IS NOT NULL AS media_count, playlist_map.%s AS pm_id", col_ptr->name);
203                         else
204                                 snprintf(temp, sizeof(temp), ", playlist_map.%s", col_ptr->name);
205                         strncat(table_query, temp, strlen(temp));
206                 }
207                 memset(temp, 0, sizeof(temp));
208         }
209
210         len = g_slist_length(column_list[MEDIA_SVC_DB_LIST_MEDIA]);
211         for (i = 1; i < len; i++) {
212                 col_ptr = g_slist_nth_data(column_list[MEDIA_SVC_DB_LIST_MEDIA], i);
213                 if (col_ptr->isView) {
214                         snprintf(temp, sizeof(temp), ", media.%s", col_ptr->name);
215                         strncat(table_query, temp, strlen(temp));
216                 }
217                 memset(temp, 0, sizeof(temp));
218         }
219         sql = sqlite3_mprintf(MEDIA_SVC_DB_QUERY_VIEW_PLAYLIST, MEDIA_SVC_DB_VIEW_PLAYLIST, table_query);
220         ret = _media_svc_sql_query(db_handle, sql, uid);
221         sqlite3_free(sql);
222         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
223
224         /*create tag_view */
225         sflag = false;
226         memset(table_query, 0, sizeof(table_query));
227
228         len = g_slist_length(column_list[MEDIA_SVC_DB_LIST_TAG]);
229         for (i = 1; i < len; i++) {
230                 col_ptr = g_slist_nth_data(column_list[MEDIA_SVC_DB_LIST_TAG], i);
231                 if (col_ptr->isView) {
232                         if (sflag == true) {
233                                 snprintf(temp, sizeof(temp), ", tag.%s", col_ptr->name);
234                                 strncat(table_query, temp, strlen(temp));
235                         } else {
236                                 snprintf(temp, sizeof(temp), "tag.%s", col_ptr->name);
237                                 strncpy(table_query, temp, strlen(temp));
238                                 sflag = true;
239                         }
240                 }
241                 memset(temp, 0, sizeof(temp));
242         }
243         len = g_slist_length(column_list[MEDIA_SVC_DB_LIST_TAG_MAP]);
244         for (i = 1; i < len; i++) {
245                 col_ptr = g_slist_nth_data(column_list[MEDIA_SVC_DB_LIST_TAG_MAP], i);
246                 if (col_ptr->isView) {
247                         if (strncmp(col_ptr->name, MEDIA_SVC_DB_COLUMN_MAP_ID, strlen(MEDIA_SVC_DB_COLUMN_MAP_ID)) == 0)
248                                 snprintf(temp, sizeof(temp), ", media_count IS NOT NULL AS media_count, tag_map.%s AS tm_id", col_ptr->name);
249                         else
250                                 snprintf(temp, sizeof(temp), ", tag_map.%s", col_ptr->name);
251                         strncat(table_query, temp, strlen(temp));
252                 }
253                 memset(temp, 0, sizeof(temp));
254         }
255
256         len = g_slist_length(column_list[MEDIA_SVC_DB_LIST_MEDIA]);
257         for (i = 1; i < len; i++) {
258                 col_ptr = g_slist_nth_data(column_list[MEDIA_SVC_DB_LIST_MEDIA], i);
259                 if (col_ptr->isView) {
260                         snprintf(temp, sizeof(temp), ", media.%s", col_ptr->name);
261                         strncat(table_query, temp, strlen(temp));
262                 }
263                 memset(temp, 0, sizeof(temp));
264         }
265         sql = sqlite3_mprintf(MEDIA_SVC_DB_QUERY_VIEW_TAG, MEDIA_SVC_DB_VIEW_TAG, table_query);
266         ret = _media_svc_sql_query(db_handle, sql, uid);
267         sqlite3_free(sql);
268         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
269
270         return MS_MEDIA_ERR_NONE;
271 }
272
273 int _media_svc_make_table_query(sqlite3 *db_handle, const char *table_name, media_svc_table_slist_e list, uid_t uid)
274 {
275         int ret = MS_MEDIA_ERR_NONE;
276         table_info *tb = NULL;
277         column_info *col_ptr = NULL;
278         char *sql = NULL;
279         char table_query[4096] = {0, };
280         char index_query[4096] = {0, };
281         char trigger_query[4096] = {0, };
282         char table_query_sub[1024] = {0, };
283         char temp[1024] = {0 ,};
284         int sflag = false;
285         int index_len = 0;
286         int trigger_len = 0;
287         int table_sub_len = 0;
288         int len = 0;
289         int i = 0;
290
291         tb = g_hash_table_lookup(table, table_name);
292         if (tb == NULL) {
293                 media_svc_debug("lookup fail.. table name [%s] ", table_name);
294                 tb = g_hash_table_lookup(table, MEDIA_SVC_DB_TABLE_MEDIA);
295         }
296
297         len = g_slist_length(column_list[list]);
298
299         if (len == 0) {
300                 media_svc_error("Invalid column");
301                 return MS_MEDIA_ERR_INTERNAL;
302         }
303
304         for (i = 1; i < len; i++) {
305                 col_ptr = g_slist_nth_data(column_list[list], i);
306                 /*create table */
307                 if (col_ptr->hasOption) {
308                         if (sflag == true) {
309                                 snprintf(temp, sizeof(temp), ", %s %s %s", col_ptr->name, col_ptr->type, col_ptr->option);
310                                 strncat(table_query, temp, strlen(temp));
311                         } else {
312                                 snprintf(temp, sizeof(temp), "%s %s %s", col_ptr->name, col_ptr->type, col_ptr->option);
313                                 strncpy(table_query, temp, strlen(temp));
314                                 sflag = true;
315                         }
316                 } else {
317                         if (sflag == true) {
318                                 snprintf(temp, sizeof(temp), ", %s %s", col_ptr->name, col_ptr->type);
319                                 strncat(table_query, temp, strlen(temp));
320                         } else {
321                                 snprintf(temp, sizeof(temp), "%s %s", col_ptr->name, col_ptr->type);
322                                 strncpy(table_query, temp, strlen(temp));
323                                 sflag = true;
324                         }
325                 }
326                 memset(temp, 0, sizeof(temp));
327
328                 /*unique */
329                 if (col_ptr->isUnique) {
330                         if (table_sub_len > 0) {
331                                 snprintf(temp, sizeof(temp), ", %s", col_ptr->name);
332                                 strncat(table_query_sub, temp, strlen(temp));
333                                 table_sub_len = strlen(table_query_sub);
334                         } else {
335                                 snprintf(temp, sizeof(temp), "%s", col_ptr->name);
336                                 strncpy(table_query_sub, temp, strlen(temp));
337                                 table_sub_len = strlen(table_query_sub);
338                         }
339                 }
340                 memset(temp, 0, sizeof(temp));
341
342                 /*create index */
343                 if (col_ptr->isIndex) {
344                         if (index_len > 0) {
345                                 snprintf(temp, sizeof(temp), MEDIA_SVC_DB_QUERY_INDEX, col_ptr->indexName, table_name, col_ptr->name);
346                                 strncat(index_query, temp, strlen(temp));
347                                 index_len = strlen(index_query);
348                         } else {
349                                 snprintf(temp, sizeof(temp), MEDIA_SVC_DB_QUERY_INDEX, col_ptr->indexName, table_name, col_ptr->name);
350                                 strncpy(index_query, temp, strlen(temp));
351                                 index_len = strlen(index_query);
352                         }
353                 }
354                 memset(temp, 0, sizeof(temp));
355
356                 /*create trigger */
357                 if (col_ptr->isTrigger) {
358                         if (STRING_VALID(tb->triggerName)) {
359                                 if (strncmp(table_name, MEDIA_SVC_DB_TABLE_ALBUM, strlen(MEDIA_SVC_DB_TABLE_ALBUM)) == 0) {
360                                         snprintf(temp, sizeof(temp), MEDIA_SVC_DB_QUERY_TRIGGER_WITH_COUNT, tb->triggerName, tb->eventTable, tb->actionTable, tb->eventTable, col_ptr->name, col_ptr->name, col_ptr->name, col_ptr->name);
361                                         strncpy(trigger_query, temp, strlen(temp));
362                                         trigger_len = strlen(trigger_query);
363                                 } else {
364                                         snprintf(temp, sizeof(temp), MEDIA_SVC_DB_QUERY_TRIGGER, tb->triggerName, tb->eventTable, tb->actionTable, col_ptr->name, col_ptr->name);
365                                         strncpy(trigger_query, temp, strlen(temp));
366                                         trigger_len = strlen(trigger_query);
367                                 }
368                         } else {
369                                 media_svc_error("invalid trigger name");
370                         }
371                 }
372                 memset(temp, 0, sizeof(temp));
373         }
374
375         /*send queries */
376         if (table_sub_len > 0) {
377                 sql = sqlite3_mprintf(MEDIA_SVC_DB_QUERY_TABLE_WITH_UNIQUE, table_name, table_query, table_query_sub);
378                 ret = _media_svc_sql_query(db_handle, sql, uid);
379                 sqlite3_free(sql);
380                 memset(table_query, 0, sizeof(table_query));
381                 memset(table_query_sub, 0, sizeof(table_query_sub));
382                 media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
383         } else {
384                 sql = sqlite3_mprintf(MEDIA_SVC_DB_QUERY_TABLE, table_name, table_query);
385                 ret = _media_svc_sql_query(db_handle, sql, uid);
386                 sqlite3_free(sql);
387                 memset(table_query, 0, sizeof(table_query));
388                 media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
389         }
390
391         if (index_len > 0) {
392                 ret = _media_svc_sql_query(db_handle, index_query, uid);
393                 memset(index_query, 0, sizeof(index_query));
394                 media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
395         }
396
397         if (trigger_len > 0) {
398                 ret = _media_svc_sql_query(db_handle, trigger_query, uid);
399                 memset(trigger_query, 0, sizeof(trigger_query));
400                 media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
401         }
402
403         /*create view */
404         sflag = false;
405         if (tb != NULL && tb->viewName != NULL) {
406                 if (strncmp(table_name, MEDIA_SVC_DB_TABLE_MEDIA, strlen(MEDIA_SVC_DB_TABLE_MEDIA)) == 0) {
407                         sql = sqlite3_mprintf(MEDIA_SVC_DB_QUERY_VIEW_MEDIA, tb->viewName, table_name);
408                         ret = _media_svc_sql_query(db_handle, sql, uid);
409                         sqlite3_free(sql);
410                         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
411
412                 } else if (strncmp(table_name, MEDIA_SVC_DB_TABLE_PLAYLIST, strlen(MEDIA_SVC_DB_TABLE_PLAYLIST)) == 0) {
413                         len = g_slist_length(column_list[MEDIA_SVC_DB_LIST_PLAYLIST]);
414                         for (i = 1; i < len; i++) {
415                                 col_ptr = g_slist_nth_data(column_list[MEDIA_SVC_DB_LIST_PLAYLIST], i);
416                                 if (col_ptr->isView) {
417                                         if (sflag == true) {
418                                                 if (strncmp(col_ptr->name, MEDIA_SVC_DB_COLUMN_THUMBNAIL, strlen(MEDIA_SVC_DB_COLUMN_THUMBNAIL)) == 0)
419                                                         snprintf(temp, sizeof(temp), ", playlist.%s AS p_thumbnail_path", col_ptr->name);
420                                                 else
421                                                         snprintf(temp, sizeof(temp), ", playlist.%s", col_ptr->name);
422                                                 strncat(table_query, temp, strlen(temp));
423                                         } else {
424                                                 snprintf(temp, sizeof(temp), "playlist.%s", col_ptr->name);
425                                                 strncpy(table_query, temp, strlen(temp));
426                                                 sflag = true;
427                                         }
428                                 }
429                                 memset(temp, 0, sizeof(temp));
430                         }
431                         len = g_slist_length(column_list[MEDIA_SVC_DB_LIST_PLAYLIST_MAP]);
432                         for (i = 1; i < len; i++) {
433                                 col_ptr = g_slist_nth_data(column_list[MEDIA_SVC_DB_LIST_PLAYLIST_MAP], i);
434                                 if (col_ptr->isView) {
435                                         if (strncmp(col_ptr->name, MEDIA_SVC_DB_COLUMN_MAP_ID, strlen(MEDIA_SVC_DB_COLUMN_MAP_ID)) == 0)
436                                                 snprintf(temp, sizeof(temp), ", media_count IS NOT NULL AS media_count, playlist_map.%s AS pm_id", col_ptr->name);
437                                         else
438                                                 snprintf(temp, sizeof(temp), ", playlist_map.%s", col_ptr->name);
439                                         strncat(table_query, temp, strlen(temp));
440                                 }
441                                 memset(temp, 0, sizeof(temp));
442                         }
443
444                         len = g_slist_length(column_list[MEDIA_SVC_DB_LIST_MEDIA]);
445                         for (i = 1; i < len; i++) {
446                                 col_ptr = g_slist_nth_data(column_list[MEDIA_SVC_DB_LIST_MEDIA], i);
447                                 if (col_ptr->isView) {
448                                         snprintf(temp, sizeof(temp), ", media.%s", col_ptr->name);
449                                         strncat(table_query, temp, strlen(temp));
450                                 }
451                                 memset(temp, 0, sizeof(temp));
452                         }
453                         sql = sqlite3_mprintf(MEDIA_SVC_DB_QUERY_VIEW_PLAYLIST, tb->viewName, table_query);
454                         ret = _media_svc_sql_query(db_handle, sql, uid);
455                         sqlite3_free(sql);
456                         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
457
458                 } else {
459                         len = g_slist_length(column_list[MEDIA_SVC_DB_LIST_TAG]);
460                         for (i = 1; i < len; i++) {
461                                 col_ptr = g_slist_nth_data(column_list[MEDIA_SVC_DB_LIST_TAG], i);
462                                 if (col_ptr->isView) {
463                                         if (sflag == true) {
464                                                 snprintf(temp, sizeof(temp), ", tag.%s", col_ptr->name);
465                                                 strncat(table_query, temp, strlen(temp));
466                                         } else {
467                                                 snprintf(temp, sizeof(temp), "tag.%s", col_ptr->name);
468                                                 strncpy(table_query, temp, strlen(temp));
469                                                 sflag = true;
470                                         }
471                                 }
472                                 memset(temp, 0, sizeof(temp));
473                         }
474                         len = g_slist_length(column_list[MEDIA_SVC_DB_LIST_TAG_MAP]);
475                         for (i = 1; i < len; i++) {
476                                 col_ptr = g_slist_nth_data(column_list[MEDIA_SVC_DB_LIST_TAG_MAP], i);
477                                 if (col_ptr->isView) {
478                                         if (strncmp(col_ptr->name, MEDIA_SVC_DB_COLUMN_MAP_ID, strlen(MEDIA_SVC_DB_COLUMN_MAP_ID)) == 0)
479                                                 snprintf(temp, sizeof(temp), ", media_count IS NOT NULL AS media_count, tag_map.%s AS tm_id", col_ptr->name);
480                                         else
481                                                 snprintf(temp, sizeof(temp), ", tag_map.%s", col_ptr->name);
482                                         strncat(table_query, temp, strlen(temp));
483                                 }
484                                 memset(temp, 0, sizeof(temp));
485                         }
486
487                         len = g_slist_length(column_list[MEDIA_SVC_DB_LIST_MEDIA]);
488                         for (i = 1; i < len; i++) {
489                                 col_ptr = g_slist_nth_data(column_list[MEDIA_SVC_DB_LIST_MEDIA], i);
490                                 if (col_ptr->isView) {
491                                         snprintf(temp, sizeof(temp), ", media.%s", col_ptr->name);
492                                         strncat(table_query, temp, strlen(temp));
493                                 }
494                                 memset(temp, 0, sizeof(temp));
495                         }
496                         sql = sqlite3_mprintf(MEDIA_SVC_DB_QUERY_VIEW_TAG, tb->viewName, table_query);
497                         ret = _media_svc_sql_query(db_handle, sql, uid);
498                         sqlite3_free(sql);
499                         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
500
501                 }
502         }
503
504         return MS_MEDIA_ERR_NONE;
505 }
506
507 int _media_svc_upgrade_table_query(sqlite3 *db_handle, const char *table_name, media_svc_table_slist_e list, uid_t uid)
508 {
509         int ret = MS_MEDIA_ERR_NONE;
510         column_info *col_ptr = NULL;
511         char *sql = NULL;
512         char temp[1024] = {0, };
513         int len, i;
514         int cur_version = 0;
515         sqlite3_stmt *sql_stmt = NULL;
516
517         len = g_slist_length(column_list[list]);
518
519         sql = sqlite3_mprintf("PRAGMA user_version");
520         ret = _media_svc_sql_prepare_to_step(db_handle, sql, &sql_stmt);
521
522         if (ret != MS_MEDIA_ERR_NONE) {
523                 media_svc_error("error when get user_version. err = [%d]", ret);
524                 return ret;
525         }
526         cur_version = sqlite3_column_int(sql_stmt, 0);
527         SQLITE3_FINALIZE(sql_stmt);
528
529         len = g_slist_length(column_list[list]);
530         for (i = 1; i < len; i++) {
531                 col_ptr = g_slist_nth_data(column_list[list], i);
532                 if (col_ptr->version > cur_version) {
533                         /*alter table */
534                         if (col_ptr->hasOption)
535                                 snprintf(temp, sizeof(temp), "%s %s %s", col_ptr->name, col_ptr->type, col_ptr->option);
536                         else
537                                 snprintf(temp, sizeof(temp), "%s %s", col_ptr->name, col_ptr->type);
538                         sql = sqlite3_mprintf(MEDIA_SVC_DB_QUERY_ALTER_TABLE, table_name, temp);
539                         ret = _media_svc_sql_query(db_handle, sql, uid);
540                         sqlite3_free(sql);
541                         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
542                         /*create index */
543                         if (col_ptr->isIndex) {
544                                 memset(temp, 0, sizeof(temp));
545                                 snprintf(temp, sizeof(temp), MEDIA_SVC_DB_QUERY_INDEX, col_ptr->indexName, table_name, col_ptr->name);
546                                 ret = _media_svc_sql_query(db_handle, temp, uid);
547                                 media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
548                         }
549                 }
550                 memset(temp, 0, sizeof(temp));
551         }
552
553         return MS_MEDIA_ERR_NONE;
554 }
555
556 int _media_svc_init_table_query(const char *event_table_name)
557 {
558         int ret = MS_MEDIA_ERR_NONE;
559         int i = 0;
560
561         /*variable initialize.. */
562         table = g_hash_table_new(g_str_hash, g_str_equal);
563         for (i = 0; i < MEDIA_SVC_DB_LIST_MAX; i++) {
564                 column_list[i] = g_slist_alloc();
565         }
566
567         /*table specification.. (table_name, index, unique set, trigger, view, trigger name, event table, action table, view name) */
568         ret = __media_svc_add_table_info(MEDIA_SVC_DB_TABLE_MEDIA, NULL, NULL, NULL, MEDIA_SVC_DB_VIEW_MEDIA);
569         ret = __media_svc_add_table_info(MEDIA_SVC_DB_TABLE_FOLDER, MEDIA_SVC_DB_TRIGGER_FOLDER, event_table_name, MEDIA_SVC_DB_TABLE_FOLDER, NULL);
570         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);
571         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);
572         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);
573         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);
574         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);
575         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);
576         ret = __media_svc_add_table_info(MEDIA_SVC_DB_TABLE_STORAGE, NULL, NULL, NULL, NULL);
577         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);
578         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);
579         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
580
581         /*insert column info.. */
582         /*media*/
583         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "media_uuid", MEDIA_SVC_DB_TYPE_TEXT, "PRIMARY KEY", USER_V2, NULL, false, false, true);
584         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "path", MEDIA_SVC_DB_TYPE_TEXT, "NOT NULL UNIQUE", USER_V2, NULL, true, false, true);
585         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "file_name", MEDIA_SVC_DB_TYPE_TEXT, "NOT NULL", USER_V2, "media_file_name_idx", true, false, true);
586         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);
587         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "mime_type", MEDIA_SVC_DB_TYPE_TEXT, NULL, USER_V2, NULL, false, false, true);
588         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "size", MEDIA_SVC_DB_TYPE_INT, "DEFAULT 0", USER_V2, NULL, false, false, true);
589         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "added_time", MEDIA_SVC_DB_TYPE_INT, "DEFAULT 0", USER_V2, NULL, false, false, true);
590         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "modified_time", MEDIA_SVC_DB_TYPE_INT, "DEFAULT 0", USER_V2, "media_modified_time_idx", false, false, true);
591         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "folder_uuid", MEDIA_SVC_DB_TYPE_TEXT, "NOT NULL", USER_V2, "folder_uuid_idx", false, false, false);
592         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "thumbnail_path", MEDIA_SVC_DB_TYPE_TEXT, NULL, USER_V2, NULL, false, false, true);
593         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "title", MEDIA_SVC_DB_TYPE_TEXT, NULL, USER_V2, "media_title_idx", false, false, true);
594         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);
595         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "album", MEDIA_SVC_DB_TYPE_TEXT, NULL, USER_V2, "media_album_idx", false, false, true);
596         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "artist", MEDIA_SVC_DB_TYPE_TEXT, NULL, USER_V2, "media_artist_idx", false, false, true);
597         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "album_artist", MEDIA_SVC_DB_TYPE_TEXT, NULL, USER_V2, NULL, false, false, true);
598         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "genre", MEDIA_SVC_DB_TYPE_TEXT, NULL, USER_V2, "media_genre_idx", false, false, true);
599         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "composer", MEDIA_SVC_DB_TYPE_TEXT, NULL, USER_V2, "media_composer_idx", false, false, true);
600         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "year", MEDIA_SVC_DB_TYPE_TEXT, NULL, USER_V2, NULL, false, false, true);
601         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "recorded_date", MEDIA_SVC_DB_TYPE_TEXT, NULL, USER_V2, NULL, false, false, true);
602         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "copyright", MEDIA_SVC_DB_TYPE_TEXT, NULL, USER_V2, NULL, false, false, true);
603         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "track_num", MEDIA_SVC_DB_TYPE_TEXT, NULL, USER_V2, NULL, false, false, true);
604         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "description", MEDIA_SVC_DB_TYPE_TEXT, NULL, USER_V2, NULL, false, false, true);
605         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "bitrate", MEDIA_SVC_DB_TYPE_INT, "DEFAULT -1", USER_V2, NULL, false, false, true);
606         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "bitpersample", MEDIA_SVC_DB_TYPE_INT, "DEFAULT 0", USER_V3, NULL, false, false, true);
607         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "samplerate", MEDIA_SVC_DB_TYPE_INT, "DEFAULT -1", USER_V2, NULL, false, false, true);
608         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "channel", MEDIA_SVC_DB_TYPE_INT, "DEFAULT -1", USER_V2, NULL, false, false, true);
609         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "duration", MEDIA_SVC_DB_TYPE_INT, "DEFAULT -1", USER_V2, NULL, false, false, true);
610         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "longitude", MEDIA_SVC_DB_TYPE_DOUBLE, "DEFAULT 0", USER_V2, NULL, false, false, true);
611         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "latitude", MEDIA_SVC_DB_TYPE_DOUBLE, "DEFAULT 0", USER_V2, NULL, false, false, true);
612         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "altitude", MEDIA_SVC_DB_TYPE_DOUBLE, "DEFAULT 0", USER_V2, NULL, false, false, true);
613         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);
614         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);
615         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);
616         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);
617         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "width", MEDIA_SVC_DB_TYPE_INT, "DEFAULT -1", USER_V2, NULL, false, false, true);
618         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "height", MEDIA_SVC_DB_TYPE_INT, "DEFAULT -1", USER_V2, NULL, false, false, true);
619         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "datetaken", MEDIA_SVC_DB_TYPE_TEXT, NULL, USER_V2, NULL, false, false, true);
620         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "orientation", MEDIA_SVC_DB_TYPE_INT, "DEFAULT -1", USER_V2, NULL, false, false, true);
621         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "burst_id", MEDIA_SVC_DB_TYPE_TEXT, NULL, USER_V2, NULL, false, false, true);
622         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "played_count", MEDIA_SVC_DB_TYPE_INT, "DEFAULT 0", USER_V2, NULL, false, false, true);
623         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "last_played_time", MEDIA_SVC_DB_TYPE_INT, "DEFAULT 0", USER_V2, NULL, false, false, true);
624         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "last_played_position", MEDIA_SVC_DB_TYPE_INT, "DEFAULT 0", USER_V2, NULL, false, false, true);
625         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "rating", MEDIA_SVC_DB_TYPE_INT, "DEFAULT 0", USER_V2, NULL, false, false, true);
626         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "favourite", MEDIA_SVC_DB_TYPE_INT, "DEFAULT 0", USER_V2, NULL, false, false, true);
627         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "author", MEDIA_SVC_DB_TYPE_TEXT, NULL, USER_V2, "media_author_idx", false, false, true);
628         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "provider", MEDIA_SVC_DB_TYPE_TEXT, NULL, USER_V2, "media_provider_idx", false, false, true);
629         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "content_name", MEDIA_SVC_DB_TYPE_TEXT, NULL, USER_V2, "media_content_name_idx", false, false, true);
630         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "category", MEDIA_SVC_DB_TYPE_TEXT, NULL, USER_V2, "media_category_idx", false, false, true);
631         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "location_tag", MEDIA_SVC_DB_TYPE_TEXT, NULL, USER_V2, "media_location_tag_idx", false, false, true);
632         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "age_rating", MEDIA_SVC_DB_TYPE_TEXT, NULL, USER_V2, NULL, false, false, true);
633         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "keyword", MEDIA_SVC_DB_TYPE_TEXT, NULL, USER_V2, NULL, false, false, true);
634         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "is_drm", MEDIA_SVC_DB_TYPE_INT, "DEFAULT 0", USER_V2, NULL, false, false, true);
635         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "storage_type", MEDIA_SVC_DB_TYPE_INT, NULL, USER_V2, NULL, false, false, true);
636         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "timeline", MEDIA_SVC_DB_TYPE_INT, "DEFAULT 0", USER_V2, "media_timeline_idx", false, false, true);
637         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "weather", MEDIA_SVC_DB_TYPE_TEXT, NULL, USER_V2, NULL, false, false, true);
638         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "sync_status", MEDIA_SVC_DB_TYPE_INT, "DEFAULT 0", USER_V2, NULL, false, false, true);
639         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "file_name_pinyin", MEDIA_SVC_DB_TYPE_TEXT, NULL, USER_V2, NULL, false, false, false);
640         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "title_pinyin", MEDIA_SVC_DB_TYPE_TEXT, NULL, USER_V2, NULL, false, false, false);
641         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "album_pinyin", MEDIA_SVC_DB_TYPE_TEXT, NULL, USER_V2, NULL, false, false, false);
642         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "artist_pinyin", MEDIA_SVC_DB_TYPE_TEXT, NULL, USER_V2, NULL, false, false, false);
643         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "album_artist_pinyin", MEDIA_SVC_DB_TYPE_TEXT, NULL, USER_V2, NULL, false, false, false);
644         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "genre_pinyin", MEDIA_SVC_DB_TYPE_TEXT, NULL, USER_V2, NULL, false, false, false);
645         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "composer_pinyin", MEDIA_SVC_DB_TYPE_TEXT, NULL, USER_V2, NULL, false, false, false);
646         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "copyright_pinyin", MEDIA_SVC_DB_TYPE_TEXT, NULL, USER_V2, NULL, false, false, false);
647         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "description_pinyin", MEDIA_SVC_DB_TYPE_TEXT, NULL, USER_V2, NULL, false, false, false);
648         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "author_pinyin", MEDIA_SVC_DB_TYPE_TEXT, NULL, USER_V2, NULL, false, false, false);
649         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "provider_pinyin", MEDIA_SVC_DB_TYPE_TEXT, NULL, USER_V2, NULL, false, false, false);
650         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "content_name_pinyin", MEDIA_SVC_DB_TYPE_TEXT, NULL, USER_V2, NULL, false, false, false);
651         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "category_pinyin", MEDIA_SVC_DB_TYPE_TEXT, NULL, USER_V2, NULL, false, false, false);
652         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "location_tag_pinyin", MEDIA_SVC_DB_TYPE_TEXT, NULL, USER_V2, NULL, false, false, false);
653         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "age_rating_pinyin", MEDIA_SVC_DB_TYPE_TEXT, NULL, USER_V2, NULL, false, false, false);
654         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "keyword_pinyin", MEDIA_SVC_DB_TYPE_TEXT, NULL, USER_V2, NULL, false, false, false);
655         /* storage_uuid column is added in DB v4. When doing DB upgrade to v4, if storage_uuid is NOT NULL, alter table failed. */
656         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);
657         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);
658         /* color column is added with dcm. */
659         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "color_r", MEDIA_SVC_DB_TYPE_INT, NULL, 0, NULL, false, false, false);
660         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "color_g", MEDIA_SVC_DB_TYPE_INT, NULL, 0, NULL, false, false, false);
661         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_MEDIA], "color_b", MEDIA_SVC_DB_TYPE_INT, NULL, 0, NULL, false, false, false);
662         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
663
664         /*folder*/
665         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_FOLDER], "folder_uuid", MEDIA_SVC_DB_TYPE_TEXT, "PRIMARY KEY", USER_V2, NULL, false, false, false);
666         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_FOLDER], "path", MEDIA_SVC_DB_TYPE_TEXT, "NOT NULL", USER_V2, NULL, true, false, false);
667         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_FOLDER], "name", MEDIA_SVC_DB_TYPE_TEXT, "NOT NULL", USER_V2, NULL, true, false, false);
668         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_FOLDER], "modified_time", MEDIA_SVC_DB_TYPE_INT, "DEFAULT 0", USER_V2, NULL, false, false, false);
669         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_FOLDER], "name_pinyin", MEDIA_SVC_DB_TYPE_TEXT, NULL, USER_V2, NULL, false, false, false);
670         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_FOLDER], "storage_type", MEDIA_SVC_DB_TYPE_INT, NULL, USER_V2, NULL, false, false, false);
671         /* storage_uuid column is added in DB v4. When doing DB upgrade to v4, if storage_uuid is NOT NULL, alter table failed. */
672         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);
673         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_FOLDER], "folder_order", MEDIA_SVC_DB_TYPE_INT, "DEFAULT 0", USER_V4, NULL, false, false, false);
674         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_FOLDER], "parent_folder_uuid", MEDIA_SVC_DB_TYPE_TEXT, NULL, USER_V4, NULL, false, false, false);
675         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);
676         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
677
678         /*playlist_map*/
679         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);
680         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);
681         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_PLAYLIST_MAP], "media_uuid", MEDIA_SVC_DB_TYPE_TEXT, "NOT NULL", USER_V2, NULL, false, true, false);
682         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_PLAYLIST_MAP], "play_order", MEDIA_SVC_DB_TYPE_INT, "NOT NULL", USER_V2, NULL, false, false, true);
683         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
684
685         /*playlist*/
686         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);
687         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_PLAYLIST], "name", MEDIA_SVC_DB_TYPE_TEXT, "NOT NULL UNIQUE", USER_V2, NULL, false, false, true);
688         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_PLAYLIST], "name_pinyin", MEDIA_SVC_DB_TYPE_TEXT, NULL, USER_V2, NULL, false, false, false);
689         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);
690         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
691
692         /*album*/
693         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);
694         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);
695         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);
696         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);
697         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
698
699         /*tag_map*/
700         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);
701         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);
702         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_TAG_MAP], "media_uuid", MEDIA_SVC_DB_TYPE_TEXT, "NOT NULL", USER_V2, NULL, true, true, false);
703         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
704
705         /*tag*/
706         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);
707         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_TAG], "name", MEDIA_SVC_DB_TYPE_TEXT, "NOT NULL UNIQUE", USER_V2, NULL, false, false, true);
708         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_TAG], "name_pinyin", MEDIA_SVC_DB_TYPE_TEXT, NULL, USER_V2, NULL, false, false, false);
709         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
710
711         /*bookmark*/
712         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);
713         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_BOOKMARK], "media_uuid", MEDIA_SVC_DB_TYPE_TEXT, "NOT NULL", USER_V2, NULL, true, true, false);
714         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_BOOKMARK], "marked_time", MEDIA_SVC_DB_TYPE_INT, "DEFAULT 0", USER_V2, NULL, true, false, false);
715         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_BOOKMARK], "thumbnail_path", MEDIA_SVC_DB_TYPE_TEXT, NULL, USER_V2, NULL, false, false, false);
716         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
717
718         /*storage*/
719         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_STORAGE], "storage_uuid", MEDIA_SVC_DB_TYPE_TEXT, "NOT NULL", USER_V3, NULL, true, false, false);
720         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_STORAGE], "storage_name", MEDIA_SVC_DB_TYPE_TEXT, NULL, USER_V3, NULL, true, false, false);
721         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);
722         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_STORAGE], "storage_account", MEDIA_SVC_DB_TYPE_TEXT, NULL, USER_V3, NULL, false, false, false);
723         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);
724         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_STORAGE], "scan_status", MEDIA_SVC_DB_TYPE_INT, "DEFAULT 0", USER_V3, NULL, false, false, false);
725         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);
726         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
727
728         /*face scan list*/
729         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_FACE_SCAN_LIST], "media_uuid", MEDIA_SVC_DB_TYPE_TEXT, "NOT NULL", 0, NULL, true, true, false);
730         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_FACE_SCAN_LIST], "storage_uuid", MEDIA_SVC_DB_TYPE_TEXT, "NOT NULL", 0, NULL, false, false, false);
731         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
732
733         /*face*/
734         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_FACE], "face_uuid", MEDIA_SVC_DB_TYPE_TEXT, "PRIMARY KEY", 0, NULL, true, false, false);
735         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_FACE], "media_uuid", MEDIA_SVC_DB_TYPE_TEXT, "NOT NULL", 0, NULL, false, true, false);
736         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_FACE], "face_rect_x", MEDIA_SVC_DB_TYPE_INT, "DEFAULT 0", 0, NULL, false, false, false);
737         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_FACE], "face_rect_y", MEDIA_SVC_DB_TYPE_INT, "DEFAULT 0", 0, NULL, false, false, false);
738         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_FACE], "face_rect_w", MEDIA_SVC_DB_TYPE_INT, "DEFAULT 0", 0, NULL, false, false, false);
739         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_FACE], "face_rect_h", MEDIA_SVC_DB_TYPE_INT, "DEFAULT 0", 0, NULL, false, false, false);
740         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_FACE], "orientation", MEDIA_SVC_DB_TYPE_INT, "DEFAULT 0", 0, NULL, false, false, false);
741         ret = __media_svc_add_column_info(&column_list[MEDIA_SVC_DB_LIST_FACE], "face_tag", MEDIA_SVC_DB_TYPE_TEXT, NULL, 0, NULL, false, false, false);
742         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
743
744         return ret;
745 }
746 void __media_svc_table_free(table_info *tb) {
747         SAFE_FREE(tb->triggerName);
748         SAFE_FREE(tb->viewName);
749         SAFE_FREE(tb->eventTable);
750         SAFE_FREE(tb->actionTable);
751         SAFE_FREE(tb);
752 }
753
754 void __media_svc_column_free(column_info *col) {
755         SAFE_FREE(col->name);
756         SAFE_FREE(col->type);
757         SAFE_FREE(col->option);
758         SAFE_FREE(col->indexName);
759         SAFE_FREE(col);
760 }
761
762 void _media_svc_destroy_table_query()
763 {
764         int i = 0;
765         table_info *tb = NULL;
766         column_info *col_ptr = NULL;
767         int len = 0;
768
769         /* Table Free */
770         tb = g_hash_table_lookup(table, MEDIA_SVC_DB_TABLE_MEDIA);
771         __media_svc_table_free(tb);
772         g_hash_table_remove (table, MEDIA_SVC_DB_TABLE_MEDIA);
773
774         tb = g_hash_table_lookup(table, MEDIA_SVC_DB_TABLE_FOLDER);
775         __media_svc_table_free(tb);
776         g_hash_table_remove (table, MEDIA_SVC_DB_TABLE_FOLDER);
777
778         tb = g_hash_table_lookup(table, MEDIA_SVC_DB_TABLE_PLAYLIST);
779         __media_svc_table_free(tb);
780         g_hash_table_remove (table, MEDIA_SVC_DB_TABLE_PLAYLIST);
781
782         tb = g_hash_table_lookup(table, MEDIA_SVC_DB_TABLE_PLAYLIST_MAP);
783         __media_svc_table_free(tb);
784         g_hash_table_remove (table, MEDIA_SVC_DB_TABLE_PLAYLIST_MAP);
785
786         tb = g_hash_table_lookup(table, MEDIA_SVC_DB_TABLE_ALBUM);
787         __media_svc_table_free(tb);
788         g_hash_table_remove (table, MEDIA_SVC_DB_TABLE_ALBUM);
789
790         tb = g_hash_table_lookup(table, MEDIA_SVC_DB_TABLE_TAG);
791         __media_svc_table_free(tb);
792         g_hash_table_remove (table, MEDIA_SVC_DB_TABLE_TAG);
793
794         tb = g_hash_table_lookup(table, MEDIA_SVC_DB_TABLE_TAG_MAP);
795         __media_svc_table_free(tb);
796         g_hash_table_remove (table, MEDIA_SVC_DB_TABLE_TAG_MAP);
797
798         tb = g_hash_table_lookup(table, MEDIA_SVC_DB_TABLE_BOOKMARK);
799         __media_svc_table_free(tb);
800         g_hash_table_remove (table, MEDIA_SVC_DB_TABLE_BOOKMARK);
801
802         tb = g_hash_table_lookup(table, MEDIA_SVC_DB_TABLE_STORAGE);
803         __media_svc_table_free(tb);
804         g_hash_table_remove (table, MEDIA_SVC_DB_TABLE_STORAGE);
805
806         g_hash_table_destroy(table);
807
808         /* Column Free */
809         len = g_slist_length(column_list[MEDIA_SVC_DB_LIST_MEDIA]);
810
811         for(i=1; i<len; i++) {
812                 col_ptr = g_slist_nth_data(column_list[MEDIA_SVC_DB_LIST_MEDIA], i);
813                 __media_svc_column_free(col_ptr);
814         }
815
816         len = g_slist_length(column_list[MEDIA_SVC_DB_LIST_FOLDER]);
817
818         for(i=1; i<len; i++) {
819                 col_ptr = g_slist_nth_data(column_list[MEDIA_SVC_DB_LIST_FOLDER], i);
820                 __media_svc_column_free(col_ptr);
821         }
822
823         len = g_slist_length(column_list[MEDIA_SVC_DB_LIST_PLAYLIST_MAP]);
824
825         for(i=1; i<len; i++) {
826                 col_ptr = g_slist_nth_data(column_list[MEDIA_SVC_DB_LIST_PLAYLIST_MAP], i);
827                 __media_svc_column_free(col_ptr);
828         }
829
830         len = g_slist_length(column_list[MEDIA_SVC_DB_LIST_PLAYLIST]);
831
832         for(i=1; i<len; i++) {
833                 col_ptr = g_slist_nth_data(column_list[MEDIA_SVC_DB_LIST_PLAYLIST], i);
834                 __media_svc_column_free(col_ptr);
835         }
836
837         len = g_slist_length(column_list[MEDIA_SVC_DB_LIST_ALBUM]);
838
839         for(i=1; i<len; i++) {
840                 col_ptr = g_slist_nth_data(column_list[MEDIA_SVC_DB_LIST_ALBUM], i);
841                 __media_svc_column_free(col_ptr);
842         }
843
844         len = g_slist_length(column_list[MEDIA_SVC_DB_LIST_TAG_MAP]);
845
846         for(i=1; i<len; i++) {
847                 col_ptr = g_slist_nth_data(column_list[MEDIA_SVC_DB_LIST_TAG_MAP], i);
848                 __media_svc_column_free(col_ptr);
849         }
850
851         len = g_slist_length(column_list[MEDIA_SVC_DB_LIST_TAG]);
852
853         for(i=1; i<len; i++) {
854                 col_ptr = g_slist_nth_data(column_list[MEDIA_SVC_DB_LIST_TAG], i);
855                 __media_svc_column_free(col_ptr);
856         }
857
858         len = g_slist_length(column_list[MEDIA_SVC_DB_LIST_BOOKMARK]);
859
860         for(i=1; i<len; i++) {
861                 col_ptr = g_slist_nth_data(column_list[MEDIA_SVC_DB_LIST_BOOKMARK], i);
862                 __media_svc_column_free(col_ptr);
863         }
864
865         len = g_slist_length(column_list[MEDIA_SVC_DB_LIST_STORAGE]);
866
867         for(i=1; i<len; i++) {
868                 col_ptr = g_slist_nth_data(column_list[MEDIA_SVC_DB_LIST_STORAGE], i);
869                 __media_svc_column_free(col_ptr);
870         }
871
872         for(i=0; i<MEDIA_SVC_DB_LIST_MAX; i++) {
873                 g_slist_free(column_list[i]);
874         }
875 }
876
877 static int __media_svc_db_upgrade(sqlite3 *db_handle, int cur_version, uid_t uid)
878 {
879         int ret = MS_MEDIA_ERR_NONE;
880         char *sql = NULL;
881
882         ret = _media_svc_init_table_query(MEDIA_SVC_DB_TABLE_MEDIA);
883         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
884
885         ret = _media_svc_upgrade_table_query(db_handle, MEDIA_SVC_DB_TABLE_MEDIA, MEDIA_SVC_DB_LIST_MEDIA, uid);
886         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
887
888         /* Upgrade issue in folder table */
889         if (cur_version < USER_V4) {
890                 /* Create tmp table */
891                 sql = sqlite3_mprintf("CREATE TABLE '%q' AS SELECT * FROM '%q';", MEDIA_SVC_DB_TABLE_TMP_TABLE, MEDIA_SVC_DB_TABLE_FOLDER);
892                 media_svc_retv_if(sql == NULL, MS_MEDIA_ERR_OUT_OF_MEMORY);
893
894                 ret = _media_svc_sql_query(db_handle, sql, uid);
895                 if (ret != MS_MEDIA_ERR_NONE) {
896                         media_svc_error("Error when create backup folder table");
897                 }
898                 sqlite3_free(sql);
899
900                 /* Drop original table */
901                 sql = sqlite3_mprintf("DROP TABLE '%q';", MEDIA_SVC_DB_TABLE_FOLDER);
902                 media_svc_retv_if(sql == NULL, MS_MEDIA_ERR_OUT_OF_MEMORY);
903
904                 ret = _media_svc_sql_query(db_handle, sql, uid);
905                 if (ret != MS_MEDIA_ERR_NONE) {
906                         media_svc_error("Error when drop table");
907                 }
908                 sqlite3_free(sql);
909
910                 /* Create new table */
911                 ret = _media_svc_make_table_query(db_handle, MEDIA_SVC_DB_TABLE_FOLDER, MEDIA_SVC_DB_LIST_FOLDER, uid);
912                 media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
913
914                 /* Insert into new table */
915                 sql = sqlite3_mprintf("INSERT INTO '%q'(folder_uuid, path, name, modified_time, name_pinyin, storage_type) SELECT folder_uuid, path, name, modified_time, name_pinyin, storage_type FROM '%q';", MEDIA_SVC_DB_TABLE_FOLDER, MEDIA_SVC_DB_TABLE_TMP_TABLE);
916                 media_svc_retv_if(sql == NULL, MS_MEDIA_ERR_OUT_OF_MEMORY);
917
918                 ret = _media_svc_sql_query(db_handle, sql, uid);
919                 if (ret != MS_MEDIA_ERR_NONE) {
920                         media_svc_error("Error when backup folder table");
921                 }
922                 sqlite3_free(sql);
923
924                 /* Drop tmp table*/
925                 sql = sqlite3_mprintf("DROP TABLE '%q';", MEDIA_SVC_DB_TABLE_TMP_TABLE);
926                 media_svc_retv_if(sql == NULL, MS_MEDIA_ERR_OUT_OF_MEMORY);
927
928                 ret = _media_svc_sql_query(db_handle, sql, uid);
929                 if (ret != MS_MEDIA_ERR_NONE) {
930                         media_svc_error("Error when drop backup folder table");
931                 }
932                 sqlite3_free(sql);
933
934         } else {
935                 ret = _media_svc_upgrade_table_query(db_handle, MEDIA_SVC_DB_TABLE_FOLDER , MEDIA_SVC_DB_LIST_FOLDER, uid);
936                 media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
937         }
938
939         ret = _media_svc_upgrade_table_query(db_handle, MEDIA_SVC_DB_TABLE_PLAYLIST_MAP, MEDIA_SVC_DB_LIST_PLAYLIST_MAP, uid);
940         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
941
942         ret = _media_svc_upgrade_table_query(db_handle, MEDIA_SVC_DB_TABLE_PLAYLIST, MEDIA_SVC_DB_LIST_PLAYLIST, uid);
943         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
944
945         ret = _media_svc_upgrade_table_query(db_handle, MEDIA_SVC_DB_TABLE_ALBUM, MEDIA_SVC_DB_LIST_ALBUM, uid);
946         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
947
948         ret = _media_svc_upgrade_table_query(db_handle, MEDIA_SVC_DB_TABLE_TAG_MAP, MEDIA_SVC_DB_LIST_TAG_MAP, uid);
949         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
950
951         ret = _media_svc_upgrade_table_query(db_handle, MEDIA_SVC_DB_TABLE_TAG, MEDIA_SVC_DB_LIST_TAG, uid);
952         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
953
954         ret = _media_svc_upgrade_table_query(db_handle, MEDIA_SVC_DB_TABLE_BOOKMARK, MEDIA_SVC_DB_LIST_BOOKMARK, uid);
955         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
956
957         ret = _media_svc_upgrade_table_query(db_handle, MEDIA_SVC_DB_TABLE_STORAGE, MEDIA_SVC_DB_LIST_STORAGE, uid);
958         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
959
960         if (cur_version < USER_V4) {
961                 /* Need to default value in storage_uuid */
962                 sql = sqlite3_mprintf("UPDATE %q SET storage_uuid = '%q';",MEDIA_SVC_DB_TABLE_MEDIA, "media");
963                 media_svc_retv_if(sql == NULL, MS_MEDIA_ERR_OUT_OF_MEMORY);
964
965                 ret = _media_svc_sql_query(db_handle, sql, uid);
966                 sqlite3_free(sql);
967
968                 sql = sqlite3_mprintf("UPDATE %q SET storage_uuid = '%q';",MEDIA_SVC_DB_TABLE_FOLDER, "media");
969                 media_svc_retv_if(sql == NULL, MS_MEDIA_ERR_OUT_OF_MEMORY);
970
971                 ret = _media_svc_sql_query(db_handle, sql, uid);
972                 sqlite3_free(sql);
973         }
974
975         ret = __media_svc_rebuild_view_query(db_handle, uid);
976
977         sql = sqlite3_mprintf("PRAGMA user_version=%d;", LATEST_VERSION_NUMBER);
978         media_svc_retv_if(sql == NULL, MS_MEDIA_ERR_OUT_OF_MEMORY);
979
980         ret = _media_svc_sql_query(db_handle, sql, uid);
981         sqlite3_free(sql);
982
983         _media_svc_destroy_table_query();
984
985         return ret;
986 }
987
988 int _media_svc_sql_query(sqlite3 *db_handle, const char *sql_str, uid_t uid)
989 {
990         int ret = MS_MEDIA_ERR_NONE;
991
992         media_svc_sec_debug("[SQL query] : %s", sql_str);
993
994         ret = media_db_request_update_db(sql_str, uid);
995
996         return ret;
997 }
998
999 int _media_svc_sql_prepare_to_step(sqlite3 *handle, const char *sql_str, sqlite3_stmt **stmt)
1000 {
1001         int err = -1;
1002
1003         media_svc_sec_debug("[SQL query] : %s", sql_str);
1004
1005         if (!STRING_VALID(sql_str)) {
1006                 media_svc_error("invalid query");
1007                 return MS_MEDIA_ERR_INVALID_PARAMETER;
1008         }
1009
1010         err = sqlite3_prepare_v2(handle, sql_str, -1, stmt, NULL);
1011         sqlite3_free((char *)sql_str);
1012
1013         if (err != SQLITE_OK) {
1014                 media_svc_error("prepare error %d[%s]", err, sqlite3_errmsg(handle));
1015                 if (err == SQLITE_CORRUPT) {
1016                         return MS_MEDIA_ERR_DB_CORRUPT;
1017                 } else if (err == SQLITE_PERM) {
1018                         return MS_MEDIA_ERR_DB_PERMISSION;
1019                 }
1020
1021                 return MS_MEDIA_ERR_DB_INTERNAL;
1022         }
1023
1024         err = sqlite3_step(*stmt);
1025         if (err != SQLITE_ROW) {
1026                 media_svc_error("[No-Error] Item not found. end of row [%s]", sqlite3_errmsg(handle));
1027                 SQLITE3_FINALIZE(*stmt);
1028                 return MS_MEDIA_ERR_DB_NO_RECORD;
1029         }
1030
1031         return MS_MEDIA_ERR_NONE;
1032 }
1033
1034 int _media_svc_sql_prepare_to_step_simple(sqlite3 *handle, const char *sql_str, sqlite3_stmt **stmt)
1035 {
1036         int err = -1;
1037
1038         media_svc_sec_debug("[SQL query] : %s", sql_str);
1039
1040         if (!STRING_VALID(sql_str)) {
1041                 media_svc_error("invalid query");
1042                 return MS_MEDIA_ERR_INVALID_PARAMETER;
1043         }
1044
1045         err = sqlite3_prepare_v2(handle, sql_str, -1, stmt, NULL);
1046         sqlite3_free((char *)sql_str);
1047
1048         if (err != SQLITE_OK) {
1049                 media_svc_error("prepare error %d[%s]", err, sqlite3_errmsg(handle));
1050                 if (err == SQLITE_CORRUPT) {
1051                         return MS_MEDIA_ERR_DB_CORRUPT;
1052                 } else if (err == SQLITE_PERM) {
1053                         return MS_MEDIA_ERR_DB_PERMISSION;
1054                 }
1055
1056                 return MS_MEDIA_ERR_DB_INTERNAL;
1057         }
1058
1059         return MS_MEDIA_ERR_NONE;
1060 }
1061
1062 int _media_svc_sql_begin_trans(sqlite3 *handle, uid_t uid)
1063 {
1064         int ret = MS_MEDIA_ERR_NONE;
1065
1066         media_svc_error("========_media_svc_sql_begin_trans");
1067
1068         ret = media_db_request_update_db_batch_start("BEGIN IMMEDIATE;", uid);
1069
1070         return ret;
1071 }
1072
1073 int _media_svc_sql_end_trans(sqlite3 *handle, uid_t uid)
1074 {
1075         int ret = MS_MEDIA_ERR_NONE;
1076
1077         media_svc_error("========_media_svc_sql_end_trans");
1078
1079         ret = media_db_request_update_db_batch_end("COMMIT;", uid);
1080
1081         return ret;
1082 }
1083
1084 int _media_svc_sql_rollback_trans(sqlite3 *handle, uid_t uid)
1085 {
1086         media_svc_error("========_media_svc_sql_rollback_trans");
1087
1088         return _media_svc_sql_query(handle, "ROLLBACK;", uid);
1089 }
1090
1091 int _media_svc_sql_query_list(sqlite3 *handle, GList **query_list, uid_t uid)
1092 {
1093         int ret = MS_MEDIA_ERR_NONE;
1094         int idx = 0;
1095         int length = g_list_length(*query_list);
1096         char *sql = NULL;
1097
1098         media_svc_debug("query list length : [%d]", length);
1099
1100         for (idx = 0; idx < length; idx++) {
1101                 sql = (char *)g_list_nth_data(*query_list, idx);
1102                 if (sql != NULL) {
1103                         /*ret = _media_svc_sql_query(handle, sql); */
1104                         ret = media_db_request_update_db_batch(sql, uid);
1105                         if (ret != MS_MEDIA_ERR_NONE) {
1106                                 media_svc_error("media_db_request_update_db_batch failed : %d", ret);
1107                         }
1108                         sqlite3_free(sql);
1109                         sql = NULL;
1110                 }
1111         }
1112
1113         _media_svc_sql_query_release(query_list);
1114
1115         return MS_MEDIA_ERR_NONE;
1116
1117 }
1118
1119 void _media_svc_sql_query_add(GList **query_list, char **query)
1120 {
1121         *query_list = g_list_append(*query_list, *query);
1122 }
1123
1124 void _media_svc_sql_query_release(GList **query_list)
1125 {
1126         if (*query_list) {
1127                 media_svc_debug("_svc_sql_query_release");
1128                 g_list_free(*query_list);
1129                 *query_list = NULL;
1130         }
1131 }
1132
1133 int _media_svc_check_db_upgrade(sqlite3 *db_handle, bool *need_full_scan, uid_t uid)
1134 {
1135         int ret = MS_MEDIA_ERR_NONE;
1136         sqlite3_stmt *sql_stmt = NULL;
1137         int cur_version;
1138         char *sql = sqlite3_mprintf("PRAGMA user_version");
1139
1140         ret = _media_svc_sql_prepare_to_step(db_handle, sql, &sql_stmt);
1141
1142         if (ret != MS_MEDIA_ERR_NONE) {
1143                 media_svc_error("error when get user_version. err = [%d]", ret);
1144                 return ret;
1145         }
1146
1147         cur_version = sqlite3_column_int(sql_stmt, 0);
1148
1149         SQLITE3_FINALIZE(sql_stmt);
1150
1151         if (cur_version < LATEST_VERSION_NUMBER) {
1152                 if (cur_version < USER_V4) {
1153                         *need_full_scan = true;
1154                 }
1155                 media_svc_error("Current DB is out of date(%d).. So start to upgrade DB(%d)", cur_version, LATEST_VERSION_NUMBER);
1156                 return __media_svc_db_upgrade(db_handle, cur_version, uid);
1157         } else {
1158                 return MS_MEDIA_ERR_NONE;
1159         }
1160 }
1161
1162 int _media_db_check_corrupt(sqlite3 *db_handle)
1163 {
1164         int ret = MS_MEDIA_ERR_NONE;
1165         char *sql = sqlite3_mprintf("PRAGMA quick_check(1)");
1166         sqlite3_stmt *sql_stmt = NULL;
1167         char *result = NULL;
1168
1169         ret = _media_svc_sql_prepare_to_step(db_handle, sql, &sql_stmt);
1170         if (ret != MS_MEDIA_ERR_NONE) {
1171                 media_svc_error("error when check db. err = [%d]", ret);
1172                 return ret;
1173         }
1174
1175         result = (char *)sqlite3_column_text(sql_stmt, 0);
1176         SQLITE3_FINALIZE(sql_stmt);
1177
1178         if (result != NULL) {
1179                 media_svc_debug("result %s", result);
1180                 if (strcasecmp(result, "OK"))
1181                         ret = MS_MEDIA_ERR_DB_CORRUPT;
1182         } else {
1183                 media_svc_error("result is NULL");
1184                 ret = MS_MEDIA_ERR_DB_INTERNAL;
1185         }
1186
1187         return ret;
1188 }
1189
1190
1191 int _media_svc_create_media_table_with_id(sqlite3 *db_handle, const char *table_id, uid_t uid)
1192 {
1193         int ret = MS_MEDIA_ERR_NONE;
1194
1195         ret = _media_svc_init_table_query(table_id);
1196         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
1197
1198         ret = _media_svc_make_table_query(db_handle, table_id, MEDIA_SVC_DB_LIST_MEDIA, uid);
1199         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
1200
1201         /* Add for trigger */
1202         ret = _media_svc_make_table_query(db_handle, MEDIA_SVC_DB_TABLE_FOLDER, MEDIA_SVC_DB_LIST_FOLDER, uid);
1203         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
1204
1205         ret = _media_svc_make_table_query(db_handle, MEDIA_SVC_DB_TABLE_PLAYLIST_MAP, MEDIA_SVC_DB_LIST_PLAYLIST_MAP, uid);
1206         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
1207
1208         ret = _media_svc_make_table_query(db_handle, MEDIA_SVC_DB_TABLE_ALBUM, MEDIA_SVC_DB_LIST_ALBUM, uid);
1209         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
1210
1211         ret = _media_svc_make_table_query(db_handle, MEDIA_SVC_DB_TABLE_TAG_MAP, MEDIA_SVC_DB_LIST_TAG_MAP, uid);
1212         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
1213
1214         ret = _media_svc_make_table_query(db_handle, MEDIA_SVC_DB_TABLE_BOOKMARK, MEDIA_SVC_DB_LIST_BOOKMARK, uid);
1215         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
1216
1217         _media_svc_destroy_table_query();
1218
1219         return ret;
1220 }
1221
1222 int _media_svc_drop_media_table(sqlite3 *handle, const char *storage_id, uid_t uid)
1223 {
1224         int ret = MS_MEDIA_ERR_NONE;
1225
1226         char *sql = sqlite3_mprintf("DROP TABLE IF EXISTS '%q'", storage_id);
1227
1228         ret = _media_svc_sql_query(handle, sql, uid);
1229         sqlite3_free(sql);
1230
1231         return ret;
1232 }
1233
1234 int _media_svc_update_media_view(sqlite3 *db_handle, uid_t uid)
1235 {
1236         int ret = MS_MEDIA_ERR_NONE;
1237         char *sql = NULL;
1238         sqlite3_stmt *sql_stmt = NULL;
1239         int item_cnt = 0;
1240         int idx = 0;
1241         GList *storage_list = NULL;
1242         char view_query[4096] = {0, };
1243         memset(view_query, 0x00, sizeof(view_query));
1244
1245         snprintf(view_query, sizeof(view_query), "DROP VIEW IF EXISTS %s; CREATE VIEW IF NOT EXISTS %s AS SELECT * from %s ", MEDIA_SVC_DB_VIEW_MEDIA, MEDIA_SVC_DB_VIEW_MEDIA, MEDIA_SVC_DB_TABLE_MEDIA);
1246
1247         /*Select list of storage*/
1248         sql = sqlite3_mprintf("SELECT storage_uuid FROM '%s' WHERE validity=1 AND storage_uuid != '%s'", MEDIA_SVC_DB_TABLE_STORAGE, MEDIA_SVC_DB_TABLE_MEDIA);
1249         ret = _media_svc_sql_prepare_to_step_simple(db_handle, sql, &sql_stmt);
1250         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
1251
1252         while (sqlite3_step(sql_stmt) == SQLITE_ROW) {
1253                 if (STRING_VALID((const char *)sqlite3_column_text(sql_stmt, 0))) {
1254                         storage_list = g_list_append(storage_list, strdup((char *)sqlite3_column_text(sql_stmt, 0)));
1255                 }
1256         }
1257         SQLITE3_FINALIZE(sql_stmt);
1258
1259         if ((storage_list != NULL) && (g_list_length(storage_list) > 0)) {
1260                 item_cnt = g_list_length(storage_list);
1261
1262                 for (idx = 0; idx < item_cnt; idx++) {
1263                         int table_cnt = 0;
1264                         char *storage_id = NULL;
1265                         storage_id = g_list_nth_data(storage_list, idx);
1266
1267                         if (STRING_VALID(storage_id)) {
1268                                 /*Select list of storage*/
1269                                 sql = sqlite3_mprintf("SELECT COUNT(*) FROM SQLITE_MASTER WHERE type='table' and name='%q'", storage_id);
1270                                 ret = _media_svc_sql_prepare_to_step(db_handle, sql, &sql_stmt);
1271                                 if (ret != MS_MEDIA_ERR_NONE) {
1272                                         SAFE_FREE(storage_id);
1273                                         continue;
1274                                 }
1275
1276                                 table_cnt = sqlite3_column_int(sql_stmt, 0);
1277                                 SQLITE3_FINALIZE(sql_stmt);
1278
1279                                 if (table_cnt > 0) {
1280                                         char append_query[128] = {0, };
1281                                         memset(append_query, 0x00, sizeof(append_query));
1282                                         snprintf(append_query, sizeof(append_query), " UNION SELECT * from '%s'", storage_id);
1283                                         strncat(view_query, append_query, strlen(append_query));
1284                                 } else {
1285                                         media_svc_error("media table not exist for storage [%s]", storage_id);
1286                                 }
1287
1288                                 SAFE_FREE(storage_id);
1289                         }
1290                 }
1291                 g_list_free(storage_list);
1292         }
1293
1294         ret = _media_svc_sql_query(db_handle, view_query, uid);
1295         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
1296
1297         return ret;
1298 }