4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
23 #include <unicode/utypes.h>
24 #include <unicode/ucol.h>
25 #include <unicode/uiter.h>
26 #include <unicode/ustring.h>
29 #include "media-util-dbg.h"
30 #include "media-util-ipc.h"
31 #include "media-util-db.h"
32 #include "media-util-err.h"
33 #include "media-util-user.h"
35 #include "media-util-socket-activation.h"
38 static int __media_db_busy_handler(void *pData, int count)
42 MSAPI_DBG("media_db_busy_handler called : %d", count);
47 /* The collating function must return an integer that is negative, zero or positive */
48 static int __media_db_collate_icu_8(void *ucol, int str1_len, const void *str1, int str2_len, const void *str2)
50 UCharIterator uiter1, uiter2;
51 UErrorCode error = U_ZERO_ERROR;
53 uiter_setUTF8(&uiter1, (const char *) str1, str1_len);
54 uiter_setUTF8(&uiter2, (const char *) str2, str2_len);
56 UCollationResult result = ucol_strcollIter((UCollator *) ucol, &uiter1, &uiter2, &error);
57 if (U_FAILURE(error)) {
58 MSAPI_DBG_ERR("ucol_strcollIter error: %d", error);
65 static void __media_db_collation_cb(void* pArg, sqlite3* handle, int charset, const char* name)
67 int ret = MS_MEDIA_ERR_NONE;
68 UErrorCode status = U_ZERO_ERROR;
69 const char* locale = NULL;
71 UCollator* ucol = NULL;
73 if (!handle || !name || strlen(name) == 0) {
74 MSAPI_DBG_ERR("Input parameter is NULL");
78 if (charset == SQLITE_UTF8 && !sqlite3_stricmp(name, "localized")) {
79 lang = vconf_get_str(VCONFKEY_LANGSET);
80 /* get current locale */
82 uloc_setDefault(lang, &status);
85 MSAPI_DBG_ERR("Fail to get current language vconf");
88 locale = uloc_getDefault();
90 MSAPI_DBG_ERR("Fail to get current locale");
93 MSAPI_DBG_INFO("locale : %s", locale);
95 ucol = ucol_open(locale, &status);
96 if (status == U_USING_DEFAULT_WARNING) {
97 MSAPI_DBG("ucol_open success with default collate option");
98 } else if (U_FAILURE(status)) {
99 MSAPI_DBG_ERR("ucol_open fail : %d", status);
103 ucol_setStrength(ucol, UCOL_SECONDARY); /* NOTICE : MCD sets UCOL_PRIMARY */
104 if (U_FAILURE(status)) {
105 MSAPI_DBG_ERR("ucol_setStrength fail : %d", status);
109 ret = sqlite3_create_collation_v2(handle, name, SQLITE_UTF8, ucol, __media_db_collate_icu_8, (void *)ucol_close);
110 if (ret != SQLITE_OK) {
111 MSAPI_DBG_ERR("sqlite3_create_collation_v2 fail : %d", ret);
114 MSAPI_DBG("sqlite3_create_collation_v2 success");
117 MSAPI_DBG_ERR("No matching collator for %s", name);
121 static int __media_db_connect_db_with_handle(sqlite3 **db_handle, uid_t uid, bool need_write)
124 char *db_path = NULL;
126 MSAPI_DBG_ERR("need_write[%d]", need_write);
127 ret = ms_user_get_media_db_path(uid, &db_path);
128 MSAPI_RETVM_IF(ret != MS_MEDIA_ERR_NONE, ret, "ms_user_get_media_db_path failed");
129 MSAPI_RETVM_IF(!db_path, MS_MEDIA_ERR_DB_INTERNAL, "db_path is NULL");
133 ret = sqlite3_open_v2(db_path, db_handle, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL);
135 ret = sqlite3_open_v2(db_path, db_handle, SQLITE_OPEN_READONLY, NULL);
137 if (SQLITE_OK != ret) {
138 MSAPI_DBG_ERR("error when db open path[%s],ret[%d]", db_path, ret);
141 return MS_MEDIA_ERR_DB_INTERNAL;
145 if (*db_handle == NULL) {
146 MSAPI_DBG_ERR("*db_handle is NULL");
147 return MS_MEDIA_ERR_DB_INTERNAL;
150 /*Register busy handler*/
151 ret = sqlite3_busy_handler(*db_handle, __media_db_busy_handler, NULL);
152 if (SQLITE_OK != ret) {
154 MSAPI_DBG_ERR("[error when register busy handler] %s", sqlite3_errmsg(*db_handle));
156 sqlite3_close_v2(*db_handle);
159 return MS_MEDIA_ERR_DB_INTERNAL;
162 /*For TV internal space issue, change TRUNCATE to OFF */
163 sql = sqlite3_mprintf("%s", "PRAGMA journal_mode = OFF");
164 ret = sqlite3_exec(*db_handle, sql, NULL, NULL, NULL);
166 if (SQLITE_OK != ret) {
168 MSAPI_DBG_ERR("[error when change the journal mode] %s", sqlite3_errmsg(*db_handle));
170 sqlite3_close_v2(*db_handle);
173 if (ret == SQLITE_CORRUPT) {
174 MSAPI_DBG_ERR("MEDIA DB IS CORRUPTED");
175 return MS_MEDIA_ERR_DB_CORRUPT;
178 return MS_MEDIA_ERR_DB_INTERNAL;
181 /* Set for localized collate */
182 sqlite3_collation_needed(*db_handle, NULL, __media_db_collation_cb);
183 MSAPI_DBG_ERR("Finish");
184 return MS_MEDIA_ERR_NONE;
188 #define SLEEP_TIME 1000 * 1000
189 static int __media_db_update_directly(sqlite3 *db_handle, const char *sql_str)
191 int ret = MS_MEDIA_ERR_NONE;
192 char *zErrMsg = NULL;
196 ret = sqlite3_exec(db_handle, sql_str, NULL, NULL, &zErrMsg);
198 if (SQLITE_OK != ret) {
199 MSAPI_ERR_SLOG("Error[%s],Query[%s]", zErrMsg, sql_str);
200 sqlite3_free(zErrMsg);
201 if (ret == SQLITE_BUSY) {
202 ret = MS_MEDIA_ERR_DB_BUSY_FAIL;
203 } else if (ret == SQLITE_CONSTRAINT) {
204 ret = MS_MEDIA_ERR_DB_CONSTRAINT_FAIL;
205 } else if (ret == SQLITE_FULL) {
206 ret = MS_MEDIA_ERR_DB_FULL_FAIL;
207 } else if (ret == SQLITE_LOCKED) {
208 if (retry_count < RETRY_CNT) {
209 MSAPI_DBG_ERR("Locked retry[%d]", retry_count);
214 ret = MS_MEDIA_ERR_DB_INTERNAL;
216 ret = MS_MEDIA_ERR_DB_INTERNAL;
223 int media_db_check_integrity(sqlite3 *handle)
225 MSAPI_RETVM_IF(handle == NULL, MS_MEDIA_ERR_INVALID_PARAMETER, "Handle is NULL");
228 sqlite3_stmt *stmt = NULL;
229 const char integrity_check_query[] = "PRAGMA integrity_check";
231 ret = sqlite3_prepare_v2(handle, integrity_check_query, strlen(integrity_check_query), &stmt, NULL);
232 if (ret != SQLITE_OK) {
233 MSAPI_DBG_ERR("prepare error, ret = %d, error = %s", ret, sqlite3_errmsg(handle));
234 return MS_MEDIA_ERR_DB_CORRUPT;
237 ret = sqlite3_step(stmt);
238 if (ret != SQLITE_ROW) {
239 MSAPI_DBG_ERR("integrity_check failed in step");
240 sqlite3_finalize(stmt);
241 return MS_MEDIA_ERR_DB_CORRUPT;
244 char* check_result = (char*) sqlite3_column_text(stmt, 0);
245 if (check_result == NULL || strncmp(check_result, "ok", strlen(check_result))) {
246 MSAPI_DBG_ERR("integrity_check failed - result(%s)\n", check_result);
247 sqlite3_finalize(stmt);
248 return MS_MEDIA_ERR_DB_CORRUPT;
250 sqlite3_finalize(stmt);
252 return MS_MEDIA_ERR_NONE;
255 int media_db_connect(sqlite3 **handle, uid_t uid, bool need_write)
257 int ret = MS_MEDIA_ERR_NONE;
258 sqlite3 * db_handle = NULL;
264 ret = __media_db_connect_db_with_handle(&db_handle, uid, need_write);
265 if (ret != MS_MEDIA_ERR_NONE) {
266 if (ret == MS_MEDIA_ERR_DB_CORRUPT && retry_cnt == 0) {
269 ret = ms_ipc_request_recovery(uid);
270 if (ret == MS_MEDIA_ERR_NONE)
273 return MS_MEDIA_ERR_DB_CORRUPT;
280 return MS_MEDIA_ERR_NONE;
283 void media_db_disconnect(sqlite3 *handle)
288 sqlite3_close_v2(handle);
293 int media_db_request_update_db(const char *query_str, uid_t uid)
295 int ret = MS_MEDIA_ERR_NONE;
299 MSAPI_RETVM_IF(!query_str || strlen(query_str) == 0, MS_MEDIA_ERR_INVALID_PARAMETER, "Invalid Query");
301 #ifdef _USE_ON_DEMAND
302 ret = ms_ipc_activate_media_server();
303 if (ret != MS_MEDIA_ERR_NONE) {
304 MSAPI_DBG_ERR("ms_ipc_activate_media_server failed : %d", ret);
308 ret = ms_ipc_request_update_db(query_str, uid);
310 if (ret != MS_MEDIA_ERR_NONE)
311 MSAPI_DBG_ERR("ms_ipc_request_update_db failed : %d", ret);
316 int media_db_update_db_direct(const char *query_str, uid_t uid)
318 int ret = MS_MEDIA_ERR_NONE;
319 sqlite3 *handle = NULL;
323 MSAPI_RETVM_IF(!query_str || strlen(query_str) == 0, MS_MEDIA_ERR_INVALID_PARAMETER, "Invalid Query");
325 ret = media_db_connect(&handle, uid, true);
326 MSAPI_RETVM_IF(ret != MS_MEDIA_ERR_NONE, ret, "Connect failed");
328 ret = __media_db_update_directly(handle, query_str);
329 if (ret != MS_MEDIA_ERR_NONE)
330 MSAPI_DBG_ERR("Query failed");
332 media_db_disconnect(handle);
337 int media_db_get_result(sqlite3 *handle, const char *sql_str, sqlite3_stmt **stmt)
341 MSAPI_RETVM_IF(!sql_str, MS_MEDIA_ERR_INVALID_PARAMETER, "invalid query");
342 MSAPI_RETVM_IF(!handle, MS_MEDIA_ERR_INVALID_PARAMETER, "handle is null");
344 MSAPI_DBG_SLOG("[SQL query] : %s", sql_str);
346 err = sqlite3_prepare_v2(handle, sql_str, -1, stmt, NULL);
347 if (err != SQLITE_OK) {
348 MSAPI_DBG_ERR("prepare error %d[%s]", err, sqlite3_errmsg(handle));
349 if (err == SQLITE_CORRUPT)
350 return MS_MEDIA_ERR_DB_CORRUPT;
352 return MS_MEDIA_ERR_DB_INTERNAL;
355 return MS_MEDIA_ERR_NONE;