Commit 68665c4a1c27de340617c156304a783a61bdb9bb

Authored by Cédric RICARD
1 parent 8a2b97fb

Improved DB migration library

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 (