@@ -318,6 +318,7 @@ def open_sqlite_library(self, library_dir: Path, is_new: bool) -> LibraryStatus:
318318 # https://docs.sqlalchemy.org/en/20/changelog/migration_07.html
319319 # Under -> sqlite-the-sqlite-dialect-now-uses-nullpool-for-file-based-databases
320320 poolclass = None if self .storage_path == ":memory:" else NullPool
321+ db_version : int = 0
321322
322323 logger .info (
323324 "[Library] Opening SQLite Library" ,
@@ -328,11 +329,13 @@ def open_sqlite_library(self, library_dir: Path, is_new: bool) -> LibraryStatus:
328329 with Session (self .engine ) as session :
329330 # dont check db version when creating new library
330331 if not is_new :
331- db_version = session .scalar (
332+ db_result = session .scalar (
332333 select (Preferences ).where (Preferences .key == LibraryPrefs .DB_VERSION .name )
333334 )
335+ if db_result :
336+ db_version = db_result .value # type: ignore
334337
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.
336339 mismatch_text = Translations .translate_formatted (
337340 "status.library_version_mismatch"
338341 )
@@ -344,15 +347,14 @@ def open_sqlite_library(self, library_dir: Path, is_new: bool) -> LibraryStatus:
344347 success = False ,
345348 message = (
346349 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 } , "
348351 f"{ expected_text } v{ LibraryPrefs .DB_VERSION .default } "
349352 ),
350353 )
351354
355+ logger .info (f"[Library] DB_VERSION: { db_version } " )
352356 make_tables (self .engine )
353357
354- # TODO: Determine a good way of updating built-in data after updates.
355-
356358 # Add default tag color namespaces.
357359 if is_new :
358360 namespaces = default_color_groups .namespaces ()
@@ -421,14 +423,52 @@ def open_sqlite_library(self, library_dir: Path, is_new: bool) -> LibraryStatus:
421423 )
422424 session .add (folder )
423425 session .expunge (folder )
424-
425426 session .commit ()
426427 self .folder = folder
427428
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+
428440 # everything is fine, set the library path
429441 self .library_dir = library_dir
430442 return LibraryStatus (success = True , library_path = library_dir )
431443
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+
432472 @property
433473 def default_fields (self ) -> list [BaseField ]:
434474 with Session (self .engine ) as session :
@@ -793,6 +833,14 @@ def remove_tag(self, tag: Tag):
793833 session .delete (child_tag )
794834 session .expunge (child_tag )
795835
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+
796844 session .delete (tag )
797845 session .commit ()
798846 session .expunge (tag )
0 commit comments