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 | 29 | /** |
| 30 | 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 | 35 | String version1, |
| 36 | 36 | String version2 |
| ... | ... | @@ -51,10 +51,10 @@ define Int |
| 51 | 51 | [h2 . t2] then |
| 52 | 52 | if h1 = h2 then compare(t1, t2) |
| 53 | 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 | 58 | else 0 |
| 59 | 59 | }, |
| 60 | 60 | }, |
| ... | ... | @@ -148,63 +148,78 @@ public type Migration: |
| 148 | 148 | define Maybe(One) |
| 149 | 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 | 158 | if migrations is |
| 160 | 159 | { |
| 161 | 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 | 172 | else |
| 176 | 173 | failure |
| 177 | -// } | |
| 178 | - ) | |
| 179 | - else | |
| 180 | - update_version_settings(db, current_version); | |
| 181 | - success(unique), | |
| 174 | + else | |
| 175 | + failure | |
| 176 | + }, | |
| 182 | 177 | [h . t] then |
| 183 | 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 | 180 | logInfo(logger, "Migrating Database from version " + db_ver + " to version " + version); |
| 186 | 181 | if migrate_to(db, logger) is failure then |
| 187 | 182 | failure |
| 188 | 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 | 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 | 191 | public define Maybe(One) |
| 196 | 192 | do_migration |
| 197 | 193 | ( |
| 198 | 194 | SQLite3DataBase db, |
| 199 | 195 | Logger logger, |
| 200 | 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 | 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 | 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 | 26 | public define Bool |
| 22 | 27 | is_table_exists |
| 23 | 28 | ( |
| ... | ... | @@ -45,6 +50,31 @@ public define Bool |
| 45 | 50 | )= |
| 46 | 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 | 78 | public define Maybe(One) |
| 49 | 79 | drop_all_triggers |
| 50 | 80 | ( |
| ... | ... | @@ -69,18 +99,27 @@ public define Maybe(One) |
| 69 | 99 | ( |
| 70 | 100 | SQLite3DataBase db, |
| 71 | 101 | Logger logger, |
| 72 | - List((String,String)) tables, | |
| 102 | + List(DbTable) tables, | |
| 73 | 103 | String version_string |
| 74 | 104 | ) = |
| 75 | 105 | if tables is |
| 76 | 106 | { |
| 77 | 107 | [] then success(unique), |
| 78 | 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 | 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 | 81 | public define One |
| 65 | 82 | update_settings |
| 66 | 83 | ( | ... | ... |