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:
Yiorgis Gozadinos 2026-03-12 11:50:13 +02:00 committed by GitHub
commit e31b692124
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 35 additions and 6 deletions

View file

@ -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

View file

@ -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)

View file

@ -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:

View file

@ -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)