/* * Created by PyramIDE. * User: Steve Marechal * Date: 25/11/2008 * Time: 11:29 * */ read tools/basis.anubis read system/files.anubis read system/logger.anubis read system/string.anubis read data_base/db_tools.anubis read xlib/database/db_utils.anubis read xlib/database/alter_table.anubis //read xlib/net_services_protocols/logger_service.anubis read mf_constants.anubis read settings.anubis read migration_common.anubis read tools/mf_loggers.anubis 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. */ public define Int compare_db_version ( String version1, String version2 ) = with compare = (List(String) v1, List(String) v2) |-compare-> (Int) if v1 is { [] then if v2 is { [] then 0, [h2 . t2] then -1 }, [h1 . t1] then if v2 is { [] then 1, [h2 . t2] then if h1 = h2 then compare(t1, t2) else 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 }, }, compare(split(version1, '.'), split(version2, '.')). public define Maybe(One) backup_database ( Logger logger, // String current_version, String db_path, String main_db_name, List(String) other_db_names, ) = // with should_copy = if file_exists(db_path + main_db_name) then // if sqlite3_open(db_path + main_db_name) is // { // error(sql_error) then false, // maybe not created yet // ok(Database db) then // with ver = get_version_settings(db), // ver != current_version // } // else false, //if should_copy then with dir_save = db_path + dir_save_database, if (Maybe(String))make_directory(dir_save) is { failure then logError(logger, "Can't create directory '"+db_path + dir_save_database+"'"); failure, success(_) then with copy_with_log = (String src, String dst) |-> if file_exists(src) then if copy_file(src, dst) is { cant_read_file then logError(logger, "Can't read source file '" + src + "'."); failure, cant_create_file then logError(logger, "Can't create destination file '" + dst + "'."); failure, copy_error then logError(logger, "Can't copy file '" + src + "' to file '" + dst + "'."); failure, copy_file_mode_error then logError(logger, "Can't get file mode for source file '" + src + "'."); failure, copy_file_times_error then logError(logger, "Can't set file times into file '" + dst + "'."); failure, copy_ok(_) then logInfo(logger, "File '" + dst + "' saved"); success(unique) } else success(unique), with copy_db = (List(String) names) |-copy_db-> if names is { [] then success(unique), [h . t] then if copy_with_log(db_path + h, dir_save + h) is { failure then failure, success(_) then copy_db(t) } }, copy_db([main_db_name . other_db_names]) } //else success(unique) . public type Migration: migration(String version, (Database, Logger) -> Maybe(One) migrate_to, (Database, Logger) -> Maybe(One) create_tables, (Database, Logger) -> Maybe(One) create_indexes, ). define Maybe(One) do_migration_loop ( Database 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 (Database, String) -> One update_db_version, ) = if migrations is { [] then if need_to_create_table is { failure then update_db_version(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_db_version(db, current_version); success(unique) else failure else failure }, [h . t] then if h is migration(version, migrate_to, _, _) 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, failure, update_db_version) else do_migration_loop(db, logger, current_version, db_ver, t, success(h), update_db_version), }. public define Maybe(One) do_migration ( Database db, Logger logger, String current_version, (Database) -> String get_db_version, (Database, String) -> One update_db_version, List(Migration) all_migrations, )= 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), update_db_version) else ( with db_version = get_db_version(db), do_migration_loop(db, logger, current_version, db_version, all_migrations, failure, update_db_version) ). public define Maybe(One) do_create_indexes ( Database 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 }.