--- /dev/null
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+#include <sqlite3.h>
+
+#include "alarm-manager-db.h"
+
+extern sqlite3 *alarmmgr_db;
+
+int migration_func_version_1(void)
+{
+ static const char *query = "CREATE TABLE IF NOT EXISTS alarmmgr_temp (\n" \
+ " alarm_id INTEGER PRIMARY KEY, \n" \
+ " start INTEGER, \n" \
+ " end INTEGER, \n" \
+ " uid INTEGER, \n" \
+ " global INTEGER, \n" \
+ " is_disabled INTEGER, \n" \
+ " caller_pkgid TEXT, \n" \
+ " callee_pkgid TEXT, \n" \
+ " app_unique_name TEXT, \n" \
+ " app_service_name TEXT, \n" \
+ " app_service_name_mod TEXT, \n" \
+ " bundle TEXT, \n" \
+ " noti_len INTEGER, \n" \
+ " noti TEXT, \n" \
+ " year INTEGER, \n" \
+ " month INTEGER, \n" \
+ " day INTEGER, \n" \
+ " hour INTEGER, \n" \
+ " min INTEGER, \n" \
+ " sec INTEGER, \n" \
+ " msec INTEGER, \n" \
+ " day_of_week INTEGER, \n" \
+ " repeat INTEGER, \n" \
+ " alarm_type INTEGER, \n" \
+ " reserved_info INTEGER, \n" \
+ " dst_service_name TEXT, \n" \
+ " dst_service_name_mod TEXT \n" \
+ ")";
+
+ static const char *insert_query = "INSERT INTO alarmmgr_temp (alarm_id, start, \
+ end, uid, global, is_disabled, caller_pkgid, callee_pkgid, \
+ app_unique_name, app_service_name, app_service_name_mod, \
+ bundle, noti_len, noti, year, month, day, hour, min, sec, msec,\
+ day_of_week, repeat, alarm_type, reserved_info, \
+ dst_service_name, dst_service_name_mod) \
+ SELECT alarm_id, start, end, uid, global, is_disabled, \
+ caller_pkgid, callee_pkgid, app_unique_name, app_service_name, \
+ app_service_name_mod, bundle, noti_len, noti, year, month, \
+ day, hour, min, sec, msec, day_of_week, repeat, alarm_type, \
+ reserved_info, dst_service_name, dst_service_name_mod \
+ FROM alarmmgr";
+
+ char *error_message = NULL;
+ int ret;
+
+ LOGD("DB migration init version start");
+
+ ret = sqlite3_exec(alarmmgr_db, "DROP TABLE IF EXISTS alarmmgr_temp", NULL,
+ NULL, &error_message);
+ if (ret != SQLITE_OK) {
+ LOGE("Don't execute drop, error message = %s", error_message);
+ sqlite3_free(error_message);
+ return ret;
+ }
+
+ ret = sqlite3_exec(alarmmgr_db, query, NULL, NULL, &error_message);
+ if (ret != SQLITE_OK) {
+ LOGE("Don't execute query = %s, error message = %s", query, error_message);
+ sqlite3_free(error_message);
+ return ret;
+ }
+
+ ret = sqlite3_exec(alarmmgr_db, insert_query, NULL, NULL, &error_message);
+ if (ret != SQLITE_OK) {
+ LOGE("Don't execute query = %s, error message = %s", insert_query, error_message);
+ sqlite3_free(error_message);
+ return ret;
+ }
+
+ ret = sqlite3_exec(alarmmgr_db, "DROP TABLE alarmmgr", NULL, NULL, &error_message);
+ if (ret != SQLITE_OK) {
+ LOGE("Don't execute drop alarmmgr, error message = %s", error_message);
+ sqlite3_free(error_message);
+ return ret;
+ }
+
+ ret = sqlite3_exec(alarmmgr_db, "ALTER TABLE alarmmgr_temp RENAME TO alarmmgr",
+ NULL, NULL, &error_message);
+ if (ret != SQLITE_OK) {
+ LOGE("Don't execute alter, error message = %s", error_message);
+ sqlite3_free(error_message);
+ return ret;
+ }
+
+ return ALARMMGR_RESULT_SUCCESS;
+}
#include "alarm-manager-db.h"
#define ALARMMGR_DB_FILE tzplatform_mkpath(TZ_SYS_DB, ".alarmmgr.db")
-#define QUERY_CREATE_TABLE_ALARMMGR "create table if not exists alarmmgr \
- (alarm_id integer primary key,\
- start integer,\
- end integer,\
- uid integer,\
- global integer,\
- is_disabled integer,\
- caller_pkgid text,\
- callee_pkgid text,\
- app_unique_name text,\
- app_service_name text,\
- app_service_name_mod text,\
- bundle text, \
- noti_len integer,\
- noti text, \
- year integer,\
- month integer,\
- day integer,\
- hour integer,\
- min integer,\
- sec integer,\
- msec integer,\
- day_of_week integer,\
- repeat integer,\
- alarm_type integer,\
- reserved_info integer,\
- dst_service_name text, \
- dst_service_name_mod text \
- )"
+#define QUERY_CREATE_TABLE_ALARMMGR \
+ " CREATE TABLE IF NOT EXISTS alarmmgr (\n" \
+ " alarm_id INTEGER PRIMARY KEY, \n" \
+ " start INTEGER, \n" \
+ " end INTEGER, \n" \
+ " uid INTEGER, \n" \
+ " global INTEGER, \n" \
+ " is_disabled INTEGER, \n" \
+ " caller_pkgid TEXT, \n" \
+ " callee_pkgid TEXT, \n" \
+ " app_unique_name TEXT, \n" \
+ " app_service_name TEXT, \n" \
+ " app_service_name_mod TEXT, \n" \
+ " bundle TEXT, \n" \
+ " noti_len INTEGER, \n" \
+ " noti TEXT, \n" \
+ " year INTEGER, \n" \
+ " month INTEGER, \n" \
+ " day INTEGER, \n" \
+ " hour INTEGER, \n" \
+ " min INTEGER, \n" \
+ " sec INTEGER, \n" \
+ " msec INTEGER, \n" \
+ " day_of_week INTEGER, \n" \
+ " repeat INTEGER, \n" \
+ " alarm_type INTEGER, \n" \
+ " reserved_info INTEGER, \n" \
+ " dst_service_name TEXT, \n" \
+ " dst_service_name_mod TEXT \n" \
+ ")"
+
+enum schema_version
+{
+ SCHEMA_VERSION_0 = 0,
+ SCHEMA_VERSION_1 = 1,
+ SCHEMA_VERSION_LATEST = SCHEMA_VERSION_1
+} schema_version_e;
+
+typedef struct
+{
+ const char *change_log;
+ int (*func)(void);
+} migration_func;
extern GSList *g_disabled_alarm_list;
extern __alarm_server_context_t alarm_context;
sqlite3 *alarmmgr_db;
static bool is_db_corrupted = false;
+static const migration_func m_func[] =
+{
+ {"SCHEMA_VERSION_0", NULL},
+ {"SCHEMA_VERSION_1", migration_func_version_1}
+};
+
+static int __create_db_version(void)
+{
+ static const char *query = "CREATE TABLE IF NOT EXISTS schema_version (version INTEGER)";
+
+ if (sqlite3_exec(alarmmgr_db, query, NULL, NULL, NULL) != SQLITE_OK) {
+ LOGE("Failed to execute the query (%s)\n", sqlite3_errmsg(alarmmgr_db));
+ return -1;
+ }
+
+ return 0;
+}
+
+static int __update_db_version(int ver)
+{
+ char *query;
+
+ if (sqlite3_exec(alarmmgr_db, "DELETE FROM schema_version", NULL, NULL, NULL)
+ != SQLITE_OK) {
+ LOGE("Failed to execute the query (%s)\n", sqlite3_errmsg(alarmmgr_db));
+ return -1;
+ }
+
+ query = sqlite3_mprintf("INSERT INTO schema_version (version) VALUES (%d)", ver);
+ if (query == NULL) {
+ LOGE("Failed to alloc query");
+ return -1;
+ }
+
+ if (sqlite3_exec(alarmmgr_db, query, NULL, NULL, NULL) != SQLITE_OK) {
+ LOGE("Failed to execute the query (%s)\n", sqlite3_errmsg(alarmmgr_db));
+ sqlite3_free(query);
+ return -1;
+ }
+
+ sqlite3_free(query);
+
+ return 0;
+}
+
+static int __get_db_version(void)
+{
+ static const char *dml = "SELECT version FROM schema_version";
+ sqlite3_stmt *stmt;
+ int ret;
+
+ ret = sqlite3_prepare_v2(alarmmgr_db, dml, -1, &stmt, NULL);
+ if (ret != SQLITE_OK) {
+ LOGE("sqlite3_prepare_v2 error : %d", ret);
+ return -1;
+ }
+
+ if (sqlite3_step(stmt) != SQLITE_ROW)
+ ret = -1;
+ else
+ ret = sqlite3_column_int(stmt, 0);
+
+ sqlite3_reset(stmt);
+ sqlite3_clear_bindings(stmt);
+ sqlite3_finalize(stmt);
+ return ret;
+}
+
+static int __db_upgrade(void)
+{
+ int ver, ret, i;
+
+ ver = __get_db_version();
+ if (ver >= SCHEMA_VERSION_LATEST)
+ return 0;
+
+ if (sqlite3_exec(alarmmgr_db, "BEGIN TRANSACTION", NULL, NULL, NULL)) {
+ LOGE("begin transaction error : %s", sqlite3_errmsg(alarmmgr_db));
+ return -1;
+ }
+
+ if (ver == -1) {
+ LOGD("Schema version not exists : %d", ver);
+ ret = __create_db_version();
+ if (ret != 0)
+ goto out;
+
+ ver = SCHEMA_VERSION_0;
+ }
+
+ for (i = ver + 1 ; i <= SCHEMA_VERSION_LATEST; i++) {
+ if (m_func[i].func() != ALARMMGR_RESULT_SUCCESS) {
+ ret = -1;
+ goto out;
+ }
+
+ }
+ ret = __update_db_version(SCHEMA_VERSION_LATEST);
+
+out:
+ if (ret == 0) {
+ if (sqlite3_exec(alarmmgr_db, "END TRANSACTION", NULL, NULL, NULL))
+ LOGE("end transaction error : %s", sqlite3_errmsg(alarmmgr_db));
+ } else {
+ if (sqlite3_exec(alarmmgr_db, "ROLLBACK TRANSACTION", NULL, NULL, NULL))
+ LOGE("rollback transaction error : %s", sqlite3_errmsg(alarmmgr_db));
+ }
+ return ret;
+}
+
static int __db_busyhandler(void *pData, int count)
{
if (5 - count > 0) {
return 0;
}
+int __check_alarmmgr_table(sqlite3 *alarmmgr_db, bool *is_exist)
+{
+ sqlite3_stmt *stmt = NULL;
+ int count, sqlret;
+
+ sqlret = sqlite3_prepare_v2(alarmmgr_db,
+ "SELECT COUNT(*) FROM sqlite_master WHERE name='alarmmgr'",
+ -1, &stmt, NULL);
+ if (sqlret != SQLITE_OK) {
+ /* LCOV_EXCL_START */
+ LOGE("sqlite3_prepare_v2 failed [%d][%s]", sqlret,
+ sqlite3_errmsg(alarmmgr_db));
+ return sqlret;
+ /* LCOV_EXCL_STOP */
+ }
+
+ sqlret = sqlite3_step(stmt);
+ if (sqlret == SQLITE_ROW)
+ count = sqlite3_column_int(stmt, 0);
+ else
+ count = 0;
+
+ LOGD("DB search result[%d]", count);
+
+ if (count > 0)
+ *is_exist = true;
+ else
+ *is_exist = false;
+
+ sqlite3_finalize(stmt);
+
+ return SQLITE_OK;
+
+}
bool _initialize_db()
{
char *error_message = NULL;
int ret;
+ bool is_exist;
/* Create or Open the DB file */
ret = sqlite3_open(ALARMMGR_DB_FILE, &alarmmgr_db);
return false;
}
}
+
+ ret = __check_alarmmgr_table(alarmmgr_db, &is_exist);
+ if (ret != SQLITE_OK) {
+ if (ret == SQLITE_CORRUPT) {
+ goto recover;
+ } else {
+ sqlite3_close(alarmmgr_db);
+ return false;
+ }
+ }
+
/* Create alarmmgr table */
ret = sqlite3_exec(alarmmgr_db, QUERY_CREATE_TABLE_ALARMMGR, NULL, NULL, &error_message);
if (ret != SQLITE_OK) {
}
}
+ if (is_exist == false) {
+ if (__create_db_version() != 0) {
+ sqlite3_close(alarmmgr_db);
+ return false;
+ }
+
+ if (__update_db_version(SCHEMA_VERSION_LATEST) != 0) {
+ sqlite3_close(alarmmgr_db);
+ return false;
+ }
+ } else {
+ ret = __db_upgrade();
+ if (ret) {
+ LOGE("Failed db's migration");
+ sqlite3_close(alarmmgr_db);
+ return false;
+ }
+ }
+
/* Check integrity of DB */
ret = sqlite3_exec(alarmmgr_db, "PRAGMA integrity_check", __check_callback, NULL, 0);
if (ret != SQLITE_OK || is_db_corrupted) {
return false;
}
+ if (__create_db_version() != 0) {
+ sqlite3_close(alarmmgr_db);
+ return false;
+ }
+
+ if (__update_db_version(SCHEMA_VERSION_LATEST) != 0) {
+ sqlite3_close(alarmmgr_db);
+ return false;
+ }
+
return true;
}