2 * Copyright (c) 2000 - 2017 Samsung Electronics Co., Ltd. All rights reserved.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
25 #include <notification_error.h>
26 #include <notification_debug.h>
27 #include <notification_db.h>
28 #include "notification_db_query.h"
30 static bool is_db_corrupted = false;
32 static int __check_integrity_cb(void *pid, int argc, char **argv, char **notUsed)
34 char *check_str = "ok";
36 if (strncmp(argv[0], check_str, strlen(check_str))) {
37 ERR("db integrity result : %s" , argv[0]);
38 is_db_corrupted = true;
42 INFO("db integrity result : %s" , argv[0]);
46 static int __recover_corrupted_db(sqlite3 *db)
48 int ret = NOTIFICATION_ERROR_NONE;
52 INFO("DB is corrupted, start to recover corrupted db");
57 sql_ret = sqlite3_open_v2(DBPATH, &db,
58 SQLITE_OPEN_CREATE |SQLITE_OPEN_READWRITE,
60 if (sql_ret != SQLITE_OK) {
61 ERR("Failed to open db[%d]", sql_ret);
63 ret = NOTIFICATION_ERROR_FROM_DB;
67 sql_ret = sqlite3_exec(db, CREATE_NOTIFICATION_TABLE, NULL, NULL, &errmsg);
68 if (sql_ret != SQLITE_OK) {
69 ERR("Failed to exec query[%d][%s]", sql_ret, errmsg);
70 ret = NOTIFICATION_ERROR_FROM_DB;
80 EXPORT_API int notification_db_init()
82 int ret = NOTIFICATION_ERROR_NONE;
87 sql_ret = sqlite3_open_v2(DBPATH, &db,
88 SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE, NULL);
89 if (sql_ret != SQLITE_OK) {
91 ERR("Failed to open db[%d]", ret);
92 ret = NOTIFICATION_ERROR_FROM_DB;
97 sql_ret = sqlite3_exec(db, CREATE_NOTIFICATION_TABLE, NULL, NULL, &errmsg);
98 if (sql_ret != SQLITE_OK) {
100 ERR("Failed to exec sqlite[%d][%s]", ret, errmsg);
101 ret = NOTIFICATION_ERROR_FROM_DB;
106 sql_ret = sqlite3_exec(db, "PRAGMA integrity_check",
107 __check_integrity_cb, NULL, &errmsg);
108 if (sql_ret != SQLITE_OK || is_db_corrupted) {
109 ERR("Failed to exec query[%d][%s]", sql_ret, errmsg);
110 ret = NOTIFICATION_ERROR_FROM_DB;
114 if (sql_ret == SQLITE_CORRUPT || sql_ret == SQLITE_NOTADB || is_db_corrupted)
115 ret = __recover_corrupted_db(db);
117 sqlite3_free(errmsg);
124 sqlite3 *notification_db_open()
129 ret = access(DBPATH, R_OK | W_OK);
131 /* LCOV_EXCL_START */
132 set_last_result(NOTIFICATION_ERROR_FROM_DB);
137 ret = sqlite3_open_v2(DBPATH, &db, SQLITE_OPEN_READWRITE, NULL);
138 if (ret != SQLITE_OK) {
139 /* LCOV_EXCL_START */
140 if (ret == SQLITE_PERM)
141 set_last_result(NOTIFICATION_ERROR_PERMISSION_DENIED);
143 set_last_result(NOTIFICATION_ERROR_FROM_DB);
152 int notification_db_close(sqlite3 **db)
156 if (db == NULL || *db == NULL)
157 return NOTIFICATION_ERROR_INVALID_PARAMETER;
159 ret = sqlite3_close(*db);
160 if (ret != SQLITE_OK) {
161 /* LCOV_EXCL_START */
162 ERR("Failed to close db[%d]", ret);
163 return NOTIFICATION_ERROR_FROM_DB;
169 return NOTIFICATION_ERROR_NONE;
172 int notification_db_exec(sqlite3 *db, const char *query, int *num_changes)
174 int ret = NOTIFICATION_ERROR_NONE;
175 sqlite3_stmt *stmt = NULL;
177 if (db == NULL || query == NULL)
178 return NOTIFICATION_ERROR_INVALID_PARAMETER;
180 ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
181 if (ret != SQLITE_OK) {
182 /* LCOV_EXCL_START */
183 ERR("Sqlite3 err[%d][%s]", ret, sqlite3_errmsg(db));
184 return NOTIFICATION_ERROR_FROM_DB;
188 ret = sqlite3_step(stmt);
189 if (ret == SQLITE_OK || ret == SQLITE_DONE) {
190 if (num_changes != NULL)
191 *num_changes = sqlite3_changes(db);
193 ret = NOTIFICATION_ERROR_NONE;
195 /* LCOV_EXCL_START */
196 ERR("Sqlite err[%d][%s]", ret, sqlite3_errmsg(db));
197 ret = NOTIFICATION_ERROR_FROM_DB;
202 sqlite3_finalize(stmt);
207 char *notification_db_column_text(sqlite3_stmt * stmt, int col)
209 const unsigned char *col_text = NULL;
211 col_text = sqlite3_column_text(stmt, col);
212 if (col_text == NULL || col_text[0] == '\0')
215 return strdup((char *)col_text);
218 bundle *notification_db_column_bundle(sqlite3_stmt * stmt, int col)
220 const unsigned char *col_bundle = NULL;
222 col_bundle = sqlite3_column_text(stmt, col);
223 if (col_bundle == NULL || col_bundle[0] == '\0')
226 return bundle_decode(col_bundle, strlen((char *)col_bundle));