Handle NULL values in the path column

As I was devving, I did something wrong and had 'beet mv' command fail on me.

Later, having spent an hour investigating why beets kept throwing me
'User-defined function raised exception' I discovered that it was
failing because that previous 'beet mv' command ended up writing value
'NULL' in one of the items 'path' column. This was not handled well by
the 'BYTELOWER' implementation.

Since we do not have a NOT NULL constraint for the 'path' column, it's
best to insure ourselves against this kind of stuff anyways.
This commit is contained in:
Šarūnas Nejus 2024-04-30 17:13:17 +01:00
parent 92fb830559
commit 065f091656
No known key found for this signature in database
GPG key ID: DD28F6704DBE3435
2 changed files with 15 additions and 16 deletions

View file

@ -29,6 +29,7 @@ from sqlite3 import Connection
from types import TracebackType
from typing import (
Any,
AnyStr,
Callable,
DefaultDict,
Dict,
@ -1088,8 +1089,22 @@ class Database:
value = value.decode()
return re.search(pattern, str(value)) is not None
def bytelower(bytestring: Optional[AnyStr]) -> Optional[AnyStr]:
"""A custom ``bytelower`` sqlite function so we can compare
bytestrings in a semi case insensitive fashion.
This is to work around sqlite builds are that compiled with
``-DSQLITE_LIKE_DOESNT_MATCH_BLOBS``. See
``https://github.com/beetbox/beets/issues/2172`` for details.
"""
if bytestring is not None:
return bytestring.lower()
return bytestring
conn.create_function("regexp", 2, regexp)
conn.create_function("unidecode", 1, unidecode)
conn.create_function("bytelower", 1, bytelower)
def _close(self):
"""Close the all connections to the underlying SQLite database

View file

@ -1550,17 +1550,6 @@ def parse_query_string(s, model_cls):
return parse_query_parts(parts, model_cls)
def _sqlite_bytelower(bytestring):
"""A custom ``bytelower`` sqlite function so we can compare
bytestrings in a semi case insensitive fashion.
This is to work around sqlite builds are that compiled with
``-DSQLITE_LIKE_DOESNT_MATCH_BLOBS``. See
``https://github.com/beetbox/beets/issues/2172`` for details.
"""
return bytestring.lower()
# The Library: interface to the database.
@ -1585,11 +1574,6 @@ class Library(dbcore.Database):
self._memotable = {} # Used for template substitution performance.
def _create_connection(self):
conn = super()._create_connection()
conn.create_function("bytelower", 1, _sqlite_bytelower)
return conn
# Adding objects to the database.
def add(self, obj):