pl-key-value-sqlite-db 0.0.2__tar.gz → 0.0.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. {pl_key_value_sqlite_db-0.0.2 → pl_key_value_sqlite_db-0.0.4}/PKG-INFO +3 -1
  2. {pl_key_value_sqlite_db-0.0.2 → pl_key_value_sqlite_db-0.0.4}/pyproject.toml +4 -2
  3. pl_key_value_sqlite_db-0.0.4/src/pl_key_value_sqlite_db/constants.py +31 -0
  4. pl_key_value_sqlite_db-0.0.4/src/pl_key_value_sqlite_db/create_key.py +8 -0
  5. pl_key_value_sqlite_db-0.0.4/src/pl_key_value_sqlite_db/create_key_value_key_unsafe.py +24 -0
  6. pl_key_value_sqlite_db-0.0.4/src/pl_key_value_sqlite_db/create_key_value_table_if_not_exists.py +21 -0
  7. pl_key_value_sqlite_db-0.0.4/src/pl_key_value_sqlite_db/delete_key_value.py +8 -0
  8. pl_key_value_sqlite_db-0.0.4/src/pl_key_value_sqlite_db/delete_key_value_key_unsafe.py +14 -0
  9. pl_key_value_sqlite_db-0.0.4/src/pl_key_value_sqlite_db/execute_key_value_sql.py +16 -0
  10. pl_key_value_sqlite_db-0.0.4/src/pl_key_value_sqlite_db/execute_sql.py +33 -0
  11. pl_key_value_sqlite_db-0.0.4/src/pl_key_value_sqlite_db/get_all_key_value_keys.py +18 -0
  12. pl_key_value_sqlite_db-0.0.4/src/pl_key_value_sqlite_db/key_types.py +25 -0
  13. pl_key_value_sqlite_db-0.0.4/src/pl_key_value_sqlite_db/key_value_migration.py +32 -0
  14. pl_key_value_sqlite_db-0.0.4/src/pl_key_value_sqlite_db/load_bool.py +6 -0
  15. pl_key_value_sqlite_db-0.0.4/src/pl_key_value_sqlite_db/load_date.py +8 -0
  16. pl_key_value_sqlite_db-0.0.4/src/pl_key_value_sqlite_db/load_datetime.py +8 -0
  17. pl_key_value_sqlite_db-0.0.4/src/pl_key_value_sqlite_db/load_int.py +6 -0
  18. pl_key_value_sqlite_db-0.0.4/src/pl_key_value_sqlite_db/load_key_value_unsafe.py +26 -0
  19. pl_key_value_sqlite_db-0.0.4/src/pl_key_value_sqlite_db/load_str.py +6 -0
  20. pl_key_value_sqlite_db-0.0.4/src/pl_key_value_sqlite_db/load_value_untyped.py +6 -0
  21. pl_key_value_sqlite_db-0.0.4/src/pl_key_value_sqlite_db/save_bool.py +6 -0
  22. pl_key_value_sqlite_db-0.0.4/src/pl_key_value_sqlite_db/save_date.py +11 -0
  23. pl_key_value_sqlite_db-0.0.4/src/pl_key_value_sqlite_db/save_datetime.py +8 -0
  24. pl_key_value_sqlite_db-0.0.4/src/pl_key_value_sqlite_db/save_int.py +6 -0
  25. pl_key_value_sqlite_db-0.0.4/src/pl_key_value_sqlite_db/save_key_value_value_unsafe.py +20 -0
  26. pl_key_value_sqlite_db-0.0.4/src/pl_key_value_sqlite_db/save_str.py +6 -0
  27. pl_key_value_sqlite_db-0.0.4/src/pl_key_value_sqlite_db/save_value_untyped.py +8 -0
  28. pl_key_value_sqlite_db-0.0.4/src/pl_key_value_sqlite_db/settings.py +28 -0
  29. pl_key_value_sqlite_db-0.0.4/src/pl_key_value_sqlite_db/testing/__init__.py +1 -0
  30. pl_key_value_sqlite_db-0.0.4/src/pl_key_value_sqlite_db/testing/key_value_sqlite_fake.py +49 -0
  31. pl_key_value_sqlite_db-0.0.4/src/pl_key_value_sqlite_db/testing/settings_fake.py +12 -0
  32. pl_key_value_sqlite_db-0.0.2/src/pl_key_value_sqlite_db/placeholder.py +0 -2
  33. {pl_key_value_sqlite_db-0.0.2 → pl_key_value_sqlite_db-0.0.4}/LICENSE +0 -0
  34. {pl_key_value_sqlite_db-0.0.2 → pl_key_value_sqlite_db-0.0.4}/README.md +0 -0
  35. {pl_key_value_sqlite_db-0.0.2 → pl_key_value_sqlite_db-0.0.4}/src/pl_key_value_sqlite_db/__init__.py +0 -0
  36. /pl_key_value_sqlite_db-0.0.2/src/pl_key_value_sqlite_db/typed.py → /pl_key_value_sqlite_db-0.0.4/src/pl_key_value_sqlite_db/py.typed +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pl-key-value-sqlite-db
