Commit 3b642ef214cf59ea5a8bf0002988e034305e72e9

Authored by Cédric RICARD
1 parent 617423df

Moving database migration from NL to CXMLib

calexium_lib/database/migration.anubis 0 → 100644
  1 +/*
  2 + * Created by PyramIDE.
  3 + * User: Steve Marechal
  4 + * Date: 25/11/2008
  5 + * Time: 11:29
  6 + *
  7 + */
  8 +
  9 +read tools/basis.anubis
  10 +read system/files.anubis
  11 +read system/logger.anubis
  12 +read system/string.anubis
  13 +read data_base/alter_table.anubis
  14 +read data_base/sqlite.anubis
  15 +
  16 +read calexium_lib/database/db_utils.anubis
  17 +read calexium_lib/net_services_protocols/logger_service.anubis
  18 +
  19 + read mf_constants.anubis
  20 +
  21 +read settings.anubis
  22 +read migration_common.anubis
  23 +
  24 + read tools/mf_loggers.anubis
  25 +
  26 +define String dir_save_database = "/db_backup/".
  27 +
  28 +
  29 +/**
  30 + * Compare two version string. Returns -1 if first is lower than second, 1 if first is greater than second, and 0 if equals.
  31 + */
  32 +define Int
  33 + compare_version
  34 + (
  35 + String version1,
  36 + String version2
  37 + ) =
  38 + with compare = (List(String) v1, List(String) v2) |-compare-> (Int)
  39 + if v1 is
  40 + {
  41 + [] then
  42 + if v2 is
  43 + {
  44 + [] then 0,
  45 + [h2 . t2] then -1
  46 + },
  47 + [h1 . t1] then
  48 + if v2 is
  49 + {
  50 + [] then 1,
  51 + [h2 . t2] then
  52 + if h1 = h2 then compare(t1, t2)
  53 + else
  54 + with v1 = force_Type(decimal_scan(h1), 0),
  55 + v2 = force_Type(decimal_scan(h2), 0),
  56 + if v1 < v2 then -1
  57 + else if v1 > v2 then 1
  58 + else 0
  59 + },
  60 + },
  61 + compare(split(version1, '.'), split(version2, '.')).
  62 +
  63 +define String
  64 + get_version_settings
  65 + (
  66 + SQLite3DataBase db
  67 + )=
  68 + if is_table_exists(db, "settings") then
  69 + select_settings(db, "MF_version", "0.0.0.0")
  70 + else "0.0.0.0".
  71 +
  72 +public define One
  73 + update_version_settings
  74 + (
  75 + SQLite3DataBase db,
  76 + String version
  77 + )=
  78 + update_settings(db, "MF_version", version).
  79 +
  80 +public define Maybe(One)
  81 + backup_database
  82 + (
  83 + Logger logger,
  84 + String current_version,
  85 + String db_path,
  86 + String main_db_name,
  87 + List(String) other_db_names,
  88 + )
  89 + =
  90 + with should_copy = if file_exists(db_path + main_db_name) then
  91 + if sqlite3_open(db_path + main_db_name) is
  92 + {
  93 + error(sql_error) then false, // maybe not created yet
  94 + ok(SQLite3DataBase db) then
  95 + with ver = get_version_settings(db),
  96 + ver != current_version
  97 + }
  98 + else false,
  99 +
  100 + if should_copy then
  101 + with dir_save = db_path + dir_save_database,
  102 + if (Maybe(String))make_directory(dir_save) is
  103 + {
  104 + failure then logError(logger, "Can't create directory '"+db_path + dir_save_database+"'"); failure,
  105 + success(_) then
  106 + with copy_with_log = (String src, String dst) |->
  107 + if file_exists(src) then
  108 + if copy_file(src, dst) is
  109 + {
  110 + cant_read_file then logError(logger, "Can't read source file '" + src + "'."); failure,
  111 + cant_create_file then logError(logger, "Can't create destination file '" + dst + "'."); failure,
  112 + copy_error then logError(logger, "Can't copy file '" + src + "' to file '" + dst + "'."); failure,
  113 + copy_file_mode_error then logError(logger, "Can't get file mode for source file '" + src + "'."); failure,
  114 + copy_file_times_error then logError(logger, "Can't set file times into file '" + dst + "'."); failure,
  115 + copy_ok(_) then logInfo(logger, "File '" + dst + "' saved"); success(unique)
  116 + }
  117 + else success(unique),
  118 + with copy_db = (List(String) names) |-copy_db->
  119 + if names is
  120 + {
  121 + [] then success(unique),
  122 + [h . t] then
  123 + if copy_with_log(db_path + h, dir_save + h) is
  124 + {
  125 + failure then failure,
  126 + success(_) then copy_db(t)
  127 + }
  128 + },
  129 + copy_db([main_db_name . other_db_names])
  130 + }
  131 + else success(unique)
  132 + .
  133 +
  134 +
  135 +
  136 +
  137 +
  138 +
  139 +public type Migration:
  140 + migration(String version,
  141 + (SQLite3DataBase, Logger) -> Maybe(One) migrate_to,
  142 + (SQLite3DataBase, Logger) -> Maybe(One) create_tables,
  143 + (SQLite3DataBase, Logger) -> Maybe(One) create_indexes,
  144 + ).
  145 +
  146 +
  147 +
  148 +define Maybe(One)
  149 + do_migration_loop
  150 + (
  151 + SQLite3DataBase db,
  152 + Logger logger,
  153 + String current_version,
  154 + String db_ver,
  155 + List(Migration) migrations,
  156 + Migration last,
  157 + Bool need_to_create_table,
  158 + )=
  159 + if migrations is
  160 + {
  161 + [] then
  162 + if need_to_create_table then
  163 + (
  164 +// if reverse(all_migrations) is
  165 +// {
  166 +// [] then success(unique),
  167 +// [last . _] then
  168 + if last is migration(_, _, create_tables, create_indexes) then
  169 + if create_tables(db, logger) is success(_) then
  170 + if create_indexes(db, logger) is success(_) then
  171 + update_version_settings(db, current_version);
  172 + success(unique)
  173 + else
  174 + failure
  175 + else
  176 + failure
  177 +// }
  178 + )
  179 + else
  180 + update_version_settings(db, current_version);
  181 + success(unique),
  182 + [h . t] then
  183 + if h is migration(version, migrate_to, _, _) then
  184 + if compare_version(db_ver, version) < 0 then
  185 + logInfo(logger, "Migrating Database from version " + db_ver + " to version " + version);
  186 + if migrate_to(db, logger) is failure then
  187 + failure
  188 + else
  189 + do_migration_loop(db, logger, current_version, version, t, h, false)
  190 + else
  191 + do_migration_loop(db, logger, current_version, db_ver, t, h, need_to_create_table),
  192 + }.
  193 +
  194 +
  195 +public define Maybe(One)
  196 + do_migration
  197 + (
  198 + SQLite3DataBase db,
  199 + Logger logger,
  200 + String current_version,
  201 + NonEmptyList(Migration) all_migrations,
  202 + )=
  203 + if is_table_exists(db, "mails") then // new empty database
  204 + (
  205 + with db_version = get_version_settings(db),
  206 + if all_migrations is [h . t] then
  207 + do_migration_loop(db, logger, current_version, db_version, [h . t], h, true)
  208 + )
  209 + else
  210 + do_migration_loop(db, logger, current_version, "", [], all_migrations.head, true).
