@@ -318,6 +318,7 @@ def open_sqlite_library(self, library_dir: Path, is_new: bool) -> LibraryStatus:
318
318
# https://docs.sqlalchemy.org/en/20/changelog/migration_07.html
319
319
# Under -> sqlite-the-sqlite-dialect-now-uses-nullpool-for-file-based-databases
320
320
poolclass = None if self .storage_path == ":memory:" else NullPool
321
+ db_version : int = 0
321
322
322
323
logger .info (
323
324
"[Library] Opening SQLite Library" ,
@@ -328,11 +329,13 @@ def open_sqlite_library(self, library_dir: Path, is_new: bool) -> LibraryStatus:
328
329
with Session (self .engine ) as session :
329
330
# dont check db version when creating new library
330
331
if not is_new :
331
- db_version = session .scalar (
332
+ db_result = session .scalar (
332
333
select (Preferences ).where (Preferences .key == LibraryPrefs .DB_VERSION .name )
333
334
)
335
+ if db_result :
336
+ db_version = db_result .value # type: ignore
334
337
335
- if not db_version or db_version . value != LibraryPrefs . DB_VERSION . default :
338
+ if db_version < 6 : # NOTE: DB_VERSION 6 is the first supported SQL DB version.
336
339
mismatch_text = Translations .translate_formatted (
337
340
"status.library_version_mismatch"
338
341
)
@@ -344,15 +347,14 @@ def open_sqlite_library(self, library_dir: Path, is_new: bool) -> LibraryStatus:
344
347
success = False ,
345
348
message = (
346
349
f"{ mismatch_text } \n "
347
- f"{ found_text } v{ 0 if not db_version else db_version . value } , "
350
+ f"{ found_text } v{ db_version } , "
348
351
f"{ expected_text } v{ LibraryPrefs .DB_VERSION .default } "
349
352
),
350
353
)
351
354
355
+ logger .info (f"[Library] DB_VERSION: { db_version } " )
352
356
make_tables (self .engine )
353
357
354
- # TODO: Determine a good way of updating built-in data after updates.
355
-
356
358
# Add default tag color namespaces.
357
359
if is_new :
358
360
namespaces = default_color_groups .namespaces ()
@@ -421,14 +423,52 @@ def open_sqlite_library(self, library_dir: Path, is_new: bool) -> LibraryStatus:
421
423
)
422
424
session .add (folder )
423
425
session .expunge (folder )
424
-
425
426
session .commit ()
426
427
self .folder = folder
427
428
429
+ # Apply any post-SQL migration patches.
430
+ if not is_new :
431
+ # NOTE: DB_VERSION 6 was first used in v9.5.0-pr1
432
+ if db_version == 6 :
433
+ self .apply_db6_patches (session )
434
+ else :
435
+ pass
436
+
437
+ # Update DB_VERSION
438
+ self .set_prefs (LibraryPrefs .DB_VERSION , LibraryPrefs .DB_VERSION .default )
439
+
428
440
# everything is fine, set the library path
429
441
self .library_dir = library_dir
430
442
return LibraryStatus (success = True , library_path = library_dir )
431
443
444
+ def apply_db6_patches (self , session : Session ):
445
+ """Apply migration patches to a library with DB_VERSION 6.
446
+
447
+ DB_VERSION 6 was first used in v9.5.0-pr1.
448
+ """
449
+ logger .info ("[Library] Applying patches to DB_VERSION: 6 library..." )
450
+ with session :
451
+ # Repair "Description" fields with a TEXT_LINE key instead of a TEXT_BOX key.
452
+ desc_stmd = (
453
+ update (ValueType )
454
+ .where (ValueType .key == _FieldID .DESCRIPTION .name )
455
+ .values (type = FieldTypeEnum .TEXT_BOX .name )
456
+ )
457
+ session .execute (desc_stmd )
458
+ session .flush ()
459
+
460
+ # Repair tags that may have a disambiguation_id pointing towards a deleted tag.
461
+ all_tag_ids : set [int ] = {tag .id for tag in self .tags }
462
+ disam_stmt = (
463
+ update (Tag )
464
+ .where (Tag .disambiguation_id .not_in (all_tag_ids ))
465
+ .values (disambiguation_id = None )
466
+ )
467
+ session .execute (disam_stmt )
468
+ session .flush ()
469
+
470
+ session .commit ()
471
+
432
472
@property
433
473
def default_fields (self ) -> list [BaseField ]:
434
474
with Session (self .engine ) as session :
@@ -793,6 +833,14 @@ def remove_tag(self, tag: Tag):
793
833
session .delete (child_tag )
794
834
session .expunge (child_tag )
795
835
836
+ disam_stmt = (
837
+ update (Tag )
838
+ .where (Tag .disambiguation_id == tag .id )
839
+ .values (disambiguation_id = None )
840
+ )
841
+ session .execute (disam_stmt )
842
+ session .flush ()
843
+
796
844
session .delete (tag )
797
845
session .commit ()
798
846
session .expunge (tag )
0 commit comments