Skip to content

Commit

Permalink
invalidate cache upon config change
Browse files Browse the repository at this point in the history
  • Loading branch information
azuline committed Oct 25, 2023
1 parent d8a208a commit b38330d
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 18 deletions.
18 changes: 15 additions & 3 deletions conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,21 @@ def config(isolated_dir: Path) -> Config:
with sqlite3.connect(cache_database_path) as conn:
with CACHE_SCHEMA_PATH.open("r") as fp:
conn.executescript(fp.read())
conn.execute("CREATE TABLE _schema_hash (value TEXT PRIMARY KEY)")
conn.execute(
"""
CREATE TABLE _schema_hash (
schema_hash TEXT
, config_hash TEXT
, PRIMARY KEY (schema_hash, config_hash)
)
"""
)
with CACHE_SCHEMA_PATH.open("rb") as fp:
latest_schema_hash = hashlib.sha256(fp.read()).hexdigest()
conn.execute("INSERT INTO _schema_hash (value) VALUES (?)", (latest_schema_hash,))
schema_hash = hashlib.sha256(fp.read()).hexdigest()
conn.execute(
"INSERT INTO _schema_hash (schema_hash, config_hash) VALUES (?, ?)",
(schema_hash, "00ff"),
)

music_source_dir = isolated_dir / "source"
music_source_dir.mkdir()
Expand All @@ -64,6 +75,7 @@ def config(isolated_dir: Path) -> Config:
fuse_hide_artists=[],
fuse_hide_genres=[],
fuse_hide_labels=[],
hash="00ff",
)


Expand Down
22 changes: 17 additions & 5 deletions rose/cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ def migrate_database(c: Config) -> None:
its own data.
"""
with CACHE_SCHEMA_PATH.open("rb") as fp:
latest_schema_hash = hashlib.sha256(fp.read()).hexdigest()
schema_hash = hashlib.sha256(fp.read()).hexdigest()

with connect(c) as conn:
cursor = conn.execute(
Expand All @@ -68,17 +68,29 @@ def migrate_database(c: Config) -> None:
"""
)
if cursor.fetchone()[0]:
cursor = conn.execute("SELECT value FROM _schema_hash")
if (row := cursor.fetchone()) and row[0] == latest_schema_hash:
cursor = conn.execute("SELECT schema_hash, config_hash FROM _schema_hash")
row = cursor.fetchone()
if row and row["schema_hash"] == schema_hash and row["config_hash"] == c.hash:
# Everything matches! Exit!
return

c.cache_database_path.unlink(missing_ok=True)
with connect(c) as conn:
with CACHE_SCHEMA_PATH.open("r") as fp:
conn.executescript(fp.read())
conn.execute("CREATE TABLE _schema_hash (value TEXT PRIMARY KEY)")
conn.execute("INSERT INTO _schema_hash (value) VALUES (?)", (latest_schema_hash,))
conn.execute(
"""
CREATE TABLE _schema_hash (
schema_hash TEXT
, config_hash TEXT
, PRIMARY KEY (schema_hash, config_hash)
)
"""
)
conn.execute(
"INSERT INTO _schema_hash (schema_hash, config_hash) VALUES (?, ?)",
(schema_hash, c.hash),
)


@dataclass
Expand Down
28 changes: 21 additions & 7 deletions rose/cache_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,26 +40,40 @@
def test_schema(config: Config) -> None:
# Test that the schema successfully bootstraps.
with CACHE_SCHEMA_PATH.open("rb") as fp:
latest_schema_hash = hashlib.sha256(fp.read()).hexdigest()
schema_hash = hashlib.sha256(fp.read()).hexdigest()
migrate_database(config)
with connect(config) as conn:
cursor = conn.execute("SELECT value FROM _schema_hash")
assert cursor.fetchone()[0] == latest_schema_hash
cursor = conn.execute("SELECT schema_hash, config_hash FROM _schema_hash")
row = cursor.fetchone()
assert row["schema_hash"] == schema_hash
assert row["config_hash"] == config.hash


def test_migration(config: Config) -> None:
# Test that "migrating" the database correctly migrates it.
config.cache_database_path.unlink()
with connect(config) as conn:
conn.execute("CREATE TABLE _schema_hash (value TEXT PRIMARY KEY)")
conn.execute("INSERT INTO _schema_hash (value) VALUES ('haha')")
conn.execute(
"""
CREATE TABLE _schema_hash (
schema_hash TEXT
, config_hash TEXT
, PRIMARY KEY (schema_hash, config_hash)
)
"""
)
conn.execute(
"INSERT INTO _schema_hash (schema_hash, config_hash) VALUES ('haha', 'lala')",
)

with CACHE_SCHEMA_PATH.open("rb") as fp:
latest_schema_hash = hashlib.sha256(fp.read()).hexdigest()
migrate_database(config)
with connect(config) as conn:
cursor = conn.execute("SELECT value FROM _schema_hash")
assert cursor.fetchone()[0] == latest_schema_hash
cursor = conn.execute("SELECT schema_hash, config_hash FROM _schema_hash")
row = cursor.fetchone()
assert row["schema_hash"] == latest_schema_hash
assert row["config_hash"] == config.hash
cursor = conn.execute("SELECT COUNT(*) FROM _schema_hash")
assert cursor.fetchone()[0] == 1

Expand Down
10 changes: 8 additions & 2 deletions rose/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import os
from collections import defaultdict
from dataclasses import dataclass
from hashlib import sha256
from pathlib import Path

import tomllib
Expand Down Expand Up @@ -46,12 +47,16 @@ class Config:
fuse_hide_genres: list[str]
fuse_hide_labels: list[str]

hash: str

@classmethod
def read(cls, config_path_override: Path | None = None) -> Config:
cfgpath = config_path_override or CONFIG_PATH
cfgtext = ""
try:
with cfgpath.open("rb") as fp:
data = tomllib.load(fp)
with cfgpath.open("r") as fp:
cfgtext = fp.read()
data = tomllib.loads(cfgtext)
except FileNotFoundError as e:
raise ConfigNotFoundError(f"Configuration file not found ({cfgpath})") from e

Expand Down Expand Up @@ -180,4 +185,5 @@ def read(cls, config_path_override: Path | None = None) -> Config:
fuse_hide_artists=fuse_hide_artists,
fuse_hide_genres=fuse_hide_genres,
fuse_hide_labels=fuse_hide_labels,
hash=sha256(cfgtext.encode()).hexdigest(),
)
4 changes: 3 additions & 1 deletion rose/config_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ def test_config_full() -> None:
""" # noqa: E501
)

assert Config.read(config_path_override=path) == Config(
c = Config.read(config_path_override=path)
assert c == Config(
music_source_dir=Path.home() / ".music-src",
fuse_mount_dir=Path.home() / "music",
cache_dir=cache_dir,
Expand All @@ -70,6 +71,7 @@ def test_config_full() -> None:
fuse_hide_artists=["xxx"],
fuse_hide_genres=["yyy"],
fuse_hide_labels=["zzz"],
hash=c.hash,
)


Expand Down

0 comments on commit b38330d

Please sign in to comment.