fbfd0abdfb9b262db70b55b2565826064133e95a
[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-util-err.h>
26 #include "media-svc-media.h"
27 #include "media-svc-media-folder.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 = MS_MEDIA_ERR_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 != MS_MEDIA_ERR_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 MS_MEDIA_ERR_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 ret = MS_MEDIA_ERR_NONE;
76         sqlite3_stmt *sql_stmt = NULL;
77         int idx = 0;
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         ret = sqlite3_prepare_v2(handle, sql, -1, &sql_stmt, NULL);
85         sqlite3_free(sql);
86         if (ret != SQLITE_OK) {
87                 media_svc_error("prepare error [%s]", sqlite3_errmsg(handle));
88                 return MS_MEDIA_ERR_DB_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 MS_MEDIA_ERR_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 = MS_MEDIA_ERR_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 != MS_MEDIA_ERR_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 MS_MEDIA_ERR_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 ret = MS_MEDIA_ERR_NONE;
128         sqlite3_stmt *sql_stmt = NULL;
129         int idx = 0;
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         ret = sqlite3_prepare_v2(handle, sql, -1, &sql_stmt, NULL);
137         sqlite3_free(sql);
138         if (ret != MS_MEDIA_ERR_NONE) {
139                 media_svc_error("prepare error [%s]", sqlite3_errmsg(handle));
140                 return ret;
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 MS_MEDIA_ERR_NONE;
151 }
152
153 int _media_svc_count_record_with_path(sqlite3 *handle, const char *path, int *count)
154 {
155         int ret = MS_MEDIA_ERR_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 != MS_MEDIA_ERR_NONE, ret);
163
164         *count = sqlite3_column_int(sql_stmt, 0);
165
166         SQLITE3_FINALIZE(sql_stmt);
167
168         return MS_MEDIA_ERR_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 ret = MS_MEDIA_ERR_NONE;
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, bitpersample, 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                 ret = _media_svc_get_burst_id(handle, &burst_id_int);
227                 if (ret != MS_MEDIA_ERR_NONE) {
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                 ret = thumbnail_request_from_db_with_size(content_info->path, thumb_path, sizeof(thumb_path), &width, &height, uid);
242                 if (ret != MS_MEDIA_ERR_NONE) {
243                         media_svc_error("thumbnail_request_from_db failed: %d", ret);
244                 } else {
245                         media_svc_debug("thumbnail_request_from_db success: %s", thumb_path);
246                         ret = __media_svc_malloc_and_strncpy(&(content_info->thumbnail_path), thumb_path);
247                         if (ret != MS_MEDIA_ERR_NONE) {
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, %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.bitpersample,
312                 content_info->media_meta.samplerate,
313                 content_info->media_meta.channel,
314                 content_info->media_meta.duration,
315                 content_info->media_meta.longitude,
316                 content_info->media_meta.latitude,
317                 content_info->media_meta.altitude,
318                 content_info->media_meta.width,
319                 content_info->media_meta.height,
320                 content_info->media_meta.datetaken,
321                 content_info->media_meta.orientation,
322                 content_info->media_meta.rating,
323                 content_info->is_drm,
324                 content_info->storage_type,
325                 burst_id,
326                 content_info->timeline,
327                 content_info->media_meta.weather,
328                 content_info->sync_status,
329                 content_info->file_name_pinyin,
330                 content_info->media_meta.title_pinyin,
331                 content_info->media_meta.album_pinyin,
332                 content_info->media_meta.artist_pinyin,
333                 content_info->media_meta.album_artist_pinyin,
334                 content_info->media_meta.genre_pinyin,
335                 content_info->media_meta.composer_pinyin,
336                 content_info->media_meta.copyright_pinyin,
337                 content_info->media_meta.description_pinyin
338                 );
339
340         if (burst_id) sqlite3_free(burst_id);
341         burst_id = NULL;
342
343         if(!stack_query) {
344                 ret = _media_svc_sql_query(handle, sql, uid);
345                 sqlite3_free(sql);
346                 if (ret != MS_MEDIA_ERR_NONE) {
347                         media_svc_error("failed to insert item");
348                         return ret;
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 MS_MEDIA_ERR_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 ret = MS_MEDIA_ERR_NONE;
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, bitpersample=%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.bitpersample,
411                 content_info->media_meta.samplerate,
412                 content_info->media_meta.channel,
413                 content_info->media_meta.duration,
414                 content_info->media_meta.longitude,
415                 content_info->media_meta.latitude,
416                 content_info->media_meta.altitude,
417                 content_info->media_meta.width,
418                 content_info->media_meta.height,
419                 content_info->media_meta.datetaken,
420                 content_info->media_meta.orientation,
421                 content_info->path
422                 );
423
424         ret = _media_svc_sql_query(handle, sql, uid);
425         sqlite3_free(sql);
426
427         return ret;
428 }
429 int _media_svc_get_thumbnail_path_by_path(sqlite3 *handle, const char *path, char *thumbnail_path)
430 {
431         int ret = MS_MEDIA_ERR_NONE;
432         sqlite3_stmt *sql_stmt = NULL;
433
434         char *sql = sqlite3_mprintf("SELECT thumbnail_path FROM %s WHERE path='%q'", MEDIA_SVC_DB_TABLE_MEDIA, path);
435
436         ret = _media_svc_sql_prepare_to_step(handle, sql, &sql_stmt);
437
438         if (ret != MS_MEDIA_ERR_NONE) {
439                 if(ret == MS_MEDIA_ERR_DB_NO_RECORD) {
440                         media_svc_debug("there is no thumbnail.");
441                 }
442                 else {
443                         media_svc_error("error when _media_svc_get_thumbnail_path_by_path. err = [%d]", ret);
444                 }
445                 return ret;
446         }
447
448         _strncpy_safe(thumbnail_path, (const char *)sqlite3_column_text(sql_stmt, 0), MEDIA_SVC_PATHNAME_SIZE);
449
450         SQLITE3_FINALIZE(sql_stmt);
451
452         return MS_MEDIA_ERR_NONE;
453 }
454
455 int _media_svc_get_media_type_by_path(sqlite3 *handle, const char *path, int *media_type)
456 {
457         int ret = MS_MEDIA_ERR_NONE;
458         sqlite3_stmt *sql_stmt = NULL;
459
460         char *sql = sqlite3_mprintf("SELECT media_type FROM %s WHERE path='%q'", MEDIA_SVC_DB_TABLE_MEDIA, path);
461
462         ret = _media_svc_sql_prepare_to_step(handle, sql, &sql_stmt);
463
464         if (ret != MS_MEDIA_ERR_NONE) {
465                 media_svc_error("error when _media_svc_get_media_type_by_path. err = [%d]", ret);
466                 return ret;
467         }
468
469         *media_type = sqlite3_column_int(sql_stmt, 0);
470
471         SQLITE3_FINALIZE(sql_stmt);
472
473         return MS_MEDIA_ERR_NONE;
474 }
475
476 int _media_svc_delete_item_by_path(sqlite3 *handle, const char *path, uid_t uid)
477 {
478         int ret = MS_MEDIA_ERR_NONE;
479         char *sql = sqlite3_mprintf("DELETE FROM %s WHERE validity=1 AND path='%q'", MEDIA_SVC_DB_TABLE_MEDIA, path);
480
481         ret = _media_svc_sql_query(handle, sql, uid);
482         sqlite3_free(sql);
483         if (ret != MS_MEDIA_ERR_NONE) {
484                 media_svc_error("failed to delete item");
485                 return ret;
486         }
487
488         return ret;
489 }
490
491 int _media_svc_truncate_table(sqlite3 *handle, media_svc_storage_type_e storage_type, uid_t uid)
492 {
493         int ret = MS_MEDIA_ERR_NONE;
494         char *sql = sqlite3_mprintf("DELETE FROM %s WHERE storage_type=%d", MEDIA_SVC_DB_TABLE_MEDIA, storage_type);
495
496         ret = _media_svc_sql_query(handle, sql, uid);
497         sqlite3_free(sql);
498
499         return ret;
500 }
501
502 int _media_svc_delete_invalid_items(sqlite3 *handle, media_svc_storage_type_e storage_type, uid_t uid)
503 {
504         int idx = 0;
505         media_svc_thumbnailpath_s *thumbpath_record = NULL;
506         int invalid_count = 0;
507         int ret = MS_MEDIA_ERR_NONE;
508
509         ret = __media_svc_count_invalid_records_with_thumbnail(handle, storage_type, &invalid_count);
510         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
511
512         media_svc_debug("invalid count: %d\n", invalid_count);
513
514         if (invalid_count > 0) {
515                 thumbpath_record = (media_svc_thumbnailpath_s *)calloc( invalid_count, sizeof(media_svc_thumbnailpath_s));
516                 if (thumbpath_record == NULL) {
517                         media_svc_error("fail to memory allocation");
518                         return MS_MEDIA_ERR_OUT_OF_MEMORY;
519                 }
520
521                 ret = __media_svc_get_invalid_records_with_thumbnail(handle, storage_type, invalid_count, thumbpath_record);
522                 if (ret != MS_MEDIA_ERR_NONE) {
523                         media_svc_error("error when get thumbnail record");
524                         SAFE_FREE(thumbpath_record);
525                         return ret;
526                 }
527         } else {
528                 media_svc_debug("There is no item with thumbnail");
529         }
530
531         char *sql = sqlite3_mprintf("DELETE FROM %s WHERE validity = 0 AND storage_type=%d", MEDIA_SVC_DB_TABLE_MEDIA, storage_type);
532         ret = _media_svc_sql_query(handle, sql, uid);
533         sqlite3_free(sql);
534         if(ret != MS_MEDIA_ERR_NONE) {
535                 SAFE_FREE(thumbpath_record);
536                 return ret;
537         }
538
539         /*Delete thumbnails*/
540         for (idx = 0; idx < invalid_count; idx++) {
541                 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)) {
542                         if (_media_svc_remove_file(thumbpath_record[idx].thumbnail_path) == FALSE) {
543                                 media_svc_error("fail to remove thumbnail file.");
544                         }
545                 }
546         }
547
548         SAFE_FREE(thumbpath_record);
549
550         return MS_MEDIA_ERR_NONE;
551 }
552
553 int _media_svc_delete_invalid_folder_items(sqlite3 *handle, const char *folder_path, uid_t uid)
554 {
555         int idx = 0;
556         media_svc_thumbnailpath_s *thumbpath_record = NULL;
557         int invalid_count = 0;
558         int ret = MS_MEDIA_ERR_NONE;
559
560         ret = __media_svc_count_invalid_folder_records_with_thumbnail(handle, folder_path, &invalid_count);
561         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
562
563         media_svc_debug("invalid count: %d", invalid_count);
564
565         if (invalid_count > 0) {
566                 thumbpath_record = (media_svc_thumbnailpath_s *)calloc( invalid_count, sizeof(media_svc_thumbnailpath_s));
567                 if (thumbpath_record == NULL) {
568                         media_svc_error("fail to memory allocation");
569                         return MS_MEDIA_ERR_OUT_OF_MEMORY;
570                 }
571
572                 ret = __media_svc_get_invalid_folder_records_with_thumbnail(handle, folder_path, invalid_count, thumbpath_record);
573                 if (ret != MS_MEDIA_ERR_NONE) {
574                         media_svc_error("error when get thumbnail record");
575                         SAFE_FREE(thumbpath_record);
576                         return ret;
577                 }
578         } else {
579                 media_svc_debug("There is no item with thumbnail");
580         }
581
582         char *sql = sqlite3_mprintf("DELETE FROM %s WHERE validity = 0 AND path LIKE '%q/%%'", MEDIA_SVC_DB_TABLE_MEDIA, folder_path);
583         ret = _media_svc_sql_query(handle, sql, uid);
584         sqlite3_free(sql);
585         if(ret != MS_MEDIA_ERR_NONE) {
586                 SAFE_FREE(thumbpath_record);
587                 return ret;
588         }
589
590         /*Delete thumbnails*/
591         for (idx = 0; idx < invalid_count; idx++) {
592                 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)) {
593                         if (_media_svc_remove_file(thumbpath_record[idx].thumbnail_path) == FALSE) {
594                                 media_svc_error("fail to remove thumbnail file [%s].", thumbpath_record[idx].thumbnail_path);
595                         }
596                 }
597         }
598
599         SAFE_FREE(thumbpath_record);
600
601         return MS_MEDIA_ERR_NONE;
602 }
603
604 int _media_svc_update_item_validity(sqlite3 *handle, const char *path, int validity, bool stack_query, uid_t uid)
605 {
606         int ret = MS_MEDIA_ERR_NONE;
607
608         char *sql = sqlite3_mprintf("UPDATE %s SET validity=%d WHERE path= '%q'", MEDIA_SVC_DB_TABLE_MEDIA, validity, path);
609
610         if(!stack_query) {
611                 ret = _media_svc_sql_query(handle, sql, uid);
612                 sqlite3_free(sql);
613         } else {
614                 _media_svc_sql_query_add(&g_media_svc_item_validity_query_list, &sql);
615         }
616
617         return ret;
618 }
619
620 int _media_svc_update_thumbnail_path(sqlite3 *handle, const char *path, const char *thumb_path, uid_t uid)
621 {
622         int ret = MS_MEDIA_ERR_NONE;
623
624         char *sql = sqlite3_mprintf("UPDATE %s SET thumbnail_path=%Q WHERE path= %Q", MEDIA_SVC_DB_TABLE_MEDIA, thumb_path, path);
625
626         ret = _media_svc_sql_query(handle, sql, uid);
627         sqlite3_free(sql);
628
629         return ret;
630 }
631
632 int _media_svc_update_storage_item_validity(sqlite3 *handle, media_svc_storage_type_e storage_type, int validity, uid_t uid)
633 {
634         int ret = MS_MEDIA_ERR_NONE;
635
636         char *sql = sqlite3_mprintf("UPDATE %s SET validity=%d WHERE storage_type=%d", MEDIA_SVC_DB_TABLE_MEDIA, validity, storage_type);
637
638         ret = _media_svc_sql_query(handle, sql, uid);
639         sqlite3_free(sql);
640
641         return ret;
642 }
643
644 int _media_svc_update_folder_item_validity(sqlite3 *handle, const char *folder_path, int validity, uid_t uid)
645 {
646         int ret = MS_MEDIA_ERR_NONE;
647         char *sql = NULL;
648         char folder_uuid[MEDIA_SVC_UUID_SIZE + 1] = {0, };
649         sqlite3_stmt *sql_stmt = NULL;
650
651         /*Get folder ID*/
652         sql = sqlite3_mprintf("SELECT folder_uuid FROM %s WHERE path='%q'", MEDIA_SVC_DB_TABLE_FOLDER, folder_path);
653         ret = _media_svc_sql_prepare_to_step(handle, sql, &sql_stmt);
654         if (ret != MS_MEDIA_ERR_NONE) {
655                 media_svc_error("error when get folder_id. err = [%d]", ret);
656                 return ret;
657         }
658
659         _strncpy_safe(folder_uuid, (const char *)sqlite3_column_text(sql_stmt, 0), MEDIA_SVC_UUID_SIZE+1);
660         SQLITE3_FINALIZE(sql_stmt);
661
662         /*Update folder item validity*/
663         sql = sqlite3_mprintf("UPDATE %s SET validity=%d WHERE folder_uuid='%q'", MEDIA_SVC_DB_TABLE_MEDIA, validity, folder_uuid);
664         ret = _media_svc_sql_query(handle, sql, uid);
665         sqlite3_free(sql);
666
667         return ret;
668 }
669
670 int _media_svc_update_recursive_folder_item_validity(sqlite3 *handle, const char *folder_path, int validity, uid_t uid)
671 {
672         int ret = MS_MEDIA_ERR_NONE;
673
674         /*Update folder item validity*/
675         char *sql = sqlite3_mprintf("UPDATE %s SET validity=%d WHERE path LIKE '%q/%%'", MEDIA_SVC_DB_TABLE_MEDIA, validity, folder_path);
676         ret = _media_svc_sql_query(handle, sql, uid);
677         sqlite3_free(sql);
678
679         return ret;
680 }
681
682 int _media_svc_update_item_by_path(sqlite3 *handle, const char *src_path, media_svc_storage_type_e dest_storage, const char *dest_path,
683                                 const char *file_name, int modified_time, const char *folder_uuid, const char *thumb_path, bool stack_query, uid_t uid)
684 {
685         /* update path, filename, modified_time, folder_uuid, thumbnail_path, */
686         /* played_count, last_played_time, last_played_position, favourite, storaget_type*/
687
688         int ret = MS_MEDIA_ERR_NONE;
689         char *sql = NULL;
690
691         if(thumb_path != NULL) {
692                 sql = sqlite3_mprintf("UPDATE %s SET \
693                                         path=%Q, file_name=%Q, modified_time=%d, folder_uuid=%Q, thumbnail_path=%Q, storage_type=%d, \
694                                         played_count=0, last_played_time=0, last_played_position=0 \
695                                         WHERE path=%Q",
696                                         MEDIA_SVC_DB_TABLE_MEDIA, dest_path, file_name, modified_time, folder_uuid, thumb_path, dest_storage, src_path);
697         } else {
698                 sql = sqlite3_mprintf("UPDATE %s SET \
699                                         path=%Q, file_name=%Q, modified_time=%d, folder_uuid=%Q, storage_type=%d, \
700                                         played_count=0, last_played_time=0, last_played_position=0 \
701                                         WHERE path=%Q",
702                                         MEDIA_SVC_DB_TABLE_MEDIA, dest_path, file_name, modified_time, folder_uuid, dest_storage, src_path);
703         }
704
705         if(!stack_query) {
706                 ret = _media_svc_sql_query(handle, sql, uid);
707                 sqlite3_free(sql);
708         } else {
709                 _media_svc_sql_query_add(&g_media_svc_move_item_query_list, &sql);
710         }
711
712         return ret;
713 }
714
715 int _media_svc_list_query_do(sqlite3 *handle, media_svc_query_type_e query_type, uid_t uid)
716 {
717         int ret = MS_MEDIA_ERR_NONE;
718
719         ret = _media_svc_sql_begin_trans(handle, uid);
720         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
721
722         if (query_type == MEDIA_SVC_QUERY_SET_ITEM_VALIDITY)
723                 ret = _media_svc_sql_query_list(handle, &g_media_svc_item_validity_query_list,uid);
724         else if (query_type == MEDIA_SVC_QUERY_MOVE_ITEM)
725                 ret = _media_svc_sql_query_list(handle, &g_media_svc_move_item_query_list, uid);
726         else if (query_type == MEDIA_SVC_QUERY_INSERT_ITEM)
727                 ret = _media_svc_sql_query_list(handle, &g_media_svc_insert_item_query_list, uid);
728         else
729                 ret = MS_MEDIA_ERR_INVALID_PARAMETER;
730
731         if (ret != MS_MEDIA_ERR_NONE) {
732                 media_svc_error("_media_svc_list_query_do failed. start rollback");
733                 _media_svc_sql_rollback_trans(handle,uid);
734                 return ret;
735         }
736
737         ret = _media_svc_sql_end_trans(handle, uid);
738         if (ret != MS_MEDIA_ERR_NONE) {
739                 media_svc_error("mb_svc_sqlite3_commit_trans failed.. Now start to rollback\n");
740                 _media_svc_sql_rollback_trans(handle,uid);
741                 return ret;
742         }
743
744         return MS_MEDIA_ERR_NONE;
745 }
746
747 int _media_svc_get_media_id_by_path(sqlite3 *handle, const char *path, char *media_uuid, int max_length)
748 {
749         int ret = MS_MEDIA_ERR_NONE;
750         sqlite3_stmt *sql_stmt = NULL;
751         char *sql = sqlite3_mprintf("SELECT media_uuid FROM %s WHERE validity=1 AND path='%q'",
752                                         MEDIA_SVC_DB_TABLE_MEDIA, path);
753
754         ret = _media_svc_sql_prepare_to_step(handle, sql, &sql_stmt);
755
756         if (ret != MS_MEDIA_ERR_NONE) {
757                 media_svc_error("error when __media_svc_count_invalid_records_with_thumbnail. err = [%d]", ret);
758                 return ret;
759         }
760
761         strncpy(media_uuid, (const char*)sqlite3_column_text(sql_stmt, 0), max_length);
762         media_uuid[max_length - 1] = '\0';
763
764         SQLITE3_FINALIZE(sql_stmt);
765
766         return MS_MEDIA_ERR_NONE;
767 }
768
769 int _media_svc_get_burst_id(sqlite3 *handle, int *id)
770 {
771         int ret = MS_MEDIA_ERR_NONE;
772         int cur_id = -1;
773         sqlite3_stmt *sql_stmt = NULL;
774         char *sql = sqlite3_mprintf("SELECT max(CAST(burst_id AS INTEGER)) FROM %s", MEDIA_SVC_DB_TABLE_MEDIA);
775
776         ret = _media_svc_sql_prepare_to_step(handle, sql, &sql_stmt);
777
778         if (ret != MS_MEDIA_ERR_NONE) {
779                 media_svc_error("error when _media_svc_get_burst_id. err = [%d]", ret);
780                 return ret;
781         }
782
783         cur_id = sqlite3_column_int(sql_stmt, 0);
784         *id = ++cur_id;
785         SQLITE3_FINALIZE(sql_stmt);
786
787         return MS_MEDIA_ERR_NONE;
788 }
789
790 int _media_svc_get_noti_info(sqlite3 *handle, const char *path, int update_item, media_svc_noti_item **item)
791 {
792         int ret = MS_MEDIA_ERR_NONE;
793         sqlite3_stmt *sql_stmt = NULL;
794         char *sql = NULL;
795         int is_root_dir = FALSE;
796
797         if (item == NULL) {
798                 media_svc_error("_media_svc_get_noti_info failed");
799                 return MS_MEDIA_ERR_INVALID_PARAMETER;
800         }
801
802         if (update_item == MS_MEDIA_ITEM_FILE) {
803                 sql = sqlite3_mprintf("SELECT media_uuid, media_type, mime_type FROM %s WHERE path=%Q", MEDIA_SVC_DB_TABLE_MEDIA, path);
804         } else if (update_item == MS_MEDIA_ITEM_DIRECTORY) {
805                 sql = sqlite3_mprintf("SELECT folder_uuid FROM %s WHERE path=%Q", MEDIA_SVC_DB_TABLE_FOLDER, path);
806         } else {
807                 media_svc_error("_media_svc_get_noti_info failed : update item");
808                 return MS_MEDIA_ERR_INVALID_PARAMETER;
809         }
810
811         ret = _media_svc_sql_prepare_to_step(handle, sql, &sql_stmt);
812
813         if (ret != MS_MEDIA_ERR_NONE) {
814                 if (ret == MS_MEDIA_ERR_DB_NO_RECORD && update_item == MS_MEDIA_ITEM_DIRECTORY) {
815                         media_svc_debug("This is root directory of media");
816                         sql_stmt = NULL;
817                         is_root_dir = TRUE;
818                 } else {
819                         media_svc_error("error when _media_svc_get_noti_info. err = [%d]", ret);
820                         return ret;
821                 }
822         }
823
824         *item = calloc(1, sizeof(media_svc_noti_item));
825         if (*item == NULL) {
826                 media_svc_error("_media_svc_get_noti_info failed : calloc");
827                 return MS_MEDIA_ERR_OUT_OF_MEMORY;
828         }
829
830         if (update_item == MS_MEDIA_ITEM_FILE) {
831                 if (sqlite3_column_text(sql_stmt, 0))
832                         (*item)->media_uuid = strdup((const char *)sqlite3_column_text(sql_stmt, 0));
833
834                 (*item)->media_type = sqlite3_column_int(sql_stmt, 1);
835
836                 if (sqlite3_column_text(sql_stmt, 2))
837                         (*item)->mime_type = strdup((const char *)sqlite3_column_text(sql_stmt, 2));
838         } else if (update_item == MS_MEDIA_ITEM_DIRECTORY) {
839                 if (is_root_dir) {
840                                 (*item)->media_uuid = NULL;
841                 } else {
842                         if (sqlite3_column_text(sql_stmt, 0))
843                                 (*item)->media_uuid = strdup((const char *)sqlite3_column_text(sql_stmt, 0));
844                 }
845         }
846
847         SQLITE3_FINALIZE(sql_stmt);
848
849         return MS_MEDIA_ERR_NONE;
850 }
851
852 int _media_svc_count_invalid_folder_items(sqlite3 *handle, const char *folder_path, int *count)
853 {
854         int ret = MS_MEDIA_ERR_NONE;
855         sqlite3_stmt *sql_stmt = NULL;
856         char *sql = sqlite3_mprintf("SELECT count(*) FROM %s WHERE validity=0 AND path LIKE '%q/%%'",
857                                         MEDIA_SVC_DB_TABLE_MEDIA, folder_path);
858
859         ret = _media_svc_sql_prepare_to_step(handle, sql, &sql_stmt);
860
861         if (ret != MS_MEDIA_ERR_NONE) {
862                 media_svc_error("error when __media_svc_count_invalid_folder_records_with_thumbnail. err = [%d]", ret);
863                 return ret;
864         }
865
866         *count = sqlite3_column_int(sql_stmt, 0);
867
868         SQLITE3_FINALIZE(sql_stmt);
869
870         return MS_MEDIA_ERR_NONE;
871 }
872
873 int _media_svc_get_thumbnail_count(sqlite3 *handle, const char *thumb_path, int *count)
874 {
875         int ret = MS_MEDIA_ERR_NONE;
876         sqlite3_stmt *sql_stmt = NULL;
877         char *sql = sqlite3_mprintf("SELECT count(*) FROM %s WHERE thumbnail_path=%Q", MEDIA_SVC_DB_TABLE_MEDIA, thumb_path);
878
879         ret = _media_svc_sql_prepare_to_step(handle, sql, &sql_stmt);
880
881         if (ret != MS_MEDIA_ERR_NONE) {
882                 media_svc_error("error when _media_svc_get_thumbnail_count. err = [%d]", ret);
883                 return ret;
884         }
885
886         *count = sqlite3_column_int(sql_stmt, 0);
887
888         SQLITE3_FINALIZE(sql_stmt);
889
890         return MS_MEDIA_ERR_NONE;
891 }