1212from os import makedirs
1313from pathlib import Path
1414from uuid import uuid4
15- from warnings import catch_warnings
1615
1716import structlog
1817from humanfriendly import format_timespan
3029 func ,
3130 or_ ,
3231 select ,
32+ text ,
3333 update ,
3434)
3535from sqlalchemy .exc import IntegrityError
4444
4545from ...constants import (
4646 BACKUP_FOLDER_NAME ,
47+ DEFAULT_LIB_VERSION ,
4748 LEGACY_TAG_FIELD_IDS ,
4849 RESERVED_TAG_END ,
4950 RESERVED_TAG_START ,
5253 TAG_META ,
5354 TS_FOLDER_NAME ,
5455)
55- from ...enums import LibraryPrefs
5656from ...settings import LibSettings
5757from .db import make_tables
5858from .enums import MAX_SQL_VARIABLES , FieldTypeEnum , FilterState , SortingModeEnum , TagColor
@@ -257,13 +257,10 @@ def open_library(self, library_dir: Path, storage_path: str | None = None) -> Li
257257 if storage_path == ":memory:" :
258258 self .storage_path = storage_path
259259 is_new = True
260+ self .settings = LibSettings (filename = "" )
260261 return self .open_sqlite_library (library_dir , is_new )
261262 else :
262263 self .storage_path = library_dir / TS_FOLDER_NAME / self .SQL_FILENAME
263- settings_path = library_dir / TS_FOLDER_NAME / "libsettings.toml"
264-
265- self .settings = LibSettings .open (settings_path )
266-
267264 if self .verify_ts_folder (library_dir ) and (is_new := not self .storage_path .exists ()):
268265 json_path = library_dir / TS_FOLDER_NAME / self .JSON_FILENAME
269266 if json_path .exists ():
@@ -307,29 +304,6 @@ def open_sqlite_library(self, library_dir: Path, is_new: bool) -> LibraryStatus:
307304 session .rollback ()
308305
309306 # dont check db version when creating new library
310- if not is_new :
311- db_version = session .scalar (
312- select (Preferences ).where (Preferences .key == LibraryPrefs .DB_VERSION .name )
313- )
314-
315- if not db_version :
316- return LibraryStatus (
317- success = False ,
318- message = (
319- "Library version mismatch.\n "
320- f"Found: v0, expected: v{ LibraryPrefs .DB_VERSION .default } "
321- ),
322- )
323-
324- for pref in LibraryPrefs :
325- with catch_warnings (record = True ):
326- try :
327- session .add (Preferences (key = pref .name , value = pref .default ))
328- session .commit ()
329- except IntegrityError :
330- logger .debug ("preference already exists" , pref = pref )
331- session .rollback ()
332-
333307 for field in _FieldID :
334308 try :
335309 session .add (
@@ -346,21 +320,58 @@ def open_sqlite_library(self, library_dir: Path, is_new: bool) -> LibraryStatus:
346320 logger .debug ("ValueType already exists" , field = field )
347321 session .rollback ()
348322
349- db_version = session .scalar (
350- select (Preferences ).where (Preferences .key == LibraryPrefs .DB_VERSION .name )
351- )
323+ settings_path = library_dir / TS_FOLDER_NAME / "notafile.toml"
324+
325+ # Will be set already if library was opened in-memory
326+ if self .settings is None :
327+ if settings_path .exists ():
328+ self .settings = LibSettings .open (settings_path )
329+ else :
330+ if (
331+ session .execute (
332+ text (
333+ """
334+ SELECT count(*)
335+ FROM sqlite_master
336+ WHERE type='table' AND lower(name)='preferences';
337+ """
338+ )
339+ ).scalar ()
340+ == 0
341+ ):
342+ # db was not created when settings were in db;
343+ # use default settings, store at default location
344+ self .settings = LibSettings (filename = str (settings_path ))
345+ else :
346+ # copy settings from db, store them in default location on next save
347+ prefs = session .scalars (select (Preferences ))
348+ settings = LibSettings (filename = str (settings_path ))
349+ for pref in prefs :
350+ # the type ignores below are due to the fact that a Preference's value
351+ # is defined as a dict, while none of them are actually dicts.
352+ # i dont know why that is how it is, but it is
353+ if pref .key == "IS_EXCLUDE_LIST" :
354+ settings .is_exclude_list = pref .value # type: ignore
355+ elif pref .key == "EXTENSION_LIST" :
356+ settings .extension_list = pref .value # type: ignore
357+ elif pref .key == "PAGE_SIZE" :
358+ settings .page_size = pref .value # type: ignore
359+ elif pref .key == "DB_VERSION" :
360+ settings .db_version = pref .value # type: ignore
361+
362+ self .settings = settings
352363 # if the db version is different, we cant proceed
353- if db_version . value != LibraryPrefs . DB_VERSION . default :
364+ if not is_new and self . settings . db_version != DEFAULT_LIB_VERSION :
354365 logger .error (
355366 "DB version mismatch" ,
356- db_version = db_version . value ,
357- expected = LibraryPrefs . DB_VERSION . default ,
367+ db_version = self . settings . db_version ,
368+ expected = DEFAULT_LIB_VERSION ,
358369 )
359370 return LibraryStatus (
360371 success = False ,
361372 message = (
362373 "Library version mismatch.\n "
363- f"Found: v{ db_version . value } , expected: v{ LibraryPrefs . DB_VERSION . default } "
374+ f"Found: v{ self . settings . db_version } , expected: v{ DEFAULT_LIB_VERSION } "
364375 ),
365376 )
366377
@@ -1107,21 +1118,6 @@ def update_parent_tags(self, tag, parent_ids, session):
11071118 )
11081119 session .add (parent_tag )
11091120
1110- def prefs (self , key : LibraryPrefs ):
1111- # load given item from Preferences table
1112- with Session (self .engine ) as session :
1113- return session .scalar (select (Preferences ).where (Preferences .key == key .name )).value
1114-
1115- def set_prefs (self , key : LibraryPrefs , value ) -> None :
1116- # set given item in Preferences table
1117- with Session (self .engine ) as session :
1118- # load existing preference and update value
1119- pref = session .scalar (select (Preferences ).where (Preferences .key == key .name ))
1120- pref .value = value
1121- session .add (pref )
1122- session .commit ()
1123- # TODO - try/except
1124-
11251121 def mirror_entry_fields (self , * entries : Entry ) -> None :
11261122 """Mirror fields among multiple Entry items."""
11271123 fields = {}
0 commit comments