calexium_lib/database/migration_common.anubis 0 → 100644
  1 +/*
  2 + * Created by PyramIDE.
  3 + * User: ricard
  4 + * Date: 03/12/2008
  5 + * Time: 13:07
  6 + *
  7 + */
  8 +
  9 +read tools/basis.anubis
  10 +read system/logger.anubis
  11 +read data_base/sqlite.anubis
  12 +read data_base/alter_table.anubis
  13 +read data_base/sqlite_foreign_key.anubis
  14 +
  15 +read calexium_lib/database/db_utils.anubis
  16 +read calexium_lib/net_services_protocols/logger_service.anubis
  17 +
  18 + read ezmailbox_constants.anubis
  19 +
  20 +
  21 +public define Bool
  22 + is_table_exists
  23 + (
  24 + SQLite3DataBase db,
  25 + String dbName,
  26 + String table_name
  27 + )=
  28 + if sql_query_timeout(db, "SELECT * FROM " + dbName + ".sqlite_master WHERE type ='table' AND name = @table_name", [bind_String("@table_name", table_name)], "is_table_exists("+table_name+")") is
  29 + {
  30 + error(_) then false, //error in the SQL request
  31 + ok(_, cursor, _) then
  32 + if cursor(unique) is
  33 + {
  34 + error(_) then false,
  35 + no_more_row then false,
  36 + row(current) then true
  37 + }
  38 + }.
  39 +
  40 +public define Bool
  41 + is_table_exists
  42 + (
  43 + SQLite3DataBase db,
  44 + String table_name
  45 + )=
  46 + is_table_exists(db, "main", table_name).
  47 +
  48 +public define Maybe(One)
  49 + drop_all_triggers
  50 + (
  51 + SQLite3DataBase db,
  52 + Logger log
  53 + ) =
  54 + if sqlite3_query(db, "SELECT name FROM sqlite_master WHERE type = 'trigger'", []) is
  55 + {
  56 + error(err) then logError(log, db_error(err, "drop_all_triggers")); failure,
  57 + ok(_, cursor, _) then
  58 + with drop_trigger = (String name) |-> if sqlite3_query(db, "DROP TRIGGER " + name, []) is
  59 + {
  60 + error(err2) then logError(log, db_error(err2, "Failed to drop trigger '" + name + "'")),
  61 + ok(_, cursor, _) then unique
  62 + },
  63 + map_forget(drop_trigger, db_get_string_list(cursor, []));
  64 + success(unique)
  65 + }.
  66 +
  67 +public define Maybe(One)
  68 + create_tables
  69 + (
  70 + SQLite3DataBase db,
  71 + Logger logger,
  72 + List((String,String)) tables,
  73 + String version_string
  74 + ) =
  75 + if tables is
  76 + {
  77 + [] then success(unique),
  78 + [h . t] then
  79 + if h is (table_name, create_string) then
  80 + if alter_table(db, table_name, create_string, logger) is
  81 + {
  82 + failure then logError(logger, "Version "+version_string+": Can't create '"+table_name+"' table"); failure,
  83 + success(_) then create_tables(db, logger, t, version_string)
  84 + }
  85 + }.
  86 +
  87 +
  88 +public define Maybe(One)
  89 + create_indexes
  90 + (
  91 + SQLite3DataBase db,
  92 + Logger logger,
  93 + List(String) indexes,
  94 + String version_string
  95 + )=
  96 + if indexes is
  97 + {
  98 + [] then success(unique),
  99 + [h . t] then
  100 + if sql_query_timeout(db, h, "Version "+version_string+": create indexes") is
  101 + {
  102 + failure then failure,
  103 + success(_) then
  104 + create_indexes(db, logger, t, version_string)
  105 + }
  106 + }.
  107 +
  108 +
  109 +public define One
  110 + make_foreign_key
  111 + (
  112 + SQLite3DataBase db,
  113 + String table_name,
  114 + String field_name,
  115 + String foreign_table_name,
  116 + String foreign_field_name,
  117 + Bool fk_null,
  118 + Bool fk_cascade,
  119 + Logger log
  120 + ) =
  121 + if (Maybe(One))make_foreign_key(db, table_name, field_name, foreign_table_name, foreign_field_name, fk_null, fk_cascade, log) is
  122 + {
  123 + failure then
  124 + logError(log, "Can't create foreign key constraint between '"+table_name+"' and '"+foreign_table_name+"' tables"),
  125 + success(_) then
  126 + unique
  127 + }.
  128 +
  129 +public define Maybe(One)
  130 + make_foreign_keys
  131 + (
  132 + SQLite3DataBase db,
  133 + Logger logger,
  134 + List((String, String, String, String, FK_Null, FK_Cascade)) relations,
  135 + String version_string
  136 + )=
  137 + if relations is
  138 + {
  139 + [] then success(unique),
  140 + [h . t] then
  141 + if h is (table_name, field_name, foreign_table_name, foreign_field_name, fk_null, fk_cascade) then
  142 + if (Maybe(One))make_foreign_key(db, table_name, field_name, foreign_table_name, foreign_field_name, fk_null, fk_cascade, logger) is
  143 + {
  144 + failure then
  145 + logError(logger, "Version "+version_string+": Can't create foreign key constraint between '"+table_name+"' and '"+foreign_table_name+"' tables"); failure,
  146 + success(_) then
  147 + make_foreign_keys(db, logger, t, version_string)
  148 + }
  149 + }.
