mirror of
https://github.com/beetbox/beets.git
synced 2025-12-15 21:14:19 +01:00
Simplify model initialization shortcut
This avoids multiple paths to setting values. It also moves the buffer check into PathType.normalize, where it belongs. This is slightly faster than the previous iteration: about 8 vs. 9 seconds to list about 13k songs on my machine.
This commit is contained in:
parent
505add7e5c
commit
d48c604b2f
2 changed files with 30 additions and 46 deletions
|
|
@ -95,7 +95,7 @@ class Model(object):
|
|||
|
||||
# Basic operation.
|
||||
|
||||
def __init__(self, db=None, fixed=None, flexattr=None, **values):
|
||||
def __init__(self, db=None, **values):
|
||||
"""Create a new object with an optional Database association and
|
||||
initial field values.
|
||||
"""
|
||||
|
|
@ -105,10 +105,24 @@ class Model(object):
|
|||
self._values_flex = {}
|
||||
|
||||
# Initial contents.
|
||||
self._bulk_update(fixed, flexattr)
|
||||
self.update(values)
|
||||
self.clear_dirty()
|
||||
|
||||
@classmethod
|
||||
def _awaken(cls, db=None, fixed_values=None, flex_values=None):
|
||||
"""Create an object with values drawn from the database.
|
||||
|
||||
This is a performance optimization: the checks involved with
|
||||
ordinary construction are bypassed.
|
||||
"""
|
||||
obj = cls(db)
|
||||
if fixed_values:
|
||||
for key, value in fixed_values.items():
|
||||
obj._values_fixed[key] = cls._fields[key].normalize(value)
|
||||
if flex_values:
|
||||
obj._values_flex.update(flex_values)
|
||||
return obj
|
||||
|
||||
def __repr__(self):
|
||||
return '{0}({1})'.format(
|
||||
type(self).__name__,
|
||||
|
|
@ -196,24 +210,6 @@ class Model(object):
|
|||
for key, value in values.items():
|
||||
self[key] = value
|
||||
|
||||
def _bulk_update(self, fixed, flexattr):
|
||||
"""Assign all values in the fixed and flex dicts.
|
||||
Using _bulk_update() bypasses many tests made by update() and
|
||||
should only be used when loading data from the db.
|
||||
"""
|
||||
if fixed:
|
||||
for (key, value) in fixed.items():
|
||||
self._set_fixed_attr(key, value)
|
||||
if flexattr:
|
||||
for (key, value) in flexattr.items():
|
||||
self._set_flex_attr(key, value)
|
||||
|
||||
def _set_fixed_attr(self, key, value):
|
||||
self._values_fixed[key] = self._fields[key].normalize(value)
|
||||
|
||||
def _set_flex_attr(self, key, value):
|
||||
self._values_flex[key] = value
|
||||
|
||||
def items(self):
|
||||
"""Iterate over (key, value) pairs that this object contains.
|
||||
Computed fields are not included.
|
||||
|
|
@ -515,7 +511,7 @@ class Results(object):
|
|||
|
||||
# Construct the Python object and yield it if it passes the
|
||||
# predicate.
|
||||
obj = self.model_class(self.db, values, flex_values)
|
||||
obj = self.model_class._awaken(self.db, values, flex_values)
|
||||
if not self.query or self.query.match(obj):
|
||||
yield obj
|
||||
|
||||
|
|
|
|||
|
|
@ -94,6 +94,19 @@ class PathType(types.Type):
|
|||
def parse(self, string):
|
||||
return normpath(bytestring_path(string))
|
||||
|
||||
def normalize(self, value):
|
||||
if isinstance(value, unicode):
|
||||
# Paths stored internally as encoded bytes.
|
||||
return bytestring_path(value)
|
||||
|
||||
elif isinstance(value, buffer):
|
||||
# SQLite must store bytestings as buffers to avoid decoding.
|
||||
# We unwrap buffers to bytes.
|
||||
return bytes(value)
|
||||
|
||||
else:
|
||||
return value
|
||||
|
||||
|
||||
# Special path format key.
|
||||
PF_KEY_DEFAULT = 'default'
|
||||
|
|
@ -295,14 +308,6 @@ class Item(LibModel):
|
|||
if self.mtime == 0 and 'mtime' in values:
|
||||
self.mtime = values['mtime']
|
||||
|
||||
def _set_fixed_attr(self, key, value):
|
||||
if key == 'path':
|
||||
if isinstance(value, unicode):
|
||||
value = bytestring_path(value)
|
||||
elif isinstance(value, buffer):
|
||||
value = str(value)
|
||||
super(Item, self)._set_fixed_attr(key, value)
|
||||
|
||||
def get_album(self):
|
||||
"""Get the Album object that this item belongs to, if any, or
|
||||
None if the item is a singleton or is not associated with a
|
||||
|
|
@ -695,23 +700,6 @@ class Album(LibModel):
|
|||
getters['path'] = Album.item_dir
|
||||
return getters
|
||||
|
||||
def _set_fixed_attr(self, key, value):
|
||||
if key == 'artpath':
|
||||
if isinstance(value, unicode):
|
||||
value = bytestring_path(value)
|
||||
elif isinstance(value, buffer):
|
||||
value = bytes(value)
|
||||
super(Album, self)._set_fixed_attr(key, value)
|
||||
|
||||
def __setitem__(self, key, value):
|
||||
"""Set the value of an album attribute."""
|
||||
if key == 'artpath':
|
||||
if isinstance(value, unicode):
|
||||
value = bytestring_path(value)
|
||||
elif isinstance(value, buffer):
|
||||
value = bytes(value)
|
||||
super(Album, self).__setitem__(key, value)
|
||||
|
||||
def items(self):
|
||||
"""Returns an iterable over the items associated with this
|
||||
album.
|
||||
|
|
|
|||
Loading…
Reference in a new issue