d7a8862fc351151e9d7ff3ada64790b49246b3d4
[platform/core/multimedia/libmedia-service.git] / src / common / media-svc-media.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 <string.h>
23 #include <grp.h>
24 #include <pwd.h>
25 #include "media-svc-media.h"
26 #include "media-svc-media-folder.h"
27 #include "media-svc-error.h"
28 #include "media-svc-debug.h"
29 #include "media-svc-util.h"
30 #include "media-svc-db-utils.h"
31 #include "media-svc-noti.h"
32
33 #define GLOBAL_USER    0 //#define     tzplatform_getenv(TZ_GLOBAL) //TODO
34
35 typedef struct{
36         char thumbnail_path[MEDIA_SVC_PATHNAME_SIZE];
37 }media_svc_thumbnailpath_s;
38
39 static __thread GList *g_media_svc_item_validity_query_list = NULL;
40 static __thread GList *g_media_svc_insert_item_query_list = NULL;
41 __thread GList *g_media_svc_move_item_query_list = NULL;
42
43 static int __media_svc_count_invalid_records_with_thumbnail(sqlite3 *handle, media_svc_storage_type_e storage_type, int *count);
44 static int __media_svc_get_invalid_records_with_thumbnail(sqlite3 *handle, media_svc_storage_type_e storage_type,
45                                                         int count, media_svc_thumbnailpath_s * thumb_path);
46 static int __media_svc_count_invalid_folder_records_with_thumbnail(sqlite3 *handle, const char *folder_path, int *count);
47 static int __media_svc_get_invalid_folder_records_with_thumbnail(sqlite3 *handle, const char *folder_path,
48                                                         int count, media_svc_thumbnailpath_s * thumb_path);
49
50 static int __media_svc_count_invalid_records_with_thumbnail(sqlite3 *handle, media_svc_storage_type_e storage_type, int *count)
51 {
52         int ret = MEDIA_INFO_ERROR_NONE;
53         sqlite3_stmt *sql_stmt = NULL;
54         char *sql = sqlite3_mprintf("SELECT count(*) FROM %s WHERE validity=0 AND storage_type=%d AND thumbnail_path IS NOT NULL",
55                                         MEDIA_SVC_DB_TABLE_MEDIA, storage_type);
56
57         ret = _media_svc_sql_prepare_to_step(handle, sql, &sql_stmt);
58
59         if (ret != MEDIA_INFO_ERROR_NONE) {
60                 media_svc_error("error when __media_svc_count_invalid_records_with_thumbnail. err = [%d]", ret);
61                 return ret;
62         }
63
64         *count = sqlite3_column_int(sql_stmt, 0);
65
66         SQLITE3_FINALIZE(sql_stmt);
67
68         return MEDIA_INFO_ERROR_NONE;
69
70 }
71
72 static int __media_svc_get_invalid_records_with_thumbnail(sqlite3 *handle, media_svc_storage_type_e storage_type,
73                                                         int count, media_svc_thumbnailpath_s * thumb_path)
74 {
75         int err = -1;
76         int idx = 0;
77         sqlite3_stmt *sql_stmt = NULL;
78
79         char *sql = sqlite3_mprintf("SELECT thumbnail_path from (select thumbnail_path, validity from %s WHERE storage_type=%d AND thumbnail_path IS NOT NULL GROUP BY thumbnail_path HAVING count() = 1) WHERE validity=0",
80                                         MEDIA_SVC_DB_TABLE_MEDIA, storage_type);
81
82         media_svc_debug("[SQL query] : %s", sql);
83
84         err = sqlite3_prepare_v2(handle, sql, -1, &sql_stmt, NULL);
85         sqlite3_free(sql);
86         if (err != SQLITE_OK) {
87                 media_svc_error("prepare error [%s]", sqlite3_errmsg(handle));
88                 return MEDIA_INFO_ERROR_DATABASE_INTERNAL;
89         }
90
91         while (sqlite3_step(sql_stmt) == SQLITE_ROW) {
92                 _strncpy_safe(thumb_path[idx].thumbnail_path, (const char *)sqlite3_column_text(sql_stmt, 0), sizeof(thumb_path[idx]));
93                 //media_svc_debug("thumb_path[%d]=[%s]", idx, thumb_path[idx].thumbnail_path);
94                 idx++;
95         }
96
97         SQLITE3_FINALIZE(sql_stmt);
98
99         return MEDIA_INFO_ERROR_NONE;
100 }
101
102 static int __media_svc_count_invalid_folder_records_with_thumbnail(sqlite3 *handle, const char *folder_path, int *count)
103 {
104         int ret = MEDIA_INFO_ERROR_NONE;
105         sqlite3_stmt *sql_stmt = NULL;
106         char *sql = sqlite3_mprintf("SELECT count(*) FROM %s WHERE validity=0 AND path LIKE '%q/%%' AND thumbnail_path IS NOT NULL",
107                                         MEDIA_SVC_DB_TABLE_MEDIA, folder_path);
108
109         ret = _media_svc_sql_prepare_to_step(handle, sql, &sql_stmt);
110
111         if (ret != MEDIA_INFO_ERROR_NONE) {
112                 media_svc_error("error when __media_svc_count_invalid_folder_records_with_thumbnail. err = [%d]", ret);
113                 return ret;
114         }
115
116         *count = sqlite3_column_int(sql_stmt, 0);
117
118         SQLITE3_FINALIZE(sql_stmt);
119
120         return MEDIA_INFO_ERROR_NONE;
121
122 }
123
124 static int __media_svc_get_invalid_folder_records_with_thumbnail(sqlite3 *handle, const char *folder_path,
125                                                         int count, media_svc_thumbnailpath_s * thumb_path)
126 {
127         int err = -1;
128         int idx = 0;
129         sqlite3_stmt *sql_stmt = NULL;
130
131         char *sql = sqlite3_mprintf("SELECT thumbnail_path from (select thumbnail_path, validity from %s WHERE path LIKE '%q/%%' AND thumbnail_path IS NOT NULL GROUP BY thumbnail_path HAVING count() = 1) WHERE validity=0",
132                                         MEDIA_SVC_DB_TABLE_MEDIA, folder_path);
133
134         media_svc_debug("[SQL query] : %s", sql);
135
136         err = sqlite3_prepare_v2(handle, sql, -1, &sql_stmt, NULL);
137         sqlite3_free(sql);
138         if (err != SQLITE_OK) {
139                 media_svc_error("prepare error [%s]", sqlite3_errmsg(handle));
140                 return MEDIA_INFO_ERROR_DATABASE_INTERNAL;
141         }
142
143         while (sqlite3_step(sql_stmt) == SQLITE_ROW) {
144                 _strncpy_safe(thumb_path[idx].thumbnail_path, (const char *)sqlite3_column_text(sql_stmt, 0), sizeof(thumb_path[idx]));
145                 idx++;
146         }
147
148         SQLITE3_FINALIZE(sql_stmt);
149
150         return MEDIA_INFO_ERROR_NONE;
151 }
152
153 int _media_svc_count_record_with_path(sqlite3 *handle, const char *path, int *count)
154 {
155         int ret = MEDIA_INFO_ERROR_NONE;
156         sqlite3_stmt *sql_stmt = NULL;
157
158         char *sql = sqlite3_mprintf("SELECT count(*) FROM %s WHERE path='%q'", MEDIA_SVC_DB_TABLE_MEDIA, path);
159
160         ret = _media_svc_sql_prepare_to_step(handle, sql, &sql_stmt);
161
162         media_svc_retv_if(ret != MEDIA_INFO_ERROR_NONE, ret);
163
164         *count = sqlite3_column_int(sql_stmt, 0);
165
166         SQLITE3_FINALIZE(sql_stmt);
167
168         return MEDIA_INFO_ERROR_NONE;
169 }
170
171 char* _media_svc_get_thumb_default_path(uid_t uid)
172 {
173         char *result_psswd = NULL;
174         struct group *grpinfo = NULL;
175         if(uid == getuid())
176         {
177                 result_psswd = strdup(MEDIA_SVC_THUMB_DEFAULT_PATH);
178                 grpinfo = getgrnam("users");
179                 if(grpinfo == NULL) {
180                         media_svc_error("getgrnam(users) returns NULL !");
181                         return NULL;
182                 }
183         }
184         else
185         {
186                 struct passwd *userinfo = getpwuid(uid);
187                 if(userinfo == NULL) {
188                         media_svc_error("getpwuid(%d) returns NULL !", uid);
189                         return NULL;
190                 }
191                 grpinfo = getgrnam("users");
192                 if(grpinfo == NULL) {
193                         media_svc_error("getgrnam(users) returns NULL !");
194                         return NULL;
195                 }
196                 // Compare git_t type and not group name
197                 if (grpinfo->gr_gid != userinfo->pw_gid) {
198                         media_svc_error("UID [%d] does not belong to 'users' group!", uid);
199                         return NULL;
200                 }
201                 asprintf(&result_psswd, "%s/data/file-manager-service/.thumb/thumb_default.png", userinfo->pw_dir);
202         }
203
204         return result_psswd;
205 }
206
207 int _media_svc_insert_item_with_data(sqlite3 *handle, media_svc_content_info_s *content_info, int is_burst, bool stack_query, uid_t uid)
208 {
209         media_svc_debug("");
210         int err = -1;
211         char *burst_id = NULL;
212
213         char * db_fields = "media_uuid, path, file_name, media_type, mime_type, size, added_time, modified_time, folder_uuid, \
214                                         thumbnail_path, title, album_id, album, artist, album_artist, genre, composer, year, recorded_date, copyright, track_num, description,\
215                                         bitrate, samplerate, channel, duration, longitude, latitude, altitude, width, height, datetaken, orientation,\
216                                         rating, is_drm, storage_type, burst_id, timeline, weather, sync_status, \
217                                         file_name_pinyin, title_pinyin, album_pinyin, artist_pinyin, album_artist_pinyin, genre_pinyin, composer_pinyin, copyright_pinyin, description_pinyin ";
218
219         /* This sql is due to sqlite3_mprintf's wrong operation when using floating point in the text format */
220         /* This code will be removed when sqlite3_mprintf works clearly */
221         char *test_sql = sqlite3_mprintf("%f, %f, %f", content_info->media_meta.longitude, content_info->media_meta.latitude, content_info->media_meta.altitude);
222         sqlite3_free(test_sql);
223
224         if (is_burst) {
225                 int burst_id_int = 0;
226                 err = _media_svc_get_burst_id(handle, &burst_id_int);
227                 if (err < 0) {
228                         burst_id = NULL;
229                 }
230
231                 if (burst_id_int > 0) {
232                         media_svc_debug("Burst id : %d", burst_id_int);
233                         burst_id = sqlite3_mprintf("%d", burst_id_int);
234                 }
235
236                 /* Get thumbnail for burst shot */
237                 char thumb_path[MEDIA_SVC_PATHNAME_SIZE + 1] = {0, };
238                 int width = 0;
239                 int height = 0;
240
241                 err = thumbnail_request_from_db_with_size(content_info->path, thumb_path, sizeof(thumb_path), &width, &height, uid);
242                 if (err < 0) {
243                         media_svc_error("thumbnail_request_from_db failed: %d", err);
244                 } else {
245                         media_svc_debug("thumbnail_request_from_db success: %s", thumb_path);
246                         err = __media_svc_malloc_and_strncpy(&(content_info->thumbnail_path), thumb_path);
247                         if (err < 0) {
248                                 content_info->thumbnail_path = NULL;
249                         }
250                 }
251
252                 if (content_info->media_meta.width <= 0)
253                         content_info->media_meta.width = width;
254
255                 if (content_info->media_meta.height <= 0)
256                         content_info->media_meta.height = height;
257         }
258
259         /*Update Pinyin If Support Pinyin*/
260         if(_media_svc_check_pinyin_support())
261         {
262                 if(STRING_VALID(content_info->file_name))
263                         _media_svc_get_pinyin_str(content_info->file_name, &content_info->file_name_pinyin);
264                 if(STRING_VALID(content_info->media_meta.title))
265                         _media_svc_get_pinyin_str(content_info->media_meta.title, &content_info->media_meta.title_pinyin);
266                 if(STRING_VALID(content_info->media_meta.album))
267                         _media_svc_get_pinyin_str(content_info->media_meta.album, &content_info->media_meta.album_pinyin);
268                 if(STRING_VALID(content_info->media_meta.artist))
269                         _media_svc_get_pinyin_str(content_info->media_meta.artist, &content_info->media_meta.artist_pinyin);
270                 if(STRING_VALID(content_info->media_meta.album_artist))
271                         _media_svc_get_pinyin_str(content_info->media_meta.album_artist, &content_info->media_meta.album_artist_pinyin);
272                 if(STRING_VALID(content_info->media_meta.genre))
273                         _media_svc_get_pinyin_str(content_info->media_meta.genre, &content_info->media_meta.genre_pinyin);
274                 if(STRING_VALID(content_info->media_meta.composer))
275                         _media_svc_get_pinyin_str(content_info->media_meta.composer, &content_info->media_meta.composer_pinyin);
276                 if(STRING_VALID(content_info->media_meta.copyright))
277                         _media_svc_get_pinyin_str(content_info->media_meta.copyright, &content_info->media_meta.copyright_pinyin);
278                 if(STRING_VALID(content_info->media_meta.description))
279                         _media_svc_get_pinyin_str(content_info->media_meta.description, &content_info->media_meta.description_pinyin);
280         }
281
282         char *sql = sqlite3_mprintf("INSERT INTO %s (%s) VALUES (%Q, %Q, %Q, %d, %Q, %lld, %d, %d, %Q, \
283                                                                                                         %Q, %Q, %d, %Q, %Q, %Q, %Q, %Q, %Q, %Q, %Q, %Q, %Q, \
284                                                                                                         %d, %d, %d, %d, %.6f, %.6f, %.6f, %d, %d, %Q, %d, \
285                                                                                                         %d, %d, %d, %Q, %d, %Q, %d, \
286                                                                                                         %Q, %Q, %Q, %Q, %Q, %Q, %Q, %Q, %Q);",
287                 MEDIA_SVC_DB_TABLE_MEDIA, db_fields,
288                 content_info->media_uuid,
289                 content_info->path,
290                 content_info->file_name,
291                 content_info->media_type,
292                 content_info->mime_type,
293                 content_info->size,
294                 content_info->added_time,
295                 content_info->modified_time,
296                 content_info->folder_uuid,
297                 content_info->thumbnail_path,           //
298                 content_info->media_meta.title,
299                 content_info->album_id,
300                 content_info->media_meta.album,
301                 content_info->media_meta.artist,
302                 content_info->media_meta.album_artist,
303                 content_info->media_meta.genre,
304                 content_info->media_meta.composer,
305                 content_info->media_meta.year,
306                 content_info->media_meta.recorded_date,
307                 content_info->media_meta.copyright,
308                 content_info->media_meta.track_num,
309                 content_info->media_meta.description,   //
310                 content_info->media_meta.bitrate,
311                 content_info->media_meta.samplerate,
312                 content_info->media_meta.channel,
313                 content_info->media_meta.duration,
314                 content_info->media_meta.longitude,
315                 content_info->media_meta.latitude,
316                 content_info->media_meta.altitude,
317                 content_info->media_meta.width,
318                 content_info->media_meta.height,
319                 content_info->media_meta.datetaken,
320                 content_info->media_meta.orientation,
321                 content_info->media_meta.rating,
322                 content_info->is_drm,
323                 content_info->storage_type,
324                 burst_id,
325                 content_info->timeline,
326                 content_info->media_meta.weather,
327                 content_info->sync_status,
328                 content_info->file_name_pinyin,
329                 content_info->media_meta.title_pinyin,
330                 content_info->media_meta.album_pinyin,
331                 content_info->media_meta.artist_pinyin,
332                 content_info->media_meta.album_artist_pinyin,
333                 content_info->media_meta.genre_pinyin,
334                 content_info->media_meta.composer_pinyin,
335                 content_info->media_meta.copyright_pinyin,
336                 content_info->media_meta.description_pinyin
337                 );
338
339         if (burst_id) sqlite3_free(burst_id);
340         burst_id = NULL;
341
342         if(!stack_query) {
343                 err = _media_svc_sql_query(handle, sql, uid);
344                 sqlite3_free(sql);
345                 if (err != SQLITE_OK) {
346                         media_svc_error("failed to insert item");
347
348                         return MEDIA_INFO_ERROR_DATABASE_INTERNAL;
349                 }
350         } else {
351                 media_svc_debug("query : %s", sql);
352                 _media_svc_sql_query_add(&g_media_svc_insert_item_query_list, &sql);
353         }
354
355         return MEDIA_INFO_ERROR_NONE;
356 }
357
358 int _media_svc_update_item_with_data(sqlite3 *handle, media_svc_content_info_s *content_info, uid_t uid)
359 {
360         int err = -1;
361
362         /* This sql is due to sqlite3_mprintf's wrong operation when using floating point in the text format */
363         /* This code will be removed when sqlite3_mprintf works clearly */
364         char *test_sql = sqlite3_mprintf("%f, %f, %f", content_info->media_meta.longitude, content_info->media_meta.latitude, content_info->media_meta.altitude);
365         sqlite3_free(test_sql);
366
367         /*Update Pinyin If Support Pinyin*/
368         if(_media_svc_check_pinyin_support())
369         {
370                 if(STRING_VALID(content_info->media_meta.title))
371                         _media_svc_get_pinyin_str(content_info->media_meta.title, &content_info->media_meta.title_pinyin);
372                 if(STRING_VALID(content_info->media_meta.album))
373                         _media_svc_get_pinyin_str(content_info->media_meta.album, &content_info->media_meta.album_pinyin);
374                 if(STRING_VALID(content_info->media_meta.artist))
375                         _media_svc_get_pinyin_str(content_info->media_meta.artist, &content_info->media_meta.artist_pinyin);
376                 if(STRING_VALID(content_info->media_meta.album_artist))
377                         _media_svc_get_pinyin_str(content_info->media_meta.album_artist, &content_info->media_meta.album_artist_pinyin);
378                 if(STRING_VALID(content_info->media_meta.genre))
379                         _media_svc_get_pinyin_str(content_info->media_meta.genre, &content_info->media_meta.genre_pinyin);
380                 if(STRING_VALID(content_info->media_meta.composer))
381                         _media_svc_get_pinyin_str(content_info->media_meta.composer, &content_info->media_meta.composer_pinyin);
382                 if(STRING_VALID(content_info->media_meta.copyright))
383                         _media_svc_get_pinyin_str(content_info->media_meta.copyright, &content_info->media_meta.copyright_pinyin);
384                 if(STRING_VALID(content_info->media_meta.description))
385                         _media_svc_get_pinyin_str(content_info->media_meta.description, &content_info->media_meta.description_pinyin);
386         }
387
388         char *sql = sqlite3_mprintf("UPDATE %s SET \
389                 size=%lld, modified_time=%d, thumbnail_path=%Q, title=%Q, album_id=%d, album=%Q, artist=%Q, album_artist=%Q, genre=%Q, \
390                 composer=%Q, year=%Q, recorded_date=%Q, copyright=%Q, track_num=%Q, description=%Q, \
391                 bitrate=%d, samplerate=%d, channel=%d, duration=%d, longitude=%f, latitude=%f, altitude=%f, width=%d, height=%d, datetaken=%Q, \
392                                                                                                         orientation=%d WHERE path=%Q",
393                 MEDIA_SVC_DB_TABLE_MEDIA,
394                 content_info->size,
395                 content_info->modified_time,
396                 content_info->thumbnail_path,
397                 content_info->media_meta.title,
398                 content_info->album_id,
399                 content_info->media_meta.album,
400                 content_info->media_meta.artist,
401                 content_info->media_meta.album_artist,
402                 content_info->media_meta.genre,
403                 content_info->media_meta.composer,
404                 content_info->media_meta.year,
405                 content_info->media_meta.recorded_date,
406                 content_info->media_meta.copyright,
407                 content_info->media_meta.track_num,
408                 content_info->media_meta.description,
409                 content_info->media_meta.bitrate,
410                 content_info->media_meta.samplerate,
411                 content_info->media_meta.channel,
412                 content_info->media_meta.duration,
413                 content_info->media_meta.longitude,
414                 content_info->media_meta.latitude,
415                 content_info->media_meta.altitude,
416                 content_info->media_meta.width,
417                 content_info->media_meta.height,
418                 content_info->media_meta.datetaken,
419                 content_info->media_meta.orientation,
420                 content_info->path
421                 );
422
423         err = _media_svc_sql_query(handle, sql, uid);
424         sqlite3_free(sql);
425         if (err != SQLITE_OK) {
426                 media_svc_error("failed to update item");
427
428                 return MEDIA_INFO_ERROR_DATABASE_INTERNAL;
429         }
430
431         return MEDIA_INFO_ERROR_NONE;
432 }
433 int _media_svc_get_thumbnail_path_by_path(sqlite3 *handle, const char *path, char *thumbnail_path)
434 {
435         int ret = MEDIA_INFO_ERROR_NONE;
436         sqlite3_stmt *sql_stmt = NULL;
437
438         char *sql = sqlite3_mprintf("SELECT thumbnail_path FROM %s WHERE path='%q'", MEDIA_SVC_DB_TABLE_MEDIA, path);
439
440         ret = _media_svc_sql_prepare_to_step(handle, sql, &sql_stmt);
441
442         if (ret != MEDIA_INFO_ERROR_NONE) {
443                 if(ret == MEDIA_INFO_ERROR_DATABASE_NO_RECORD) {
444                         media_svc_debug("there is no thumbnail.");
445                 }
446                 else {
447                         media_svc_error("error when _media_svc_get_thumbnail_path_by_path. err = [%d]", ret);
448                 }
449                 return ret;
450         }
451
452         _strncpy_safe(thumbnail_path, (const char *)sqlite3_column_text(sql_stmt, 0), MEDIA_SVC_PATHNAME_SIZE);
453
454         SQLITE3_FINALIZE(sql_stmt);
455
456         return MEDIA_INFO_ERROR_NONE;
457 }
458
459 int _media_svc_get_media_type_by_path(sqlite3 *handle, const char *path, int *media_type)
460 {
461         int ret = MEDIA_INFO_ERROR_NONE;
462         sqlite3_stmt *sql_stmt = NULL;
463
464         char *sql = sqlite3_mprintf("SELECT media_type FROM %s WHERE path='%q'", MEDIA_SVC_DB_TABLE_MEDIA, path);
465
466         ret = _media_svc_sql_prepare_to_step(handle, sql, &sql_stmt);
467
468         if (ret != MEDIA_INFO_ERROR_NONE) {
469                 media_svc_error("error when _media_svc_get_media_type_by_path. err = [%d]", ret);
470                 return ret;
471         }
472
473         *media_type = sqlite3_column_int(sql_stmt, 0);
474
475         SQLITE3_FINALIZE(sql_stmt);
476
477         return MEDIA_INFO_ERROR_NONE;
478 }
479
480 int _media_svc_delete_item_by_path(sqlite3 *handle, const char *path, uid_t uid)
481 {
482         int err = -1;
483         char *sql = sqlite3_mprintf("DELETE FROM %s WHERE validity=1 AND path='%q'", MEDIA_SVC_DB_TABLE_MEDIA, path);
484
485         err = _media_svc_sql_query(handle, sql, uid);
486         sqlite3_free(sql);
487         if (err != SQLITE_OK) {
488                 media_svc_error("It failed to delete item (%d)", err);
489                 return MEDIA_INFO_ERROR_DATABASE_INTERNAL;
490         }
491
492         return MEDIA_INFO_ERROR_NONE;
493 }
494
495 int _media_svc_truncate_table(sqlite3 *handle, media_svc_storage_type_e storage_type, uid_t uid)
496 {
497         int err = -1;
498         char *sql = sqlite3_mprintf("DELETE FROM %s WHERE storage_type=%d", MEDIA_SVC_DB_TABLE_MEDIA, storage_type);
499
500         err = _media_svc_sql_query(handle, sql, uid);
501         sqlite3_free(sql);
502         if (err != SQLITE_OK) {
503                 media_svc_error("It failed to truncate table (%d)", err);
504                 return MEDIA_INFO_ERROR_DATABASE_INTERNAL;
505         }
506
507         return MEDIA_INFO_ERROR_NONE;
508
509 }
510
511 int _media_svc_delete_invalid_items(sqlite3 *handle, media_svc_storage_type_e storage_type, uid_t uid)
512 {
513         int idx = 0;
514         media_svc_thumbnailpath_s *thumbpath_record = NULL;
515         int err = -1;
516         int invalid_count = 0;
517         int ret = MEDIA_INFO_ERROR_NONE;
518
519         ret = __media_svc_count_invalid_records_with_thumbnail(handle, storage_type, &invalid_count);
520         media_svc_retv_if(ret != MEDIA_INFO_ERROR_NONE, ret);
521
522         media_svc_debug("invalid count: %d\n", invalid_count);
523
524         if (invalid_count > 0) {
525                 thumbpath_record = (media_svc_thumbnailpath_s *)calloc( invalid_count, sizeof(media_svc_thumbnailpath_s));
526                 if (thumbpath_record == NULL) {
527                         media_svc_error("fail to memory allocation");
528                         return MEDIA_INFO_ERROR_OUT_OF_MEMORY;
529                 }
530
531                 ret = __media_svc_get_invalid_records_with_thumbnail(handle, storage_type, invalid_count, thumbpath_record);
532                 if (ret != MEDIA_INFO_ERROR_NONE) {
533                         media_svc_error("error when get thumbnail record");
534                         SAFE_FREE(thumbpath_record);
535                         return ret;
536                 }
537         } else {
538                 media_svc_debug("There is no item with thumbnail");
539         }
540
541         char *sql = sqlite3_mprintf("DELETE FROM %s WHERE validity = 0 AND storage_type=%d", MEDIA_SVC_DB_TABLE_MEDIA, storage_type);
542         err = _media_svc_sql_query(handle, sql, uid);
543         sqlite3_free(sql);
544         if (err != SQLITE_OK) {
545                 media_svc_error("To delete invalid items is failed(%d)", err);
546                 SAFE_FREE(thumbpath_record);
547                 return MEDIA_INFO_ERROR_DATABASE_INTERNAL;
548         }
549
550         /*Delete thumbnails*/
551         for (idx = 0; idx < invalid_count; idx++) {
552                 if ((strlen(thumbpath_record[idx].thumbnail_path) > 0) && (strncmp(thumbpath_record[idx].thumbnail_path, _media_svc_get_thumb_default_path(uid), sizeof(_media_svc_get_thumb_default_path(uid))) != 0)) {
553                         if (_media_svc_remove_file(thumbpath_record[idx].thumbnail_path) == FALSE) {
554                                 media_svc_error("fail to remove thumbnail file.");
555                                 //SAFE_FREE(thumbpath_record);
556                                 //return MEDIA_INFO_ERROR_INTERNAL;
557                         }
558                 }
559         }
560
561         SAFE_FREE(thumbpath_record);
562
563         return MEDIA_INFO_ERROR_NONE;
564 }
565
566 int _media_svc_delete_invalid_folder_items(sqlite3 *handle, const char *folder_path, uid_t uid)
567 {
568         int idx = 0;
569         media_svc_thumbnailpath_s *thumbpath_record = NULL;
570         int err = -1;
571         int invalid_count = 0;
572         int ret = MEDIA_INFO_ERROR_NONE;
573
574         ret = __media_svc_count_invalid_folder_records_with_thumbnail(handle, folder_path, &invalid_count);
575         media_svc_retv_if(ret != MEDIA_INFO_ERROR_NONE, ret);
576
577         media_svc_debug("invalid count: %d\n", invalid_count);
578
579         if (invalid_count > 0) {
580                 thumbpath_record = (media_svc_thumbnailpath_s *)calloc( invalid_count, sizeof(media_svc_thumbnailpath_s));
581                 if (thumbpath_record == NULL) {
582                         media_svc_error("fail to memory allocation");
583                         return MEDIA_INFO_ERROR_OUT_OF_MEMORY;
584                 }
585
586                 ret = __media_svc_get_invalid_folder_records_with_thumbnail(handle, folder_path, invalid_count, thumbpath_record);
587                 if (ret != MEDIA_INFO_ERROR_NONE) {
588                         media_svc_error("error when get thumbnail record");
589                         SAFE_FREE(thumbpath_record);
590                         return ret;
591                 }
592         } else {
593                 media_svc_debug("There is no item with thumbnail");
594         }
595
596         char *sql = sqlite3_mprintf("DELETE FROM %s WHERE validity = 0 AND path LIKE '%q/%%'", MEDIA_SVC_DB_TABLE_MEDIA, folder_path);
597         err = _media_svc_sql_query(handle, sql, uid);
598         sqlite3_free(sql);
599         if (err != SQLITE_OK) {
600                 media_svc_error("To delete invalid items is failed(%d)", err);
601                 SAFE_FREE(thumbpath_record);
602                 return MEDIA_INFO_ERROR_DATABASE_INTERNAL;
603         }
604
605         /*Delete thumbnails*/
606         for (idx = 0; idx < invalid_count; idx++) {
607                 if ((strlen(thumbpath_record[idx].thumbnail_path) > 0) && (strncmp(thumbpath_record[idx].thumbnail_path, _media_svc_get_thumb_default_path(uid), sizeof(_media_svc_get_thumb_default_path(uid))) != 0)) {
608                         if (_media_svc_remove_file(thumbpath_record[idx].thumbnail_path) == FALSE) {
609                                 media_svc_error("fail to remove thumbnail file [%s].", thumbpath_record[idx].thumbnail_path);
610                                 //SAFE_FREE(thumbpath_record);
611                                 //return MEDIA_INFO_ERROR_INTERNAL;
612                         }
613                 }
614         }
615
616         SAFE_FREE(thumbpath_record);
617
618         return MEDIA_INFO_ERROR_NONE;
619 }
620
621
622 int _media_svc_update_item_validity(sqlite3 *handle, const char *path, int validity, bool stack_query, uid_t uid)
623 {
624         int err = -1;
625
626         char *sql = sqlite3_mprintf("UPDATE %s SET validity=%d WHERE path= '%q'", MEDIA_SVC_DB_TABLE_MEDIA, validity, path);
627
628         if(!stack_query) {
629                 err = _media_svc_sql_query(handle, sql, uid);
630                 sqlite3_free(sql);
631                 if (err != SQLITE_OK) {
632                         media_svc_error("To update item as valid is failed(%d)", err);
633                         return MEDIA_INFO_ERROR_DATABASE_INTERNAL;
634                 }
635         } else {
636                 _media_svc_sql_query_add(&g_media_svc_item_validity_query_list, &sql);
637         }
638
639         return MEDIA_INFO_ERROR_NONE;
640 }
641
642 int _media_svc_update_thumbnail_path(sqlite3 *handle, const char *path, const char *thumb_path, uid_t uid)
643 {
644         int err = -1;
645
646         char *sql = sqlite3_mprintf("UPDATE %s SET thumbnail_path=%Q WHERE path= %Q", MEDIA_SVC_DB_TABLE_MEDIA, thumb_path, path);
647
648         err = _media_svc_sql_query(handle, sql, uid);
649         sqlite3_free(sql);
650         if (err != SQLITE_OK) {
651                 media_svc_error("To update thumb path failed(%d)", err);
652                 return MEDIA_INFO_ERROR_DATABASE_INTERNAL;
653         }
654
655         return MEDIA_INFO_ERROR_NONE;
656 }
657
658 int _media_svc_update_storage_item_validity(sqlite3 *handle, media_svc_storage_type_e storage_type, int validity, uid_t uid)
659 {
660         int err = -1;
661         char *sql = sqlite3_mprintf("UPDATE %s SET validity=%d WHERE storage_type=%d", MEDIA_SVC_DB_TABLE_MEDIA, validity, storage_type);
662         err = _media_svc_sql_query(handle, sql, uid);
663         sqlite3_free(sql);
664         if (err != SQLITE_OK) {
665                 media_svc_error("To update item as valid is failed(%d)", err);
666                 return MEDIA_INFO_ERROR_DATABASE_INTERNAL;
667         }
668
669         return MEDIA_INFO_ERROR_NONE;
670 }
671
672 int _media_svc_update_folder_item_validity(sqlite3 *handle, const char *folder_path, int validity, uid_t uid)
673 {
674         int err = -1;
675         int ret = MEDIA_INFO_ERROR_NONE;
676         char *sql = NULL;
677         char folder_uuid[MEDIA_SVC_UUID_SIZE + 1] = {0, };
678         sqlite3_stmt *sql_stmt = NULL;
679
680         /*Get folder ID*/
681         sql = sqlite3_mprintf("SELECT folder_uuid FROM %s WHERE path='%q'", MEDIA_SVC_DB_TABLE_FOLDER, folder_path);
682         ret = _media_svc_sql_prepare_to_step(handle, sql, &sql_stmt);
683         if (ret != MEDIA_INFO_ERROR_NONE) {
684                 media_svc_error("error when get folder_id. err = [%d]", ret);
685                 return ret;
686         }
687
688         _strncpy_safe(folder_uuid, (const char *)sqlite3_column_text(sql_stmt, 0), MEDIA_SVC_UUID_SIZE+1);
689         SQLITE3_FINALIZE(sql_stmt);
690
691         /*Update folder item validity*/
692         sql = sqlite3_mprintf("UPDATE %s SET validity=%d WHERE folder_uuid='%q'", MEDIA_SVC_DB_TABLE_MEDIA, validity, folder_uuid);
693         err = _media_svc_sql_query(handle, sql, uid);
694         sqlite3_free(sql);
695         if (err != SQLITE_OK) {
696                 media_svc_error("To update folder item as valid is failed(%d)", err);
697                 return MEDIA_INFO_ERROR_DATABASE_INTERNAL;
698         }
699
700         return MEDIA_INFO_ERROR_NONE;
701 }
702
703 int _media_svc_update_recursive_folder_item_validity(sqlite3 *handle, const char *folder_path, int validity, uid_t uid)
704 {
705         int err = -1;
706
707         /*Update folder item validity*/
708         char *sql = sqlite3_mprintf("UPDATE %s SET validity=%d WHERE path LIKE '%q/%%'", MEDIA_SVC_DB_TABLE_MEDIA, validity, folder_path);
709         err = _media_svc_sql_query(handle, sql, uid);
710         sqlite3_free(sql);
711         if (err != SQLITE_OK) {
712                 media_svc_error("To update recursive folder item validity is failed(%d)", err);
713                 return MEDIA_INFO_ERROR_DATABASE_INTERNAL;
714         }
715
716         return MEDIA_INFO_ERROR_NONE;
717 }
718
719 int _media_svc_update_item_by_path(sqlite3 *handle, const char *src_path, media_svc_storage_type_e dest_storage, const char *dest_path,
720                                 const char *file_name, int modified_time, const char *folder_uuid, const char *thumb_path, bool stack_query, uid_t uid)
721 {
722         /* update path, filename, modified_time, folder_uuid, thumbnail_path, */
723         /* played_count, last_played_time, last_played_position, favourite, storaget_type*/
724
725         int err = -1;
726         char *sql = NULL;
727
728         if(thumb_path != NULL) {
729                 sql = sqlite3_mprintf("UPDATE %s SET \
730                                         path=%Q, file_name=%Q, modified_time=%d, folder_uuid=%Q, thumbnail_path=%Q, storage_type=%d, \
731                                         played_count=0, last_played_time=0, last_played_position=0 \
732                                         WHERE path=%Q",
733                                         MEDIA_SVC_DB_TABLE_MEDIA, dest_path, file_name, modified_time, folder_uuid, thumb_path, dest_storage, src_path);
734         } else {
735                 sql = sqlite3_mprintf("UPDATE %s SET \
736                                         path=%Q, file_name=%Q, modified_time=%d, folder_uuid=%Q, storage_type=%d, \
737                                         played_count=0, last_played_time=0, last_played_position=0 \
738                                         WHERE path=%Q",
739                                         MEDIA_SVC_DB_TABLE_MEDIA, dest_path, file_name, modified_time, folder_uuid, dest_storage, src_path);
740         }
741
742         if(!stack_query) {
743                 err = _media_svc_sql_query(handle, sql, uid);
744                 sqlite3_free(sql);
745                 if (err != SQLITE_OK) {
746                         media_svc_error("It failed to update metadata (%d)", err);
747                         return MEDIA_INFO_ERROR_DATABASE_INTERNAL;
748                 }
749         } else {
750                 _media_svc_sql_query_add(&g_media_svc_move_item_query_list, &sql);
751         }
752
753         return MEDIA_INFO_ERROR_NONE;
754 }
755
756 int _media_svc_list_query_do(sqlite3 *handle, media_svc_query_type_e query_type, uid_t uid)
757 {
758         int ret = MEDIA_INFO_ERROR_NONE;
759
760         ret = _media_svc_sql_begin_trans(handle, uid);
761         media_svc_retv_if(ret != MEDIA_INFO_ERROR_NONE, ret);
762
763         if (query_type == MEDIA_SVC_QUERY_SET_ITEM_VALIDITY)
764                 ret = _media_svc_sql_query_list(handle, &g_media_svc_item_validity_query_list,uid);
765         else if (query_type == MEDIA_SVC_QUERY_MOVE_ITEM)
766                 ret = _media_svc_sql_query_list(handle, &g_media_svc_move_item_query_list, uid);
767         else if (query_type == MEDIA_SVC_QUERY_INSERT_ITEM)
768                 ret = _media_svc_sql_query_list(handle, &g_media_svc_insert_item_query_list, uid);
769         else
770                 ret = MEDIA_INFO_ERROR_INVALID_PARAMETER;
771
772         if (ret != MEDIA_INFO_ERROR_NONE) {
773                 media_svc_error("_media_svc_list_query_do failed. start rollback");
774                 _media_svc_sql_rollback_trans(handle,uid);
775                 return ret;
776         }
777
778         ret = _media_svc_sql_end_trans(handle, uid);
779         if (ret != MEDIA_INFO_ERROR_NONE) {
780                 media_svc_error("mb_svc_sqlite3_commit_trans failed.. Now start to rollback\n");
781                 _media_svc_sql_rollback_trans(handle,uid);
782                 return ret;
783         }
784
785         return MEDIA_INFO_ERROR_NONE;
786 }
787
788 int _media_svc_get_media_id_by_path(sqlite3 *handle, const char *path, char *media_uuid, int max_length)
789 {
790         int ret = MEDIA_INFO_ERROR_NONE;
791         sqlite3_stmt *sql_stmt = NULL;
792         char *sql = sqlite3_mprintf("SELECT media_uuid FROM %s WHERE validity=1 AND path='%q'",
793                                         MEDIA_SVC_DB_TABLE_MEDIA, path);
794
795         ret = _media_svc_sql_prepare_to_step(handle, sql, &sql_stmt);
796
797         if (ret != MEDIA_INFO_ERROR_NONE) {
798                 media_svc_error("error when __media_svc_count_invalid_records_with_thumbnail. err = [%d]", ret);
799                 return ret;
800         }
801
802         strncpy(media_uuid, (const char*)sqlite3_column_text(sql_stmt, 0), max_length);
803         media_uuid[max_length - 1] = '\0';
804
805         SQLITE3_FINALIZE(sql_stmt);
806
807         return MEDIA_INFO_ERROR_NONE;
808 }
809
810 int _media_svc_get_burst_id(sqlite3 *handle, int *id)
811 {
812         int ret = MEDIA_INFO_ERROR_NONE;
813         int cur_id = -1;
814         sqlite3_stmt *sql_stmt = NULL;
815         char *sql = sqlite3_mprintf("SELECT max(CAST(burst_id AS INTEGER)) FROM %s", MEDIA_SVC_DB_TABLE_MEDIA);
816
817         ret = _media_svc_sql_prepare_to_step(handle, sql, &sql_stmt);
818
819         if (ret != MEDIA_INFO_ERROR_NONE) {
820                 media_svc_error("error when _media_svc_get_burst_id. err = [%d]", ret);
821                 return ret;
822         }
823
824         cur_id = sqlite3_column_int(sql_stmt, 0);
825         *id = ++cur_id;
826         SQLITE3_FINALIZE(sql_stmt);
827
828         return MEDIA_INFO_ERROR_NONE;
829 }
830
831 int _media_svc_get_noti_info(sqlite3 *handle, const char *path, int update_item, media_svc_noti_item **item)
832 {
833         int ret = MEDIA_INFO_ERROR_NONE;
834         sqlite3_stmt *sql_stmt = NULL;
835         char *sql = NULL;
836         int is_root_dir = FALSE;
837
838         if (item == NULL) {
839                 media_svc_error("_media_svc_get_noti_info failed");
840                 return MEDIA_INFO_ERROR_INVALID_PARAMETER;
841         }
842
843         if (update_item == MS_MEDIA_ITEM_FILE) {
844                 sql = sqlite3_mprintf("SELECT media_uuid, media_type, mime_type FROM %s WHERE path=%Q", MEDIA_SVC_DB_TABLE_MEDIA, path);
845         } else if (update_item == MS_MEDIA_ITEM_DIRECTORY) {
846                 sql = sqlite3_mprintf("SELECT folder_uuid FROM %s WHERE path=%Q", MEDIA_SVC_DB_TABLE_FOLDER, path);
847         } else {
848                 media_svc_error("_media_svc_get_noti_info failed : update item");
849                 return MEDIA_INFO_ERROR_INVALID_PARAMETER;
850         }
851
852         ret = _media_svc_sql_prepare_to_step(handle, sql, &sql_stmt);
853
854         if (ret != MEDIA_INFO_ERROR_NONE) {
855                 if (ret == MEDIA_INFO_ERROR_DATABASE_NO_RECORD && update_item == MS_MEDIA_ITEM_DIRECTORY) {
856                         media_svc_error("This is root directory of media");
857                         sql_stmt = NULL;
858                         is_root_dir = TRUE;
859                 } else {
860                         media_svc_error("error when _media_svc_get_noti_info. err = [%d]", ret);
861                         return ret;
862                 }
863         }
864
865         *item = calloc(1, sizeof(media_svc_noti_item));
866         if (*item == NULL) {
867                 media_svc_error("_media_svc_get_noti_info failed : calloc");
868                 return MEDIA_INFO_ERROR_OUT_OF_MEMORY;
869         }
870
871         if (update_item == MS_MEDIA_ITEM_FILE) {
872                 if (sqlite3_column_text(sql_stmt, 0))
873                         (*item)->media_uuid = strdup((const char *)sqlite3_column_text(sql_stmt, 0));
874
875                 (*item)->media_type = sqlite3_column_int(sql_stmt, 1);
876
877                 if (sqlite3_column_text(sql_stmt, 2))
878                         (*item)->mime_type = strdup((const char *)sqlite3_column_text(sql_stmt, 2));
879         } else if (update_item == MS_MEDIA_ITEM_DIRECTORY) {
880                 if (is_root_dir) {
881                                 (*item)->media_uuid = NULL;
882                 } else {
883                         if (sqlite3_column_text(sql_stmt, 0))
884                                 (*item)->media_uuid = strdup((const char *)sqlite3_column_text(sql_stmt, 0));
885                 }
886         }
887
888         SQLITE3_FINALIZE(sql_stmt);
889
890         return MEDIA_INFO_ERROR_NONE;
891 }
892
893 int _media_svc_count_invalid_folder_items(sqlite3 *handle, const char *folder_path, int *count)
894 {
895         int ret = MEDIA_INFO_ERROR_NONE;
896         sqlite3_stmt *sql_stmt = NULL;
897         char *sql = sqlite3_mprintf("SELECT count(*) FROM %s WHERE validity=0 AND path LIKE '%q/%%'",
898                                         MEDIA_SVC_DB_TABLE_MEDIA, folder_path);
899
900         ret = _media_svc_sql_prepare_to_step(handle, sql, &sql_stmt);
901
902         if (ret != MEDIA_INFO_ERROR_NONE) {
903                 media_svc_error("error when __media_svc_count_invalid_folder_records_with_thumbnail. err = [%d]", ret);
904                 return ret;
905         }
906
907         *count = sqlite3_column_int(sql_stmt, 0);
908
909         SQLITE3_FINALIZE(sql_stmt);
910
911         return MEDIA_INFO_ERROR_NONE;
912 }
913
914 int _media_svc_get_thumbnail_count(sqlite3 *handle, const char *thumb_path, int *count)
915 {
916         int ret = MEDIA_INFO_ERROR_NONE;
917         sqlite3_stmt *sql_stmt = NULL;
918         char *sql = sqlite3_mprintf("SELECT count(*) FROM %s WHERE thumbnail_path=%Q", MEDIA_SVC_DB_TABLE_MEDIA, thumb_path);
919
920         ret = _media_svc_sql_prepare_to_step(handle, sql, &sql_stmt);
921
922         if (ret != MEDIA_INFO_ERROR_NONE) {
923                 media_svc_error("error when _media_svc_get_thumbnail_count. err = [%d]", ret);
924                 return ret;
925         }
926
927         *count = sqlite3_column_int(sql_stmt, 0);
928
929         SQLITE3_FINALIZE(sql_stmt);
930
931         return MEDIA_INFO_ERROR_NONE;
932 }