From 0f1b5d6f7c63402761cdf0bafc5287887888df3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0ar=C5=ABnas=20Nejus?= Date: Tue, 4 Apr 2023 10:25:27 +0100 Subject: [PATCH 1/2] Perform regex lookup in SQL This improves performance of some string field lookups, for example `beet list path::aa` --- beets/dbcore/db.py | 9 +++++++++ beets/dbcore/query.py | 3 +++ docs/changelog.rst | 1 + 3 files changed, 13 insertions(+) diff --git a/beets/dbcore/db.py b/beets/dbcore/db.py index c181f7b33..55c78c88d 100755 --- a/beets/dbcore/db.py +++ b/beets/dbcore/db.py @@ -975,6 +975,7 @@ class Database: conn = sqlite3.connect( py3_path(self.path), timeout=self.timeout ) + self.add_functions(conn) if self.supports_extensions: conn.enable_load_extension(True) @@ -987,6 +988,14 @@ class Database: conn.row_factory = sqlite3.Row return conn + def add_functions(self, conn): + def regexp(value, pattern): + if isinstance(value, bytes): + value = value.decode() + return re.search(pattern, str(value)) is not None + + conn.create_function("regexp", 2, regexp) + def _close(self): """Close the all connections to the underlying SQLite database from all threads. This does not render the database object diff --git a/beets/dbcore/query.py b/beets/dbcore/query.py index a0d79da70..016fe2c1a 100644 --- a/beets/dbcore/query.py +++ b/beets/dbcore/query.py @@ -231,6 +231,9 @@ class RegexpQuery(StringFieldQuery): "a regular expression", format(exc)) + def col_clause(self): + return f" regexp({self.field}, ?)", [self.pattern.pattern] + @staticmethod def _normalize(s): """Normalize a Unicode string's representation (used on both diff --git a/docs/changelog.rst b/docs/changelog.rst index 39cd8fa2d..f1cca7570 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -13,6 +13,7 @@ New features: * --from-logfile now parses log files using a UTF-8 encoding in `beets/beets/ui/commands.py`. :bug:`4693` +* :ref:`list-cmd` lookups using the pattern operator `::` have been made faster * Added additional error handling for `spotify` plugin. :bug:`4686` * We now import the remixer field from Musicbrainz into the library. From b5b1afbfff93d842d8c34cfd17c9e5bf36625917 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0ar=C5=ABnas=20Nejus?= Date: Sat, 8 Apr 2023 05:30:32 +0100 Subject: [PATCH 2/2] Also perform bareasc queries in SQL --- beets/dbcore/db.py | 3 +++ beetsplug/bareasc.py | 8 ++++++++ docs/changelog.rst | 1 + 3 files changed, 12 insertions(+) diff --git a/beets/dbcore/db.py b/beets/dbcore/db.py index 55c78c88d..94396f81b 100755 --- a/beets/dbcore/db.py +++ b/beets/dbcore/db.py @@ -23,6 +23,8 @@ import threading import sqlite3 import contextlib +from unidecode import unidecode + import beets from beets.util import functemplate from beets.util import py3_path @@ -995,6 +997,7 @@ class Database: return re.search(pattern, str(value)) is not None conn.create_function("regexp", 2, regexp) + conn.create_function("unidecode", 1, unidecode) def _close(self): """Close the all connections to the underlying SQLite database diff --git a/beetsplug/bareasc.py b/beetsplug/bareasc.py index 218369364..3343786f9 100644 --- a/beetsplug/bareasc.py +++ b/beetsplug/bareasc.py @@ -42,6 +42,14 @@ class BareascQuery(StringFieldQuery): val = unidecode(val) return pattern in val + def col_clause(self): + """Compare ascii version of the pattern.""" + clause = f"unidecode({self.field})" + if self.pattern.islower(): + clause = f"lower({clause})" + + return rf"{clause} LIKE ? ESCAPE '\'", [f"%{unidecode(self.pattern)}%"] + class BareascPlugin(BeetsPlugin): """Plugin to provide bare-ASCII option for beets matching.""" diff --git a/docs/changelog.rst b/docs/changelog.rst index f1cca7570..7a5ecdfe7 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -13,6 +13,7 @@ New features: * --from-logfile now parses log files using a UTF-8 encoding in `beets/beets/ui/commands.py`. :bug:`4693` +* :doc:`/plugins/bareasc` lookups have been made faster * :ref:`list-cmd` lookups using the pattern operator `::` have been made faster * Added additional error handling for `spotify` plugin. :bug:`4686`