Add disk-backed SQLite cache mode as an alternative to in-memory
This commit is contained in:
@@ -58,3 +58,50 @@ def test_backup_and_reload(tmp_path, source_conn):
|
||||
c2 = CacheManager(db_path=db_path, backup_interval=9999)
|
||||
assert c2.is_table_cached("users") is True
|
||||
c2.close()
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Disk-backed mode (in_memory=False)
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def test_disk_mode_persists_without_backup(tmp_path, source_conn):
|
||||
"""Disk mode writes straight to the file — no explicit backup/close needed."""
|
||||
db_path = tmp_path / "cache.db"
|
||||
c = CacheManager(db_path=db_path, backup_interval=9999, in_memory=False)
|
||||
c.load_table("users", ["name"], source_conn)
|
||||
# Data is already on disk; a brand-new disk-mode manager sees it.
|
||||
c2 = CacheManager(db_path=db_path, backup_interval=9999, in_memory=False)
|
||||
assert c2.is_table_cached("users") is True
|
||||
c2.close()
|
||||
c.close()
|
||||
|
||||
|
||||
def test_disk_mode_file_created_immediately(tmp_path, source_conn):
|
||||
db_path = tmp_path / "cache.db"
|
||||
c = CacheManager(db_path=db_path, backup_interval=9999, in_memory=False)
|
||||
c.load_table("users", ["name"], source_conn)
|
||||
assert db_path.exists()
|
||||
c.close()
|
||||
|
||||
|
||||
def test_disk_mode_reload_in_new_instance(tmp_path, source_conn):
|
||||
db_path = tmp_path / "cache.db"
|
||||
c1 = CacheManager(db_path=db_path, backup_interval=9999, in_memory=False)
|
||||
c1.load_table("users", ["name", "email"], source_conn)
|
||||
c1.close()
|
||||
|
||||
c2 = CacheManager(db_path=db_path, backup_interval=9999, in_memory=False)
|
||||
rows = c2.connection.execute("SELECT name FROM users").fetchall()
|
||||
assert {r[0] for r in rows} == {"alice", "bob"}
|
||||
c2.close()
|
||||
|
||||
|
||||
def test_disk_mode_reset_keeps_file(tmp_path, source_conn):
|
||||
db_path = tmp_path / "cache.db"
|
||||
c = CacheManager(db_path=db_path, backup_interval=9999, in_memory=False)
|
||||
c.load_table("users", ["name"], source_conn)
|
||||
c.reset()
|
||||
# File stays (the connection is still open) but the table is gone.
|
||||
assert db_path.exists()
|
||||
assert c.is_table_cached("users") is False
|
||||
c.close()
|
||||
|
||||
@@ -289,3 +289,45 @@ def test_invalidate_then_refetch_works(engine):
|
||||
|
||||
def test_invalidate_unknown_table_is_noop(engine):
|
||||
engine.invalidate("nonexistent_table") # must not raise
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Disk-backed cache (in_memory=False)
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def test_disk_mode_query_works(source_engine, cache_path, monkeypatch):
|
||||
monkeypatch.setattr(eng_mod, "CACHE_DB_PATH", cache_path)
|
||||
monkeypatch.setattr(eng_mod, "BACKUP_INTERVAL_SECONDS", 9999)
|
||||
|
||||
ce = CachingEngine(source_engine, in_memory=False)
|
||||
rows = ce.execute("SELECT id, name FROM products")
|
||||
assert {r["name"] for r in rows} == {"Widget", "Gadget", "Doohickey"}
|
||||
assert ce._cache._in_memory is False
|
||||
ce.close()
|
||||
|
||||
|
||||
def test_disk_mode_persists_across_instances(source_engine, cache_path, monkeypatch):
|
||||
monkeypatch.setattr(eng_mod, "CACHE_DB_PATH", cache_path)
|
||||
monkeypatch.setattr(eng_mod, "BACKUP_INTERVAL_SECONDS", 9999)
|
||||
|
||||
ce1 = CachingEngine(source_engine, in_memory=False)
|
||||
ce1.execute("SELECT id, name FROM products")
|
||||
ce1.close()
|
||||
|
||||
# Second instance opens the same on-disk cache and finds the table already there.
|
||||
ce2 = CachingEngine(source_engine, in_memory=False)
|
||||
assert ce2._cache.is_table_cached("products") is True
|
||||
rows = ce2.execute("SELECT id, name FROM products")
|
||||
assert {r["name"] for r in rows} == {"Widget", "Gadget", "Doohickey"}
|
||||
ce2.close()
|
||||
|
||||
|
||||
def test_in_memory_override_respects_config(source_engine, cache_path, monkeypatch):
|
||||
"""in_memory=None falls back to the IN_MEMORY config default."""
|
||||
monkeypatch.setattr(eng_mod, "CACHE_DB_PATH", cache_path)
|
||||
monkeypatch.setattr(eng_mod, "BACKUP_INTERVAL_SECONDS", 9999)
|
||||
monkeypatch.setattr(eng_mod, "IN_MEMORY", False)
|
||||
|
||||
ce = CachingEngine(source_engine) # no explicit in_memory
|
||||
assert ce._cache._in_memory is False
|
||||
ce.close()
|
||||
|
||||
Reference in New Issue
Block a user