/* * Created by PyramIDE. * User: David René * Date: 31/08/2011 * Time: 2:09 * */ read tools/basis.anubis read system/files.anubis read system/logger.anubis read system/string.anubis read data_base/sqlite.anubis read calexium_lib/database/alter_table.anubis read calexium_lib/net_services_protocols/logger_service.anubis read migration_common_sqlite3.anubis public type Migration: migration(DB_Version version, (SQLite3DataBase, Logger) -> Maybe(One) migrate_to, (SQLite3DataBase, Logger) -> Maybe(One) create_tables, (SQLite3DataBase, Logger) -> Maybe(One) create_indexes, ). define String dir_save_database = "/db_backup/". public define Bool migration_less ( Migration a, Migration b )= db_version_less(a.version, b.version) . /** * 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) . // //define Maybe(One) // do_migration_loop // ( // SQLite3DataBase db, // Logger logger, // String current_version, //current version of app // String db_ver, //version found in db settings // List(Migration) migrations, // Maybe(Migration) need_to_create_table, // success in case of new DB or when no migration have been done // (SQLite3DataBase, 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 // since h is migration(version, migrate_to, _, _), // 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), // }. // ///* SQLite 3 version */ //public define Maybe(One) // do_migration // ( // SQLite3DataBase db, // Logger logger, // String current_version, // (SQLite3DataBase) -> String get_db_version, // (SQLite3DataBase, 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), // //if app required db version is same as db_version, there is nothing to migrate // if compare_db_version(db_version, current_version) = 0 then // logInfo(logger, "Database version "+db_version+". No database migration found."); // success(unique) // else // do_migration_loop(db, logger, current_version, db_version, all_migrations, failure, update_db_version) // ). /* SQLite 3 version hk_settings with DB_Version*/ define Maybe(One) do_table_indexes ( SQLite3DataBase db, Logger logger, Migration _migration, (DB_Version) -> One update_db_version )= since _migration is migration(mig_version, _, create_tables, create_indexes), if create_tables(db, logger) is success(_) then if create_indexes(db, logger) is success(_) then update_db_version(mig_version); success(unique) else failure else failure . define Maybe(One) do_migration_loop ( SQLite3DataBase db, Logger logger, // String current_version, //current version of app DB_Version db_ver, //version found in db settings List(Migration) migrations, (DB_Version) -> One update_db_version, ) = if migrations is { [] then success(unique), [h . t] then since h is migration(migration_version, migrate_to, create_tables, create_indexes), if compare_db_version(db_ver, migration_version) is { less then logInfo(logger, "[less] Migrating Database from version " + db_ver + " to version " + migration_version); if migrate_to(db, logger) is failure then failure else update_db_version(migration_version); do_migration_loop(db, logger, migration_version, t, update_db_version) more then logInfo(logger, "[more] No Database migration found from version " + db_ver + " to version " + migration_version); do_migration_loop(db, logger, db_ver, t, update_db_version) equal then logInfo(logger, "[equal] No Database migration found from version " + db_ver + " to version " + migration_version); do_migration_loop(db, logger, db_ver, t, update_db_version) equal_but_sign then logInfo(logger, "Database migration found from version " + db_ver + " to version " + migration_version+ " by hash difference "); if do_table_indexes(db, logger, h, update_db_version) is success(_) then update_db_version(migration_version); do_migration_loop(db, logger, migration_version, t, update_db_version) else failure } }. public define Maybe(One) do_migration ( SQLite3DataBase db, Logger logger, DB_Version current_db_version, (DB_Version) -> 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..."); if last(all_migrations) is success(migration) then do_table_indexes(db, logger, migration, update_db_version) else logError(logger, "No database migration found. Can't create Database"); failure else ( // with db_version = get_db_version, // //if app version is same as db_version, there is nothing to migrate // if compare_db_version(db_version, current_version) = 0 then // logInfo(logger, "Database version "+db_version+". No database migration found."); // success(unique) // else do_migration_loop(db, logger, current_db_version, all_migrations, update_db_version) ). public define Maybe(One) do_create_indexes ( SQLite3DataBase db, Logger logger, 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 }.