mirror of
https://github.com/beetbox/beets.git
synced 2025-12-15 21:14:19 +01:00
add "albums" table to library database (including migrations)
This commit is contained in:
parent
6394371628
commit
5d4f452393
3 changed files with 52 additions and 17 deletions
|
|
@ -62,6 +62,14 @@ ITEM_KEYS_WRITABLE = [f[0] for f in ITEM_FIELDS if f[3] and f[2]]
|
|||
ITEM_KEYS_META = [f[0] for f in ITEM_FIELDS if f[3]]
|
||||
ITEM_KEYS = [f[0] for f in ITEM_FIELDS]
|
||||
|
||||
# Database fields for the "albums" table.
|
||||
ALBUM_FIELDS = [
|
||||
('id', 'integer primary key'),
|
||||
('artist', 'text'),
|
||||
('album', 'text'),
|
||||
('artpath', 'text'),
|
||||
]
|
||||
|
||||
# Default search fields for various granularities.
|
||||
ARTIST_DEFAULT_FIELDS = ('artist',)
|
||||
ALBUM_DEFAULT_FIELDS = ARTIST_DEFAULT_FIELDS + ('album', 'genre')
|
||||
|
|
@ -644,7 +652,8 @@ class Library(BaseLibrary):
|
|||
def __init__(self, path='library.blb',
|
||||
directory='~/Music',
|
||||
path_format='$artist/$album/$track $title',
|
||||
fields=ITEM_FIELDS):
|
||||
item_fields=ITEM_FIELDS,
|
||||
album_fields=ALBUM_FIELDS):
|
||||
self.path = path
|
||||
self.directory = directory
|
||||
self.path_format = path_format
|
||||
|
|
@ -653,16 +662,17 @@ class Library(BaseLibrary):
|
|||
self.conn.row_factory = sqlite3.Row
|
||||
# this way we can access our SELECT results like dictionaries
|
||||
|
||||
self._setup(fields)
|
||||
self._make_table('items', item_fields)
|
||||
self._make_table('albums', album_fields)
|
||||
|
||||
def _setup(self, fields):
|
||||
"""Set up the schema of the library file. fields is a list
|
||||
of all the fields that should be present in the table. Columns
|
||||
are added if necessary.
|
||||
def _make_table(self, table, fields):
|
||||
"""Set up the schema of the library file. fields is a list of
|
||||
all the fields that should be present in the indicated table.
|
||||
Columns are added if necessary.
|
||||
"""
|
||||
# Get current schema.
|
||||
cur = self.conn.cursor()
|
||||
cur.execute('PRAGMA table_info(items)')
|
||||
cur.execute('PRAGMA table_info(%s)' % table)
|
||||
current_fields = set([row[1] for row in cur])
|
||||
|
||||
field_names = set([f[0] for f in fields])
|
||||
|
|
@ -672,7 +682,7 @@ class Library(BaseLibrary):
|
|||
|
||||
if not current_fields:
|
||||
# No table exists.
|
||||
setup_sql = 'CREATE TABLE items ('
|
||||
setup_sql = 'CREATE TABLE %s (' % table
|
||||
setup_sql += ', '.join(['%s %s' % f[:2] for f in fields])
|
||||
setup_sql += ');'
|
||||
|
||||
|
|
@ -685,8 +695,8 @@ class Library(BaseLibrary):
|
|||
break
|
||||
else:
|
||||
assert False
|
||||
setup_sql += 'ALTER TABLE items ADD COLUMN ' \
|
||||
'%s %s;\n' % field[:2]
|
||||
setup_sql += 'ALTER TABLE %s ' % table
|
||||
setup_sql += 'ADD COLUMN %s %s;\n' % field[:2]
|
||||
|
||||
self.conn.executescript(setup_sql)
|
||||
self.conn.commit()
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -15,7 +15,10 @@
|
|||
"""Tests for non-query database functions of Item.
|
||||
"""
|
||||
|
||||
import unittest, sys, os
|
||||
import unittest
|
||||
import sys
|
||||
import os
|
||||
import sqlite3
|
||||
sys.path.append('..')
|
||||
import beets.library
|
||||
|
||||
|
|
@ -257,7 +260,8 @@ class MigrationTest(unittest.TestCase):
|
|||
|
||||
# Set up a library with old_fields.
|
||||
self.libfile = os.path.join('rsrc', 'templib.blb')
|
||||
old_lib = beets.library.Library(self.libfile, fields=self.old_fields)
|
||||
old_lib = beets.library.Library(self.libfile,
|
||||
item_fields=self.old_fields)
|
||||
# Add an item to the old library.
|
||||
old_lib.conn.execute(
|
||||
'insert into items (field_one, field_two) values (4, 2)'
|
||||
|
|
@ -269,36 +273,57 @@ class MigrationTest(unittest.TestCase):
|
|||
os.unlink(self.libfile)
|
||||
|
||||
def test_open_with_same_fields_leaves_untouched(self):
|
||||
new_lib = beets.library.Library(self.libfile, fields=self.old_fields)
|
||||
new_lib = beets.library.Library(self.libfile,
|
||||
item_fields=self.old_fields)
|
||||
c = new_lib.conn.cursor()
|
||||
c.execute("select * from items")
|
||||
row = c.fetchone()
|
||||
self.assertEqual(len(row), len(self.old_fields))
|
||||
|
||||
def test_open_with_new_field_adds_column(self):
|
||||
new_lib = beets.library.Library(self.libfile, fields=self.new_fields)
|
||||
new_lib = beets.library.Library(self.libfile,
|
||||
item_fields=self.new_fields)
|
||||
c = new_lib.conn.cursor()
|
||||
c.execute("select * from items")
|
||||
row = c.fetchone()
|
||||
self.assertEqual(len(row), len(self.new_fields))
|
||||
|
||||
def test_open_with_fewer_fields_leaves_untouched(self):
|
||||
new_lib = beets.library.Library(self.libfile, fields=self.older_fields)
|
||||
new_lib = beets.library.Library(self.libfile,
|
||||
item_fields=self.older_fields)
|
||||
c = new_lib.conn.cursor()
|
||||
c.execute("select * from items")
|
||||
row = c.fetchone()
|
||||
self.assertEqual(len(row), len(self.old_fields))
|
||||
|
||||
def test_open_with_multiple_new_fields(self):
|
||||
new_lib = beets.library.Library(self.libfile, fields=self.newer_fields)
|
||||
new_lib = beets.library.Library(self.libfile,
|
||||
item_fields=self.newer_fields)
|
||||
c = new_lib.conn.cursor()
|
||||
c.execute("select * from items")
|
||||
row = c.fetchone()
|
||||
self.assertEqual(len(row), len(self.newer_fields))
|
||||
|
||||
|
||||
def test_open_old_db_adds_album_table(self):
|
||||
conn = sqlite3.connect(self.libfile)
|
||||
conn.execute('drop table albums')
|
||||
conn.close()
|
||||
|
||||
conn = sqlite3.connect(self.libfile)
|
||||
self.assertRaises(sqlite3.OperationalError, conn.execute,
|
||||
'select * from albums')
|
||||
conn.close()
|
||||
|
||||
new_lib = beets.library.Library(self.libfile,
|
||||
item_fields=self.newer_fields)
|
||||
try:
|
||||
new_lib.conn.execute("select * from albums")
|
||||
except sqlite3.OperationalError:
|
||||
self.fail("select failed")
|
||||
|
||||
def suite():
|
||||
return unittest.TestLoader().loadTestsFromName(__name__)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main(defaultTest='suite')
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue