-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add database schema & execute migration on command run
- Loading branch information
Showing
13 changed files
with
328 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
-- bootstrap | ||
-- depends: | ||
|
||
DROP TABLE playlists_tracks; | ||
DROP TABLE playlists; | ||
DROP TABLE collections_releases; | ||
DROP TABLE collections; | ||
DROP TABLE tracks_artists; | ||
DROP TABLE releases_artists; | ||
DROP TABLE artists; | ||
DROP TABLE artist_role_enum; | ||
DROP TABLE tracks; | ||
DROP TABLE releases; | ||
DROP TABLE release_type_enum; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
-- bootstrap | ||
-- depends: | ||
|
||
CREATE TABLE release_type_enum (value TEXT PRIMARY KEY); | ||
INSERT INTO release_type_enum (value) VALUES | ||
('album'), | ||
('single'), | ||
('ep'), | ||
('compilation'), | ||
('soundtrack'), | ||
('live'), | ||
('remix'), | ||
('djmix'), | ||
('mixtape'), | ||
('other'), | ||
('unknown'); | ||
|
||
CREATE TABLE releases ( | ||
id INTEGER PRIMARY KEY, | ||
source_path TEXT NOT NULL UNIQUE, | ||
title TEXT NOT NULL, | ||
release_type TEXT NOT NULL REFERENCES release_type_enum(value), | ||
release_year INTEGER | ||
); | ||
CREATE INDEX releases_source_path ON releases(source_path); | ||
CREATE INDEX releases_release_year ON releases(release_year); | ||
|
||
CREATE TABLE tracks ( | ||
id INTEGER PRIMARY KEY, | ||
source_path TEXT NOT NULL UNIQUE, | ||
title TEXT NOT NULL, | ||
release_id INTEGER NOT NULL REFERENCES releases(id), | ||
track_number TEXT NOT NULL, | ||
disc_number TEXT NOT NULL, | ||
duration_seconds INTEGER NOT NULL | ||
); | ||
CREATE INDEX tracks_source_path ON tracks(source_path); | ||
CREATE INDEX tracks_release_id ON tracks(release_id); | ||
CREATE INDEX tracks_ordering ON tracks(release_id, disc_number, track_number); | ||
|
||
CREATE TABLE artists ( | ||
id INTEGER PRIMARY KEY, | ||
name TEXT NOT NULL | ||
); | ||
CREATE INDEX artists_name ON artists(name); | ||
|
||
CREATE TABLE artist_role_enum (value TEXT PRIMARY KEY); | ||
INSERT INTO artist_role_enum (value) VALUES | ||
('main'), | ||
('feature'), | ||
('remixer'), | ||
('producer'), | ||
('composer'), | ||
('conductor'), | ||
('djmixer'); | ||
|
||
CREATE TABLE releases_artists ( | ||
release_id INTEGER REFERENCES releases(id) ON DELETE CASCADE, | ||
artist_id INTEGER REFERENCES artists(id) ON DELETE CASCADE, | ||
role TEXT REFERENCES artist_role_enum(value), | ||
PRIMARY KEY (release_id, artist_id) | ||
); | ||
CREATE INDEX releases_artists_release_id ON releases_artists(release_id); | ||
CREATE INDEX releases_artists_artist_id ON releases_artists(artist_id); | ||
|
||
CREATE TABLE tracks_artists ( | ||
track_id INTEGER REFERENCES tracks(id) ON DELETE CASCADE, | ||
artist_id INTEGER REFERENCES artists(id) ON DELETE CASCADE, | ||
role TEXT REFERENCES artist_role_enum(value), | ||
PRIMARY KEY (track_id, artist_id) | ||
); | ||
CREATE INDEX tracks_artists_track_id ON tracks_artists(track_id); | ||
CREATE INDEX tracks_artists_artist_id ON tracks_artists(artist_id); | ||
|
||
CREATE TABLE collections ( | ||
id INTEGER PRIMARY KEY, | ||
name TEXT NOT NULL, | ||
source_path TEXT UNIQUE NOT NULL | ||
); | ||
CREATE INDEX collections_source_path ON collections(source_path); | ||
|
||
CREATE TABLE collections_releases ( | ||
collection_id INTEGER REFERENCES collections(id) ON DELETE CASCADE, | ||
release_id INTEGER REFERENCES releases(id) ON DELETE CASCADE, | ||
position INTEGER NOT NULL | ||
); | ||
CREATE INDEX collections_releases_collection_id ON collections_releases(collection_id); | ||
CREATE INDEX collections_releases_release_id ON collections_releases(release_id); | ||
CREATE UNIQUE INDEX collections_releases_collection_position ON collections_releases(collection_id, position); | ||
|
||
CREATE TABLE playlists ( | ||
id INTEGER PRIMARY KEY, | ||
name TEXT NOT NULL, | ||
source_path TEXT UNIQUE NOT NULL | ||
); | ||
CREATE INDEX playlists_source_path ON playlists(source_path); | ||
|
||
CREATE TABLE playlists_tracks ( | ||
playlist_id INTEGER REFERENCES playlists(id) ON DELETE CASCADE, | ||
track_id INTEGER REFERENCES tracks(id) ON DELETE CASCADE, | ||
position INTEGER NOT NULL | ||
); | ||
CREATE INDEX playlists_tracks_playlist_id ON playlists_tracks(playlist_id); | ||
CREATE INDEX playlists_tracks_track_id ON playlists_tracks(track_id); | ||
CREATE UNIQUE INDEX playlists_tracks_playlist_position ON playlists_tracks(playlist_id, position); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import logging | ||
import sqlite3 | ||
from collections.abc import Iterator | ||
from contextlib import contextmanager | ||
|
||
import yoyo | ||
|
||
from rose.foundation.conf import MIGRATIONS_PATH, Config | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
||
@contextmanager | ||
def connect(c: Config) -> Iterator[sqlite3.Connection]: | ||
conn = connect_fn(c) | ||
try: | ||
yield conn | ||
finally: | ||
conn.close() | ||
|
||
|
||
def connect_fn(c: Config) -> sqlite3.Connection: | ||
"""Non-context manager version of connect.""" | ||
conn = sqlite3.connect( | ||
c.cache_database_path, | ||
detect_types=sqlite3.PARSE_DECLTYPES, | ||
isolation_level=None, | ||
timeout=15.0, | ||
) | ||
|
||
conn.row_factory = sqlite3.Row | ||
conn.execute("PRAGMA foreign_keys=ON") | ||
conn.execute("PRAGMA journal_mode=WAL") | ||
|
||
return conn | ||
|
||
|
||
def migrate_database(c: Config) -> None: | ||
db_backend = yoyo.get_backend(f"sqlite:///{c.cache_database_path}") | ||
db_migrations = yoyo.read_migrations(str(MIGRATIONS_PATH)) | ||
|
||
logger.debug("Applying database migrations") | ||
with db_backend.lock(): | ||
db_backend.apply_migrations(db_backend.to_apply(db_migrations)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import sqlite3 | ||
from pathlib import Path | ||
|
||
import yoyo | ||
|
||
from conftest import freeze_database_time | ||
from rose.cache.database import migrate_database | ||
from rose.foundation.conf import MIGRATIONS_PATH, Config | ||
|
||
|
||
def test_run_database_migrations(config: Config) -> None: | ||
migrate_database(config) | ||
assert config.cache_database_path.exists() | ||
|
||
with sqlite3.connect(str(config.cache_database_path)) as conn: | ||
freeze_database_time(conn) | ||
cursor = conn.execute("SELECT 1 FROM _yoyo_version") | ||
assert len(cursor.fetchall()) > 0 | ||
|
||
|
||
def test_migrations(isolated_dir: Path) -> None: | ||
""" | ||
Test that, for each migration, the up -> down -> up path doesn't | ||
cause an error. Basically, ladder our way up through the migration | ||
chain. | ||
""" | ||
backend = yoyo.get_backend(f"sqlite:///{isolated_dir / 'db.sqlite3'}") | ||
migrations = yoyo.read_migrations(str(MIGRATIONS_PATH)) | ||
|
||
assert len(migrations) > 0 | ||
for mig in migrations: | ||
backend.apply_one(mig) | ||
backend.rollback_one(mig) | ||
backend.apply_one(mig) |
Oops, something went wrong.