Commit 68665c4a1c27de340617c156304a783a61bdb9bb
1 parent
8a2b97fb
Improved DB migration library
Showing
3 changed files
with
119 additions
and
48 deletions
Show diff stats
calexium_lib/database/migration.anubis
| @@ -29,8 +29,8 @@ define String dir_save_database = "/db_backup/". | @@ -29,8 +29,8 @@ define String dir_save_database = "/db_backup/". | ||
| 29 | /** | 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. | 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 | */ | 31 | */ |
| 32 | -define Int | ||
| 33 | - compare_version | 32 | +public define Int |
| 33 | + compare_db_version | ||
| 34 | ( | 34 | ( |
| 35 | String version1, | 35 | String version1, |
| 36 | String version2 | 36 | String version2 |
| @@ -51,10 +51,10 @@ define Int | @@ -51,10 +51,10 @@ define Int | ||
| 51 | [h2 . t2] then | 51 | [h2 . t2] then |
| 52 | if h1 = h2 then compare(t1, t2) | 52 | if h1 = h2 then compare(t1, t2) |
| 53 | else | 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 | 54 | + with v1i = force_Type(decimal_scan(h1), 0), |
| 55 | + v2i = force_Type(decimal_scan(h2), 0), | ||
| 56 | + if v1i < v2i then -1 | ||
| 57 | + else if v1i > v2i then 1 | ||
| 58 | else 0 | 58 | else 0 |
| 59 | }, | 59 | }, |
| 60 | }, | 60 | }, |
| @@ -148,63 +148,78 @@ public type Migration: | @@ -148,63 +148,78 @@ public type Migration: | ||
| 148 | define Maybe(One) | 148 | define Maybe(One) |
| 149 | do_migration_loop | 149 | do_migration_loop |
| 150 | ( | 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 | - )= | 151 | + SQLite3DataBase db, |
| 152 | + Logger logger, | ||
| 153 | + String current_version, | ||
| 154 | + String db_ver, | ||
| 155 | + List(Migration) migrations, | ||
| 156 | + Maybe(Migration) need_to_create_table // success in case of new DB or when no migration have been done | ||
| 157 | + ) = | ||
| 159 | if migrations is | 158 | if migrations is |
| 160 | { | 159 | { |
| 161 | [] then | 160 | [] 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 | 161 | + if need_to_create_table is |
| 162 | + { | ||
| 163 | + failure then | ||
| 164 | + update_version_settings(db, current_version); | ||
| 165 | + success(unique), | ||
| 166 | + success(last) then | ||
| 167 | + if last is migration(_, _, create_tables, create_indexes) then | ||
| 168 | + if create_tables(db, logger) is success(_) then | ||
| 169 | + if create_indexes(db, logger) is success(_) then | ||
| 170 | + update_version_settings(db, current_version); | ||
| 171 | + success(unique) | ||
| 175 | else | 172 | else |
| 176 | failure | 173 | failure |
| 177 | -// } | ||
| 178 | - ) | ||
| 179 | - else | ||
| 180 | - update_version_settings(db, current_version); | ||
| 181 | - success(unique), | 174 | + else |
| 175 | + failure | ||
| 176 | + }, | ||
| 182 | [h . t] then | 177 | [h . t] then |
| 183 | if h is migration(version, migrate_to, _, _) then | 178 | if h is migration(version, migrate_to, _, _) then |
| 184 | - if compare_version(db_ver, version) < 0 then | 179 | + if compare_db_version(db_ver, version) < 0 then |
| 185 | logInfo(logger, "Migrating Database from version " + db_ver + " to version " + version); | 180 | logInfo(logger, "Migrating Database from version " + db_ver + " to version " + version); |
| 186 | if migrate_to(db, logger) is failure then | 181 | if migrate_to(db, logger) is failure then |
| 187 | failure | 182 | failure |
| 188 | else | 183 | else |
| 189 | - do_migration_loop(db, logger, current_version, version, t, h, false) | 184 | + do_migration_loop(db, logger, current_version, version, t, failure) |
| 190 | else | 185 | else |
| 191 | - do_migration_loop(db, logger, current_version, db_ver, t, h, need_to_create_table), | 186 | + do_migration_loop(db, logger, current_version, db_ver, t, success(h)), |
| 192 | }. | 187 | }. |
| 193 | 188 | ||
| 194 | 189 | ||
| 190 | + | ||
| 195 | public define Maybe(One) | 191 | public define Maybe(One) |
| 196 | do_migration | 192 | do_migration |
| 197 | ( | 193 | ( |
| 198 | SQLite3DataBase db, | 194 | SQLite3DataBase db, |
| 199 | Logger logger, | 195 | Logger logger, |
| 200 | String current_version, | 196 | String current_version, |
| 201 | - NonEmptyList(Migration) all_migrations, | 197 | + List(Migration) all_migrations, |
| 202 | )= | 198 | )= |
| 203 | - if is_table_exists(db, "mails") then // new empty database | 199 | + if is_empty_database(db) then // new empty database |
| 200 | + logInfo(logger, "No database found. Creating a new one..."); | ||
| 201 | + do_migration_loop(db, logger, current_version, "", [], last(all_migrations)) | ||
| 202 | + else | ||
| 204 | ( | 203 | ( |
| 205 | with db_version = get_version_settings(db), | 204 | 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). | 205 | + do_migration_loop(db, logger, current_version, db_version, all_migrations, failure) |
| 206 | + ). | ||
| 207 | + | ||
| 208 | +public define Maybe(One) | ||
| 209 | + do_create_indexes | ||
| 210 | + ( | ||
| 211 | + SQLite3DataBase db, | ||
| 212 | + Logger logger, | ||
| 213 | + String current_version, | ||
| 214 | + List(Migration) all_migrations, | ||
| 215 | + )= | ||
| 216 | + if last(all_migrations) is | ||
| 217 | + { | ||
| 218 | + failure then logCriticalError(logger, "Index creation: migration list is empty!"); failure, | ||
| 219 | + success(last_migration) then | ||
| 220 | + if last_migration is migration(_, _, _, create_indexes) then | ||
| 221 | + if create_indexes(db, logger) is success(_) then | ||
| 222 | + success(unique) | ||
| 223 | + else | ||
| 224 | + failure | ||
| 225 | + }. |
calexium_lib/database/migration_common.anubis
| @@ -18,6 +18,11 @@ read calexium_lib/net_services_protocols/logger_service.anubis | @@ -18,6 +18,11 @@ read calexium_lib/net_services_protocols/logger_service.anubis | ||
| 18 | read ezmailbox_constants.anubis | 18 | read ezmailbox_constants.anubis |
| 19 | 19 | ||
| 20 | 20 | ||
| 21 | +public type DbTable: | ||
| 22 | + table(String name, String create_query), | ||
| 23 | + table(String db_name, String name, String create_query). | ||
| 24 | + | ||
| 25 | + | ||
| 21 | public define Bool | 26 | public define Bool |
| 22 | is_table_exists | 27 | is_table_exists |
| 23 | ( | 28 | ( |
| @@ -45,6 +50,31 @@ public define Bool | @@ -45,6 +50,31 @@ public define Bool | ||
| 45 | )= | 50 | )= |
| 46 | is_table_exists(db, "main", table_name). | 51 | is_table_exists(db, "main", table_name). |
| 47 | 52 | ||
| 53 | +public define Bool | ||
| 54 | + is_empty_database | ||
| 55 | + ( | ||
| 56 | + SQLite3DataBase db, | ||
| 57 | + String dbName, | ||
| 58 | + )= | ||
| 59 | + if sql_query_timeout(db, "SELECT * FROM " + dbName + ".sqlite_master", [], "is_empty_database("+dbName+")") is | ||
| 60 | + { | ||
| 61 | + error(_) then true, //error in the SQL request | ||
| 62 | + ok(_, cursor, _) then | ||
| 63 | + if cursor(unique) is | ||
| 64 | + { | ||
| 65 | + error(_) then true, | ||
| 66 | + no_more_row then true, | ||
| 67 | + row(current) then false | ||
| 68 | + } | ||
| 69 | + }. | ||
| 70 | + | ||
| 71 | +public define Bool | ||
| 72 | + is_empty_database | ||
| 73 | + ( | ||
| 74 | + SQLite3DataBase db, | ||
| 75 | + )= | ||
| 76 | + is_empty_database(db, "main"). | ||
| 77 | + | ||
| 48 | public define Maybe(One) | 78 | public define Maybe(One) |
| 49 | drop_all_triggers | 79 | drop_all_triggers |
| 50 | ( | 80 | ( |
| @@ -69,18 +99,27 @@ public define Maybe(One) | @@ -69,18 +99,27 @@ public define Maybe(One) | ||
| 69 | ( | 99 | ( |
| 70 | SQLite3DataBase db, | 100 | SQLite3DataBase db, |
| 71 | Logger logger, | 101 | Logger logger, |
| 72 | - List((String,String)) tables, | 102 | + List(DbTable) tables, |
| 73 | String version_string | 103 | String version_string |
| 74 | ) = | 104 | ) = |
| 75 | if tables is | 105 | if tables is |
| 76 | { | 106 | { |
| 77 | [] then success(unique), | 107 | [] then success(unique), |
| 78 | [h . t] then | 108 | [h . t] then |
| 79 | - if h is (table_name, create_string) then | ||
| 80 | - if alter_table(db, table_name, create_string, logger) is | 109 | + if h is |
| 81 | { | 110 | { |
| 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) | 111 | + table(table_name, create_string) then |
| 112 | + if alter_table(db, table_name, create_string, logger) is | ||
| 113 | + { | ||
| 114 | + failure then logError(logger, "Version "+version_string+": Can't create '"+table_name+"' table"); failure, | ||
| 115 | + success(_) then create_tables(db, logger, t, version_string) | ||
| 116 | + }, | ||
| 117 | + table(db_name, table_name, create_string) then | ||
| 118 | + if alter_table(db, db_name, table_name, create_string, logger) is | ||
| 119 | + { | ||
| 120 | + failure then logError(logger, "Version "+version_string+": Can't create '"+db_name+"."+table_name+"' table"); failure, | ||
| 121 | + success(_) then create_tables(db, logger, t, version_string) | ||
| 122 | + } | ||
| 84 | } | 123 | } |
| 85 | }. | 124 | }. |
| 86 | 125 |
calexium_lib/database/settings.anubis
| @@ -60,7 +60,24 @@ public define Int | @@ -60,7 +60,24 @@ public define Int | ||
| 60 | } | 60 | } |
| 61 | }. | 61 | }. |
| 62 | 62 | ||
| 63 | - | 63 | +public define Bool |
| 64 | + select_settings | ||
| 65 | + ( | ||
| 66 | + SQLite3DataBase db, | ||
| 67 | + String var, | ||
| 68 | + Bool default | ||
| 69 | + )= | ||
| 70 | + if select_settings(db, var) is | ||
| 71 | + { | ||
| 72 | + failure then default, //error in the SQL request | ||
| 73 | + success(value) then | ||
| 74 | + if decimal_scan(value) is | ||
| 75 | + { | ||
| 76 | + failure then default, | ||
| 77 | + success(v) then v!=0 | ||
| 78 | + } | ||
| 79 | + }. | ||
| 80 | + | ||
| 64 | public define One | 81 | public define One |
| 65 | update_settings | 82 | update_settings |
| 66 | ( | 83 | ( |