apexdevkit 1.20.2__tar.gz → 1.20.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.
- {apexdevkit-1.20.2 → apexdevkit-1.20.4}/PKG-INFO +1 -1
- {apexdevkit-1.20.2 → apexdevkit-1.20.4}/apexdevkit/fastapi/__init__.py +2 -2
- {apexdevkit-1.20.2 → apexdevkit-1.20.4}/apexdevkit/fastapi/builder.py +8 -0
- {apexdevkit-1.20.2 → apexdevkit-1.20.4}/apexdevkit/fastapi/dependable.py +2 -29
- {apexdevkit-1.20.2 → apexdevkit-1.20.4}/apexdevkit/fastapi/router.py +0 -9
- {apexdevkit-1.20.2 → apexdevkit-1.20.4}/apexdevkit/fastapi/service.py +7 -27
- {apexdevkit-1.20.2 → apexdevkit-1.20.4}/apexdevkit/formatter.py +36 -5
- {apexdevkit-1.20.2 → apexdevkit-1.20.4}/apexdevkit/query/generator.py +2 -2
- {apexdevkit-1.20.2 → apexdevkit-1.20.4}/apexdevkit/repository/database.py +2 -2
- {apexdevkit-1.20.2 → apexdevkit-1.20.4}/apexdevkit/repository/mongo.py +2 -2
- {apexdevkit-1.20.2 → apexdevkit-1.20.4}/apexdevkit/repository/mssql.py +6 -6
- {apexdevkit-1.20.2 → apexdevkit-1.20.4}/apexdevkit/repository/sql.py +4 -2
- {apexdevkit-1.20.2 → apexdevkit-1.20.4}/apexdevkit/repository/sqlite.py +7 -7
- {apexdevkit-1.20.2 → apexdevkit-1.20.4}/pyproject.toml +1 -1
- {apexdevkit-1.20.2 → apexdevkit-1.20.4}/LICENSE +0 -0
- {apexdevkit-1.20.2 → apexdevkit-1.20.4}/README.md +0 -0
- {apexdevkit-1.20.2 → apexdevkit-1.20.4}/apexdevkit/__init__.py +0 -0
- {apexdevkit-1.20.2 → apexdevkit-1.20.4}/apexdevkit/annotation/__init__.py +0 -0
- {apexdevkit-1.20.2 → apexdevkit-1.20.4}/apexdevkit/annotation/deprecate.py +0 -0
- {apexdevkit-1.20.2 → apexdevkit-1.20.4}/apexdevkit/environment.py +0 -0
- {apexdevkit-1.20.2 → apexdevkit-1.20.4}/apexdevkit/error.py +0 -0
- {apexdevkit-1.20.2 → apexdevkit-1.20.4}/apexdevkit/fastapi/docs.py +0 -0
- {apexdevkit-1.20.2 → apexdevkit-1.20.4}/apexdevkit/fastapi/name.py +0 -0
- {apexdevkit-1.20.2 → apexdevkit-1.20.4}/apexdevkit/fastapi/request.py +0 -0
- {apexdevkit-1.20.2 → apexdevkit-1.20.4}/apexdevkit/fastapi/resource.py +0 -0
- {apexdevkit-1.20.2 → apexdevkit-1.20.4}/apexdevkit/fastapi/response.py +0 -0
- {apexdevkit-1.20.2 → apexdevkit-1.20.4}/apexdevkit/fastapi/schema.py +0 -0
- {apexdevkit-1.20.2 → apexdevkit-1.20.4}/apexdevkit/fluent.py +0 -0
- {apexdevkit-1.20.2 → apexdevkit-1.20.4}/apexdevkit/http/__init__.py +0 -0
- {apexdevkit-1.20.2 → apexdevkit-1.20.4}/apexdevkit/http/fake.py +0 -0
- {apexdevkit-1.20.2 → apexdevkit-1.20.4}/apexdevkit/http/fluent.py +0 -0
- {apexdevkit-1.20.2 → apexdevkit-1.20.4}/apexdevkit/http/httpx/__init__.py +0 -0
- {apexdevkit-1.20.2 → apexdevkit-1.20.4}/apexdevkit/http/httpx/client.py +0 -0
- {apexdevkit-1.20.2 → apexdevkit-1.20.4}/apexdevkit/http/httpx/hooks.py +0 -0
- {apexdevkit-1.20.2 → apexdevkit-1.20.4}/apexdevkit/http/json.py +0 -0
- {apexdevkit-1.20.2 → apexdevkit-1.20.4}/apexdevkit/http/url.py +0 -0
- {apexdevkit-1.20.2 → apexdevkit-1.20.4}/apexdevkit/id.py +0 -0
- {apexdevkit-1.20.2 → apexdevkit-1.20.4}/apexdevkit/key_fn.py +0 -0
- {apexdevkit-1.20.2 → apexdevkit-1.20.4}/apexdevkit/py.typed +0 -0
- {apexdevkit-1.20.2 → apexdevkit-1.20.4}/apexdevkit/query/__init__.py +0 -0
- {apexdevkit-1.20.2 → apexdevkit-1.20.4}/apexdevkit/query/query.py +0 -0
- {apexdevkit-1.20.2 → apexdevkit-1.20.4}/apexdevkit/repository/__init__.py +0 -0
- {apexdevkit-1.20.2 → apexdevkit-1.20.4}/apexdevkit/repository/base.py +0 -0
- {apexdevkit-1.20.2 → apexdevkit-1.20.4}/apexdevkit/repository/connector.py +0 -0
- {apexdevkit-1.20.2 → apexdevkit-1.20.4}/apexdevkit/repository/decorator.py +0 -0
- {apexdevkit-1.20.2 → apexdevkit-1.20.4}/apexdevkit/repository/in_memory.py +0 -0
- {apexdevkit-1.20.2 → apexdevkit-1.20.4}/apexdevkit/repository/interface.py +0 -0
- {apexdevkit-1.20.2 → apexdevkit-1.20.4}/apexdevkit/server.py +0 -0
- {apexdevkit-1.20.2 → apexdevkit-1.20.4}/apexdevkit/synchronization.py +0 -0
- {apexdevkit-1.20.2 → apexdevkit-1.20.4}/apexdevkit/testing/__init__.py +0 -0
- {apexdevkit-1.20.2 → apexdevkit-1.20.4}/apexdevkit/testing/database.py +0 -0
- {apexdevkit-1.20.2 → apexdevkit-1.20.4}/apexdevkit/testing/fake.py +0 -0
- {apexdevkit-1.20.2 → apexdevkit-1.20.4}/apexdevkit/testing/rest.py +0 -0
- {apexdevkit-1.20.2 → apexdevkit-1.20.4}/apexdevkit/value.py +0 -0
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
from apexdevkit.fastapi.builder import FastApiBuilder, RestfulServiceBuilder
|
|
2
2
|
from apexdevkit.fastapi.dependable import inject
|
|
3
|
-
from apexdevkit.fastapi.service import
|
|
3
|
+
from apexdevkit.fastapi.service import RestfulRepository
|
|
4
4
|
|
|
5
5
|
__all__ = [
|
|
6
6
|
"FastApiBuilder",
|
|
7
7
|
"RestfulServiceBuilder",
|
|
8
8
|
"inject",
|
|
9
|
-
"
|
|
9
|
+
"RestfulRepository",
|
|
10
10
|
]
|
|
@@ -76,3 +76,11 @@ class RestfulServiceBuilder(ABC):
|
|
|
76
76
|
@abstractmethod
|
|
77
77
|
def build(self) -> RestfulService: # pragma: no cover
|
|
78
78
|
pass
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
@dataclass
|
|
82
|
+
class PreBuilt(RestfulServiceBuilder): # pragma: no cover
|
|
83
|
+
service: RestfulService
|
|
84
|
+
|
|
85
|
+
def build(self) -> RestfulService:
|
|
86
|
+
return self.service
|
|
@@ -4,7 +4,6 @@ from typing import Annotated, Any, Callable, Protocol
|
|
|
4
4
|
from fastapi import Depends, Path
|
|
5
5
|
from fastapi.requests import Request
|
|
6
6
|
|
|
7
|
-
from apexdevkit.annotation import deprecated
|
|
8
7
|
from apexdevkit.error import ApiError, DoesNotExistError
|
|
9
8
|
from apexdevkit.fastapi import RestfulServiceBuilder
|
|
10
9
|
from apexdevkit.fastapi.name import RestfulName
|
|
@@ -72,17 +71,6 @@ class UserDependency:
|
|
|
72
71
|
return Annotated[RestfulServiceBuilder, Depends(_)]
|
|
73
72
|
|
|
74
73
|
|
|
75
|
-
@dataclass(frozen=True)
|
|
76
|
-
class InfraDependency:
|
|
77
|
-
infra: RestfulServiceBuilder
|
|
78
|
-
|
|
79
|
-
def as_dependable(self) -> type[RestfulServiceBuilder]:
|
|
80
|
-
def _() -> RestfulServiceBuilder:
|
|
81
|
-
return self.infra
|
|
82
|
-
|
|
83
|
-
return Annotated[RestfulServiceBuilder, Depends(_)]
|
|
84
|
-
|
|
85
|
-
|
|
86
74
|
_BuilderCallable = Callable[..., RestfulServiceBuilder]
|
|
87
75
|
|
|
88
76
|
|
|
@@ -99,32 +87,17 @@ class BuilderCallableDependency:
|
|
|
99
87
|
|
|
100
88
|
@dataclass(frozen=True)
|
|
101
89
|
class DependableBuilder:
|
|
102
|
-
dependency: _Dependency
|
|
90
|
+
dependency: _Dependency
|
|
103
91
|
|
|
104
92
|
@classmethod
|
|
105
93
|
def from_callable(cls, value: _BuilderCallable) -> "DependableBuilder":
|
|
106
|
-
return
|
|
107
|
-
|
|
108
|
-
@deprecated(
|
|
109
|
-
"""
|
|
110
|
-
DependableBuilder().from_infra() is deprecated,
|
|
111
|
-
use DependencyBuilder.from_callable() instead
|
|
112
|
-
"""
|
|
113
|
-
)
|
|
114
|
-
def from_infra(self, value: RestfulServiceBuilder) -> "DependableBuilder":
|
|
115
|
-
return DependableBuilder(InfraDependency(value))
|
|
94
|
+
return cls(BuilderCallableDependency(value))
|
|
116
95
|
|
|
117
96
|
def with_parent(self, value: RestfulName) -> "DependableBuilder":
|
|
118
|
-
if self.dependency is None:
|
|
119
|
-
raise RuntimeError("RestfulServiceBuilder type not set")
|
|
120
97
|
return DependableBuilder(ParentDependency(value, self.dependency))
|
|
121
98
|
|
|
122
99
|
def with_user(self, extract_user: Callable[..., Any]) -> "DependableBuilder":
|
|
123
|
-
if self.dependency is None:
|
|
124
|
-
raise RuntimeError("RestfulServiceBuilder type not set")
|
|
125
100
|
return DependableBuilder(UserDependency(extract_user, self.dependency))
|
|
126
101
|
|
|
127
102
|
def as_dependable(self) -> type[RestfulService]:
|
|
128
|
-
if self.dependency is None:
|
|
129
|
-
raise RuntimeError("RestfulServiceBuilder type not set")
|
|
130
103
|
return ServiceDependency(self.dependency).as_dependable()
|
|
@@ -6,7 +6,6 @@ from typing import Annotated, Any, Protocol, Self, TypeVar
|
|
|
6
6
|
from fastapi import APIRouter, Depends, Path, Query
|
|
7
7
|
from fastapi.responses import JSONResponse
|
|
8
8
|
|
|
9
|
-
from apexdevkit.fastapi.builder import RestfulServiceBuilder
|
|
10
9
|
from apexdevkit.fastapi.name import RestfulName
|
|
11
10
|
from apexdevkit.fastapi.resource import RestfulResource, SummaryResponse
|
|
12
11
|
from apexdevkit.fastapi.response import RestfulResponse
|
|
@@ -24,14 +23,6 @@ class Dependency(Protocol): # pragma: no cover
|
|
|
24
23
|
pass
|
|
25
24
|
|
|
26
25
|
|
|
27
|
-
@dataclass
|
|
28
|
-
class PreBuiltRestfulService(RestfulServiceBuilder): # pragma: no cover
|
|
29
|
-
service: RestfulService
|
|
30
|
-
|
|
31
|
-
def build(self) -> RestfulService:
|
|
32
|
-
return self.service
|
|
33
|
-
|
|
34
|
-
|
|
35
26
|
@dataclass
|
|
36
27
|
class RestfulRouter:
|
|
37
28
|
router: APIRouter = field(default_factory=APIRouter)
|
|
@@ -2,14 +2,14 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
from abc import ABC
|
|
4
4
|
from dataclasses import dataclass
|
|
5
|
-
from typing import Any, Dict, Generic, Iterable, TypeVar
|
|
5
|
+
from typing import Any, Dict, Generic, Iterable, Mapping, TypeVar
|
|
6
6
|
|
|
7
7
|
from apexdevkit.formatter import Formatter
|
|
8
8
|
from apexdevkit.query.query import FooterOptions, QueryOptions, Summary
|
|
9
9
|
from apexdevkit.repository.decorator import BatchRepositoryDecorator
|
|
10
10
|
from apexdevkit.repository.interface import Repository
|
|
11
11
|
|
|
12
|
-
RawItem =
|
|
12
|
+
RawItem = Mapping[str, Any]
|
|
13
13
|
RawCollection = Iterable[RawItem]
|
|
14
14
|
|
|
15
15
|
|
|
@@ -63,31 +63,11 @@ ItemT = TypeVar("ItemT")
|
|
|
63
63
|
|
|
64
64
|
|
|
65
65
|
@dataclass(frozen=True)
|
|
66
|
-
class
|
|
67
|
-
formatter: Formatter[dict[str, Any], ItemT] | None = None
|
|
68
|
-
repository: Repository[ItemT] | None = None
|
|
69
|
-
|
|
70
|
-
def with_formatter(
|
|
71
|
-
self, formatter: Formatter[dict[str, Any], ItemT]
|
|
72
|
-
) -> RestfulRepositoryBuilder[ItemT]:
|
|
73
|
-
return RestfulRepositoryBuilder[ItemT](formatter, self.repository)
|
|
74
|
-
|
|
75
|
-
def with_repository(
|
|
76
|
-
self, repository: Repository[ItemT]
|
|
77
|
-
) -> RestfulRepositoryBuilder[ItemT]:
|
|
78
|
-
return RestfulRepositoryBuilder[ItemT](self.formatter, repository)
|
|
79
|
-
|
|
80
|
-
def build(self) -> RestfulService:
|
|
81
|
-
if self.formatter is None or self.repository is None:
|
|
82
|
-
raise RuntimeError("Formatter or repository not provided.")
|
|
83
|
-
return _RestfulRepository(self.formatter, self.repository)
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
@dataclass(frozen=True)
|
|
87
|
-
class _RestfulRepository(RestfulService, Generic[ItemT]):
|
|
88
|
-
formatter: Formatter[dict[str, Any], ItemT]
|
|
66
|
+
class RestfulRepository(RestfulService, Generic[ItemT]):
|
|
89
67
|
repository: Repository[ItemT]
|
|
90
68
|
|
|
69
|
+
formatter: Formatter[Mapping[str, Any], ItemT]
|
|
70
|
+
|
|
91
71
|
def create_one(self, item: RawItem) -> RawItem:
|
|
92
72
|
return self.formatter.dump(self.repository.create(self.formatter.load(item)))
|
|
93
73
|
|
|
@@ -106,7 +86,7 @@ class _RestfulRepository(RestfulService, Generic[ItemT]):
|
|
|
106
86
|
return [self.formatter.dump(item) for item in self.repository]
|
|
107
87
|
|
|
108
88
|
def update_one(self, item_id: str, **with_fields: Any) -> RawItem:
|
|
109
|
-
data = self.formatter.dump(self.repository.read(item_id))
|
|
89
|
+
data = dict(self.formatter.dump(self.repository.read(item_id)))
|
|
110
90
|
data.update(**with_fields)
|
|
111
91
|
|
|
112
92
|
self.repository.update(self.formatter.load(data))
|
|
@@ -116,7 +96,7 @@ class _RestfulRepository(RestfulService, Generic[ItemT]):
|
|
|
116
96
|
def update_many(self, items: RawCollectionWithId) -> RawCollection:
|
|
117
97
|
updates = []
|
|
118
98
|
for fields in items:
|
|
119
|
-
data = self.formatter.dump(self.repository.read(fields["id"]))
|
|
99
|
+
data = dict(self.formatter.dump(self.repository.read(fields["id"])))
|
|
120
100
|
data.update(**fields)
|
|
121
101
|
|
|
122
102
|
updates.append(self.formatter.load(data))
|
|
@@ -3,7 +3,7 @@ from __future__ import annotations
|
|
|
3
3
|
import pickle
|
|
4
4
|
from copy import deepcopy
|
|
5
5
|
from dataclasses import asdict, dataclass, field, fields, is_dataclass
|
|
6
|
-
from typing import Any, Generic, Protocol, Self, TypeVar, get_args
|
|
6
|
+
from typing import Any, Generic, Mapping, Protocol, Self, TypeVar, get_args
|
|
7
7
|
|
|
8
8
|
from typing_extensions import get_type_hints
|
|
9
9
|
|
|
@@ -23,6 +23,37 @@ class Formatter(Protocol[_SourceT, _TargetT]): # pragma: no cover
|
|
|
23
23
|
pass
|
|
24
24
|
|
|
25
25
|
|
|
26
|
+
@dataclass(frozen=True)
|
|
27
|
+
class AliasFormatter(Formatter[Mapping[str, Any], _TargetT]):
|
|
28
|
+
inner: Formatter[Mapping[str, Any], _TargetT]
|
|
29
|
+
|
|
30
|
+
alias: AliasMapping
|
|
31
|
+
|
|
32
|
+
def load(self, source: Mapping[str, Any]) -> _TargetT:
|
|
33
|
+
return self.inner.load(self.alias.reverse().translate(source))
|
|
34
|
+
|
|
35
|
+
def dump(self, target: _TargetT) -> Mapping[str, Any]:
|
|
36
|
+
return self.alias.translate(self.inner.dump(target))
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
@dataclass(frozen=True)
|
|
40
|
+
class AliasMapping:
|
|
41
|
+
alias: Mapping[str, str]
|
|
42
|
+
|
|
43
|
+
@classmethod
|
|
44
|
+
def parse(cls, **alias: str) -> AliasMapping:
|
|
45
|
+
return cls(alias)
|
|
46
|
+
|
|
47
|
+
def reverse(self) -> AliasMapping:
|
|
48
|
+
return AliasMapping({value: key for key, value in self.alias.items()})
|
|
49
|
+
|
|
50
|
+
def translate(self, mapping: Mapping[str, Any]) -> Mapping[str, Any]:
|
|
51
|
+
return {self.value_of(key): value for key, value in mapping.items()}
|
|
52
|
+
|
|
53
|
+
def value_of(self, key: str) -> str:
|
|
54
|
+
return self.alias.get(key, key)
|
|
55
|
+
|
|
56
|
+
|
|
26
57
|
class PickleFormatter(Generic[_ItemT]):
|
|
27
58
|
def dump(self, item: _ItemT) -> bytes:
|
|
28
59
|
return pickle.dumps(item)
|
|
@@ -55,7 +86,7 @@ class DataclassFormatter(Generic[_TargetT]):
|
|
|
55
86
|
|
|
56
87
|
return self
|
|
57
88
|
|
|
58
|
-
def load(self, raw:
|
|
89
|
+
def load(self, raw: Mapping[str, Any]) -> _TargetT:
|
|
59
90
|
raw = FluentDict[Any](deepcopy(raw)).select(
|
|
60
91
|
*self.resource.__annotations__.keys()
|
|
61
92
|
)
|
|
@@ -82,13 +113,13 @@ class DataclassFormatter(Generic[_TargetT]):
|
|
|
82
113
|
|
|
83
114
|
return self.resource(**raw)
|
|
84
115
|
|
|
85
|
-
def dump(self, item: _TargetT) ->
|
|
116
|
+
def dump(self, item: _TargetT) -> Mapping[str, Any]:
|
|
86
117
|
return asdict(item) # type: ignore
|
|
87
118
|
|
|
88
119
|
|
|
89
120
|
class ValueFormatter:
|
|
90
|
-
def load(self, raw:
|
|
121
|
+
def load(self, raw: Mapping[str, Any]) -> Value:
|
|
91
122
|
return DataclassFormatter(Value).load(raw)
|
|
92
123
|
|
|
93
|
-
def dump(self, value: Value) ->
|
|
124
|
+
def dump(self, value: Value) -> Mapping[str, Any]:
|
|
94
125
|
return DataclassFormatter(Value).dump(value)
|
|
@@ -2,7 +2,7 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
from collections import defaultdict
|
|
4
4
|
from dataclasses import dataclass, field
|
|
5
|
-
from typing import Any, ClassVar, Generic, Iterable, Protocol, TypeVar
|
|
5
|
+
from typing import Any, ClassVar, Generic, Iterable, Mapping, Protocol, TypeVar
|
|
6
6
|
|
|
7
7
|
from apexdevkit.annotation import deprecated
|
|
8
8
|
from apexdevkit.error import ForbiddenError
|
|
@@ -27,7 +27,7 @@ ItemT = TypeVar("ItemT", covariant=True)
|
|
|
27
27
|
|
|
28
28
|
|
|
29
29
|
class _Loader(Protocol[ItemT]):
|
|
30
|
-
def load(self, raw:
|
|
30
|
+
def load(self, raw: Mapping[str, Any]) -> ItemT:
|
|
31
31
|
pass
|
|
32
32
|
|
|
33
33
|
|
|
@@ -2,9 +2,9 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
from copy import deepcopy
|
|
4
4
|
from dataclasses import dataclass, field
|
|
5
|
-
from typing import Any, ContextManager, Iterable, Protocol
|
|
5
|
+
from typing import Any, ContextManager, Iterable, Mapping, Protocol
|
|
6
6
|
|
|
7
|
-
_RawData =
|
|
7
|
+
_RawData = Mapping[str, Any]
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
@dataclass(frozen=True)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
from dataclasses import dataclass
|
|
4
|
-
from typing import Any, ContextManager, Generic, Iterator, Protocol, TypeVar
|
|
4
|
+
from typing import Any, ContextManager, Generic, Iterator, Mapping, Protocol, TypeVar
|
|
5
5
|
|
|
6
6
|
from pymongo import MongoClient, ReturnDocument
|
|
7
7
|
from pymongo.collection import Collection
|
|
@@ -24,7 +24,7 @@ class MongoRepository(Generic[ItemT]):
|
|
|
24
24
|
connector: MongoConnector
|
|
25
25
|
database_name: str
|
|
26
26
|
collection_name: str
|
|
27
|
-
formatter: Formatter[
|
|
27
|
+
formatter: Formatter[Mapping[str, Any], ItemT]
|
|
28
28
|
|
|
29
29
|
def collection(self, client: MongoClient[Any]) -> Collection[Any]:
|
|
30
30
|
return client[self.database_name][self.collection_name]
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
from dataclasses import dataclass
|
|
4
|
-
from typing import Any, Generic, Iterable, Iterator, TypeVar
|
|
4
|
+
from typing import Any, Generic, Iterable, Iterator, Mapping, TypeVar
|
|
5
5
|
|
|
6
6
|
from pymssql.exceptions import DatabaseError
|
|
7
7
|
|
|
@@ -81,7 +81,7 @@ class SqlTable(Generic[ItemT]): # pragma: no cover
|
|
|
81
81
|
def update(self, item: ItemT) -> DatabaseCommand:
|
|
82
82
|
raise NotImplementedError
|
|
83
83
|
|
|
84
|
-
def load(self, data:
|
|
84
|
+
def load(self, data: Mapping[str, Any]) -> ItemT:
|
|
85
85
|
raise NotImplementedError
|
|
86
86
|
|
|
87
87
|
def exists(self, duplicate: ItemT) -> ExistsError:
|
|
@@ -143,7 +143,7 @@ class MsSqlTableBuilder(Generic[ItemT]):
|
|
|
143
143
|
username: str | None = None
|
|
144
144
|
schema: str | None = None
|
|
145
145
|
table: str | None = None
|
|
146
|
-
formatter: Formatter[
|
|
146
|
+
formatter: Formatter[Mapping[str, Any], ItemT] | None = None
|
|
147
147
|
fields: list[_SqlField] | None = None
|
|
148
148
|
|
|
149
149
|
def with_username(self, value: str) -> MsSqlTableBuilder[ItemT]:
|
|
@@ -174,7 +174,7 @@ class MsSqlTableBuilder(Generic[ItemT]):
|
|
|
174
174
|
)
|
|
175
175
|
|
|
176
176
|
def with_formatter(
|
|
177
|
-
self, value: Formatter[
|
|
177
|
+
self, value: Formatter[Mapping[str, Any], ItemT]
|
|
178
178
|
) -> MsSqlTableBuilder[ItemT]:
|
|
179
179
|
return MsSqlTableBuilder[ItemT](
|
|
180
180
|
self.username,
|
|
@@ -226,7 +226,7 @@ class MsSqlTableBuilder(Generic[ItemT]):
|
|
|
226
226
|
class DefaultSqlTable(SqlTable[ItemT]):
|
|
227
227
|
schema: str
|
|
228
228
|
table: str
|
|
229
|
-
formatter: Formatter[
|
|
229
|
+
formatter: Formatter[Mapping[str, Any], ItemT]
|
|
230
230
|
fields: SqlFieldManager
|
|
231
231
|
username: str | None = None
|
|
232
232
|
|
|
@@ -336,7 +336,7 @@ class DefaultSqlTable(SqlTable[ItemT]):
|
|
|
336
336
|
REVERT
|
|
337
337
|
""").with_data(self.fields.with_fixed({}))
|
|
338
338
|
|
|
339
|
-
def load(self, data:
|
|
339
|
+
def load(self, data: Mapping[str, Any]) -> ItemT:
|
|
340
340
|
return self.formatter.load(data)
|
|
341
341
|
|
|
342
342
|
def exists(self, duplicate: ItemT) -> ExistsError:
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
from dataclasses import dataclass, field
|
|
4
|
-
from typing import Any, Iterator
|
|
4
|
+
from typing import Any, Iterator, Mapping
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
@dataclass(frozen=True)
|
|
@@ -155,7 +155,9 @@ class SqlFieldManager:
|
|
|
155
155
|
else:
|
|
156
156
|
return ""
|
|
157
157
|
|
|
158
|
-
def with_fixed(self,
|
|
158
|
+
def with_fixed(self, raw: Mapping[str, Any]) -> dict[str, Any]:
|
|
159
|
+
data = dict(raw)
|
|
160
|
+
|
|
159
161
|
for key in self.fields:
|
|
160
162
|
if key.is_parent:
|
|
161
163
|
data[key.name] = key.parent_value
|
|
@@ -2,7 +2,7 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
from dataclasses import dataclass
|
|
4
4
|
from sqlite3 import IntegrityError
|
|
5
|
-
from typing import Any, Generic, Iterable, Iterator
|
|
5
|
+
from typing import Any, Generic, Iterable, Iterator, Mapping
|
|
6
6
|
|
|
7
7
|
from apexdevkit.error import DoesNotExistError, ExistsError
|
|
8
8
|
from apexdevkit.formatter import Formatter
|
|
@@ -87,7 +87,7 @@ class SqlTable(Generic[ItemT]): # pragma: no cover
|
|
|
87
87
|
def delete_all(self) -> DatabaseCommand:
|
|
88
88
|
raise NotImplementedError
|
|
89
89
|
|
|
90
|
-
def load(self, data:
|
|
90
|
+
def load(self, data: Mapping[str, Any]) -> ItemT:
|
|
91
91
|
raise NotImplementedError
|
|
92
92
|
|
|
93
93
|
def duplicate(self, item: ItemT) -> ExistsError:
|
|
@@ -96,20 +96,20 @@ class SqlTable(Generic[ItemT]): # pragma: no cover
|
|
|
96
96
|
|
|
97
97
|
@dataclass
|
|
98
98
|
class UnknownError(Exception):
|
|
99
|
-
raw:
|
|
99
|
+
raw: Mapping[str, Any]
|
|
100
100
|
|
|
101
101
|
|
|
102
102
|
@dataclass(frozen=True)
|
|
103
103
|
class SqliteTableBuilder(Generic[ItemT]):
|
|
104
104
|
table_name: str | None = None
|
|
105
|
-
formatter: Formatter[
|
|
105
|
+
formatter: Formatter[Mapping[str, Any], ItemT] | None = None
|
|
106
106
|
fields: list[_SqlField] | None = None
|
|
107
107
|
|
|
108
108
|
def with_name(self, value: str) -> SqliteTableBuilder[ItemT]:
|
|
109
109
|
return SqliteTableBuilder[ItemT](value, self.formatter, self.fields)
|
|
110
110
|
|
|
111
111
|
def with_formatter(
|
|
112
|
-
self, value: Formatter[
|
|
112
|
+
self, value: Formatter[Mapping[str, Any], ItemT]
|
|
113
113
|
) -> SqliteTableBuilder[ItemT]:
|
|
114
114
|
return SqliteTableBuilder[ItemT](self.table_name, value, self.fields)
|
|
115
115
|
|
|
@@ -150,7 +150,7 @@ class SqliteTableBuilder(Generic[ItemT]):
|
|
|
150
150
|
@dataclass(frozen=True)
|
|
151
151
|
class _DefaultSqlTable(SqlTable[ItemT]):
|
|
152
152
|
table_name: str
|
|
153
|
-
formatter: Formatter[
|
|
153
|
+
formatter: Formatter[Mapping[str, Any], ItemT]
|
|
154
154
|
fields: SqlFieldManager
|
|
155
155
|
|
|
156
156
|
def count_all(self) -> DatabaseCommand:
|
|
@@ -244,7 +244,7 @@ class _DefaultSqlTable(SqlTable[ItemT]):
|
|
|
244
244
|
{self.fields.where_statement(include_id=False)};
|
|
245
245
|
""").with_data(self.fields.with_fixed({}))
|
|
246
246
|
|
|
247
|
-
def load(self, data:
|
|
247
|
+
def load(self, data: Mapping[str, Any]) -> ItemT:
|
|
248
248
|
return self.formatter.load(data)
|
|
249
249
|
|
|
250
250
|
def duplicate(self, item: ItemT) -> ExistsError:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|