I surprisingly found that many queries for fields that exist in the
database are 'slow'. Querying items with 'month:0' used a slow query
while 'title:0' used a fast one.
I found the mistake in the logic: the field existence in the db check
was done *after* prepending the table name to the field. This meant that
the logic wrongly checked e.g. 'items.field' instead of 'field'.
This commit fixes the above and renames the variables for more clarity.
In order to include the table name for fields in this query, use the
`field_query` method.
Since `AnyFieldQuery` is just an `OrQuery` under the hood, remove it and
construct `OrQuery` explicitly instead.
Unify query creation logic from
- queryparse.py:construct_query_part,
- Model.field_query,
- DefaultTemplateFunctions._tmpl_unique
to a single implementation under `LibModel.field_query` class method.
This method should be used for query resolution for model (flex)fields.
Allow filtering item attributes in album queries and vice versa by
merging `flex_attrs` from Album and Item together as `all_flex_attrs`.
This field is only used for filtering and is discarded after.
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.
- Add NamedQuery abstract class to be able to express the expectation
that a query should be such a query (and have a specific constructor
signature) in construct_query_part
- slightly (and probably completely irrelevantly) improve Query.__hash__
- also, sprinkle some ABC/abstractmethod around to clarify things
* Revise the NotQuery syntax, replacing the '¬' character with '^'. Fix tests
to conform to this change, and cleanup the PARSE_QUERY_PART_REGEX.
* Modify parse_query_part() docstring to mention the negate parameter on the
returned tuple, and added an example.
* Update the negation query sintax so that the negation prefix ("-" or "¬") is
always the first part of a query, instead of after the ":" separator.
* Modify queryparse, so that the detection of the negation is done inside
parse_query_part() (using the modified PARSE_QUERY_PART_REGEX, and returning
the negation flag) instead of construct_query_part.
* Revert the prefixes dict on beets.library to the original dict (only one item,
with the RegexpQuery prefix).
* Modify NotQuery so it subclasses Query instead of MutableCollectionQuery.
* Update instances where NotQuery objects are created on tests and queryparse,
as NotQuery expects a single Query as a parameter to the constructor instead of
a list of Queries.
* Add support for user friendly "not" operator in queries without requiring to
use regular expressions, via adding NotQuery to beets.dbcore.query.
* Update the prefix list at library.parse_query_parts() and the query parsing
mechanisms in order to create a NotQuery when the prefix is found.
* Add two TestCases, NotQueryMatchTest as the negated version of MatchTest, and
the more generic NotQueryTest for testing the integration of the NotQuery with
the rest of the existing Query subclasses.
Slighly modify Sort parsing: avoid building MultiplSort() instances
comptised of a single sort, but return that sort instead, since it wraps
things with any gain.
Include import of __future__ features division, absolute_imports and
print_function everywhere. Don't add unicode_literals yet for it is
harder to convert.
Goal is smoothing the transition to python 3.