mirror of
https://github.com/beetbox/beets.git
synced 2025-12-31 21:12:43 +01:00
Remove NamedQuery
Remove 'NamedQuery' since it is not being used by any queries any more. This simplifies query parsing logic in 'queryparse.py'. We know that this logic can only receive 'FieldQuery' thus I adjusted types and removed the logic that handles other cases. Effectively, this means that the query parsing logic does not any more care whether the query is named by the corresponding DB field. Instead, queries like 'SingletonQuery' and 'PlaylistQuery' are responsible for translating 'singleton' and 'playlist' to the underlying DB filters.
This commit is contained in:
parent
68eee96c03
commit
a57c164348
5 changed files with 17 additions and 48 deletions
|
|
@ -22,7 +22,6 @@ from .query import (
|
|||
FieldQuery,
|
||||
InvalidQueryError,
|
||||
MatchQuery,
|
||||
NamedQuery,
|
||||
OrQuery,
|
||||
Query,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -12,8 +12,7 @@
|
|||
# The above copyright notice and this permission notice shall be
|
||||
# included in all copies or substantial portions of the Software.
|
||||
|
||||
"""The central Model and Database constructs for DBCore.
|
||||
"""
|
||||
"""The central Model and Database constructs for DBCore."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
|
|
@ -309,7 +308,7 @@ class Model(ABC):
|
|||
are subclasses of `Sort`.
|
||||
"""
|
||||
|
||||
_queries: Dict[str, Type[Query]] = {}
|
||||
_queries: Dict[str, Type[FieldQuery]] = {}
|
||||
"""Named queries that use a field-like `name:value` syntax but which
|
||||
do not relate to any specific field.
|
||||
"""
|
||||
|
|
@ -599,8 +598,7 @@ class Model(ABC):
|
|||
# Deleted flexible attributes.
|
||||
for key in self._dirty:
|
||||
tx.mutate(
|
||||
"DELETE FROM {} "
|
||||
"WHERE entity_id=? AND key=?".format(self._flex_table),
|
||||
f"DELETE FROM {self._flex_table} WHERE entity_id=? AND key=?",
|
||||
(self.id, key),
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -115,15 +115,6 @@ class Query(ABC):
|
|||
return hash(type(self))
|
||||
|
||||
|
||||
class NamedQuery(Query):
|
||||
"""Non-field query, i.e. the query prefix is not a field but identifies the
|
||||
query class.
|
||||
"""
|
||||
|
||||
@abstractmethod
|
||||
def __init__(self, pattern): ...
|
||||
|
||||
|
||||
P = TypeVar("P")
|
||||
SQLiteType = Union[str, float, int, memoryview]
|
||||
AnySQLiteType = TypeVar("AnySQLiteType", bound=SQLiteType)
|
||||
|
|
|
|||
|
|
@ -12,15 +12,14 @@
|
|||
# The above copyright notice and this permission notice shall be
|
||||
# included in all copies or substantial portions of the Software.
|
||||
|
||||
"""Parsing of strings into DBCore queries.
|
||||
"""
|
||||
"""Parsing of strings into DBCore queries."""
|
||||
|
||||
import itertools
|
||||
import re
|
||||
from typing import Collection, Dict, List, Optional, Sequence, Tuple, Type
|
||||
|
||||
from . import Model, query
|
||||
from .query import Query, Sort
|
||||
from .query import Sort
|
||||
|
||||
PARSE_QUERY_PART_REGEX = re.compile(
|
||||
# Non-capturing optional segment for the keyword.
|
||||
|
|
@ -36,10 +35,10 @@ PARSE_QUERY_PART_REGEX = re.compile(
|
|||
|
||||
def parse_query_part(
|
||||
part: str,
|
||||
query_classes: Dict = {},
|
||||
query_classes: Dict[str, Type[query.FieldQuery]] = {},
|
||||
prefixes: Dict = {},
|
||||
default_class: Type[query.SubstringQuery] = query.SubstringQuery,
|
||||
) -> Tuple[Optional[str], str, Type[query.Query], bool]:
|
||||
) -> Tuple[Optional[str], str, Type[query.FieldQuery], bool]:
|
||||
"""Parse a single *query part*, which is a chunk of a complete query
|
||||
string representing a single criterion.
|
||||
|
||||
|
|
@ -128,7 +127,7 @@ def construct_query_part(
|
|||
|
||||
# Use `model_cls` to build up a map from field (or query) names to
|
||||
# `Query` classes.
|
||||
query_classes: Dict[str, Type[Query]] = {}
|
||||
query_classes: Dict[str, Type[query.FieldQuery]] = {}
|
||||
for k, t in itertools.chain(
|
||||
model_cls._fields.items(), model_cls._types.items()
|
||||
):
|
||||
|
|
@ -143,30 +142,17 @@ def construct_query_part(
|
|||
# If there's no key (field name) specified, this is a "match
|
||||
# anything" query.
|
||||
if key is None:
|
||||
if issubclass(query_class, query.FieldQuery):
|
||||
# The query type matches a specific field, but none was
|
||||
# specified. So we use a version of the query that matches
|
||||
# any field.
|
||||
out_query = query.AnyFieldQuery(
|
||||
pattern, model_cls._search_fields, query_class
|
||||
)
|
||||
elif issubclass(query_class, query.NamedQuery):
|
||||
# Non-field query type.
|
||||
out_query = query_class(pattern)
|
||||
else:
|
||||
assert False, "Unexpected query type"
|
||||
# The query type matches a specific field, but none was
|
||||
# specified. So we use a version of the query that matches
|
||||
# any field.
|
||||
out_query = query.AnyFieldQuery(
|
||||
pattern, model_cls._search_fields, query_class
|
||||
)
|
||||
|
||||
# Field queries get constructed according to the name of the field
|
||||
# they are querying.
|
||||
elif issubclass(query_class, query.FieldQuery):
|
||||
key = key.lower()
|
||||
out_query = query_class(key.lower(), pattern, key in model_cls._fields)
|
||||
|
||||
# Non-field (named) query.
|
||||
elif issubclass(query_class, query.NamedQuery):
|
||||
out_query = query_class(pattern)
|
||||
else:
|
||||
assert False, "Unexpected query type"
|
||||
out_query = query_class(key.lower(), pattern, key in model_cls._fields)
|
||||
|
||||
# Apply negation.
|
||||
if negate:
|
||||
|
|
|
|||
|
|
@ -12,8 +12,7 @@
|
|||
# The above copyright notice and this permission notice shall be
|
||||
# included in all copies or substantial portions of the Software.
|
||||
|
||||
"""Tests for the DBCore database abstraction.
|
||||
"""
|
||||
"""Tests for the DBCore database abstraction."""
|
||||
|
||||
import os
|
||||
import shutil
|
||||
|
|
@ -32,7 +31,7 @@ class SortFixture(dbcore.query.FieldSort):
|
|||
pass
|
||||
|
||||
|
||||
class QueryFixture(dbcore.query.NamedQuery):
|
||||
class QueryFixture(dbcore.query.FieldQuery):
|
||||
def __init__(self, pattern):
|
||||
self.pattern = pattern
|
||||
|
||||
|
|
@ -605,10 +604,6 @@ class QueryFromStringsTest(unittest.TestCase):
|
|||
q = self.qfs([""])
|
||||
self.assertIsInstance(q.subqueries[0], dbcore.query.TrueQuery)
|
||||
|
||||
def test_parse_named_query(self):
|
||||
q = self.qfs(["some_query:foo"])
|
||||
self.assertIsInstance(q.subqueries[0], QueryFixture)
|
||||
|
||||
|
||||
class SortFromStringsTest(unittest.TestCase):
|
||||
def sfs(self, strings):
|
||||
|
|
|
|||
Loading…
Reference in a new issue