replace strdup to g_strdup because g_strdup check input param NULL
[platform/core/multimedia/libmedia-service.git] / src / common / media-svc-storage.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 "media-util-err.h"
23 #include "media-svc-debug.h"
24 #include "media-svc-env.h"
25 #include "media-svc-db-utils.h"
26 #include "media-svc-util.h"
27 #include "media-svc-storage.h"
28
29 int _media_svc_init_storage(sqlite3 *handle, uid_t uid)
30 {
31         int ret = MS_MEDIA_ERR_NONE;
32         char *sql = NULL;
33         sqlite3_stmt *sql_stmt = NULL;
34         int storage_cnt = 0;
35
36         /*Add Internal storage*/
37         sql = sqlite3_mprintf("SELECT COUNT(*) FROM '%s' WHERE storage_uuid='%s' AND storage_name='%s'", MEDIA_SVC_DB_TABLE_STORAGE, MEDIA_SVC_DB_TABLE_MEDIA, MEDIA_SVC_DB_TABLE_MEDIA);
38         ret = _media_svc_sql_prepare_to_step(handle, sql, &sql_stmt);
39         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
40
41         storage_cnt = sqlite3_column_int(sql_stmt, 0);
42         SQLITE3_FINALIZE(sql_stmt);
43
44         if (storage_cnt == 0) {
45                 sql = sqlite3_mprintf("INSERT INTO %s (storage_uuid, storage_name, storage_path, storage_type) VALUES ('%s', '%s', '%s', 0);",
46                                       MEDIA_SVC_DB_TABLE_STORAGE, MEDIA_SVC_DB_TABLE_MEDIA, MEDIA_SVC_DB_TABLE_MEDIA, _media_svc_get_path(uid));
47
48                 ret = _media_svc_sql_query(handle, sql, uid);
49                 sqlite3_free(sql);
50                 media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
51         }
52
53         return ret;
54 }
55
56 int _media_svc_get_mmc_info(MediaSvcHandle *handle, char **storage_name, char **storage_path, int *validity, bool *info_exist)
57 {
58         int ret = MS_MEDIA_ERR_NONE;
59         sqlite3_stmt *sql_stmt = NULL;
60         char *sql = NULL;
61
62         sql = sqlite3_mprintf("SELECT * FROM '%s' WHERE storage_uuid=%Q AND storage_name IS NOT '%s'", MEDIA_SVC_DB_TABLE_STORAGE, MEDIA_SVC_DB_TABLE_MEDIA, MEDIA_SVC_DB_TABLE_MEDIA);
63
64         ret = _media_svc_sql_prepare_to_step(handle, sql, &sql_stmt);
65         if (ret != MS_MEDIA_ERR_NONE) {
66                 *storage_name = NULL;
67                 *storage_path = NULL;
68                 *validity = 0;
69                 *info_exist = FALSE;
70
71                 if (ret == MS_MEDIA_ERR_DB_NO_RECORD) {
72                         *info_exist = FALSE;
73                 }
74
75                 return ret;
76         }
77
78         *storage_name = g_strdup((const char *)sqlite3_column_text(sql_stmt, 1));
79         *storage_path = g_strdup((const char *)sqlite3_column_text(sql_stmt, 2));
80         *validity = sqlite3_column_int(sql_stmt, 6);
81
82         *info_exist = TRUE;
83
84         SQLITE3_FINALIZE(sql_stmt);
85
86         return MS_MEDIA_ERR_NONE;
87 }
88
89 int _media_svc_check_storage(sqlite3 *handle, const char *storage_id, const char *storage_name, char **storage_path, int *validity)
90 {
91         int ret = MS_MEDIA_ERR_NONE;
92         sqlite3_stmt *sql_stmt = NULL;
93         char *sql = NULL;
94
95         *storage_path = NULL;
96         *validity = 0;
97
98         if(storage_name != NULL)
99                 sql = sqlite3_mprintf("SELECT * FROM '%s' WHERE storage_uuid=%Q AND storage_name=%Q", MEDIA_SVC_DB_TABLE_STORAGE, storage_id, storage_name);
100         else
101                 sql = sqlite3_mprintf("SELECT * FROM '%s' WHERE storage_uuid=%Q", MEDIA_SVC_DB_TABLE_STORAGE, storage_id);
102
103         ret = _media_svc_sql_prepare_to_step(handle, sql, &sql_stmt);
104
105         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
106
107         *storage_path = g_strdup((const char *)sqlite3_column_text(sql_stmt, 2));
108         *validity = sqlite3_column_int(sql_stmt, 6);
109
110         SQLITE3_FINALIZE(sql_stmt);
111
112         return MS_MEDIA_ERR_NONE;
113 }
114
115 int _media_svc_append_storage(sqlite3 *handle, const char *storage_id, const char *storage_name, const char *storage_path, const char *storage_account, media_svc_storage_type_e storage_type, uid_t uid)
116 {
117         int ret = MS_MEDIA_ERR_NONE;
118         char *sql = sqlite3_mprintf("INSERT INTO %s (storage_uuid, storage_name, storage_path, storage_account, storage_type) values (%Q, %Q, %Q, %Q, %d); ",
119                                     MEDIA_SVC_DB_TABLE_STORAGE, storage_id, storage_name, storage_path, storage_account, storage_type);
120
121         ret = _media_svc_sql_query(handle, sql, uid);
122         sqlite3_free(sql);
123
124         return ret;
125 }
126
127 int _media_svc_update_storage_path(sqlite3 *handle, const char *storage_id, const char *path, uid_t uid)
128 {
129         int ret = MS_MEDIA_ERR_NONE;
130         char *sql = NULL;
131         char *old_storage_path = NULL;
132         int validity = 0;
133
134         /*Get old path*/
135         ret = _media_svc_check_storage(handle, storage_id, NULL, &old_storage_path, &validity);
136         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
137
138         /*Storage table update*/
139         sql = sqlite3_mprintf("UPDATE '%s' SET storage_path=%Q WHERE storage_uuid=%Q", MEDIA_SVC_DB_TABLE_STORAGE, path, storage_id);
140         ret = _media_svc_sql_query(handle, sql, uid);
141         sqlite3_free(sql);
142         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
143
144         /*Folder table update*/
145         sql = sqlite3_mprintf("UPDATE '%s' SET path=REPLACE(path, %Q, %Q) WHERE storage_uuid=%Q", MEDIA_SVC_DB_TABLE_FOLDER, old_storage_path, path, storage_id);
146         ret = _media_svc_sql_query(handle, sql, uid);
147         sqlite3_free(sql);
148         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
149
150         /*Media table update*/
151         sql = sqlite3_mprintf("UPDATE '%s' SET path=REPLACE(path, %Q, %Q)", storage_id, old_storage_path, path);
152         ret = _media_svc_sql_query(handle, sql, uid);
153         sqlite3_free(sql);
154         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
155
156         return ret;
157 }
158
159 int _media_svc_delete_storage(sqlite3 *handle, const char *storage_id, const char *storage_name, uid_t uid)
160 {
161         int ret = MS_MEDIA_ERR_NONE;
162         char *sql = NULL;
163
164         if (storage_name != NULL)
165                         sql = sqlite3_mprintf("DELETE FROM '%s' WHERE storage_uuid=%Q AND storage_name=%Q", MEDIA_SVC_DB_TABLE_STORAGE, storage_id, storage_name);
166         else if (storage_id != NULL)
167                 sql = sqlite3_mprintf("DELETE FROM '%s' WHERE storage_uuid=%Q", MEDIA_SVC_DB_TABLE_STORAGE, storage_id);
168
169         ret = _media_svc_sql_query(handle, sql, uid);
170         sqlite3_free(sql);
171
172         return ret;
173 }
174
175 int _media_svc_update_storage_validity(sqlite3 *handle, const char *storage_id, int validity, uid_t uid)
176 {
177         int ret = MS_MEDIA_ERR_NONE;
178         char *sql = NULL;
179
180         if (storage_id == NULL) {
181                 sql = sqlite3_mprintf("UPDATE '%s' SET validity=%d WHERE storage_uuid != 'media' AND storage_type != %d", MEDIA_SVC_DB_TABLE_STORAGE, validity, MEDIA_SVC_STORAGE_CLOUD);
182         } else {
183                 sql = sqlite3_mprintf("UPDATE '%s' SET validity=%d WHERE storage_uuid=%Q;", MEDIA_SVC_DB_TABLE_STORAGE, validity, storage_id);
184         }
185
186         ret = _media_svc_sql_query(handle, sql, uid);
187         sqlite3_free(sql);
188
189         return ret;
190 }
191
192 int _media_svc_get_storage_uuid(sqlite3 *handle, const char *path, char *storage_id)
193 {
194         int ret = MS_MEDIA_ERR_NONE;
195         sqlite3_stmt *sql_stmt = NULL;
196         char *sql = NULL;
197         char *storage_path = NULL;
198         char *remain_path = NULL;
199         int remain_len = 0;
200
201         if(strncmp(path, MEDIA_ROOT_PATH_INTERNAL, strlen(MEDIA_ROOT_PATH_INTERNAL)) == 0)
202         {
203                 _strncpy_safe(storage_id, MEDIA_SVC_DB_TABLE_MEDIA, MEDIA_SVC_UUID_SIZE+1);
204                 return MS_MEDIA_ERR_NONE;
205         }
206
207         sql = sqlite3_mprintf("SELECT storage_uuid, storage_path FROM '%s' WHERE validity=1", MEDIA_SVC_DB_TABLE_STORAGE);
208
209         ret = _media_svc_sql_prepare_to_step_simple(handle, sql, &sql_stmt);
210
211         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
212
213         remain_path = strstr(path+strlen(MEDIA_ROOT_PATH_USB) +1, "/");
214         if (remain_path != NULL)
215                 remain_len = strlen(remain_path);
216
217         storage_path = strndup(path, strlen(path) - remain_len);
218
219         while(sqlite3_step(sql_stmt) == SQLITE_ROW)
220         {
221                 if(STRING_VALID((const char *)sqlite3_column_text(sql_stmt, 1)))
222                 {
223                         if (strlen(storage_path)  == strlen((const char *)sqlite3_column_text(sql_stmt, 1)))
224                         {
225                                 if(strncmp(storage_path, (const char *)sqlite3_column_text(sql_stmt, 1), strlen(storage_path)) == 0)
226                                 {
227                                         _strncpy_safe(storage_id, (const char *)sqlite3_column_text(sql_stmt, 0), MEDIA_SVC_UUID_SIZE+1);
228                                         break;
229                                 }
230                         }
231                 }
232
233         }
234
235         SQLITE3_FINALIZE(sql_stmt);
236         SAFE_FREE(storage_path);
237
238         if(!STRING_VALID(storage_id))
239         {
240                 media_svc_error("Not found valid storage id [%s]", path);
241                 ret = MS_MEDIA_ERR_INVALID_PARAMETER;
242         }
243
244         return ret;
245 }
246
247 int _media_svc_get_storage_type(sqlite3 *handle, const char *storage_id, media_svc_storage_type_e *storage_type)
248 {
249         int ret = MS_MEDIA_ERR_NONE;
250         sqlite3_stmt *sql_stmt = NULL;
251         char *sql = NULL;
252
253         if(!STRING_VALID(storage_id))
254         {
255                 media_svc_error("Invalid storage_idid");
256                 ret = MS_MEDIA_ERR_INVALID_PARAMETER;
257         }
258
259         sql = sqlite3_mprintf("SELECT storage_type FROM '%s' WHERE (storage_uuid=%Q AND validity=1)", MEDIA_SVC_DB_TABLE_STORAGE, storage_id);
260
261         ret = _media_svc_sql_prepare_to_step(handle, sql, &sql_stmt);
262
263         if (ret != MS_MEDIA_ERR_NONE) {
264                 if(ret == MS_MEDIA_ERR_DB_NO_RECORD) {
265                         media_svc_debug("there is no storage.");
266                 }
267                 else {
268                         media_svc_error("error when _media_svc_get_storage_type. err = [%d]", ret);
269                 }
270                 return ret;
271         }
272
273         *storage_type = sqlite3_column_int(sql_stmt, 0);
274
275         SQLITE3_FINALIZE(sql_stmt);
276
277         return ret;
278 }
279
280 int _media_svc_get_storage_path(sqlite3 *handle, const char *storage_id, char **storage_path)
281 {
282         int ret = MS_MEDIA_ERR_NONE;
283         sqlite3_stmt *sql_stmt = NULL;
284         char *sql = NULL;
285
286         if(!STRING_VALID(storage_id))
287         {
288                 media_svc_error("Invalid storage_idid");
289                 ret = MS_MEDIA_ERR_INVALID_PARAMETER;
290         }
291
292         sql = sqlite3_mprintf("SELECT storage_path FROM '%s' WHERE (storage_uuid=%Q AND validity=1)", MEDIA_SVC_DB_TABLE_STORAGE, storage_id);
293
294         ret = _media_svc_sql_prepare_to_step(handle, sql, &sql_stmt);
295
296         if (ret != MS_MEDIA_ERR_NONE) {
297                 if(ret == MS_MEDIA_ERR_DB_NO_RECORD) {
298                         media_svc_debug("there is no storage.");
299                 }
300                 else {
301                         media_svc_error("error when _media_svc_get_storage_type. err = [%d]", ret);
302                 }
303                 return ret;
304         }
305
306         *storage_path = g_strdup((char *)sqlite3_column_text(sql_stmt, 0));
307
308         SQLITE3_FINALIZE(sql_stmt);
309
310         return ret;
311 }
312
313 int _media_svc_get_storage_scan_status(sqlite3 *handle, const char *storage_id, media_svc_scan_status_type_e *scan_status)
314 {
315         int ret = MS_MEDIA_ERR_NONE;
316         sqlite3_stmt *sql_stmt = NULL;
317         char *sql = NULL;
318
319         if(!STRING_VALID(storage_id))
320         {
321                 media_svc_error("Invalid storage_id");
322                 return MS_MEDIA_ERR_INVALID_PARAMETER;
323         }
324
325         sql = sqlite3_mprintf("SELECT scan_status FROM '%s' WHERE (storage_uuid=%Q AND validity=1)", MEDIA_SVC_DB_TABLE_STORAGE, storage_id);
326
327         ret = _media_svc_sql_prepare_to_step(handle, sql, &sql_stmt);
328
329         if (ret != MS_MEDIA_ERR_NONE) {
330                 if(ret == MS_MEDIA_ERR_DB_NO_RECORD) {
331                         media_svc_debug("there is no storage.");
332                 }
333                 else {
334                         media_svc_error("error when _media_svc_get_storage_scan_status. err = [%d]", ret);
335                 }
336                 return ret;
337         }
338
339         *scan_status = sqlite3_column_int(sql_stmt, 0);
340
341         SQLITE3_FINALIZE(sql_stmt);
342
343         return ret;
344 }
345
346 int _media_svc_set_storage_scan_status(sqlite3 *handle, const char *storage_id, media_svc_scan_status_type_e scan_status, uid_t uid)
347 {
348         int ret = MS_MEDIA_ERR_NONE;
349         char *sql = NULL;
350
351         if (storage_id == NULL) {
352                 sql = sqlite3_mprintf("UPDATE '%s' SET scan_status=%d WHERE storage_uuid != 'media'", MEDIA_SVC_DB_TABLE_STORAGE, scan_status);
353         } else {
354                 sql = sqlite3_mprintf("UPDATE '%s' SET scan_status=%d WHERE storage_uuid=%Q", MEDIA_SVC_DB_TABLE_STORAGE, scan_status, storage_id);
355         }
356
357         ret = _media_svc_sql_query(handle, sql, uid);
358         sqlite3_free(sql);
359
360         return ret;
361 }
362
363 static int __media_svc_count_all_storage(sqlite3 *handle, int *count)
364 {
365         int ret = MS_MEDIA_ERR_NONE;
366         sqlite3_stmt *sql_stmt = NULL;
367         char *sql = sqlite3_mprintf("SELECT count(*) FROM '%s' WHERE validity = 1", MEDIA_SVC_DB_TABLE_STORAGE);
368
369         ret = _media_svc_sql_prepare_to_step(handle, sql, &sql_stmt);
370         if (ret != MS_MEDIA_ERR_NONE) {
371                 media_svc_error("error when _media_svc_sql_prepare_to_step. err = [%d]", ret);
372                 return ret;
373         }
374
375         *count = sqlite3_column_int(sql_stmt, 0);
376
377         SQLITE3_FINALIZE(sql_stmt);
378
379         return MS_MEDIA_ERR_NONE;
380 }
381
382 int _media_svc_get_all_storage(sqlite3 *handle, char ***storage_list, char ***storage_id_list, int **scan_status_list, int *count)
383 {
384         int ret = MS_MEDIA_ERR_NONE;
385         int idx = 0;
386         sqlite3_stmt *sql_stmt = NULL;
387         char *sql = NULL;
388         int cnt =0;
389
390         ret  = __media_svc_count_all_storage(handle, &cnt);
391         if (ret != MS_MEDIA_ERR_NONE) {
392                 media_svc_error("error when __media_svc_count_all_folders. err = [%d]", ret);
393                 return ret;
394         }
395
396         if (cnt > 0) {
397                 sql = sqlite3_mprintf("SELECT storage_path, storage_uuid, scan_status FROM '%s' WHERE validity = 1", MEDIA_SVC_DB_TABLE_STORAGE);
398         } else {
399                 *storage_list = NULL;
400                 *scan_status_list = NULL;
401                 return MS_MEDIA_ERR_NONE;
402         }
403
404         *storage_list = malloc(sizeof(char *) * cnt);
405         *storage_id_list = malloc(sizeof(char *) * cnt);
406         *scan_status_list = malloc(sizeof(int) * cnt);
407
408         ret = _media_svc_sql_prepare_to_step(handle, sql, &sql_stmt);
409         if (ret != MS_MEDIA_ERR_NONE) {
410                 media_svc_error("prepare error [%s]", sqlite3_errmsg(handle));
411                 SAFE_FREE(*storage_list);
412                 SAFE_FREE(*scan_status_list);
413                 return ret;
414         }
415
416         media_svc_debug("QEURY OK");
417
418         while (1) {
419                 (*storage_list)[idx] = g_strdup((char *)sqlite3_column_text(sql_stmt, 0));
420                 (*storage_id_list)[idx] = g_strdup((char *)sqlite3_column_text(sql_stmt, 1));
421                 (*scan_status_list)[idx] = (int)sqlite3_column_int(sql_stmt, 2);
422                 if(sqlite3_step(sql_stmt) != SQLITE_ROW)
423                         break;
424                 idx++;
425         }
426
427         if (cnt == idx + 1) {
428                 *count = cnt;
429                 media_svc_debug("OK");
430         } else {
431                 /* free all data */
432                 int i =0;
433                 for (i  = 0; i < idx; i ++) {
434                         SAFE_FREE((*storage_list)[i]);
435                         SAFE_FREE((*storage_id_list)[i]);
436                 }
437                 SAFE_FREE(*storage_list);
438                 SAFE_FREE(*storage_id_list);
439                 SAFE_FREE(*scan_status_list);
440                 *count = 0;
441                 ret = MS_MEDIA_ERR_INTERNAL;
442         }
443
444         SQLITE3_FINALIZE(sql_stmt);
445
446         return ret;
447 }