From 93dae86356a11fafef8a588aac825ae6be617a3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0ar=C5=ABnas=20Nejus?= Date: Fri, 1 Aug 2025 17:08:08 +0100 Subject: [PATCH] dbcore: replace _check_db by db cached attribute --- beets/dbcore/db.py | 19 +++++++++++-------- beets/library/models.py | 8 +++----- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/beets/dbcore/db.py b/beets/dbcore/db.py index cc172d0d8..6ee880597 100755 --- a/beets/dbcore/db.py +++ b/beets/dbcore/db.py @@ -34,6 +34,7 @@ from collections.abc import ( Mapping, Sequence, ) +from functools import cached_property from sqlite3 import Connection, sqlite_version_info from typing import TYPE_CHECKING, Any, AnyStr, Generic @@ -360,6 +361,10 @@ class Model(ABC, Generic[D]): """Fields in the related table.""" return cls._relation._fields.keys() - cls.shared_db_fields + @cached_property + def db(self) -> D: + return self._check_db() + @classmethod def _getters(cls: type[Model]): """Return a mapping from field names to getter functions.""" @@ -599,7 +604,6 @@ class Model(ABC, Generic[D]): """ if fields is None: fields = self._fields - db = self._check_db() # Build assignments for query. assignments = [] @@ -611,7 +615,7 @@ class Model(ABC, Generic[D]): value = self._type(key).to_sql(self[key]) subvars.append(value) - with db.transaction() as tx: + with self.db.transaction() as tx: # Main table update. if assignments: query = f"UPDATE {self._table} SET {','.join(assignments)} WHERE id=?" @@ -645,11 +649,10 @@ class Model(ABC, Generic[D]): If check_revision is true, the database is only queried loaded when a transaction has been committed since the item was last loaded. """ - db = self._check_db() - if not self._dirty and db.revision == self._revision: + if not self._dirty and self.db.revision == self._revision: # Exit early return - stored_obj = db._get(type(self), self.id) + stored_obj = self.db._get(type(self), self.id) assert stored_obj is not None, f"object {self.id} not in DB" self._values_fixed = LazyConvertDict(self) self._values_flex = LazyConvertDict(self) @@ -658,8 +661,7 @@ class Model(ABC, Generic[D]): def remove(self): """Remove the object's associated rows from the database.""" - db = self._check_db() - with db.transaction() as tx: + with self.db.transaction() as tx: tx.mutate(f"DELETE FROM {self._table} WHERE id=?", (self.id,)) tx.mutate( f"DELETE FROM {self._flex_table} WHERE entity_id=?", (self.id,) @@ -675,7 +677,7 @@ class Model(ABC, Generic[D]): """ if db: self._db = db - db = self._check_db(False) + db = self._check_db(need_id=False) with db.transaction() as tx: new_id = tx.mutate(f"INSERT INTO {self._table} DEFAULT VALUES") @@ -742,6 +744,7 @@ class Model(ABC, Generic[D]): """ state = self.__dict__.copy() state["_db"] = None + state["db"] = None return state diff --git a/beets/library/models.py b/beets/library/models.py index cbee2a411..76618d929 100644 --- a/beets/library/models.py +++ b/beets/library/models.py @@ -1143,7 +1143,6 @@ class Item(LibModel): If `store` is `False` however, the item won't be stored and it will have to be manually stored after invoking this method. """ - self._check_db() dest = self.destination(basedir=basedir) # Create necessary ancestry for the move. @@ -1183,9 +1182,8 @@ class Item(LibModel): is true, returns just the fragment of the path underneath the library base directory. """ - db = self._check_db() - basedir = basedir or db.directory - path_formats = path_formats or db.path_formats + basedir = basedir or self.db.directory + path_formats = path_formats or self.db.path_formats # Use a path format based on a query, falling back on the # default. @@ -1224,7 +1222,7 @@ class Item(LibModel): ) lib_path_str, fallback = util.legalize_path( - subpath, db.replacements, self.filepath.suffix + subpath, self.db.replacements, self.filepath.suffix ) if fallback: # Print an error message if legalization fell back to