Update for modification of db utilities.
[platform/core/multimedia/libmedia-service.git] / src / common / media-svc-media-folder.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 <glib/gstdio.h>
23 #include <media-util-err.h>
24 #include "media-svc-media-folder.h"
25 #include "media-svc-debug.h"
26 #include "media-svc-env.h"
27 #include "media-svc-util.h"
28 #include "media-svc-db-utils.h"
29
30 extern __thread GList *g_media_svc_move_item_query_list;
31
32 int _media_svc_get_folder_id_by_foldername(sqlite3 *handle, const char *storage_id, const char *folder_name, char *folder_id)
33 {
34         int ret = MS_MEDIA_ERR_NONE;
35         sqlite3_stmt *sql_stmt = NULL;
36         char *sql = NULL;
37
38         if(STRING_VALID(storage_id))
39                 sql = sqlite3_mprintf("SELECT folder_uuid FROM '%s' WHERE storage_uuid = '%q' AND path = '%q';", MEDIA_SVC_DB_TABLE_FOLDER, storage_id, folder_name);
40         else
41                 sql = sqlite3_mprintf("SELECT folder_uuid FROM '%s' WHERE path = '%q';", MEDIA_SVC_DB_TABLE_FOLDER, folder_name);
42
43         ret = _media_svc_sql_prepare_to_step(handle, sql, &sql_stmt);
44
45         if (ret != MS_MEDIA_ERR_NONE) {
46                 if(ret == MS_MEDIA_ERR_DB_NO_RECORD) {
47                         media_svc_debug("there is no folder.");
48                 }
49                 else {
50                         media_svc_error("error when _media_svc_get_folder_id_by_foldername. err = [%d]", ret);
51                 }
52                 return ret;
53         }
54
55         _strncpy_safe(folder_id, (const char *)sqlite3_column_text(sql_stmt, 0), MEDIA_SVC_UUID_SIZE+1);
56
57         SQLITE3_FINALIZE(sql_stmt);
58
59         return ret;
60 }
61
62 int _media_svc_append_folder(sqlite3 *handle, const char *storage_id, media_svc_storage_type_e storage_type,
63                                     const char *folder_id, const char *path_name, const char *folder_name, int modified_date, const char *parent_folder_uuid, uid_t uid)
64 {
65         int ret = MS_MEDIA_ERR_NONE;
66
67         /*Update Pinyin If Support Pinyin*/
68         char *folder_name_pinyin = NULL;
69         if(_media_svc_check_pinyin_support())
70                 _media_svc_get_pinyin_str(folder_name, &folder_name_pinyin);
71
72         char *sql = sqlite3_mprintf("INSERT INTO %s (folder_uuid, path, name, storage_uuid, storage_type, modified_time, name_pinyin, parent_folder_uuid) \
73                                                         values (%Q, %Q, %Q, %Q, '%d', '%d', %Q, %Q); ",
74                                                      MEDIA_SVC_DB_TABLE_FOLDER, folder_id, path_name, folder_name, storage_id, storage_type, modified_date, folder_name_pinyin, parent_folder_uuid);
75         ret = _media_svc_sql_query(handle, sql, uid);
76         sqlite3_free(sql);
77
78         SAFE_FREE(folder_name_pinyin);
79
80         return ret;
81 }
82
83 int _media_svc_update_folder_modified_time_by_folder_uuid(sqlite3 *handle, const char *folder_uuid, const char *folder_path, bool stack_query, uid_t uid)
84 {
85         int ret = MS_MEDIA_ERR_NONE;
86         int modified_time = 0;
87
88         modified_time = _media_svc_get_file_time(folder_path);
89
90         char *sql = sqlite3_mprintf("UPDATE %s SET modified_time=%d WHERE folder_uuid=%Q;", MEDIA_SVC_DB_TABLE_FOLDER, modified_time, folder_uuid);
91
92         if(!stack_query) {
93                 ret = _media_svc_sql_query(handle, sql, uid);
94                 sqlite3_free(sql);
95         } else {
96                 _media_svc_sql_query_add(&g_media_svc_move_item_query_list, &sql);
97         }
98
99         return ret;
100 }
101
102 int __media_svc_get_and_append_parent_folder(sqlite3 *handle, const char *storage_id, const char *path, media_svc_storage_type_e storage_type, char *folder_id, uid_t uid)
103 {
104         int ret = MS_MEDIA_ERR_NONE;
105         unsigned int next_pos;
106         char *next = NULL;
107         char *dir_path = NULL;
108         char *token = "/";
109         char *folder_uuid = NULL;
110         char *folder_name = NULL;
111         int folder_modified_date = 0;
112         char parent_folder_uuid[MEDIA_SVC_UUID_SIZE+1] = {0,};
113         bool folder_search_end = FALSE;
114
115         memset(parent_folder_uuid, 0, sizeof(parent_folder_uuid));
116
117         if(strncmp(path, _media_svc_get_path(uid), strlen(_media_svc_get_path(uid))) == 0)
118                 next_pos = strlen(_media_svc_get_path(uid));
119         else if (strncmp(path, MEDIA_ROOT_PATH_SDCARD, strlen(MEDIA_ROOT_PATH_SDCARD)) == 0)
120                 next_pos = strlen(MEDIA_ROOT_PATH_SDCARD);
121         else
122         {
123                 media_svc_error("Invalid Path");
124                 return MS_MEDIA_ERR_INTERNAL;
125         }
126
127         while (!folder_search_end)
128         {
129                 next = strstr(path + next_pos , token);
130                 if (next != NULL)
131                 {
132                         next_pos = (next - path);
133                         dir_path = strndup(path, next_pos);
134                         next_pos++;
135                 }
136                 else
137                 {
138                         media_svc_error("End Path");
139                         dir_path = strndup(path, strlen(path));
140                         folder_search_end = TRUE;
141                 }
142
143                 ret = _media_svc_get_folder_id_by_foldername(handle, storage_id, dir_path, parent_folder_uuid);
144                 if (ret == MS_MEDIA_ERR_DB_NO_RECORD)
145                 {
146                         media_svc_error("NOT EXIST dir path : %s", dir_path);
147
148                         folder_uuid = _media_info_generate_uuid();
149                         if(folder_uuid == NULL )
150                         {
151                         media_svc_error("Invalid UUID");
152                                 SAFE_FREE(dir_path);
153                         return MS_MEDIA_ERR_INTERNAL;
154                 }
155
156                         folder_name = g_path_get_basename(dir_path);
157                         folder_modified_date = _media_svc_get_file_time(dir_path);
158
159                         ret = _media_svc_append_folder(handle, storage_id, storage_type, folder_uuid, dir_path, folder_name, folder_modified_date, parent_folder_uuid, uid);
160                 if (ret != MS_MEDIA_ERR_NONE) {
161                         media_svc_error("_media_svc_append_folder is failed");
162                 }
163
164                         _strncpy_safe(parent_folder_uuid, folder_uuid, MEDIA_SVC_UUID_SIZE+1);
165
166                 SAFE_FREE(folder_name);
167                 }
168                 else
169                 {
170                         media_svc_error("EXIST dir path : %s\n", dir_path);
171                 }
172
173                 SAFE_FREE(dir_path);
174         }
175
176                 _strncpy_safe(folder_id, folder_uuid, MEDIA_SVC_UUID_SIZE+1);
177
178         return MS_MEDIA_ERR_NONE;
179 }
180
181 int _media_svc_get_and_append_folder(sqlite3 *handle, const char *storage_id, const char *path, media_svc_storage_type_e storage_type, char *folder_id, uid_t uid)
182 {
183         int ret = MS_MEDIA_ERR_NONE;
184
185         ret = _media_svc_get_folder_id_by_foldername(handle, storage_id, path, folder_id);
186
187         if(ret == MS_MEDIA_ERR_DB_NO_RECORD)
188         {
189                 ret = __media_svc_get_and_append_parent_folder(handle, storage_id, path, storage_type, folder_id, uid);
190         }
191
192         return ret;
193 }
194
195 int _media_svc_get_and_append_folder_id_by_path(sqlite3 *handle, const char *storage_id, const char *path, media_svc_storage_type_e storage_type, char *folder_id, uid_t uid)
196 {
197         char *path_name = NULL;
198         int ret = MS_MEDIA_ERR_NONE;
199
200         path_name = g_path_get_dirname(path);
201
202         ret =  _media_svc_get_and_append_folder(handle, storage_id, path_name, storage_type, folder_id, uid);
203
204         SAFE_FREE(path_name);
205
206         return ret;
207 }
208
209 int _media_svc_update_folder_table(sqlite3 *handle, uid_t uid)
210 {
211         int ret = MS_MEDIA_ERR_NONE;
212         char *sql = NULL;
213
214         sql = sqlite3_mprintf("DELETE FROM %s WHERE folder_uuid IN (SELECT folder_uuid FROM %s WHERE folder_uuid NOT IN (SELECT folder_uuid FROM %s))",
215              MEDIA_SVC_DB_TABLE_FOLDER, MEDIA_SVC_DB_TABLE_FOLDER, MEDIA_SVC_DB_TABLE_MEDIA);
216
217         ret = _media_svc_sql_query(handle, sql, uid);
218         sqlite3_free(sql);
219
220         return ret;
221 }
222
223 static int __media_svc_count_all_folders(sqlite3 *handle, char* start_path, int *count)
224 {
225         int ret = MS_MEDIA_ERR_NONE;
226         sqlite3_stmt *sql_stmt = NULL;
227         char *sql = sqlite3_mprintf("SELECT count(*) FROM %s WHERE path LIKE '%q%%'", MEDIA_SVC_DB_TABLE_FOLDER, start_path);
228
229         ret = _media_svc_sql_prepare_to_step(handle, sql, &sql_stmt);
230         if (ret != MS_MEDIA_ERR_NONE) {
231                 media_svc_error("error when _media_svc_sql_prepare_to_step. err = [%d]", ret);
232                 return ret;
233         }
234
235         *count = sqlite3_column_int(sql_stmt, 0);
236
237         SQLITE3_FINALIZE(sql_stmt);
238
239         return MS_MEDIA_ERR_NONE;
240 }
241
242 int _media_svc_get_all_folders(sqlite3 *handle, char *start_path, char ***folder_list, time_t **modified_time_list, int **item_num_list, int *count)
243 {
244         int ret = MS_MEDIA_ERR_NONE;
245         int idx = 0;
246         sqlite3_stmt *sql_stmt = NULL;
247         char *sql = NULL;
248         int cnt =0;
249         char **folder_uuid = NULL;
250         int i =0;
251
252         ret  = __media_svc_count_all_folders(handle, start_path, &cnt);
253         if (ret != MS_MEDIA_ERR_NONE) {
254                 media_svc_error("error when __media_svc_count_all_folders. err = [%d]", ret);
255                 return ret;
256         }
257
258         if (cnt > 0) {
259                 sql = sqlite3_mprintf("SELECT path, modified_time, folder_uuid FROM %s WHERE path LIKE '%q%%'", MEDIA_SVC_DB_TABLE_FOLDER, start_path);
260         } else {
261                 *folder_list = NULL;
262                 *modified_time_list = NULL;
263                 *item_num_list = NULL;
264                 return MS_MEDIA_ERR_NONE;
265         }
266
267         *folder_list = malloc(sizeof(char *) * cnt);
268         *modified_time_list = malloc(sizeof(int) * cnt);
269         *item_num_list = malloc(sizeof(int) * cnt);
270         folder_uuid = malloc(sizeof(char *) * cnt);
271
272         if((*folder_list == NULL) || (*modified_time_list == NULL) || (*item_num_list == NULL) ||(folder_uuid == NULL)) {
273                 media_svc_error("Out of memory");
274                 goto ERROR;
275         }
276         memset(folder_uuid, 0x0, sizeof(char *) * cnt);
277
278         ret = _media_svc_sql_prepare_to_step(handle, sql, &sql_stmt);
279         if (ret != MS_MEDIA_ERR_NONE) {
280                 media_svc_error("prepare error [%s]", sqlite3_errmsg(handle));
281                 goto ERROR;
282         }
283
284         media_svc_debug("QEURY OK");
285
286         while (1) {
287                 if(STRING_VALID((char *)sqlite3_column_text(sql_stmt, 0)))
288                         (*folder_list)[idx] = strdup((char *)sqlite3_column_text(sql_stmt, 0));
289
290                 (*modified_time_list)[idx] = (int)sqlite3_column_int(sql_stmt, 1);
291
292                 /* get the folder's id */
293                 if(STRING_VALID((char *)sqlite3_column_text(sql_stmt, 2)))
294                         folder_uuid[idx] = strdup((char *)sqlite3_column_text(sql_stmt, 2));
295
296                 idx++;
297
298                 if(sqlite3_step(sql_stmt) != SQLITE_ROW)
299                         break;
300         }
301         SQLITE3_FINALIZE(sql_stmt);
302
303         /*get the numbder of item in the folder by using folder's id */
304         for (i = 0; i < idx; i ++) {
305                 if(STRING_VALID(folder_uuid[i])) {
306                         sql = sqlite3_mprintf("SELECT COUNT(*) FROM %s WHERE (folder_uuid='%q' AND validity = 1)", MEDIA_SVC_DB_TABLE_MEDIA, folder_uuid[i]);
307                         ret = _media_svc_sql_prepare_to_step(handle, sql, &sql_stmt);
308                         if (ret != MS_MEDIA_ERR_NONE) {
309                                 media_svc_error("prepare error [%s]", sqlite3_errmsg(handle));
310                                 goto ERROR;
311                         }
312
313                         (*item_num_list)[i] = (int)sqlite3_column_int(sql_stmt, 0);
314
315                         SQLITE3_FINALIZE(sql_stmt);
316                 } else
317                 {
318                         media_svc_error("Invalid Folder Id");
319                 }
320         }
321
322         if (cnt == idx) {
323                 *count = cnt;
324                 media_svc_debug("Get Folder is OK");
325         } else {
326                 media_svc_error("Fail to get folder");
327                 ret = MS_MEDIA_ERR_INTERNAL;
328                 goto ERROR;
329         }
330
331         /* free all data */
332         for (i  = 0; i < idx; i ++) {
333                 SAFE_FREE(folder_uuid[i]);
334         }
335         SAFE_FREE(folder_uuid);
336
337         return ret;
338
339 ERROR:
340
341         /* free all data */
342         for (i  = 0; i < idx; i ++) {
343                 SAFE_FREE((*folder_list)[i]);
344                 SAFE_FREE(folder_uuid[i]);
345         }
346         SAFE_FREE(*folder_list);
347         SAFE_FREE(*modified_time_list);
348         SAFE_FREE(*item_num_list);
349         SAFE_FREE(folder_uuid);
350
351         *count = 0;
352
353         return ret;
354 }
355
356 int _media_svc_get_folder_info_by_foldername(sqlite3 *handle, const char *folder_name, char *folder_id, time_t *modified_time)
357 {
358         int ret = MS_MEDIA_ERR_NONE;
359         sqlite3_stmt *sql_stmt = NULL;
360
361         char *sql = sqlite3_mprintf("SELECT folder_uuid, modified_time FROM %s WHERE path = '%q';", MEDIA_SVC_DB_TABLE_FOLDER, folder_name);
362
363         ret = _media_svc_sql_prepare_to_step(handle, sql, &sql_stmt);
364
365         if (ret != MS_MEDIA_ERR_NONE) {
366                 if(ret == MS_MEDIA_ERR_DB_NO_RECORD) {
367                         media_svc_debug("there is no folder.");
368                 }
369                 else {
370                         media_svc_error("error when _media_svc_get_folder_id_by_foldername. err = [%d]", ret);
371                 }
372                 return ret;
373         }
374
375         _strncpy_safe(folder_id, (const char *)sqlite3_column_text(sql_stmt, 0), MEDIA_SVC_UUID_SIZE+1);
376         *modified_time = (int)sqlite3_column_int(sql_stmt, 1);
377
378         SQLITE3_FINALIZE(sql_stmt);
379
380         return ret;
381 }