From eb8941b6252aca2c68e5cd4310d2fa2ced5a7f3b Mon Sep 17 00:00:00 2001 From: Research Assistant Date: Tue, 12 May 2026 17:35:19 +0800 Subject: [PATCH] feat(memory): add db.py with connection and path resolution --- paperforge/memory/__init__.py | 8 ++++++++ paperforge/memory/db.py | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 paperforge/memory/__init__.py create mode 100644 paperforge/memory/db.py diff --git a/paperforge/memory/__init__.py b/paperforge/memory/__init__.py new file mode 100644 index 00000000..97d74fc9 --- /dev/null +++ b/paperforge/memory/__init__.py @@ -0,0 +1,8 @@ +from __future__ import annotations + +from paperforge.memory.db import get_connection, get_memory_db_path + +__all__ = [ + "get_connection", + "get_memory_db_path", +] diff --git a/paperforge/memory/db.py b/paperforge/memory/db.py new file mode 100644 index 00000000..19dbf837 --- /dev/null +++ b/paperforge/memory/db.py @@ -0,0 +1,35 @@ +from __future__ import annotations + +import sqlite3 +from pathlib import Path + +from paperforge.config import paperforge_paths + + +def get_memory_db_path(vault: Path) -> Path: + """Return the absolute path to paperforge.db.""" + paths = paperforge_paths(vault) + db_path = paths.get("memory_db") + if not db_path: + raise FileNotFoundError("memory_db path not configured") + return db_path + + +def get_connection(db_path: Path, read_only: bool = False) -> sqlite3.Connection: + """Open a SQLite connection to paperforge.db with WAL mode. + + Args: + db_path: Path to paperforge.db. + read_only: If True, open in read-only mode (for queries). + """ + if read_only: + uri = "file:" + db_path.as_posix() + "?mode=ro" + conn = sqlite3.connect(uri, uri=True) + else: + db_path.parent.mkdir(parents=True, exist_ok=True) + conn = sqlite3.connect(str(db_path)) + conn.row_factory = sqlite3.Row + if not read_only: + conn.execute("PRAGMA journal_mode=WAL;") + conn.execute("PRAGMA foreign_keys=ON;") + return conn