apexdevkit 1.29.1__tar.gz → 1.29.2__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 (62) hide show
  1. {apexdevkit-1.29.1 → apexdevkit-1.29.2}/PKG-INFO +1 -1
  2. {apexdevkit-1.29.1 → apexdevkit-1.29.2}/apexdevkit/fastapi/service.py +2 -4
  3. {apexdevkit-1.29.1 → apexdevkit-1.29.2}/apexdevkit/formatter.py +13 -13
  4. {apexdevkit-1.29.1 → apexdevkit-1.29.2}/apexdevkit/repository/__init__.py +7 -3
  5. {apexdevkit-1.29.1 → apexdevkit-1.29.2}/apexdevkit/repository/core/__init__.py +2 -1
  6. {apexdevkit-1.29.1 → apexdevkit-1.29.2}/apexdevkit/repository/core/interface.py +14 -1
  7. apexdevkit-1.29.2/apexdevkit/repository/in_memory/__init__.py +10 -0
  8. apexdevkit-1.29.2/apexdevkit/repository/in_memory/mixin.py +20 -0
  9. apexdevkit-1.29.2/apexdevkit/repository/in_memory/repository.py +70 -0
  10. {apexdevkit-1.29.1 → apexdevkit-1.29.2}/apexdevkit/repository/in_memory/store.py +2 -16
  11. {apexdevkit-1.29.1 → apexdevkit-1.29.2}/apexdevkit/repository/sql/mssql.py +2 -4
  12. {apexdevkit-1.29.1 → apexdevkit-1.29.2}/pyproject.toml +1 -1
  13. apexdevkit-1.29.1/apexdevkit/repository/in_memory/__init__.py +0 -8
  14. apexdevkit-1.29.1/apexdevkit/repository/in_memory/builder.py +0 -62
  15. apexdevkit-1.29.1/apexdevkit/repository/in_memory/multi_key.py +0 -53
  16. apexdevkit-1.29.1/apexdevkit/repository/in_memory/single_key.py +0 -51
  17. {apexdevkit-1.29.1 → apexdevkit-1.29.2}/LICENSE +0 -0
  18. {apexdevkit-1.29.1 → apexdevkit-1.29.2}/README.md +0 -0
  19. {apexdevkit-1.29.1 → apexdevkit-1.29.2}/apexdevkit/__init__.py +0 -0
  20. {apexdevkit-1.29.1 → apexdevkit-1.29.2}/apexdevkit/annotation/__init__.py +0 -0
  21. {apexdevkit-1.29.1 → apexdevkit-1.29.2}/apexdevkit/annotation/deprecate.py +0 -0
  22. {apexdevkit-1.29.1 → apexdevkit-1.29.2}/apexdevkit/date.py +0 -0
  23. {apexdevkit-1.29.1 → apexdevkit-1.29.2}/apexdevkit/environment.py +0 -0
  24. {apexdevkit-1.29.1 → apexdevkit-1.29.2}/apexdevkit/error.py +0 -0
  25. {apexdevkit-1.29.1 → apexdevkit-1.29.2}/apexdevkit/fastapi/__init__.py +0 -0
  26. {apexdevkit-1.29.1 → apexdevkit-1.29.2}/apexdevkit/fastapi/builder.py +0 -0
  27. {apexdevkit-1.29.1 → apexdevkit-1.29.2}/apexdevkit/fastapi/dependable.py +0 -0
  28. {apexdevkit-1.29.1 → apexdevkit-1.29.2}/apexdevkit/fastapi/docs.py +0 -0
  29. {apexdevkit-1.29.1 → apexdevkit-1.29.2}/apexdevkit/fastapi/name.py +0 -0
  30. {apexdevkit-1.29.1 → apexdevkit-1.29.2}/apexdevkit/fastapi/resource.py +0 -0
  31. {apexdevkit-1.29.1 → apexdevkit-1.29.2}/apexdevkit/fastapi/response.py +0 -0
  32. {apexdevkit-1.29.1 → apexdevkit-1.29.2}/apexdevkit/fastapi/router.py +0 -0
  33. {apexdevkit-1.29.1 → apexdevkit-1.29.2}/apexdevkit/fastapi/schema.py +0 -0
  34. {apexdevkit-1.29.1 → apexdevkit-1.29.2}/apexdevkit/fluent.py +0 -0
  35. {apexdevkit-1.29.1 → apexdevkit-1.29.2}/apexdevkit/http/__init__.py +0 -0
  36. {apexdevkit-1.29.1 → apexdevkit-1.29.2}/apexdevkit/http/fake.py +0 -0
  37. {apexdevkit-1.29.1 → apexdevkit-1.29.2}/apexdevkit/http/fluent.py +0 -0
  38. {apexdevkit-1.29.1 → apexdevkit-1.29.2}/apexdevkit/http/httpx/__init__.py +0 -0
  39. {apexdevkit-1.29.1 → apexdevkit-1.29.2}/apexdevkit/http/httpx/client.py +0 -0
  40. {apexdevkit-1.29.1 → apexdevkit-1.29.2}/apexdevkit/http/httpx/hooks.py +0 -0
  41. {apexdevkit-1.29.1 → apexdevkit-1.29.2}/apexdevkit/http/json.py +0 -0
  42. {apexdevkit-1.29.1 → apexdevkit-1.29.2}/apexdevkit/http/url.py +0 -0
  43. {apexdevkit-1.29.1 → apexdevkit-1.29.2}/apexdevkit/id.py +0 -0
  44. {apexdevkit-1.29.1 → apexdevkit-1.29.2}/apexdevkit/key_fn.py +0 -0
  45. {apexdevkit-1.29.1 → apexdevkit-1.29.2}/apexdevkit/py.typed +0 -0
  46. {apexdevkit-1.29.1 → apexdevkit-1.29.2}/apexdevkit/query/__init__.py +0 -0
  47. {apexdevkit-1.29.1 → apexdevkit-1.29.2}/apexdevkit/query/generator.py +0 -0
  48. {apexdevkit-1.29.1 → apexdevkit-1.29.2}/apexdevkit/query/query.py +0 -0
  49. {apexdevkit-1.29.1 → apexdevkit-1.29.2}/apexdevkit/repository/core/database.py +0 -0
  50. {apexdevkit-1.29.1 → apexdevkit-1.29.2}/apexdevkit/repository/core/decorator.py +0 -0
  51. {apexdevkit-1.29.1 → apexdevkit-1.29.2}/apexdevkit/repository/core/multi.py +0 -0
  52. {apexdevkit-1.29.1 → apexdevkit-1.29.2}/apexdevkit/repository/sql/__init__.py +0 -0
  53. {apexdevkit-1.29.1 → apexdevkit-1.29.2}/apexdevkit/repository/sql/connector.py +0 -0
  54. {apexdevkit-1.29.1 → apexdevkit-1.29.2}/apexdevkit/repository/sql/field.py +0 -0
  55. {apexdevkit-1.29.1 → apexdevkit-1.29.2}/apexdevkit/repository/sql/sqlite.py +0 -0
  56. {apexdevkit-1.29.1 → apexdevkit-1.29.2}/apexdevkit/server.py +0 -0
  57. {apexdevkit-1.29.1 → apexdevkit-1.29.2}/apexdevkit/synchronization.py +0 -0
  58. {apexdevkit-1.29.1 → apexdevkit-1.29.2}/apexdevkit/testing/__init__.py +0 -0
  59. {apexdevkit-1.29.1 → apexdevkit-1.29.2}/apexdevkit/testing/database.py +0 -0
  60. {apexdevkit-1.29.1 → apexdevkit-1.29.2}/apexdevkit/testing/fake.py +0 -0
  61. {apexdevkit-1.29.1 → apexdevkit-1.29.2}/apexdevkit/testing/rest.py +0 -0
  62. {apexdevkit-1.29.1 → apexdevkit-1.29.2}/apexdevkit/value.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: apexdevkit
