Reject a database with no name or location
A blank name is falsy, so source routing reads it as absent, and a blank location resolves to the working directory. `is_read_only` reports the mode the client was opened with, which a client covering a set can answer without a store.
This commit is contained in:
parent
e94623ec37
commit
bc04dfdb7a
3 changed files with 44 additions and 2 deletions
|
|
@ -127,8 +127,12 @@ class HaikuRAG:
|
|||
|
||||
@property
|
||||
def is_read_only(self) -> bool:
|
||||
"""Whether the client is in read-only mode."""
|
||||
return self.store.is_read_only
|
||||
"""Whether the client is in read-only mode.
|
||||
|
||||
The mode the client was opened with, which is the mode every database it
|
||||
covers is opened with. A client covering a set has no store to ask.
|
||||
"""
|
||||
return self._read_only
|
||||
|
||||
@property
|
||||
def embedder(self) -> "EmbedderWrapper":
|
||||
|
|
|
|||
|
|
@ -123,6 +123,13 @@ class LanceDBConfig(ConfigModel):
|
|||
"lancedb.uri and lancedb.databases are mutually exclusive: "
|
||||
"use uri for one database, databases for several"
|
||||
)
|
||||
for name, location in self.databases.items():
|
||||
# A blank name is falsy, so source routing reads it as absent; a
|
||||
# blank location resolves to the working directory.
|
||||
if not name.strip():
|
||||
raise ValueError("lancedb.databases has an entry with no name")
|
||||
if not location.strip():
|
||||
raise ValueError(f"lancedb.databases[{name}] has no location")
|
||||
return self
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -28,6 +28,23 @@ class TestConfig:
|
|||
assert LanceDBConfig(uri="s3://b/one.lancedb").databases == {}
|
||||
|
||||
|
||||
class TestNamingIsRequired:
|
||||
def test_a_blank_name_is_rejected(self):
|
||||
"""An unnamed database is unreachable: every source check reads the
|
||||
empty name as no name at all."""
|
||||
with pytest.raises(ValidationError, match="entry with no name"):
|
||||
LanceDBConfig(databases={"": "/tmp/a.lancedb"})
|
||||
with pytest.raises(ValidationError, match="entry with no name"):
|
||||
LanceDBConfig(databases={" ": "/tmp/a.lancedb"})
|
||||
|
||||
def test_a_blank_location_is_rejected(self):
|
||||
"""A blank location resolves to the working directory."""
|
||||
with pytest.raises(
|
||||
ValidationError, match=r"databases\[alpha\] has no location"
|
||||
):
|
||||
LanceDBConfig(databases={"alpha": ""})
|
||||
|
||||
|
||||
def _config(tmp_path, names) -> AppConfig:
|
||||
return AppConfig(
|
||||
lancedb=LanceDBConfig(
|
||||
|
|
@ -279,6 +296,20 @@ class TestLookupByIdentifier:
|
|||
assert await rag.get_document_by_uri("test://nowhere") is None
|
||||
|
||||
|
||||
class TestReadOnlyMode:
|
||||
@pytest.mark.asyncio
|
||||
async def test_a_client_covering_a_set_reports_its_mode(self, tmp_path):
|
||||
"""A client covering a set has no store of its own to ask."""
|
||||
config = _config(tmp_path, ["alpha", "beta"])
|
||||
await _seed(config, "alpha", ["alpha one"])
|
||||
await _seed(config, "beta", ["beta one"])
|
||||
|
||||
async with HaikuRAG(config=config, read_only=True) as rag:
|
||||
assert rag.is_read_only is True
|
||||
async with HaikuRAG(config=config) as rag:
|
||||
assert rag.is_read_only is False
|
||||
|
||||
|
||||
class TestDocumentsNameTheirDatabase:
|
||||
"""A listing that spans databases is unreadable when the documents do not
|
||||
say which one they came from, the same reason a search result carries one."""
|
||||
|
|
|
|||
Loading…
Reference in a new issue