diff --git a/calexium_lib/database/migration.anubis b/calexium_lib/database/migration.anubis index 01075a2..597f9a8 100644 --- a/calexium_lib/database/migration.anubis +++ b/calexium_lib/database/migration.anubis @@ -29,8 +29,8 @@ define String dir_save_database = "/db_backup/". /** * Compare two version string. Returns -1 if first is lower than second, 1 if first is greater than second, and 0 if equals. */ -define Int - compare_version +public define Int + compare_db_version ( String version1, String version2 @@ -51,10 +51,10 @@ define Int [h2 . t2] then if h1 = h2 then compare(t1, t2) else - with v1 = force_Type(decimal_scan(h1), 0), - v2 = force_Type(decimal_scan(h2), 0), - if v1 < v2 then -1 - else if v1 > v2 then 1 + with v1i = force_Type(decimal_scan(h1), 0), + v2i = force_Type(decimal_scan(h2), 0), + if v1i < v2i then -1 + else if v1i > v2i then 1 else 0 }, }, @@ -148,63 +148,78 @@ public type Migration: define Maybe(One) do_migration_loop ( - SQLite3DataBase db, - Logger logger, - String current_version, - String db_ver, - List(Migration) migrations, - Migration last, - Bool need_to_create_table, - )= + SQLite3DataBase db, + Logger logger, + String current_version, + String db_ver, + List(Migration) migrations, + Maybe(Migration) need_to_create_table // success in case of new DB or when no migration have been done + ) = if migrations is { [] then - if need_to_create_table then - ( -// if reverse(all_migrations) is -// { -// [] then success(unique), -// [last . _] then - if last is migration(_, _, create_tables, create_indexes) then - if create_tables(db, logger) is success(_) then - if create_indexes(db, logger) is success(_) then - update_version_settings(db, current_version); - success(unique) - else - failure + if need_to_create_table is + { + failure then + update_version_settings(db, current_version); + success(unique), + success(last) then + if last is migration(_, _, create_tables, create_indexes) then + if create_tables(db, logger) is success(_) then + if create_indexes(db, logger) is success(_) then + update_version_settings(db, current_version); + success(unique) else failure -// } - ) - else - update_version_settings(db, current_version); - success(unique), + else + failure + }, [h . t] then if h is migration(version, migrate_to, _, _) then - if compare_version(db_ver, version) < 0 then + if compare_db_version(db_ver, version) < 0 then logInfo(logger, "Migrating Database from version " + db_ver + " to version " + version); if migrate_to(db, logger) is failure then failure else - do_migration_loop(db, logger, current_version, version, t, h, false) + do_migration_loop(db, logger, current_version, version, t, failure) else - do_migration_loop(db, logger, current_version, db_ver, t, h, need_to_create_table), + do_migration_loop(db, logger, current_version, db_ver, t, success(h)), }. + public define Maybe(One) do_migration ( SQLite3DataBase db, Logger logger, String current_version, - NonEmptyList(Migration) all_migrations, + List(Migration) all_migrations, )= - if is_table_exists(db, "mails") then // new empty database + if is_empty_database(db) then // new empty database + logInfo(logger, "No database found. Creating a new one..."); + do_migration_loop(db, logger, current_version, "", [], last(all_migrations)) + else ( with db_version = get_version_settings(db), - if all_migrations is [h . t] then - do_migration_loop(db, logger, current_version, db_version, [h . t], h, true) - ) - else - do_migration_loop(db, logger, current_version, "", [], all_migrations.head, true). + do_migration_loop(db, logger, current_version, db_version, all_migrations, failure) + ). + +public define Maybe(One) + do_create_indexes + ( + SQLite3DataBase db, + Logger logger, + String current_version, + List(Migration) all_migrations, + )= + if last(all_migrations) is + { + failure then logCriticalError(logger, "Index creation: migration list is empty!"); failure, + success(last_migration) then + if last_migration is migration(_, _, _, create_indexes) then + if create_indexes(db, logger) is success(_) then + success(unique) + else + failure + }. diff --git a/calexium_lib/database/migration_common.anubis b/calexium_lib/database/migration_common.anubis index 3575b8b..3c4d0ff 100644 --- a/calexium_lib/database/migration_common.anubis +++ b/calexium_lib/database/migration_common.anubis @@ -18,6 +18,11 @@ read calexium_lib/net_services_protocols/logger_service.anubis read ezmailbox_constants.anubis +public type DbTable: + table(String name, String create_query), + table(String db_name, String name, String create_query). + + public define Bool is_table_exists ( @@ -45,6 +50,31 @@ public define Bool )= is_table_exists(db, "main", table_name). +public define Bool + is_empty_database + ( + SQLite3DataBase db, + String dbName, + )= + if sql_query_timeout(db, "SELECT * FROM " + dbName + ".sqlite_master", [], "is_empty_database("+dbName+")") is + { + error(_) then true, //error in the SQL request + ok(_, cursor, _) then + if cursor(unique) is + { + error(_) then true, + no_more_row then true, + row(current) then false + } + }. + +public define Bool + is_empty_database + ( + SQLite3DataBase db, + )= + is_empty_database(db, "main"). + public define Maybe(One) drop_all_triggers ( @@ -69,18 +99,27 @@ public define Maybe(One) ( SQLite3DataBase db, Logger logger, - List((String,String)) tables, + List(DbTable) tables, String version_string ) = if tables is { [] then success(unique), [h . t] then - if h is (table_name, create_string) then - if alter_table(db, table_name, create_string, logger) is + if h is { - failure then logError(logger, "Version "+version_string+": Can't create '"+table_name+"' table"); failure, - success(_) then create_tables(db, logger, t, version_string) + table(table_name, create_string) then + if alter_table(db, table_name, create_string, logger) is + { + failure then logError(logger, "Version "+version_string+": Can't create '"+table_name+"' table"); failure, + success(_) then create_tables(db, logger, t, version_string) + }, + table(db_name, table_name, create_string) then + if alter_table(db, db_name, table_name, create_string, logger) is + { + failure then logError(logger, "Version "+version_string+": Can't create '"+db_name+"."+table_name+"' table"); failure, + success(_) then create_tables(db, logger, t, version_string) + } } }. diff --git a/calexium_lib/database/settings.anubis b/calexium_lib/database/settings.anubis index 13a83e9..6448676 100644 --- a/calexium_lib/database/settings.anubis +++ b/calexium_lib/database/settings.anubis @@ -60,7 +60,24 @@ public define Int } }. - +public define Bool + select_settings + ( + SQLite3DataBase db, + String var, + Bool default + )= + if select_settings(db, var) is + { + failure then default, //error in the SQL request + success(value) then + if decimal_scan(value) is + { + failure then default, + success(v) then v!=0 + } + }. + public define One update_settings ( -- libgit2 0.21.4