calexium_lib/database/settings.anubis 0 → 100644
  1 +/*
  2 + * Created by PyramIDE.
  3 + * User: Steve Marechal
  4 + * Date: 09/12/2008
  5 + * Time: 17:19
  6 + */
  7 +
  8 +read tools/basis.anubis
  9 +read data_base/sqlite.anubis
  10 +
  11 +read calexium_lib/database/db_utils.anubis
  12 +
  13 +
  14 +public define Maybe(String)
  15 + select_settings
  16 + (
  17 + SQLite3DataBase db,
  18 + String var,
  19 + )=
  20 + if sql_query_timeout(db, "SELECT var_value FROM settings WHERE var_name=" + db_make_sql_string(var) + ";", "select_settings") is
  21 + {
  22 + failure then failure, //error in the SQL request
  23 + success(table_cursor) then
  24 + if table_cursor(next_row) is
  25 + {
  26 + error(_) then failure,
  27 + no_more_row then failure, //can't find the var_value in the table, because the row is empty
  28 + row(current) then success(text(current)(0))
  29 + }
  30 + }.
  31 +
  32 +public define String
  33 + select_settings
  34 + (
  35 + SQLite3DataBase db,
  36 + String var,
  37 + String default
  38 + )=
  39 + if select_settings(db, var) is
  40 + {
  41 + failure then default, //error in the SQL request
  42 + success(value) then value
  43 + }.
  44 +
  45 +public define Int
  46 + select_settings
  47 + (
  48 + SQLite3DataBase db,
  49 + String var,
  50 + Int default
  51 + )=
  52 + if select_settings(db, var) is
  53 + {
  54 + failure then default, //error in the SQL request
  55 + success(value) then
  56 + if decimal_scan(value) is
  57 + {
  58 + failure then default,
  59 + success(v) then v
  60 + }
  61 + }.
  62 +
  63 +
  64 +public define One
  65 + update_settings
  66 + (
  67 + SQLite3DataBase db,
  68 + String var,
  69 + String value
  70 + )=
  71 + if select_settings(db, var) is success(_) then
  72 + forget(sql_query_timeout(db, "UPDATE settings SET var_value = @value WHERE var_name = @name;", [bind_String("@name", var), bind_String("@value", value)], "update_settings"))
  73 + else
  74 + forget(sql_query_timeout(db, "INSERT INTO settings (var_name, var_value) VALUES (@name, @value)", [bind_String("@name", var), bind_String("@value", value)], "update_settings"))
  75 + .
  76 +