3
- Version: 0.0.2
3
+ Version: 0.0.4
4
4
  Summary: A persistent key-value store on top of SQLite.
5
5
  Author: Peter Lavigne
6
6
  License-Expression: Apache-2.0
@@ -8,6 +8,8 @@ License-File: LICENSE
8
8
  Classifier: License :: OSI Approved :: Apache Software License
9
9
  Requires-Dist: pl-run-program==0.0.30
10
10
  Requires-Dist: pl-mocks-and-fakes==0.0.30
11
+ Requires-Dist: pl-user-io==0.0.17
12
+ Requires-Dist: pl-tiny-clients==0.0.37
11
13
  Requires-Dist: pydantic>=2.12.5
12
14
  Requires-Dist: pydantic-settings>=2.13.1
13
15
  Requires-Python: >=3.12
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "pl-key-value-sqlite-db"
3
- version = "0.0.2"
3
+ version = "0.0.4"
4
4
  description = "A persistent key-value store on top of SQLite."
5
5
  readme = "README.md"
6
6
  authors = [{ name = "Peter Lavigne" }]
@@ -8,6 +8,8 @@ requires-python = ">=3.12"
8
8
  dependencies = [
9
9
  "pl-run-program==0.0.30",
10
10
  "pl-mocks-and-fakes==0.0.30",
11
+ "pl-user-io==0.0.17",
12
+ "pl-tiny-clients==0.0.37",
11
13
  "pydantic>=2.12.5",
12
14
  "pydantic-settings>=2.13.1",
13
15
  ]
@@ -55,7 +57,7 @@ extend-ignore = ["UP047"]
55
57
  typeCheckingMode = "strict"
56
58
 
57
59
  [tool.coverage.run]
58
- omit = ["tests/*", "src/pl_key_value_sqlite_db/testing/*"]
60
+ omit = ["tests/*", "src/pl_key_value_sqlite_db/testing/*", "*_fake.py"]
59
61
 
60
62
  [tool.coverage.report]
61
63
  # Ignore all functions mocked in unit tests.
