Change GArray to GPtrArray
[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_check_storage(sqlite3 *handle, const char *storage_id, char **storage_path, int *validity, uid_t uid)
30 {
31         int ret = MS_MEDIA_ERR_NONE;
32         sqlite3_stmt *sql_stmt = NULL;
33         char *sql = NULL;
34
35         media_svc_retvm_if(storage_id == NULL, MS_MEDIA_ERR_INVALID_PARAMETER, "storage_id is NULL");
36         media_svc_retvm_if(storage_path == NULL, MS_MEDIA_ERR_INVALID_PARAMETER, "storage_path is NULL");
37         media_svc_retvm_if(validity == NULL, MS_MEDIA_ERR_INVALID_PARAMETER, "validity is NULL");
38
39         *storage_path = NULL;
40         *validity = 0;
41
42         sql = sqlite3_mprintf("SELECT storage_path, validity FROM '%q' WHERE storage_id=%Q", MEDIA_SVC_DB_TABLE_STORAGE, storage_id);
43         ret = _media_svc_sql_prepare_to_step(handle, sql, &sql_stmt);
44         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
45
46         *storage_path = g_strdup((const char *)sqlite3_column_text(sql_stmt, 0));
47         *validity = sqlite3_column_int(sql_stmt, 1);
48
49         SQLITE3_FINALIZE(sql_stmt);
50
51         /*check storage media table*/
52         if (STRING_VALID(storage_id)) {
53                 int table_cnt = 0;
54
55                 /*Select list of storage*/
56                 sql = sqlite3_mprintf("SELECT COUNT(*) FROM SQLITE_MASTER WHERE type='table' and name='%q'", storage_id);
57                 ret = _media_svc_sql_prepare_to_step(handle, sql, &sql_stmt);
58                 media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
59
60                 table_cnt = sqlite3_column_int(sql_stmt, 0);
61                 SQLITE3_FINALIZE(sql_stmt);
62
63                 if (table_cnt > 0) {
64                         /*DO NOT THING*/
65                 } else {
66                         media_svc_error("media table not exist for storage [%s]", storage_id);
67                         /*make storage media table*/
68                         ret = _media_svc_create_media_table_with_id(storage_id, uid);
69                         media_svc_retvm_if(ret != MS_MEDIA_ERR_NONE, ret, "create media table failed : %d", ret);
70                 }
71         }
72
73         return MS_MEDIA_ERR_NONE;
74 }
75
76 int _media_svc_append_storage(const char *storage_id, const char *storage_path, ms_user_storage_type_e storage_type, uid_t uid)
77 {
78         int ret = MS_MEDIA_ERR_NONE;
79         char *sql = sqlite3_mprintf("INSERT INTO %q (storage_id, storage_path, storage_type) values (%Q, %Q, %d);",
80                                                 MEDIA_SVC_DB_TABLE_STORAGE, storage_id, storage_path, storage_type);
81
82         ret = _media_svc_sql_query_direct(sql, uid);
83         SQLITE3_SAFE_FREE(sql);
84
85         return ret;
86 }
87
88 int _media_svc_update_storage_path(sqlite3 *handle, const char *storage_id, const char *path, uid_t uid)
89 {
90         int ret = MS_MEDIA_ERR_NONE;
91         char *sql = NULL;
92         char *old_storage_path = NULL;
93         int validity = 0;
94
95         media_svc_retvm_if(storage_id == NULL, MS_MEDIA_ERR_INVALID_PARAMETER, "storage_id is NULL");
96         media_svc_retvm_if(path == NULL, MS_MEDIA_ERR_INVALID_PARAMETER, "path is NULL");
97
98         /*Get old path*/
99         ret = _media_svc_check_storage(handle, storage_id, &old_storage_path, &validity, uid);
100         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
101
102         /*Storage table update*/
103         sql = sqlite3_mprintf("UPDATE '%q' SET storage_path=%Q WHERE storage_id=%Q;", MEDIA_SVC_DB_TABLE_STORAGE, path, storage_id);
104         ret = _media_svc_sql_query_direct(sql, uid);
105         SQLITE3_SAFE_FREE(sql);
106         if (ret != MS_MEDIA_ERR_NONE) {
107                 g_free(old_storage_path);
108                 return ret;
109         }
110
111         /*Folder table update*/
112         sql = sqlite3_mprintf("UPDATE '%q' SET folder_path=REPLACE(folder_path, %Q, %Q) WHERE storage_uuid=%Q;", MEDIA_SVC_DB_TABLE_FOLDER, old_storage_path, path, storage_id);
113         ret = _media_svc_sql_query_direct(sql, uid);
114         SQLITE3_SAFE_FREE(sql);
115         if (ret != MS_MEDIA_ERR_NONE) {
116                 g_free(old_storage_path);
117                 return ret;
118         }
119
120         /*Media table update*/
121         sql = sqlite3_mprintf("UPDATE '%q' SET media_path=REPLACE(media_path, %Q, %Q);", storage_id, old_storage_path, path);
122         ret = _media_svc_sql_query_direct(sql, uid);
123         SQLITE3_SAFE_FREE(sql);
124         g_free(old_storage_path);
125         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
126
127         return ret;
128 }
129
130 int __media_svc_delete_thumbnail(sqlite3 *handle, const char *storage_id)
131 {
132         int ret = MS_MEDIA_ERR_NONE;
133         char *sql = NULL;
134         sqlite3_stmt *sql_stmt = NULL;
135
136         sql = sqlite3_mprintf("SELECT media_thumbnail_path FROM '%q' WHERE media_thumbnail_path is not null;", storage_id);
137         ret = _media_svc_sql_prepare_to_step_simple(handle, sql, &sql_stmt);
138         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
139
140         while (sqlite3_step(sql_stmt) == SQLITE_ROW)
141                 _media_svc_remove_file((const char *)sqlite3_column_text(sql_stmt, 0));
142
143         SQLITE3_FINALIZE(sql_stmt);
144
145         return ret;
146 }
147
148 int _media_svc_delete_invalid_storage(sqlite3 *handle, uid_t uid)
149 {
150         int ret = MS_MEDIA_ERR_NONE;
151         char *sql = NULL;
152         char *storage_id = NULL;
153         sqlite3_stmt *sql_stmt = NULL;
154         GPtrArray *storage_list = NULL;
155         int i = 0;
156
157         sql = sqlite3_mprintf("SELECT storage_id FROM '%q' WHERE validity=0;", MEDIA_SVC_DB_TABLE_STORAGE);
158         ret = _media_svc_sql_prepare_to_step_simple(handle, sql, &sql_stmt);
159         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
160
161         storage_list = g_ptr_array_new_with_free_func(g_free);
162
163         while (sqlite3_step(sql_stmt) == SQLITE_ROW) {
164                 storage_id = g_strdup((const char *)sqlite3_column_text(sql_stmt, 0));
165                 if (storage_id != NULL)
166                         g_ptr_array_add(storage_list, storage_id);
167         }
168
169         SQLITE3_FINALIZE(sql_stmt);
170
171         for (i = 0; i < storage_list->len; i++) {
172                 storage_id = g_ptr_array_index(storage_list, i);
173
174                 ret = __media_svc_delete_thumbnail(handle, storage_id);
175                 if (ret != MS_MEDIA_ERR_NONE)
176                         media_svc_error("Fail to remove thumbnail");
177
178                 /* remove media before drop table (for clear playlist, and tag table)*/
179                 sql = sqlite3_mprintf("DELETE FROM '%q';DROP TABLE '%q';", storage_id, storage_id);
180                 ret = _media_svc_sql_query_direct(sql, uid);
181                 SQLITE3_SAFE_FREE(sql);
182                 if (ret != MS_MEDIA_ERR_NONE)
183                         media_svc_error("Fail to drop table[%s]", storage_id);
184         }
185
186         /* Update storage, folder table */
187         sql = sqlite3_mprintf("DELETE FROM %q WHERE validity=0;DELETE FROM %q WHERE validity=0;", MEDIA_SVC_DB_TABLE_STORAGE, MEDIA_SVC_DB_TABLE_FOLDER);
188         ret = _media_svc_sql_query_direct(sql, uid);
189         SQLITE3_SAFE_FREE(sql);
190         if (ret != MS_MEDIA_ERR_NONE)
191                 media_svc_error("Fail to update storage table");
192
193         g_ptr_array_free(storage_list, TRUE);
194
195         return ret;
196 }
197
198 int _media_svc_update_storage_validity(const char *storage_id, int validity, uid_t uid)
199 {
200         int ret = MS_MEDIA_ERR_NONE;
201         char *sql = NULL;
202
203         if (storage_id == NULL)
204                 sql = sqlite3_mprintf("UPDATE '%q' SET validity=%d;", MEDIA_SVC_DB_TABLE_STORAGE, validity);
205         else
206                 sql = sqlite3_mprintf("UPDATE '%q' SET validity=%d WHERE storage_id=%Q;", MEDIA_SVC_DB_TABLE_STORAGE, validity, storage_id);
207
208         ret = _media_svc_sql_query_direct(sql, uid);
209         SQLITE3_SAFE_FREE(sql);
210
211         return ret;
212 }
213
214 int _media_svc_get_storage_uuid(sqlite3 *handle, const char *path, char *storage_id, uid_t uid)
215 {
216         int ret = MS_MEDIA_ERR_NONE;
217         sqlite3_stmt *sql_stmt = NULL;
218         char *sql = NULL;
219         char *storage_path = NULL;
220         char *remain_path = NULL;
221         int remain_len = 0;
222         char *internal_path = NULL;
223
224         media_svc_retvm_if(path == NULL, MS_MEDIA_ERR_INVALID_PARAMETER, "path is NULL");
225
226         ret = ms_user_get_internal_root_path(uid, &internal_path);
227         media_svc_retvm_if(ret != MS_MEDIA_ERR_NONE, ret, "Fail to get root path");
228
229         if (STRING_VALID(internal_path) && strncmp(path, internal_path, strlen(internal_path)) == 0) {
230                 SAFE_STRLCPY(storage_id, MEDIA_SVC_DB_TABLE_MEDIA, MEDIA_SVC_UUID_SIZE+1);
231                 SAFE_FREE(internal_path);
232                 return MS_MEDIA_ERR_NONE;
233         }
234
235         SAFE_FREE(internal_path);
236
237         remain_path = strstr(path + (STRING_VALID(MEDIA_ROOT_PATH_USB) ? strlen(MEDIA_ROOT_PATH_USB) : 0) + 1, "/");
238         if (remain_path != NULL)
239                 remain_len = strlen(remain_path);
240
241         storage_path = strndup(path, strlen(path) - remain_len);
242
243         sql = sqlite3_mprintf("SELECT storage_id FROM '%q' WHERE validity=1 AND storage_path = '%q'", MEDIA_SVC_DB_TABLE_STORAGE, storage_path);
244
245         ret = _media_svc_sql_prepare_to_step(handle, sql, &sql_stmt);
246         SAFE_FREE(storage_path);
247         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
248
249         if (STRING_VALID((const char *)sqlite3_column_text(sql_stmt, 0)))
250                 SAFE_STRLCPY(storage_id, (const char *)sqlite3_column_text(sql_stmt, 0), MEDIA_SVC_UUID_SIZE+1);
251
252         SQLITE3_FINALIZE(sql_stmt);
253
254         if (!STRING_VALID(storage_id)) {
255                 media_svc_error("Not found valid storage id [%s]", path);
256                 ret = MS_MEDIA_ERR_INVALID_PARAMETER;
257         }
258
259         return ret;
260 }
261
262 int _media_svc_get_storage_path(sqlite3 *handle, GPtrArray **storage_path)
263 {
264         int ret = MS_MEDIA_ERR_NONE;
265         sqlite3_stmt *sql_stmt = NULL;
266         char *sql = NULL;
267         char *root_path = NULL;
268
269         media_svc_retvm_if(!storage_path, MS_MEDIA_ERR_INVALID_PARAMETER, "storage_path is NULL");
270
271         sql = sqlite3_mprintf("SELECT storage_path FROM %q WHERE validity=1", MEDIA_SVC_DB_TABLE_STORAGE);
272
273         ret = _media_svc_sql_prepare_to_step_simple(handle, sql, &sql_stmt);
274         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
275
276         while (sqlite3_step(sql_stmt) == SQLITE_ROW) {
277                 root_path = g_strdup((const char *)sqlite3_column_text(sql_stmt, 0));
278                 g_ptr_array_add(*storage_path, root_path);
279         }
280
281         SQLITE3_FINALIZE(sql_stmt);
282
283         return ret;
284 }
285