Merge pull request #306 from ggozad/fix/read-only-inits-on-empty-folder
Prevent read-only mode from creating tables in empty directories
This commit is contained in:
commit
e31b692124
4 changed files with 35 additions and 6 deletions
|
|
@ -1,6 +1,10 @@
|
|||
# Changelog
|
||||
## [Unreleased]
|
||||
|
||||
### Fixed
|
||||
|
||||
- **Read-only mode table creation**: `--read-only` no longer creates lance tables when pointed at an empty directory. `Store._init_tables()` now raises `ReadOnlyError` when tables are missing in read-only mode.
|
||||
|
||||
## [0.33.2] - 2026-03-11
|
||||
|
||||
### Changed
|
||||
|
|
|
|||
|
|
@ -23,7 +23,10 @@ from haiku.rag.config import ( # noqa: E402
|
|||
set_config,
|
||||
)
|
||||
from haiku.rag.logging import configure_cli_logging # noqa: E402
|
||||
from haiku.rag.store.exceptions import MigrationRequiredError # noqa: E402
|
||||
from haiku.rag.store.exceptions import ( # noqa: E402
|
||||
MigrationRequiredError,
|
||||
ReadOnlyError,
|
||||
)
|
||||
from haiku.rag.utils import is_up_to_date # noqa: E402
|
||||
|
||||
_cli = typer.Typer(
|
||||
|
|
@ -34,7 +37,7 @@ _cli = typer.Typer(
|
|||
def cli():
|
||||
try:
|
||||
_cli()
|
||||
except MigrationRequiredError as e:
|
||||
except (MigrationRequiredError, ReadOnlyError) as e:
|
||||
typer.echo(f"Error: {e}", err=True)
|
||||
sys.exit(1)
|
||||
|
||||
|
|
|
|||
|
|
@ -333,10 +333,17 @@ class Store:
|
|||
|
||||
def _init_tables(self):
|
||||
"""Initialize database tables (create if they don't exist)."""
|
||||
# Get list of existing tables
|
||||
existing_tables = self.db.table_names()
|
||||
required_tables = {"documents", "chunks", "settings"}
|
||||
missing_tables = required_tables - set(existing_tables)
|
||||
|
||||
# Create or get documents table
|
||||
if missing_tables and self._read_only:
|
||||
raise ReadOnlyError(
|
||||
"Cannot create tables in read-only mode. "
|
||||
"Use 'haiku-rag init' to create a new database."
|
||||
)
|
||||
|
||||
# Create or open documents table
|
||||
if "documents" in existing_tables:
|
||||
self.documents_table = self.db.open_table("documents")
|
||||
else:
|
||||
|
|
@ -344,7 +351,7 @@ class Store:
|
|||
"documents", schema=get_documents_arrow_schema()
|
||||
)
|
||||
|
||||
# Create or get chunks table
|
||||
# Create or open chunks table
|
||||
if "chunks" in existing_tables:
|
||||
self.chunks_table = self.db.open_table("chunks")
|
||||
else:
|
||||
|
|
@ -354,7 +361,7 @@ class Store:
|
|||
"content_fts", replace=True, with_position=True, remove_stop_words=False
|
||||
)
|
||||
|
||||
# Create or get settings table
|
||||
# Create or open settings table
|
||||
if "settings" in existing_tables:
|
||||
self.settings_table = self.db.open_table("settings")
|
||||
else:
|
||||
|
|
|
|||
|
|
@ -28,6 +28,21 @@ class TestReadOnlyError:
|
|||
|
||||
|
||||
class TestStoreReadOnly:
|
||||
def test_store_read_only_raises_on_empty_directory(self, tmp_path):
|
||||
"""Opening an empty directory in read-only mode raises ReadOnlyError."""
|
||||
empty_dir = tmp_path / "empty_db"
|
||||
empty_dir.mkdir()
|
||||
|
||||
with pytest.raises(
|
||||
ReadOnlyError, match="Cannot create tables in read-only mode"
|
||||
):
|
||||
Store(
|
||||
empty_dir,
|
||||
read_only=True,
|
||||
skip_validation=True,
|
||||
skip_migration_check=True,
|
||||
)
|
||||
|
||||
def test_store_default_is_not_read_only(self, temp_db_path):
|
||||
"""Store defaults to not read-only."""
|
||||
store = Store(temp_db_path, create=True)
|
||||
|
|
|
|||
Loading…
Reference in a new issue