@@ -0,0 +1,31 @@
1
+ import pytest
2
+
3
+ PYTEST_INTEGRATION_MARKER = pytest.mark.integration
4
+
5
+ PYTEST_SLOW_MARKER = pytest.mark.slow
6
+ PYTEST_NONDETERMINISTIC_MARKER = pytest.mark.nondeterministic
7
+ PYTEST_DEPENDENT_MARKER = pytest.mark.dependent
8
+ PYTEST_EXPENSIVE_MARKER = pytest.mark.expensive
9
+ PYTEST_MANUAL_MARKER = pytest.mark.manual
10
+
11
+ PYTEST_THIRD_PARTY_API_MARKERS = [
12
+ PYTEST_SLOW_MARKER,
13
+ PYTEST_NONDETERMINISTIC_MARKER,
14
+ PYTEST_DEPENDENT_MARKER,
15
+ ]
16
+
17
+ PYTEST_MANUAL_MARKERS = [
18
+ PYTEST_SLOW_MARKER,
19
+ PYTEST_NONDETERMINISTIC_MARKER,
20
+ PYTEST_DEPENDENT_MARKER,
21
+ PYTEST_MANUAL_MARKER,
22
+ ]
23
+
24
+ PYTEST_INTEGRATION_TEST_MARKERS = [
25
+ PYTEST_INTEGRATION_MARKER,
26
+ PYTEST_SLOW_MARKER,
27
+ PYTEST_NONDETERMINISTIC_MARKER,
28
+ PYTEST_DEPENDENT_MARKER,
29
+ PYTEST_EXPENSIVE_MARKER,
30
+ PYTEST_MANUAL_MARKER,
31
+ ]
@@ -0,0 +1,8 @@
1
+ from pl_key_value_sqlite_db.create_key_value_key_unsafe import (
2
+ create_key_value_key_unsafe,
3
+ )
4
+ from pl_key_value_sqlite_db.key_types import BaseKey
5
+
6
+
7
+ def create_key(key: BaseKey, value: str) -> None:
8
+ create_key_value_key_unsafe(key.value, value)
@@ -0,0 +1,24 @@
1
+ from pl_mocks_and_fakes import MockInUnitTests, MockReason
2
+
3
+ from pl_key_value_sqlite_db.create_key_value_table_if_not_exists import (
4
+ KEY_COLUMN_NAME,
5
+ TABLE_NAME,
6
+ VALUE_COLUMN_NAME,
7
+ )
8
+ from pl_key_value_sqlite_db.execute_key_value_sql import execute_key_value_sql
9
+
10
+
11
+ @MockInUnitTests(MockReason.UNINVESTIGATED)
12
+ def create_key_value_key_unsafe(key: str, value: str) -> None:
13
+ """
14
+ Create a key in the database without type-safety.
15
+
16
+ You should probably use key_value.create_key instead.
17
+ """
18
+ sql = f"""
19
+ INSERT INTO {TABLE_NAME}
20
+ ({KEY_COLUMN_NAME}, {VALUE_COLUMN_NAME})
21
+ VALUES (?, ?)
22
+ """
23
+ with execute_key_value_sql(sql, (key, value)):
24
+ pass
@@ -0,0 +1,21 @@
1
+ from types import NoneType
2
+
3
+ from pl_mocks_and_fakes import MockInUnitTests, MockReason
4
+
5
+ from pl_key_value_sqlite_db.execute_key_value_sql import execute_key_value_sql
6
+
7
+ TABLE_NAME = "key_value"
8
+ KEY_COLUMN_NAME = "key"
9
+ VALUE_COLUMN_NAME = "value"
10
+
11
+
12
+ @MockInUnitTests(MockReason.UNINVESTIGATED)
13
+ def create_key_value_table_if_not_exists() -> NoneType:
14
+ with execute_key_value_sql(f"""
15
+ CREATE TABLE IF NOT EXISTS {TABLE_NAME} (
16
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
17
+ {KEY_COLUMN_NAME} TEXT NOT NULL UNIQUE,
18
+ {VALUE_COLUMN_NAME} TEXT NOT NULL
19
+ )
20
+ """):
21
+ pass
@@ -0,0 +1,8 @@
1
+ from pl_key_value_sqlite_db.delete_key_value_key_unsafe import (
2
+ delete_key_value_key_unsafe,
3
+ )
4
+ from pl_key_value_sqlite_db.key_types import BaseKey
5
+
6
+
7
+ def delete_key_value(key: BaseKey) -> None:
8
+ delete_key_value_key_unsafe(key.value)
@@ -0,0 +1,14 @@
1
+ from pl_mocks_and_fakes import MockInUnitTests, MockReason
2
+
3
+ from pl_key_value_sqlite_db.create_key_value_table_if_not_exists import TABLE_NAME
4
+ from pl_key_value_sqlite_db.execute_key_value_sql import execute_key_value_sql
5
+
6
+
7
+ @MockInUnitTests(MockReason.UNINVESTIGATED)
8
+ def delete_key_value_key_unsafe(key: str) -> None:
9
+ sql = f"""
10
+ DELETE FROM {TABLE_NAME}
11
+ WHERE key = ?
12
+ """
13
+ with execute_key_value_sql(sql, (key,)):
14
+ pass
@@ -0,0 +1,16 @@
1
+ from collections.abc import Generator
2
+ from contextlib import contextmanager
3
+
4
+ from pl_mocks_and_fakes import MockInUnitTests, MockReason
5
+
6
+ from pl_key_value_sqlite_db.execute_sql import ExecuteSqlResponse, execute_sql
7
+ from pl_key_value_sqlite_db.settings import get_settings
8
+
9
+
10
+ @MockInUnitTests(MockReason.UNINVESTIGATED)
11
+ @contextmanager
12
+ def execute_key_value_sql(
13
+ sql: str, params: tuple[str, ...] = ()
14
+ ) -> Generator[ExecuteSqlResponse]:
15
+ with execute_sql(sql, get_settings().key_value_db_path, params) as cursor:
16
+ yield cursor
@@ -0,0 +1,33 @@
1
+ import logging
2
+ import sqlite3
3
+ from collections.abc import Callable, Generator
4
+ from contextlib import contextmanager
5
+ from typing import Any, NamedTuple
6
+
7
+ from pl_mocks_and_fakes import MockInUnitTests, MockReason
8
+
9
+
10
+ class ExecuteSqlResponse(NamedTuple):
11
+ fetch_one: Callable[[], tuple[Any, ...] | None]
12
+ fetch_all: Callable[[], list[tuple[Any, ...]]]
13
+
14
+
15
+ @MockInUnitTests(MockReason.UNINVESTIGATED)
16
+ @contextmanager
17
+ def execute_sql(
18
+ sql: str, database_file_path: str, params: tuple[str, ...] = ()
19
+ ) -> Generator[ExecuteSqlResponse]:
20
+ conn = sqlite3.connect(
21
+ database_file_path
22
+ ) # Creates the DB file if it doesn't exist
23
+ cursor = conn.cursor()
24
+ logging.debug(f"Executing SQL:\n```\n{sql}\n```\nwith params: {params}")
25
+ try:
26
+ cursor.execute(sql, params)
27
+ yield ExecuteSqlResponse(
28
+ fetch_one=cursor.fetchone,
29
+ fetch_all=cursor.fetchall,
30
+ )
31
+ conn.commit()
32
+ finally:
33
+ conn.close()
@@ -0,0 +1,18 @@
1
+ import logging
2
+
3
+ from pl_mocks_and_fakes import MockInUnitTests, MockReason
4
+
5
+ from pl_key_value_sqlite_db.create_key_value_table_if_not_exists import TABLE_NAME
6
+ from pl_key_value_sqlite_db.execute_key_value_sql import execute_key_value_sql
7
+
8
+
9
+ @MockInUnitTests(MockReason.UNINVESTIGATED)
10
+ def get_all_key_value_keys() -> list[str]:
11
+ sql = f"""
12
+ SELECT key
13
+ FROM {TABLE_NAME}
14
+ """
15
+ with execute_key_value_sql(sql) as cursor:
16
+ result = [row[0] for row in cursor.fetch_all()]
17
+ logging.debug(f"Returned value: {result}")
18
+ return result
@@ -0,0 +1,25 @@
1
+ from enum import Enum
2
+
3
+
4
+ class BaseKey(Enum):
5
+ pass
6
+
7
+
8
+ class DateKey(BaseKey):
9
+ pass
10
+
11
+
12
+ class BoolKey(BaseKey):
13
+ pass
14
+
15
+
16
+ class DatetimeKey(BaseKey):
17
+ pass
18
+
19
+
20
+ class StrKey(BaseKey):
21
+ pass
22
+
23
+
24
+ class IntKey(BaseKey):
25
+ pass
@@ -0,0 +1,32 @@
1
+ import logging
2
+ from pathlib import Path
3
+
4
+ from pl_key_value_sqlite_db.create_key import create_key
5
+ from pl_key_value_sqlite_db.create_key_value_table_if_not_exists import (
6
+ create_key_value_table_if_not_exists,
7
+ )
8
+ from pl_key_value_sqlite_db.delete_key_value_key_unsafe import (
9
+ delete_key_value_key_unsafe,
10
+ )
11
+ from pl_key_value_sqlite_db.get_all_key_value_keys import get_all_key_value_keys
12
+ from pl_key_value_sqlite_db.key_types import BaseKey
13
+ from pl_key_value_sqlite_db.settings import get_settings
14
+
15
+
16
+ def run_migrations(initial_entries: dict[BaseKey, str]) -> None:
17
+ logging.info("Checking for migrations to run.")
18
+
19
+ if not Path(get_settings().key_value_db_path).exists():
20
+ create_key_value_table_if_not_exists()
21
+
22
+ existing_keys = get_all_key_value_keys()
23
+
24
+ for key, value in initial_entries.items():
25
+ if key.value not in existing_keys:
26
+ create_key(key, value)
27
+
28
+ for key in existing_keys:
29
+ if key not in [k.value for k in initial_entries]:
30
+ delete_key_value_key_unsafe(key)
31
+
32
+ logging.info("Finished running migrations.")
@@ -0,0 +1,6 @@
1
+ from pl_key_value_sqlite_db.key_types import BoolKey
2
+ from pl_key_value_sqlite_db.load_value_untyped import load_value_untyped
3
+
4
+
5
+ def load_bool(key: BoolKey) -> bool:
6
+ return load_value_untyped(key) == "True"
@@ -0,0 +1,8 @@
1
+ from datetime import date
2
+
3
+ from pl_key_value_sqlite_db.key_types import DateKey
4
+ from pl_key_value_sqlite_db.load_value_untyped import load_value_untyped
5
+
6
+
7
+ def load_date(key: DateKey) -> date:
8
+ return date.fromisoformat(load_value_untyped(key))
@@ -0,0 +1,8 @@
1
+ from datetime import datetime
2
+
3
+ from pl_key_value_sqlite_db.key_types import DatetimeKey
4
+ from pl_key_value_sqlite_db.load_value_untyped import load_value_untyped
5
+
6
+
7
+ def load_datetime(key: DatetimeKey) -> datetime:
8
+ return datetime.fromisoformat(load_value_untyped(key))
@@ -0,0 +1,6 @@
1
+ from pl_key_value_sqlite_db.key_types import IntKey
2
+ from pl_key_value_sqlite_db.load_value_untyped import load_value_untyped
3
+
4
+
5
+ def load_int(key: IntKey) -> int:
6
+ return int(load_value_untyped(key))
@@ -0,0 +1,26 @@
1
+ import logging
2
+
3
+ from pl_mocks_and_fakes import MockInUnitTests, MockReason
4
+
5
+ from pl_key_value_sqlite_db.create_key_value_table_if_not_exists import TABLE_NAME
6
+ from pl_key_value_sqlite_db.execute_key_value_sql import execute_key_value_sql
7
+
8
+
9
+ @MockInUnitTests(MockReason.UNINVESTIGATED)
10
+ def load_key_value_unsafe(key: str) -> str:
11
+ """
12
+ Get a value in the database by key without type-safety.
13
+
14
+ You should probably use key_value.get_value instead.
15
+ """
16
+ sql = f"""
17
+ SELECT value
18
+ FROM {TABLE_NAME}
19
+ WHERE key = ?
20
+ """
21
+ with execute_key_value_sql(sql, (key,)) as cursor:
22
+ result = cursor.fetch_one()
23
+ assert result is not None, f"Key '{key}' not found in database."
24
+ result_value = result[0]
25
+ logging.debug(f"Returned value: {result_value}")
26
+ return result_value
@@ -0,0 +1,6 @@
1
+ from pl_key_value_sqlite_db.key_types import StrKey
2
+ from pl_key_value_sqlite_db.load_value_untyped import load_value_untyped
3
+
4
+
5
+ def load_str(key: StrKey) -> str:
6
+ return load_value_untyped(key)
@@ -0,0 +1,6 @@
1
+ from pl_key_value_sqlite_db.key_types import BaseKey
2
+ from pl_key_value_sqlite_db.load_key_value_unsafe import load_key_value_unsafe
3
+
4
+
5
+ def load_value_untyped(key: BaseKey) -> str:
6
+ return load_key_value_unsafe(key.value)
@@ -0,0 +1,6 @@
1
+ from pl_key_value_sqlite_db.key_types import BoolKey
2
+ from pl_key_value_sqlite_db.save_value_untyped import save_value_untyped
3
+
4
+
5
+ def save_bool(key: BoolKey, value: bool) -> None:
6
+ save_value_untyped(key, str(value))
@@ -0,0 +1,11 @@
1
+ from datetime import date
2
+
3
+ from pl_key_value_sqlite_db.key_types import DateKey
4
+ from pl_key_value_sqlite_db.save_value_untyped import save_value_untyped
5
+
6
+
7
+ def save_date(key: DateKey, value: date) -> None:
8
+ if value.__class__.__name__ != "date":
9
+ msg = f"Expected date object, got {value.__class__.__name__}"
10
+ raise TypeError(msg)
11
+ save_value_untyped(key, value.isoformat())
@@ -0,0 +1,8 @@
1
+ from datetime import datetime
2
+
3
+ from pl_key_value_sqlite_db.key_types import DatetimeKey
4
+ from pl_key_value_sqlite_db.save_value_untyped import save_value_untyped
5
+
6
+
7
+ def save_datetime(key: DatetimeKey, value: datetime) -> None:
8
+ save_value_untyped(key, value.isoformat())
@@ -0,0 +1,6 @@
1
+ from pl_key_value_sqlite_db.key_types import IntKey
2
+ from pl_key_value_sqlite_db.save_value_untyped import save_value_untyped
3
+
4
+
5
+ def save_int(key: IntKey, value: int) -> None:
6
+ save_value_untyped(key, str(value))
@@ -0,0 +1,20 @@
1
+ from pl_mocks_and_fakes import MockInUnitTests, MockReason
2
+
3
+ from pl_key_value_sqlite_db.create_key_value_table_if_not_exists import TABLE_NAME
4
+ from pl_key_value_sqlite_db.execute_key_value_sql import execute_key_value_sql
5
+
6
+
7
+ @MockInUnitTests(MockReason.UNINVESTIGATED)
8
+ def save_key_value_value_unsafe(key: str, value: str) -> None:
9
+ """
10
+ Set a value in the database by key without type-safety.
11
+
12
+ You should probably use key_value.set_value instead.
13
+ """
14
+ sql = f"""
15
+ UPDATE {TABLE_NAME}
16
+ SET value = ?
17
+ WHERE key = ?
18
+ """
19
+ with execute_key_value_sql(sql, (value, key)):
20
+ pass
@@ -0,0 +1,6 @@
1
+ from pl_key_value_sqlite_db.key_types import StrKey
2
+ from pl_key_value_sqlite_db.save_value_untyped import save_value_untyped
3
+
4
+
5
+ def save_str(key: StrKey, value: str) -> None:
6
+ save_value_untyped(key, value)
@@ -0,0 +1,8 @@
1
+ from pl_key_value_sqlite_db.key_types import BaseKey
2
+ from pl_key_value_sqlite_db.save_key_value_value_unsafe import (
3
+ save_key_value_value_unsafe,
4
+ )
5
+
6
+
7
+ def save_value_untyped(key: BaseKey, value: str) -> None:
8
+ save_key_value_value_unsafe(key.value, value)
@@ -0,0 +1,28 @@
1
+ from pathlib import Path
2
+
3
+ from pl_mocks_and_fakes import MockInUnitTests, MockReason
4
+ from pydantic import Field
5
+ from pydantic_settings import (
6
+ BaseSettings,
7
+ SettingsConfigDict,
8
+ )
9
+
10
+
11
+ class Settings(BaseSettings):
12
+ model_config = SettingsConfigDict(
13
+ env_file=".env",
14
+ extra="ignore",
15
+ secrets_dir=Path.home() / ".secrets-files",
16
+ )
17
+
18
+ # Env-specific config
19
+ key_value_db_path: str = Field(
20
+ validation_alias="KEY_VALUE_DB_PATH", default="~/bin/key_value.db"
21
+ )
22
+
23
+
24
+ @MockInUnitTests(MockReason.UNMITIGATED_SIDE_EFFECT)
25
+ def get_settings() -> Settings:
26
+ """Get settings. Raises exception if required settings are missing or invalid."""
27
+ # Required fields are populated from env/.env at runtime; pyright doesn't model that.
28
+ return Settings() # pyright: ignore[reportCallIssue]
@@ -0,0 +1,49 @@
1
+ from pl_mocks_and_fakes import Fake, mock_for
2
+
3
+ from pl_key_value_sqlite_db.create_key_value_key_unsafe import (
4
+ create_key_value_key_unsafe,
5
+ )
6
+ from pl_key_value_sqlite_db.delete_key_value_key_unsafe import (
7
+ delete_key_value_key_unsafe,
8
+ )
9
+ from pl_key_value_sqlite_db.get_all_key_value_keys import get_all_key_value_keys
10
+ from pl_key_value_sqlite_db.load_key_value_unsafe import load_key_value_unsafe
11
+ from pl_key_value_sqlite_db.save_key_value_value_unsafe import (
12
+ save_key_value_value_unsafe,
13
+ )
14
+
15
+
16
+ class KeyValueSqliteFake(Fake):
17
+ def __init__(self) -> None:
18
+ def _get_all_keys_side_effect() -> list[str]:
19
+ return list(self.store.keys())
20
+
21
+ def _create_key_unsafe_side_effect(key: str, value: str) -> None:
22
+ if key not in self.store:
23
+ self.store[key] = value
24
+
25
+ def _delete_key_unsafe_side_effect(key: str) -> None:
26
+ del self.store[key]
27
+
28
+ def _load_value_unsafe_side_effect(key: str) -> str:
29
+ return self.store[key]
30
+
31
+ def _save_value_unsafe_side_effect(key: str, value: str) -> None:
32
+ if key not in self.store:
33
+ msg = f"Key `{key}` does not exist."
34
+ raise Exception(msg)
35
+ self.store[key] = value
36
+
37
+ self.store: dict[str, str] = {}
38
+
39
+ mock_for(get_all_key_value_keys).side_effect = _get_all_keys_side_effect
40
+ mock_for(
41
+ create_key_value_key_unsafe
42
+ ).side_effect = _create_key_unsafe_side_effect
43
+ mock_for(
44
+ delete_key_value_key_unsafe
45
+ ).side_effect = _delete_key_unsafe_side_effect
46
+ mock_for(load_key_value_unsafe).side_effect = _load_value_unsafe_side_effect
47
+ mock_for(
48
+ save_key_value_value_unsafe
49
+ ).side_effect = _save_value_unsafe_side_effect
@@ -0,0 +1,12 @@
1
+ from pl_mocks_and_fakes import Fake, stub
2
+
3
+ from pl_key_value_sqlite_db.settings import Settings, get_settings
4
+
5
+
6
+ class SettingsFake(Fake):
7
+ def __init__(self) -> None:
8
+ self.settings = Settings(
9
+ key_value_db_path="",
10
+ )
11
+ self.settings.key_value_db_path = ""
12
+ stub(get_settings)(self.settings)
@@ -1,2 +0,0 @@
1
- def placeholder() -> None:
2
- pass