Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions beets/library.py
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,10 @@ class LibModel(FlexModel):
"""The flex field SQLite table name.
"""

_relation_table = None
"""The relation field SQLite table name.
"""

_bytes_keys = ('path', 'artpath')
"""Keys whose values should be stored as raw bytes blobs rather than
strings.
Expand Down Expand Up @@ -438,6 +442,7 @@ class Item(LibModel):
_fields = ITEM_KEYS
_table = 'items'
_flex_table = 'item_attributes'
_relation_table = 'item_relations'
_search_fields = ITEM_DEFAULT_FIELDS

@classmethod
Expand Down Expand Up @@ -775,6 +780,7 @@ class Album(LibModel):
_fields = ALBUM_KEYS
_table = 'albums'
_flex_table = 'album_attributes'
_relation_table = 'album_relations'
_search_fields = ALBUM_DEFAULT_FIELDS

def __setitem__(self, key, value):
Expand Down Expand Up @@ -1604,6 +1610,8 @@ def __init__(self, path='library.blb',
self._make_table(Album._table, album_fields)
self._make_attribute_table(Item._flex_table)
self._make_attribute_table(Album._flex_table)
self._make_relation_table(Item._relation_table)
self._make_relation_table(Album._relation_table)

def _make_table(self, table, fields):
"""Set up the schema of the library file. fields is a list of
Expand Down Expand Up @@ -1672,6 +1680,27 @@ def _make_attribute_table(self, flex_table):
ON {0} (entity_id);
""".format(flex_table))

def _make_relation_table(self, relation_table):
"""Create a table and associated index for relation attributes
for the given entities (if they don't exist).
"""
with self.transaction() as tx:
tx.script("""
CREATE TABLE IF NOT EXISTS {0} (
id INTEGER PRIMARY KEY,
from_entity_id INTEGER,
to_entity_id INTEGER,
key TEXT,
value TEXT,
UNIQUE(from_entity_id, key, to_entity_id)
ON CONFLICT REPLACE);
CREATE INDEX IF NOT EXISTS {0}_by_from_entity
ON {0} (from_entity_id);
CREATE INDEX IF NOT EXISTS {0}_by_to_entity
ON {0} (to_entity_id);
""".format(relation_table))


def _connection(self):
"""Get a SQLite connection object to the underlying database.
One connection object is created per thread.
Expand Down
6 changes: 3 additions & 3 deletions beets/ui/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -774,9 +774,9 @@ def _raw_main(args):
get_path_formats(),
get_replacements(),
)
except sqlite3.OperationalError:
raise UserError(u"database file {0} could not be opened".format(
util.displayable_path(dbpath)
except sqlite3.OperationalError, e:
raise UserError(u"database file {0} could not be opened: {1}".format(
util.displayable_path(dbpath), e
))
plugins.send("library_opened", lib=lib)

Expand Down