From 04ee04150ac6ce41393c4e8e0d04030f3c5e2596 Mon Sep 17 00:00:00 2001 From: Andrew Rogl Date: Mon, 30 Sep 2024 19:28:15 +1000 Subject: [PATCH] Reworked #4709 after latest release (#5447) Fixes #4709 SQL use of Double Quoted Strings. --- CONTRIBUTING.rst | 4 ++-- beets/dbcore/query.py | 4 ++-- beets/library.py | 7 ++----- beetsplug/web/__init__.py | 2 +- docs/changelog.rst | 2 ++ test/test_library.py | 10 ++++++---- 6 files changed, 15 insertions(+), 14 deletions(-) diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index b9593741c..ee4edbdcb 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -237,7 +237,7 @@ There are a few coding conventions we use in beets: .. code-block:: python with g.lib.transaction() as tx: - rows = tx.query('SELECT DISTINCT "{0}" FROM "{1}" ORDER BY "{2}"' + rows = tx.query("SELECT DISTINCT '{0}' FROM '{1}' ORDER BY '{2}'" .format(field, model._table, sort_field)) To fetch Item objects from the database, use lib.items(…) and supply @@ -248,7 +248,7 @@ There are a few coding conventions we use in beets: .. code-block:: python with lib.transaction() as tx: - rows = tx.query('SELECT …') + rows = tx.query("SELECT …") Transaction objects help control concurrent access to the database and assist in debugging conflicting accesses. diff --git a/beets/dbcore/query.py b/beets/dbcore/query.py index f8cf7fe4c..5088b1e77 100644 --- a/beets/dbcore/query.py +++ b/beets/dbcore/query.py @@ -1040,8 +1040,8 @@ class FixedFieldSort(FieldSort): if self.case_insensitive: field = ( "(CASE " - 'WHEN TYPEOF({0})="text" THEN LOWER({0}) ' - 'WHEN TYPEOF({0})="blob" THEN LOWER({0}) ' + "WHEN TYPEOF({0})='text' THEN LOWER({0}) " + "WHEN TYPEOF({0})='blob' THEN LOWER({0}) " "ELSE {0} END)".format(self.field) ) else: diff --git a/beets/library.py b/beets/library.py index e8e0f0f83..1f099e2d0 100644 --- a/beets/library.py +++ b/beets/library.py @@ -312,11 +312,8 @@ class SmartArtistSort(dbcore.query.Sort): order = "ASC" if self.ascending else "DESC" field = "albumartist" if self.album else "artist" collate = "COLLATE NOCASE" if self.case_insensitive else "" - return ( - "(CASE {0}_sort WHEN NULL THEN {0} " - 'WHEN "" THEN {0} ' - "ELSE {0}_sort END) {1} {2}" - ).format(field, collate, order) + + return f"COALESCE(NULLIF({field}_sort, ''), {field}) {collate} {order}" def sort(self, objs): if self.album: diff --git a/beetsplug/web/__init__.py b/beetsplug/web/__init__.py index dcd0ba38c..55864f503 100644 --- a/beetsplug/web/__init__.py +++ b/beetsplug/web/__init__.py @@ -231,7 +231,7 @@ def _get_unique_table_field_values(model, field, sort_field): raise KeyError with g.lib.transaction() as tx: rows = tx.query( - 'SELECT DISTINCT "{}" FROM "{}" ORDER BY "{}"'.format( + "SELECT DISTINCT '{}' FROM '{}' ORDER BY '{}'".format( field, model._table, sort_field ) ) diff --git a/docs/changelog.rst b/docs/changelog.rst index 33a4b5f94..63ce2e0c4 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -40,6 +40,8 @@ Bug fixes: issues in the future. :bug:`5289` * :doc:`plugins/discogs`: Fix the ``TypeError`` when there is no description. +* Remove single quotes from all SQL queries + :bug:`4709` For packagers: diff --git a/test/test_library.py b/test/test_library.py index 9b29505a3..c48044210 100644 --- a/test/test_library.py +++ b/test/test_library.py @@ -59,7 +59,7 @@ class StoreTest(ItemInDBTestCase): self.i.store() new_year = ( self.lib._connection() - .execute("select year from items where " 'title="the title"') + .execute("select year from items where title = ?", (self.i.title,)) .fetchone()["year"] ) assert new_year == 1987 @@ -70,7 +70,7 @@ class StoreTest(ItemInDBTestCase): self.i.store() new_genre = ( self.lib._connection() - .execute("select genre from items where " 'title="the title"') + .execute("select genre from items where title = ?", (self.i.title,)) .fetchone()["genre"] ) assert new_genre == original_genre @@ -104,7 +104,8 @@ class AddTest(BeetsTestCase): new_grouping = ( self.lib._connection() .execute( - "select grouping from items " 'where composer="the composer"' + "select grouping from items where composer = ?", + (self.i.composer,), ) .fetchone()["grouping"] ) @@ -118,7 +119,8 @@ class AddTest(BeetsTestCase): new_grouping = ( self.lib._connection() .execute( - "select grouping from items " 'where composer="the composer"' + "select grouping from items where composer = ?", + (self.i.composer,), ) .fetchone()["grouping"] )