calexium_lib/web/CXM_dojo.anubis
@@ -10,19 +10,13 @@ read tools/basis.anubis @@ -10,19 +10,13 @@ read tools/basis.anubis
10 read tools/base64.anubis 10 read tools/base64.anubis
11 read locale/L3LanguageInfo.anubis 11 read locale/L3LanguageInfo.anubis
12 read system/string.anubis 12 read system/string.anubis
  13 +read system/logger.anubis
13 14
14 read calexium_lib/web/CXM_common.anubis 15 read calexium_lib/web/CXM_common.anubis
15 read calexium_lib/web/CXM_making_a_web_site.anubis 16 read calexium_lib/web/CXM_making_a_web_site.anubis
16 read calexium_lib/web/CXM_multihost_http_server.anubis 17 read calexium_lib/web/CXM_multihost_http_server.anubis
17 read calexium_lib/net_services_protocols/logger_service.anubis 18 read calexium_lib/net_services_protocols/logger_service.anubis
18 19
19 -read mailfountain_constants.anubis  
20 -read mailfountain_types.anubis  
21 -read common/language_management.anubis  
22 -  
23 -read tools/mf_loggers.anubis  
24 -read system/logger.anubis  
25 -  
26 public type Dojo_Grid_Data : 20 public type Dojo_Grid_Data :
27 grid_data(String). 21 grid_data(String).
28 22