Add NoneQuery

This makes fast SQL queries for singletons possible
This commit is contained in:
Thomas Scholtes 2014-09-17 11:23:00 +02:00
parent 89d7c5d896
commit ad71af2c3d
2 changed files with 54 additions and 9 deletions

View file

@ -83,6 +83,23 @@ class MatchQuery(FieldQuery):
return pattern == value
class NoneQuery(FieldQuery):
def __init__(self, field, fast=True):
self.field = field
self.fast = fast
def col_clause(self):
return self.field + " IS NULL", ()
@classmethod
def match(self, item):
try:
return item[self.field] is None
except KeyError:
return True
class StringFieldQuery(FieldQuery):
"""A FieldQuery that converts values to strings before matching
them.

View file

@ -16,14 +16,26 @@
"""
import _common
from _common import unittest
from helper import TestHelper
import helper
import beets.library
from beets import dbcore
from beets.dbcore import types
from beets.dbcore.query import NoneQuery
from beets.library import Library, Item
class TestHelper(helper.TestHelper):
def assertInResult(self, item, results):
result_ids = map(lambda i: i.id, results)
self.assertIn(item.id, result_ids)
def assertNotInResult(self, item, results):
result_ids = map(lambda i: i.id, results)
self.assertNotIn(item.id, result_ids)
class AnyFieldQueryTest(_common.LibTestCase):
def test_no_restriction(self):
q = dbcore.query.AnyFieldQuery(
@ -469,14 +481,6 @@ class BoolQueryTest(unittest.TestCase, TestHelper):
self.assertInResult(item_false, matched)
self.assertNotInResult(item_true, matched)
def assertInResult(self, item, results):
result_ids = map(lambda i: i.id, results)
self.assertIn(item.id, result_ids)
def assertNotInResult(self, item, results):
result_ids = map(lambda i: i.id, results)
self.assertNotIn(item.id, result_ids)
class DefaultSearchFieldsTest(DummyDataTestCase):
def test_albums_matches_album(self):
@ -496,6 +500,30 @@ class DefaultSearchFieldsTest(DummyDataTestCase):
self.assert_matched(items, [])
class NoneQueryTest(unittest.TestCase, TestHelper):
def setUp(self):
self.lib = Library(':memory:')
def test_match_singletons(self):
singleton = self.add_item()
album_item = self.add_album().items().get()
matched = self.lib.items(NoneQuery('album_id'))
self.assertInResult(singleton, matched)
self.assertNotInResult(album_item, matched)
def test_match_after_set_none(self):
item = self.add_item(rg_track_gain=0)
matched = self.lib.items(NoneQuery('rg_track_gain'))
self.assertNotInResult(item, matched)
item['rg_track_gain'] = None
item.store()
matched = self.lib.items(NoneQuery('rg_track_gain'))
self.assertInResult(item, matched)
def suite():
return unittest.TestLoader().loadTestsFromName(__name__)