3
- Version: 1.29.1
3
+ Version: 1.29.2
4
4
  Summary: Apex Development Tools for python.
5
5
  License-File: LICENSE
6
6
  Author: Apex Dev
@@ -3,10 +3,11 @@ from __future__ import annotations
3
3
  from collections.abc import Iterable, Mapping
4
4
  from dataclasses import dataclass
5
5
  from functools import cached_property
6
- from typing import Any, Generic, TypeVar
6
+ from typing import Any, Generic
7
7
 
8
8
  from apexdevkit.formatter import Formatter
9
9
  from apexdevkit.repository import BruteForceBatch, Repository
10
+ from apexdevkit.repository.core import ItemT
10
11
 
11
12
  RawItem = Mapping[str, Any]
12
13
  RawCollection = Iterable[RawItem]
@@ -58,9 +59,6 @@ class RestfulService: # pragma: no cover
58
59
  raise NotImplementedError(self.delete_one.__name__)
59
60
 
60
61
 
61
- ItemT = TypeVar("ItemT")
62
-
63
-
64
62
  @dataclass(frozen=True)
65
63
  class RestfulRepository(RestfulService, Generic[ItemT]):
66
64
  repository: Repository[ItemT]
@@ -85,8 +85,8 @@ class DataclassFormatter(Generic[_TargetT]):
85
85
 
