From d2f24f77dd82602cb9d9b1a38d2c062fade3e8ee Mon Sep 17 00:00:00 2001 From: Abhay Agarwal Date: Tue, 17 Sep 2019 18:16:38 +0900 Subject: [PATCH] Add functionality to check database version Change-Id: I3c8f7194cd04b2822569de24e9e8e763b16c5311 Signed-off-by: Abhay Agarwal --- packaging/ua-manager.spec | 2 +- ua-daemon/src/ua-manager-db.c | 123 ++++++++++++++++++++++++++++++++++++++---- 2 files changed, 114 insertions(+), 11 deletions(-) diff --git a/packaging/ua-manager.spec b/packaging/ua-manager.spec index b42b3f5..77315aa 100644 --- a/packaging/ua-manager.spec +++ b/packaging/ua-manager.spec @@ -1,6 +1,6 @@ Name: ua-manager Summary: User awareness manager -Version: 0.9.1 +Version: 0.9.2 Release: 1 License: Apache-2.0 Source0: %{name}-%{version}.tar.gz diff --git a/ua-daemon/src/ua-manager-db.c b/ua-daemon/src/ua-manager-db.c index 95c9866..74c01ca 100644 --- a/ua-daemon/src/ua-manager-db.c +++ b/ua-daemon/src/ua-manager-db.c @@ -31,12 +31,6 @@ #define UAM_DB_DEVICE_SERVICES_TABLE "device_services" /**< Device services DB table name */ #define UAM_DB_IBEACON_ADV_TABLE "ibeacon_adv" /**< iBeacon adv DB table name */ -/* - * 13) Need to version table for changing DB schema. - * For instance, In case of frequent OS upgrade, VD should make a dicision - * Whether it is needed to DB migration. - */ - #define CREATE_USERDATA_TABLE "CREATE TABLE IF NOT EXISTS userdata ( " \ "name TEXT, " \ "user_id INTEGER, " \ @@ -83,7 +77,10 @@ "PRIMARY KEY(ibeacon_adv) " \ "); " +#define VERSION 1 + sqlite3 *database; +static sqlite3_stmt *select_version; static int __uam_db_exec_sql(char *sql, void *cb) { @@ -151,6 +148,110 @@ static int __uam_db_busy(void *data, int attempt) return 0; } +static int __uam_db_get_version(unsigned int *ver) +{ + FUNC_ENTRY; + int error_code = UAM_ERROR_NONE; + int rc; + char *sql = NULL; + sql = sqlite3_mprintf("PRAGMA user_version"); + sqlite3_stmt *stmt = select_version; + + rc = sqlite3_prepare_v2(database, sql, -1, &stmt, NULL); + if (rc != SQLITE_OK) { + stmt = NULL; + FINALIZE(select_version); + UAM_ERR("Failed to prepare \"%s\" query", sql); + return rc; + } + + do { + rc = sqlite3_step(stmt); + + switch (rc) { + case SQLITE_DONE: + break; + case SQLITE_ROW: + *ver = sqlite3_column_int(stmt, 0); + UAM_INFO("database version %d", *ver); + break; + case SQLITE_ERROR: + default: + UAM_ERR("Failed to select database version info: %s", + sqlite3_errmsg(__uam_db_recover_database())); + } + } while (rc == SQLITE_ROW); + + FINALIZE(select_version); + sqlite3_reset(stmt); + FUNC_EXIT; + return error_code; +} + +static int __uam_db_update_version(unsigned int version) +{ + FUNC_ENTRY; + char *sql = NULL; + + sql = sqlite3_mprintf("PRAGMA user_version = '%d';", version); + retv_if(UAM_ERROR_NONE != __uam_db_exec_sql(sql, NULL), UAM_ERROR_DB_FAILED); + sqlite3_free(sql); + + UAM_DBG("Successfully updated database version to %d", version); + + FUNC_EXIT; + return UAM_ERROR_NONE; +} + +static int __uam_db_upgrade(unsigned int version) +{ + FUNC_ENTRY; + /* + This code should handle all the database upgrade after initial version + */ + + /* update database version */ + retv_if(UAM_ERROR_NONE != __uam_db_update_version(version), UAM_ERROR_DB_FAILED); + UAM_DBG("Successfully upgraded database version to %d", version); + + FUNC_EXIT; + return UAM_ERROR_NONE; +} + +static int __uam_db_upgrade_version(unsigned int old_ver, unsigned int new_ver) +{ + FUNC_ENTRY; + unsigned int i; + + for (i = old_ver + 1; i <= new_ver; i++) { + retv_if(UAM_ERROR_NONE != __uam_db_upgrade(i), UAM_ERROR_DB_FAILED); + } + + FUNC_EXIT; + return UAM_ERROR_NONE; +} + +int _uam_db_check_version(void) +{ + FUNC_ENTRY; + unsigned int curr_ver = VERSION; + unsigned int old_ver = 0; + + /* check database version */ + retv_if(UAM_ERROR_NONE != __uam_db_get_version(&old_ver), UAM_ERROR_DB_FAILED); + + if (0 == old_ver) { + retv_if(UAM_ERROR_NONE != __uam_db_update_version(curr_ver), UAM_ERROR_DB_FAILED); + } else if (old_ver != curr_ver) { + UAM_DBG("Database version changed, needs upgrade"); + /* upgrade database to new version */ + retv_if(UAM_ERROR_NONE != __uam_db_upgrade_version(old_ver, curr_ver), UAM_ERROR_DB_FAILED); + } + + FUNC_EXIT; + return UAM_ERROR_NONE; +} + static bool __uam_db_is_table_existing(const char *table) { int ret; @@ -278,10 +379,6 @@ static int __uam_db_verify() /* check table existance*/ retv_if(UAM_ERROR_NONE != __uam_db_check_table_creation(), UAM_ERROR_DB_FAILED); - /* - * 2) __check_integrity() should be executed before DB open - * Move __check_integrity() ahead of _ua_db_initialize_once() - */ /* check db integrity */ retv_if(UAM_ERROR_NONE != __uam_db_check_integrity(), UAM_ERROR_DB_FAILED); @@ -344,7 +441,13 @@ int _uam_db_initialize(void) FUNC_ENTRY; database = NULL; + /* initialize database */ EXEC(UAM_ERROR_NONE, _uam_db_initialize_once(), handle_error); + + /* check database version */ + EXEC(UAM_ERROR_NONE, _uam_db_check_version(), handle_error); + + /* initialize tables */ EXEC(UAM_ERROR_NONE, _uam_user_db_initialize(), handle_error); EXEC(UAM_ERROR_NONE, _ua_device_db_initialize(), handle_error); EXEC(UAM_ERROR_NONE, _ua_service_db_initialize(), handle_error); -- 2.7.4