86
86
  return self
87
87
 
88
- def load(self, raw: Mapping[str, Any]) -> _TargetT:
89
- raw = FluentDict[Any](deepcopy(raw)).select(
88
+ def load(self, source: Mapping[str, Any]) -> _TargetT:
89
+ source = FluentDict[Any](deepcopy(source)).select(
90
90
  *self.resource.__annotations__.keys(),
91
91
  "id",
92
92
  "idempotency_id",
@@ -95,27 +95,27 @@ class DataclassFormatter(Generic[_TargetT]):
95
95
  for key in fields(self.resource): # type: ignore
96
96
  types = get_type_hints(self.resource)
97
97
  key_type = types[key.name]
98
- if key.name not in raw:
98
+ if key.name not in source:
99
99
  continue
100
100
  if key.name in self.sub_formatters:
101
- raw[key.name] = (
102
- self.sub_formatters[key.name].load(raw.pop(key.name))
103
- if raw[key.name]
104
- else raw[key.name]
101
+ source[key.name] = (
102
+ self.sub_formatters[key.name].load(source.pop(key.name))
103
+ if source[key.name]
104
+ else source[key.name]
105
105
  )
106
106
  elif is_dataclass(key_type):
107
- raw[key.name] = DataclassFormatter(key_type).load(raw[key.name]) # type: ignore
107
+ source[key.name] = DataclassFormatter(key_type).load(source[key.name]) # type: ignore
108
108
  else:
109
109
  args = get_args(key_type)
110
110
  if len(args) == 1 and is_dataclass(args[0]):
111
- raw[key.name] = ListFormatter(DataclassFormatter(args[0])).load( # type: ignore
112
- raw[key.name]
111
+ source[key.name] = ListFormatter(DataclassFormatter(args[0])).load( # type: ignore
112
+ source[key.name]
113
113
  )
114
114
 
115
- return self.resource(**raw)
115
+ return self.resource(**source)
116
116
 
117
- def dump(self, item: _TargetT) -> Mapping[str, Any]:
118
- return asdict(item) # type: ignore
117
+ def dump(self, target: _TargetT) -> Mapping[str, Any]:
118
+ return asdict(target) # type: ignore
119
119
 
120
120
 
121
121
  class ValueFormatter:
@@ -1,4 +1,4 @@
1
- from apexdevkit.repository.core import (
1
+ from .core import (
2
2
  BruteForceBatch,
3
3
  Connection,
4
4
  Connector,
@@ -9,14 +9,17 @@ from apexdevkit.repository.core import (
9
9
  RepositoryBase,
10
10
  RepositoryDecorator,
11
11
  )
12
- from apexdevkit.repository.in_memory import (
12
+ from .core.interface import Entity
13
+ from .in_memory import (
14
+ CacheMixin,
13
15
  InMemoryByteStore,
14
16
  InMemoryRepository,
15
17
  KeyValueStore,
16
18
  )
17
- from apexdevkit.repository.sql import MsSqlRepository, SqliteRepository
19
+ from .sql import MsSqlRepository, SqliteRepository
18
20
 
19
21
  __all__ = [
22
+ "Entity",
20
23
  # Core
21
24
  "BruteForceBatch",
22
25
  "Connection",
@@ -28,6 +31,7 @@ __all__ = [
28
31
  "RepositoryBase",
29
32
  "RepositoryDecorator",
30
33
  # In-memory
34
+ "CacheMixin",
31
35
  "InMemoryByteStore",
32
36
  "InMemoryRepository",
33
37
  "KeyValueStore",
@@ -7,7 +7,7 @@ from .database import (
7
7
  DatabaseCommand,
8
8
  )
9
9
  from .decorator import BruteForceBatch, RepositoryDecorator
10
- from .interface import Repository, RepositoryBase
10
+ from .interface import ItemT, Repository, RepositoryBase
11
11
 
12
12
  __all__ = [
13
13
  # Database
@@ -21,6 +21,7 @@ __all__ = [
21
21
  "RepositoryDecorator",
22
22
  "BruteForceBatch",
23
23
  # Interface
24
+ "ItemT",
24
25
  "Repository",
25
26
  "RepositoryBase",
26
27
  ]
@@ -1,9 +1,22 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  from collections.abc import Callable, Iterable, Iterator
4
+ from dataclasses import dataclass, field
4
5
  from typing import Generic, Protocol, TypeVar
6
+ from uuid import uuid4
5
7
 
6
- ItemT = TypeVar("ItemT")
8
+
9
+ def _uuid() -> str:
10
+ return str(uuid4())
11
+
12
+
13
+ @dataclass(frozen=True, kw_only=True)
14
+ class Entity:
15
+ id: str = field(default_factory=_uuid)
16
+ idempotency_id: str | None = field(default=None)
17
+
18
+
19
+ ItemT = TypeVar("ItemT", bound=Entity)
7
20
  KeyFn = Callable[[ItemT], str]
8
21
 
9
22
 
@@ -0,0 +1,10 @@
1
+ from .mixin import CacheMixin
2
+ from .repository import InMemoryRepository
3
+ from .store import InMemoryByteStore, KeyValueStore
4
+
5
+ __all__ = [
6
+ "CacheMixin",
7
+ "InMemoryRepository",
8
+ "InMemoryByteStore",
9
+ "KeyValueStore",
10
+ ]
@@ -0,0 +1,20 @@
1
+ from collections import defaultdict
2
+ from collections.abc import MutableMapping
3
+ from dataclasses import dataclass
4
+ from functools import cached_property
5
+ from typing import Any
6
+
7
+ from .store import InMemoryByteStore, KeyValueStore
8
+
9
+
10
+ @dataclass(frozen=True)
11
+ class CacheMixin:
12
+ @cached_property
13
+ def _entries(self) -> MutableMapping[str, KeyValueStore[Any]]:
14
+ return defaultdict(InMemoryByteStore)
15
+
16
+ def store_for(self, name: str) -> KeyValueStore[Any]:
17
+ return self._entries[name]
18
+
19
+ def clear(self) -> None:
20
+ self._entries.clear()
@@ -0,0 +1,70 @@
1
+ from __future__ import annotations
2
+
3
+ from collections.abc import Iterator
4
+ from contextlib import suppress
5
+ from dataclasses import dataclass, field
6
+
7
+ from apexdevkit.error import DoesNotExistError, ExistsError
8
+ from apexdevkit.key_fn import AttributeKey
9
+ from apexdevkit.repository.core import ItemT, RepositoryBase
10
+ from apexdevkit.repository.core.interface import KeyFn
11
+
12
+ from .store import InMemoryByteStore, KeyValueStore
13
+
14
+
15
+ @dataclass(frozen=True)
16
+ class InMemoryRepository(RepositoryBase[ItemT]):
17
+ store: KeyValueStore[ItemT] = field(default_factory=InMemoryByteStore)
18
+ keys: list[KeyFn[ItemT]] = field(default_factory=lambda: [AttributeKey("id")])
19
+
20
+ def and_key(self, function: KeyFn[ItemT]) -> InMemoryRepository[ItemT]:
21
+ return self.with_key(function)
22
+
23
+ def with_key(self, function: KeyFn[ItemT]) -> InMemoryRepository[ItemT]:
24
+ self.keys.append(function)
25
+
26
+ return self
27
+
28
+ def and_seeded(self, *items: ItemT) -> InMemoryRepository[ItemT]:
29
+ return self.with_seeded(*items)
30
+
31
+ def with_seeded(self, *items: ItemT) -> InMemoryRepository[ItemT]:
32
+ for seed in items:
33
+ with suppress(ExistsError):
34
+ self.create(seed)
35
+
36
+ return self
37
+
38
+ def create(self, item: ItemT) -> ItemT:
39
+ self._ensure_does_not_exist(item)
40
+ self.store.set(item.id, item)
41
+
42
+ return item
43
+
44
+ def _ensure_does_not_exist(self, new: ItemT) -> None:
45
+ for existing in self:
46
+ for key in self.keys:
47
+ if key(new) == key(existing):
48
+ ExistsError(existing).with_duplicate(key).fire()
49
+
50
+ def update(self, item: ItemT) -> None:
51
+ self.delete(item.id)
52
+ self.create(item)
53
+
54
+ def delete(self, item_id: str) -> None:
55
+ item = self.read(item_id)
56
+ self.store.drop(item.id)
57
+
58
+ def read(self, item_id: str) -> ItemT:
59
+ for key in self.keys:
60
+ for item in self:
61
+ if key(item) == str(item_id):
62
+ return item
63
+
64
+ raise DoesNotExistError(item_id)
65
+
66
+ def __iter__(self) -> Iterator[ItemT]:
67
+ return iter(self.store.values())
68
+
69
+ def __len__(self) -> int:
70
+ return self.store.count()
@@ -1,9 +1,8 @@
1
1
  from __future__ import annotations
2
2
 
3
- from collections import defaultdict
4
- from collections.abc import Iterable, MutableMapping
3
+ from collections.abc import Iterable
5
4
  from dataclasses import dataclass, field
6
- from typing import Any, Generic, Protocol
5
+ from typing import Generic, Protocol
7
6
 
8
7
  from apexdevkit.formatter import Formatter, PickleFormatter
9
8
  from apexdevkit.repository.core.interface import ItemT
@@ -47,16 +46,3 @@ class InMemoryByteStore(Generic[ItemT]):
47
46
  def values(self) -> Iterable[ItemT]:
48
47
  for raw in self.items.values():
49
48
  yield self.formatter.load(raw)
50
-
51
- @dataclass
52
- class Cache:
53
- items: MutableMapping[str, InMemoryByteStore[Any]] = field(init=False)
54
-
55
- def __post_init__(self) -> None:
56
- self.items = defaultdict(InMemoryByteStore)
57
-
58
- def store_for(self, name: str) -> InMemoryByteStore[Any]:
59
- return self.items[name]
60
-
61
- def clear(self) -> None:
62
- self.items.clear()
@@ -2,17 +2,15 @@ from __future__ import annotations
2
2
 
3
3
  from collections.abc import Iterable, Iterator, Mapping
4
4
  from dataclasses import dataclass
5
- from typing import Any, Generic, TypeVar
5
+ from typing import Any, Generic
6
6
 
7
7
  from pymssql.exceptions import DatabaseError, OperationalError
8
8
 
9
9
  from apexdevkit.error import DoesNotExistError, ExistsError
10
10
  from apexdevkit.formatter import Formatter
11
- from apexdevkit.repository import Database, DatabaseCommand, RepositoryBase
11
+ from apexdevkit.repository.core import Database, DatabaseCommand, ItemT, RepositoryBase
12
12
  from apexdevkit.repository.sql.field import NotNone, SqlFieldManager, _SqlField
13
13
 
14
- ItemT = TypeVar("ItemT")
15
-
16
14
 
17
15
  @dataclass
18
16
  class MsSqlRepository(RepositoryBase[ItemT]):
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "apexdevkit"
3
- version = "1.29.1"
3
+ version = "1.29.2"
4
4
  description = "Apex Development Tools for python."
5
5
  readme = "README.md"
6
6
  authors = [
@@ -1,8 +0,0 @@
1
- from apexdevkit.repository.in_memory.builder import InMemoryRepository
2
- from apexdevkit.repository.in_memory.store import InMemoryByteStore, KeyValueStore
3
-
4
- __all__ = [
5
- "InMemoryRepository",
6
- "InMemoryByteStore",
7
- "KeyValueStore",
8
- ]
@@ -1,62 +0,0 @@
1
- from __future__ import annotations
2
-
3
- from contextlib import suppress
4
- from dataclasses import dataclass, field
5
- from typing import Generic
6
-
7
- from apexdevkit.error import ExistsError
8
- from apexdevkit.key_fn import AttributeKey
9
- from apexdevkit.repository.core.interface import ItemT, KeyFn, Repository
10
-
11
- from .multi_key import MultiKeyRepository
12
- from .single_key import SingleKeyRepository
13
- from .store import InMemoryByteStore, KeyValueStore
14
-
15
-
16
- @dataclass(frozen=True)
17
- class InMemoryRepository(Generic[ItemT]):
18
- store: KeyValueStore[ItemT] = field(default_factory=lambda: InMemoryByteStore())
19
- keys: list[KeyFn[ItemT]] = field(default_factory=list)
20
- seeds: frozenset[ItemT] = field(default_factory=frozenset)
21
-
22
- def with_store(self, value: KeyValueStore[ItemT]) -> InMemoryRepository[ItemT]:
23
- return InMemoryRepository(store=value, keys=self.keys, seeds=self.seeds)
24
-
25
- def and_key(self, function: KeyFn[ItemT]) -> InMemoryRepository[ItemT]:
26
- return self.with_key(function)
27
-
28
- def with_key(self, function: KeyFn[ItemT]) -> InMemoryRepository[ItemT]:
29
- return InMemoryRepository(
30
- store=self.store,
31
- keys=[*self.keys, function],
32
- seeds=self.seeds,
33
- )
34
-
35
- def and_seeded(self, *items: ItemT) -> InMemoryRepository[ItemT]:
36
- return self.with_seeded(*items)
37
-
38
- def with_seeded(self, *items: ItemT) -> InMemoryRepository[ItemT]:
39
- return InMemoryRepository(
40
- store=self.store,
41
- keys=self.keys,
42
- seeds=self.seeds.union(set(items)),
43
- )
44
-
45
- def build(self) -> Repository[ItemT]:
46
- return self._seed(self._create())
47
-
48
- def _seed(self, repository: Repository[ItemT]) -> Repository[ItemT]:
49
- for seed in self.seeds:
50
- with suppress(ExistsError):
51
- repository.create(seed)
52
-
53
- return repository
54
-
55
- def _create(self) -> Repository[ItemT]:
56
- match len(self.keys):
57
- case 0:
58
- return SingleKeyRepository(self.store, pk=AttributeKey("id"))
59
- case 1:
60
- return SingleKeyRepository(self.store, pk=self.keys[0])
61
- case _:
62
- return MultiKeyRepository(self.store, keys=self.keys)
@@ -1,53 +0,0 @@
1
- from __future__ import annotations
2
-
3
- from collections.abc import Iterator
4
- from dataclasses import dataclass, field
5
-
6
- from apexdevkit.error import DoesNotExistError, ExistsError
7
- from apexdevkit.repository.core.interface import ItemT, KeyFn, RepositoryBase
8
-
9
- from .store import KeyValueStore
10
-
11
-
12
- @dataclass
13
- class MultiKeyRepository(RepositoryBase[ItemT]):
14
- store: KeyValueStore[ItemT]
15
-
16
- keys: list[KeyFn[ItemT]] = field(default_factory=list)
17
-
18
- def create(self, item: ItemT) -> ItemT:
19
- self._ensure_does_not_exist(item)
20
- self.store.set(self._pk(item), item)
21
-
22
- return item
23
-
24
- def _ensure_does_not_exist(self, new: ItemT) -> None:
25
- for existing in self:
26
- for key in self.keys:
27
- if key(new) == key(existing):
28
- ExistsError(existing).with_duplicate(key).fire()
29
-
30
- def _pk(self, item: ItemT) -> str:
31
- return self.keys[0](item)
32
-
33
- def update(self, item: ItemT) -> None:
34
- self.delete(self._pk(item))
35
- self.create(item)
36
-
37
- def delete(self, item_id: str) -> None:
38
- item = self.read(item_id)
39
- self.store.drop(self._pk(item))
40
-
41
- def read(self, item_id: str) -> ItemT:
42
- for key in self.keys:
43
- for item in self:
44
- if key(item) == str(item_id):
45
- return item
46
-
47
- raise DoesNotExistError(item_id)
48
-
49
- def __iter__(self) -> Iterator[ItemT]:
50
- return iter(self.store.values())
51
-
52
- def __len__(self) -> int:
53
- return self.store.count()
@@ -1,51 +0,0 @@
1
- from __future__ import annotations
2
-
3
- from collections.abc import Iterator
4
- from dataclasses import dataclass
5
-
6
- from apexdevkit.error import DoesNotExistError, ExistsError
7
- from apexdevkit.repository.core.interface import ItemT, KeyFn, RepositoryBase
8
-
9
- from .store import KeyValueStore
10
-
11
-
12
- @dataclass
13
- class SingleKeyRepository(RepositoryBase[ItemT]):
14
- store: KeyValueStore[ItemT]
15
- pk: KeyFn[ItemT]
16
-
17
- def create(self, item: ItemT) -> ItemT:
18
- self._ensure_does_not_exist(item)
19
- self.store.set(self.pk(item), item)
20
-
21
- return item
22
-
23
- def _ensure_does_not_exist(self, new: ItemT) -> None:
24
- try:
25
- existing = self.store.get(self.pk(new))
26
- except KeyError:
27
- return
28
-
29
- ExistsError(existing).with_duplicate(self.pk).fire()
30
-
31
- def update(self, item: ItemT) -> None:
32
- self.delete(self.pk(item))
33
- self.create(item)
34
-
35
- def delete(self, item_id: str) -> None:
36
- try:
37
- self.store.drop(item_id)
38
- except KeyError as e:
39
- raise DoesNotExistError(item_id) from e
40
-
41
- def read(self, item_id: str) -> ItemT:
42
- try:
43
- return self.store.get(item_id)
44
- except KeyError as e:
45
- raise DoesNotExistError(item_id) from e
46
-
47
- def __iter__(self) -> Iterator[ItemT]:
48
- return iter(self.store.values())
49
-
50
- def __len__(self) -> int:
51
- return self.store.count()
File without changes
File without changes