apexdevkit 1.17.7__tar.gz → 1.17.8__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.17.7 → apexdevkit-1.17.8}/PKG-INFO +1 -1
- {apexdevkit-1.17.7 → apexdevkit-1.17.8}/apexdevkit/repository/mssql.py +47 -151
- {apexdevkit-1.17.7 → apexdevkit-1.17.8}/apexdevkit/repository/sqlite.py +53 -141
- {apexdevkit-1.17.7 → apexdevkit-1.17.8}/pyproject.toml +1 -1
- {apexdevkit-1.17.7 → apexdevkit-1.17.8}/LICENSE +0 -0
- {apexdevkit-1.17.7 → apexdevkit-1.17.8}/README.md +0 -0
- {apexdevkit-1.17.7 → apexdevkit-1.17.8}/apexdevkit/__init__.py +0 -0
- {apexdevkit-1.17.7 → apexdevkit-1.17.8}/apexdevkit/annotation/__init__.py +0 -0
- {apexdevkit-1.17.7 → apexdevkit-1.17.8}/apexdevkit/annotation/deprecate.py +0 -0
- {apexdevkit-1.17.7 → apexdevkit-1.17.8}/apexdevkit/environment.py +0 -0
- {apexdevkit-1.17.7 → apexdevkit-1.17.8}/apexdevkit/error.py +0 -0
- {apexdevkit-1.17.7 → apexdevkit-1.17.8}/apexdevkit/fastapi/__init__.py +0 -0
- {apexdevkit-1.17.7 → apexdevkit-1.17.8}/apexdevkit/fastapi/builder.py +0 -0
- {apexdevkit-1.17.7 → apexdevkit-1.17.8}/apexdevkit/fastapi/dependable.py +0 -0
- {apexdevkit-1.17.7 → apexdevkit-1.17.8}/apexdevkit/fastapi/docs.py +0 -0
- {apexdevkit-1.17.7 → apexdevkit-1.17.8}/apexdevkit/fastapi/name.py +0 -0
- {apexdevkit-1.17.7 → apexdevkit-1.17.8}/apexdevkit/fastapi/request.py +0 -0
- {apexdevkit-1.17.7 → apexdevkit-1.17.8}/apexdevkit/fastapi/resource.py +0 -0
- {apexdevkit-1.17.7 → apexdevkit-1.17.8}/apexdevkit/fastapi/response.py +0 -0
- {apexdevkit-1.17.7 → apexdevkit-1.17.8}/apexdevkit/fastapi/router.py +0 -0
- {apexdevkit-1.17.7 → apexdevkit-1.17.8}/apexdevkit/fastapi/schema.py +0 -0
- {apexdevkit-1.17.7 → apexdevkit-1.17.8}/apexdevkit/fastapi/service.py +0 -0
- {apexdevkit-1.17.7 → apexdevkit-1.17.8}/apexdevkit/fluent.py +0 -0
- {apexdevkit-1.17.7 → apexdevkit-1.17.8}/apexdevkit/formatter.py +0 -0
- {apexdevkit-1.17.7 → apexdevkit-1.17.8}/apexdevkit/http/__init__.py +0 -0
- {apexdevkit-1.17.7 → apexdevkit-1.17.8}/apexdevkit/http/fake.py +0 -0
- {apexdevkit-1.17.7 → apexdevkit-1.17.8}/apexdevkit/http/fluent.py +0 -0
- {apexdevkit-1.17.7 → apexdevkit-1.17.8}/apexdevkit/http/httpx.py +0 -0
- {apexdevkit-1.17.7 → apexdevkit-1.17.8}/apexdevkit/http/json.py +0 -0
- {apexdevkit-1.17.7 → apexdevkit-1.17.8}/apexdevkit/http/url.py +0 -0
- {apexdevkit-1.17.7 → apexdevkit-1.17.8}/apexdevkit/key_fn.py +0 -0
- {apexdevkit-1.17.7 → apexdevkit-1.17.8}/apexdevkit/py.typed +0 -0
- {apexdevkit-1.17.7 → apexdevkit-1.17.8}/apexdevkit/repository/__init__.py +0 -0
- {apexdevkit-1.17.7 → apexdevkit-1.17.8}/apexdevkit/repository/base.py +0 -0
- {apexdevkit-1.17.7 → apexdevkit-1.17.8}/apexdevkit/repository/connector.py +0 -0
- {apexdevkit-1.17.7 → apexdevkit-1.17.8}/apexdevkit/repository/database.py +0 -0
- {apexdevkit-1.17.7 → apexdevkit-1.17.8}/apexdevkit/repository/decorator.py +0 -0
- {apexdevkit-1.17.7 → apexdevkit-1.17.8}/apexdevkit/repository/in_memory.py +0 -0
- {apexdevkit-1.17.7 → apexdevkit-1.17.8}/apexdevkit/repository/interface.py +0 -0
- {apexdevkit-1.17.7 → apexdevkit-1.17.8}/apexdevkit/repository/mongo.py +0 -0
- {apexdevkit-1.17.7 → apexdevkit-1.17.8}/apexdevkit/server.py +0 -0
- {apexdevkit-1.17.7 → apexdevkit-1.17.8}/apexdevkit/synchronization.py +0 -0
- {apexdevkit-1.17.7 → apexdevkit-1.17.8}/apexdevkit/testing/__init__.py +0 -0
- {apexdevkit-1.17.7 → apexdevkit-1.17.8}/apexdevkit/testing/database.py +0 -0
- {apexdevkit-1.17.7 → apexdevkit-1.17.8}/apexdevkit/testing/fake.py +0 -0
- {apexdevkit-1.17.7 → apexdevkit-1.17.8}/apexdevkit/testing/rest.py +0 -0
- {apexdevkit-1.17.7 → apexdevkit-1.17.8}/apexdevkit/value.py +0 -0
|
@@ -144,9 +144,6 @@ class MsSqlTableBuilder(Generic[ItemT]):
|
|
|
144
144
|
table: str | None = None
|
|
145
145
|
formatter: Formatter[dict[str, Any], ItemT] | None = None
|
|
146
146
|
fields: list[MsSqlField] | None = None
|
|
147
|
-
ordering: list[str] | None = None
|
|
148
|
-
parent_field: str | None = None
|
|
149
|
-
parent_value: Any | None = None
|
|
150
147
|
|
|
151
148
|
def with_username(self, value: str) -> MsSqlTableBuilder[ItemT]:
|
|
152
149
|
return MsSqlTableBuilder[ItemT](
|
|
@@ -155,9 +152,6 @@ class MsSqlTableBuilder(Generic[ItemT]):
|
|
|
155
152
|
self.table,
|
|
156
153
|
self.formatter,
|
|
157
154
|
self.fields,
|
|
158
|
-
self.ordering,
|
|
159
|
-
self.parent_field,
|
|
160
|
-
self.parent_value,
|
|
161
155
|
)
|
|
162
156
|
|
|
163
157
|
def with_schema(self, value: str) -> MsSqlTableBuilder[ItemT]:
|
|
@@ -167,9 +161,6 @@ class MsSqlTableBuilder(Generic[ItemT]):
|
|
|
167
161
|
self.table,
|
|
168
162
|
self.formatter,
|
|
169
163
|
self.fields,
|
|
170
|
-
self.ordering,
|
|
171
|
-
self.parent_field,
|
|
172
|
-
self.parent_value,
|
|
173
164
|
)
|
|
174
165
|
|
|
175
166
|
def with_table(self, value: str) -> MsSqlTableBuilder[ItemT]:
|
|
@@ -179,9 +170,6 @@ class MsSqlTableBuilder(Generic[ItemT]):
|
|
|
179
170
|
value,
|
|
180
171
|
self.formatter,
|
|
181
172
|
self.fields,
|
|
182
|
-
self.ordering,
|
|
183
|
-
self.parent_field,
|
|
184
|
-
self.parent_value,
|
|
185
173
|
)
|
|
186
174
|
|
|
187
175
|
def with_formatter(
|
|
@@ -193,73 +181,20 @@ class MsSqlTableBuilder(Generic[ItemT]):
|
|
|
193
181
|
self.table,
|
|
194
182
|
value,
|
|
195
183
|
self.fields,
|
|
196
|
-
self.ordering,
|
|
197
|
-
self.parent_field,
|
|
198
|
-
self.parent_value,
|
|
199
184
|
)
|
|
200
185
|
|
|
201
|
-
def with_fields(self,
|
|
186
|
+
def with_fields(self, value: Iterable[MsSqlField]) -> MsSqlTableBuilder[ItemT]:
|
|
187
|
+
field_list = list(value)
|
|
188
|
+
if len([field for field in field_list if field.is_id]) != 1:
|
|
189
|
+
raise ValueError("Pass only one identifier field.")
|
|
190
|
+
if len([field for field in field_list if field.is_parent]) > 1:
|
|
191
|
+
raise ValueError("Pass only one parent field.")
|
|
202
192
|
return MsSqlTableBuilder[ItemT](
|
|
203
193
|
self.username,
|
|
204
194
|
self.schema,
|
|
205
195
|
self.table,
|
|
206
196
|
self.formatter,
|
|
207
|
-
|
|
208
|
-
self.ordering,
|
|
209
|
-
self.parent_field,
|
|
210
|
-
self.parent_value,
|
|
211
|
-
)
|
|
212
|
-
|
|
213
|
-
def with_order_fields(self, ordering: Iterable[str]) -> MsSqlTableBuilder[ItemT]:
|
|
214
|
-
ordered = list(ordering)
|
|
215
|
-
assert self.fields is not None, "Set fields first."
|
|
216
|
-
|
|
217
|
-
for key in ordered:
|
|
218
|
-
if key not in [field.name for field in self.fields]:
|
|
219
|
-
raise ValueError("Missing fields in the table.")
|
|
220
|
-
return MsSqlTableBuilder[ItemT](
|
|
221
|
-
self.username,
|
|
222
|
-
self.schema,
|
|
223
|
-
self.table,
|
|
224
|
-
self.formatter,
|
|
225
|
-
self.fields,
|
|
226
|
-
ordered,
|
|
227
|
-
self.parent_field,
|
|
228
|
-
self.parent_value,
|
|
229
|
-
)
|
|
230
|
-
|
|
231
|
-
def with_id(self, identifier: str) -> MsSqlTableBuilder[ItemT]:
|
|
232
|
-
assert self.fields is not None, "Set fields first."
|
|
233
|
-
if identifier not in [field.name for field in self.fields]:
|
|
234
|
-
raise ValueError("Missing fields in the table.")
|
|
235
|
-
|
|
236
|
-
return MsSqlTableBuilder[ItemT](
|
|
237
|
-
self.username,
|
|
238
|
-
self.schema,
|
|
239
|
-
self.table,
|
|
240
|
-
self.formatter,
|
|
241
|
-
[MsSqlField(field.name, field.name == identifier) for field in self.fields],
|
|
242
|
-
self.ordering,
|
|
243
|
-
self.parent_field,
|
|
244
|
-
self.parent_value,
|
|
245
|
-
)
|
|
246
|
-
|
|
247
|
-
def with_parent(
|
|
248
|
-
self, parent_field: str, parent_value: Any
|
|
249
|
-
) -> MsSqlTableBuilder[ItemT]:
|
|
250
|
-
assert self.fields is not None, "Set fields first."
|
|
251
|
-
if parent_field not in [field.name for field in self.fields]:
|
|
252
|
-
raise ValueError("Missing fields in the table.")
|
|
253
|
-
|
|
254
|
-
return MsSqlTableBuilder[ItemT](
|
|
255
|
-
self.username,
|
|
256
|
-
self.schema,
|
|
257
|
-
self.table,
|
|
258
|
-
self.formatter,
|
|
259
|
-
self.fields,
|
|
260
|
-
self.ordering,
|
|
261
|
-
parent_field,
|
|
262
|
-
parent_value,
|
|
197
|
+
field_list,
|
|
263
198
|
)
|
|
264
199
|
|
|
265
200
|
def build(self) -> SqlTable[ItemT]:
|
|
@@ -267,48 +202,32 @@ class MsSqlTableBuilder(Generic[ItemT]):
|
|
|
267
202
|
raise ValueError("Cannot build sql table.")
|
|
268
203
|
|
|
269
204
|
return DefaultSqlTable(
|
|
270
|
-
self.username,
|
|
271
205
|
self.schema,
|
|
272
206
|
self.table,
|
|
273
207
|
self.formatter,
|
|
274
208
|
self.fields,
|
|
275
|
-
self.
|
|
276
|
-
self.parent_field,
|
|
277
|
-
self.parent_value,
|
|
209
|
+
self.username,
|
|
278
210
|
)
|
|
279
211
|
|
|
280
212
|
|
|
281
213
|
@dataclass(frozen=True)
|
|
282
214
|
class DefaultSqlTable(SqlTable[ItemT]):
|
|
283
|
-
username: str | None
|
|
284
215
|
schema: str
|
|
285
216
|
table: str
|
|
286
217
|
formatter: Formatter[dict[str, Any], ItemT]
|
|
287
218
|
fields: list[MsSqlField]
|
|
288
|
-
|
|
289
|
-
parent_key: str | None
|
|
290
|
-
parent_value: Any | None
|
|
219
|
+
username: str | None = None
|
|
291
220
|
|
|
292
221
|
def count_all(self) -> DatabaseCommand:
|
|
293
|
-
where_statement = ""
|
|
294
|
-
if self.parent_key is not None:
|
|
295
|
-
where_statement += (
|
|
296
|
-
"WHERE [" + self.parent_key + "] = " + self._parent_value_sql
|
|
297
|
-
)
|
|
298
|
-
|
|
299
222
|
return DatabaseCommand(f"""
|
|
300
223
|
{self._user_check}
|
|
301
224
|
SELECT count(*) AS n_items
|
|
302
225
|
FROM [{self.schema}].[{self.table}]
|
|
303
|
-
{
|
|
226
|
+
{self._where_statement(include_id=False)}
|
|
304
227
|
REVERT
|
|
305
|
-
""")
|
|
228
|
+
""").with_data(self._data_with_replaced_parent({}))
|
|
306
229
|
|
|
307
230
|
def insert(self, item: ItemT) -> DatabaseCommand:
|
|
308
|
-
dumped = self.formatter.dump(item)
|
|
309
|
-
if self.parent_key is not None:
|
|
310
|
-
dumped[self.parent_key] = self.parent_value
|
|
311
|
-
|
|
312
231
|
columns = ", ".join(["[" + field.name + "]" for field in self.fields])
|
|
313
232
|
placeholders = ", ".join([f"%({key.name})s" for key in self.fields])
|
|
314
233
|
output = ", ".join(["INSERTED." + field.name for field in self.fields])
|
|
@@ -323,17 +242,9 @@ class DefaultSqlTable(SqlTable[ItemT]):
|
|
|
323
242
|
{placeholders}
|
|
324
243
|
)
|
|
325
244
|
REVERT
|
|
326
|
-
""").with_data(
|
|
245
|
+
""").with_data(self._data_with_replaced_parent(self.formatter.dump(item)))
|
|
327
246
|
|
|
328
247
|
def select(self, item_id: str) -> DatabaseCommand:
|
|
329
|
-
raw: dict[str, Any] = {self._id: item_id}
|
|
330
|
-
where_statement = f"WHERE [{self._id}] = %({self._id})s"
|
|
331
|
-
if self.parent_key is not None:
|
|
332
|
-
raw[self.parent_key] = self.parent_value
|
|
333
|
-
where_statement += (
|
|
334
|
-
" AND [" + self.parent_key + "] = %(" + self.parent_key + ")s"
|
|
335
|
-
)
|
|
336
|
-
|
|
337
248
|
columns = ", ".join(["[" + field.name + "]" for field in self.fields])
|
|
338
249
|
|
|
339
250
|
return DatabaseCommand(f"""
|
|
@@ -341,44 +252,29 @@ class DefaultSqlTable(SqlTable[ItemT]):
|
|
|
341
252
|
SELECT
|
|
342
253
|
{columns}
|
|
343
254
|
FROM [{self.schema}].[{self.table}]
|
|
344
|
-
{
|
|
255
|
+
{self._where_statement(include_id=True)}
|
|
345
256
|
REVERT
|
|
346
|
-
""").with_data(
|
|
257
|
+
""").with_data(self._data_with_replaced_parent({self._id: item_id}))
|
|
347
258
|
|
|
348
259
|
def select_all(self) -> DatabaseCommand:
|
|
349
260
|
columns = ", ".join(["[" + field.name + "]" for field in self.fields])
|
|
350
|
-
where_statement = ""
|
|
351
|
-
if self.parent_key is not None:
|
|
352
|
-
where_statement += (
|
|
353
|
-
"WHERE [" + self.parent_key + "] = " + self._parent_value_sql
|
|
354
|
-
)
|
|
355
261
|
|
|
356
262
|
return DatabaseCommand(f"""
|
|
357
263
|
{self._user_check}
|
|
358
264
|
SELECT
|
|
359
265
|
{columns}
|
|
360
266
|
FROM [{self.schema}].[{self.table}]
|
|
361
|
-
{
|
|
267
|
+
{self._where_statement(include_id=False)}
|
|
362
268
|
{self._order}
|
|
363
269
|
REVERT
|
|
364
|
-
""")
|
|
270
|
+
""").with_data(self._data_with_replaced_parent({}))
|
|
365
271
|
|
|
366
272
|
def update(self, item: ItemT) -> DatabaseCommand:
|
|
367
|
-
dumped = self.formatter.dump(item)
|
|
368
|
-
if self.parent_key is not None:
|
|
369
|
-
dumped[self.parent_key] = self.parent_value
|
|
370
|
-
|
|
371
|
-
where_statement = f"WHERE [{self._id}] = %({self._id})s"
|
|
372
|
-
if self.parent_key is not None:
|
|
373
|
-
where_statement += (
|
|
374
|
-
" AND [" + self.parent_key + "] = %(" + self.parent_key + ")s"
|
|
375
|
-
)
|
|
376
|
-
|
|
377
273
|
updates = ", ".join(
|
|
378
274
|
[
|
|
379
275
|
f"{field.name} = %({field.name})s"
|
|
380
276
|
for field in self.fields
|
|
381
|
-
if not field.is_id and field.
|
|
277
|
+
if not field.is_id and not field.is_parent
|
|
382
278
|
]
|
|
383
279
|
)
|
|
384
280
|
|
|
@@ -387,41 +283,27 @@ class DefaultSqlTable(SqlTable[ItemT]):
|
|
|
387
283
|
UPDATE [{self.schema}].[{self.table}]
|
|
388
284
|
SET
|
|
389
285
|
{updates}
|
|
390
|
-
{
|
|
286
|
+
{self._where_statement(include_id=True)}
|
|
391
287
|
REVERT
|
|
392
|
-
""").with_data(
|
|
288
|
+
""").with_data(self._data_with_replaced_parent(self.formatter.dump(item)))
|
|
393
289
|
|
|
394
290
|
def delete(self, item_id: str) -> DatabaseCommand:
|
|
395
|
-
raw: dict[str, Any] = {self._id: item_id}
|
|
396
|
-
where_statement = f"WHERE [{self._id}] = %({self._id})s"
|
|
397
|
-
if self.parent_key is not None:
|
|
398
|
-
raw[self.parent_key] = self.parent_value
|
|
399
|
-
where_statement += (
|
|
400
|
-
" AND [" + self.parent_key + "] = %(" + self.parent_key + ")s"
|
|
401
|
-
)
|
|
402
|
-
|
|
403
291
|
return DatabaseCommand(f"""
|
|
404
292
|
{self._user_check}
|
|
405
293
|
DELETE
|
|
406
294
|
FROM [{self.schema}].[{self.table}]
|
|
407
|
-
{
|
|
295
|
+
{self._where_statement(include_id=True)}
|
|
408
296
|
REVERT
|
|
409
|
-
""").with_data(
|
|
297
|
+
""").with_data(self._data_with_replaced_parent({self._id: item_id}))
|
|
410
298
|
|
|
411
299
|
def delete_all(self) -> DatabaseCommand:
|
|
412
|
-
where_statement = ""
|
|
413
|
-
if self.parent_key is not None:
|
|
414
|
-
where_statement += (
|
|
415
|
-
"WHERE [" + self.parent_key + "] = " + self._parent_value_sql
|
|
416
|
-
)
|
|
417
|
-
|
|
418
300
|
return DatabaseCommand(f"""
|
|
419
301
|
{self._user_check}
|
|
420
302
|
DELETE
|
|
421
303
|
FROM [{self.schema}].[{self.table}]
|
|
422
|
-
{
|
|
304
|
+
{self._where_statement(include_id=False)}
|
|
423
305
|
REVERT
|
|
424
|
-
""")
|
|
306
|
+
""").with_data(self._data_with_replaced_parent({}))
|
|
425
307
|
|
|
426
308
|
def load(self, data: dict[str, Any]) -> ItemT:
|
|
427
309
|
return self.formatter.load(data)
|
|
@@ -432,6 +314,22 @@ class DefaultSqlTable(SqlTable[ItemT]):
|
|
|
432
314
|
lambda i: f"{self._id}<{raw[self._id]}>"
|
|
433
315
|
)
|
|
434
316
|
|
|
317
|
+
def _where_statement(self, include_id: bool = False) -> str:
|
|
318
|
+
result = next((field for field in self.fields if field.is_parent), None)
|
|
319
|
+
if result is None:
|
|
320
|
+
return f"WHERE [{self._id}] = %({self._id})s" if include_id else ""
|
|
321
|
+
else:
|
|
322
|
+
statement = "WHERE [" + result.name + "] = %(" + result.name + ")s"
|
|
323
|
+
if include_id:
|
|
324
|
+
statement += f" AND [{self._id}] = %({self._id})s"
|
|
325
|
+
return statement
|
|
326
|
+
|
|
327
|
+
def _data_with_replaced_parent(self, data: dict[str, Any]) -> dict[str, Any]:
|
|
328
|
+
result = next((field for field in self.fields if field.is_parent), None)
|
|
329
|
+
if result is not None:
|
|
330
|
+
data[result.name] = result.fixed_value
|
|
331
|
+
return data
|
|
332
|
+
|
|
435
333
|
@property
|
|
436
334
|
def _id(self) -> str:
|
|
437
335
|
result = next((field for field in self.fields if field.is_id), None)
|
|
@@ -448,20 +346,18 @@ class DefaultSqlTable(SqlTable[ItemT]):
|
|
|
448
346
|
|
|
449
347
|
@property
|
|
450
348
|
def _order(self) -> str:
|
|
451
|
-
|
|
452
|
-
|
|
349
|
+
ordering = [field.name for field in self.fields if field.is_ordered]
|
|
350
|
+
if len(ordering) > 0:
|
|
351
|
+
return "ORDER BY " + ", ".join(ordering)
|
|
453
352
|
else:
|
|
454
353
|
return ""
|
|
455
354
|
|
|
456
|
-
@property
|
|
457
|
-
def _parent_value_sql(self) -> str:
|
|
458
|
-
if isinstance(self.parent_value, str):
|
|
459
|
-
return "'" + self.parent_value + "'"
|
|
460
|
-
else:
|
|
461
|
-
return str(self.parent_value)
|
|
462
|
-
|
|
463
355
|
|
|
464
356
|
@dataclass(frozen=True)
|
|
465
357
|
class MsSqlField:
|
|
466
358
|
name: str
|
|
467
|
-
is_id: bool
|
|
359
|
+
is_id: bool = False
|
|
360
|
+
is_ordered: bool = False
|
|
361
|
+
|
|
362
|
+
is_parent: bool = False
|
|
363
|
+
fixed_value: Any | None = None
|
|
@@ -103,91 +103,35 @@ class SqliteTableBuilder(Generic[ItemT]):
|
|
|
103
103
|
table_name: str | None = None
|
|
104
104
|
formatter: Formatter[dict[str, Any], ItemT] | None = None
|
|
105
105
|
fields: list[SqliteField] | None = None
|
|
106
|
-
parent_field: str | None = None
|
|
107
|
-
parent_value: Any | None = None
|
|
108
106
|
|
|
109
107
|
def with_name(self, value: str) -> SqliteTableBuilder[ItemT]:
|
|
110
|
-
return SqliteTableBuilder[ItemT](
|
|
111
|
-
value, self.formatter, self.fields, self.parent_field, self.parent_value
|
|
112
|
-
)
|
|
108
|
+
return SqliteTableBuilder[ItemT](value, self.formatter, self.fields)
|
|
113
109
|
|
|
114
110
|
def with_formatter(
|
|
115
111
|
self, value: Formatter[dict[str, Any], ItemT]
|
|
116
112
|
) -> SqliteTableBuilder[ItemT]:
|
|
117
|
-
return SqliteTableBuilder[ItemT](
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
[SqliteField(field, field == "id", False) for field in list(fields)],
|
|
126
|
-
self.parent_field,
|
|
127
|
-
self.parent_value,
|
|
128
|
-
)
|
|
129
|
-
|
|
130
|
-
def with_id(self, identifier: str) -> SqliteTableBuilder[ItemT]:
|
|
131
|
-
assert self.fields is not None, "Set fields first."
|
|
132
|
-
if identifier not in [field.name for field in self.fields]:
|
|
133
|
-
raise ValueError("Missing fields in the table.")
|
|
134
|
-
|
|
135
|
-
return SqliteTableBuilder[ItemT](
|
|
136
|
-
self.table_name,
|
|
137
|
-
self.formatter,
|
|
138
|
-
[
|
|
139
|
-
SqliteField(field.name, field.name == identifier, field.is_composite)
|
|
140
|
-
for field in self.fields
|
|
141
|
-
],
|
|
142
|
-
self.parent_field,
|
|
143
|
-
self.parent_value,
|
|
144
|
-
)
|
|
145
|
-
|
|
146
|
-
def with_composite_key(
|
|
147
|
-
self, composites: Iterable[str]
|
|
148
|
-
) -> SqliteTableBuilder[ItemT]:
|
|
149
|
-
assert self.fields is not None, "Set fields first."
|
|
150
|
-
|
|
151
|
-
names = [field.name for field in self.fields]
|
|
152
|
-
if not all(field in names for field in list(composites)):
|
|
153
|
-
raise ValueError("Missing fields in the table.")
|
|
154
|
-
|
|
113
|
+
return SqliteTableBuilder[ItemT](self.table_name, value, self.fields)
|
|
114
|
+
|
|
115
|
+
def with_fields(self, value: Iterable[SqliteField]) -> SqliteTableBuilder[ItemT]:
|
|
116
|
+
field_list = list(value)
|
|
117
|
+
if len([field for field in field_list if field.is_id]) != 1:
|
|
118
|
+
raise ValueError("Pass only one identifier field.")
|
|
119
|
+
if len([field for field in field_list if field.is_parent]) > 1:
|
|
120
|
+
raise ValueError("Pass only one parent field.")
|
|
155
121
|
return SqliteTableBuilder[ItemT](
|
|
156
122
|
self.table_name,
|
|
157
123
|
self.formatter,
|
|
158
|
-
|
|
159
|
-
SqliteField(field.name, field.is_id, field.name in list(composites))
|
|
160
|
-
for field in self.fields
|
|
161
|
-
],
|
|
162
|
-
self.parent_field,
|
|
163
|
-
self.parent_value,
|
|
164
|
-
)
|
|
165
|
-
|
|
166
|
-
def with_parent(
|
|
167
|
-
self, parent_field: str, parent_value: Any
|
|
168
|
-
) -> SqliteTableBuilder[ItemT]:
|
|
169
|
-
assert self.fields is not None, "Set fields first."
|
|
170
|
-
if parent_field not in [field.name for field in self.fields]:
|
|
171
|
-
raise ValueError("Missing fields in the table.")
|
|
172
|
-
|
|
173
|
-
return SqliteTableBuilder[ItemT](
|
|
174
|
-
self.table_name,
|
|
175
|
-
self.formatter,
|
|
176
|
-
self.fields,
|
|
177
|
-
parent_field,
|
|
178
|
-
parent_value,
|
|
124
|
+
field_list,
|
|
179
125
|
)
|
|
180
126
|
|
|
181
127
|
def build(self) -> SqlTable[ItemT]:
|
|
182
128
|
if not self.table_name or not self.formatter or not self.fields:
|
|
183
|
-
raise ValueError("
|
|
129
|
+
raise ValueError("Parameter missing.")
|
|
184
130
|
|
|
185
131
|
return _DefaultSqlTable(
|
|
186
132
|
self.table_name,
|
|
187
133
|
self.formatter,
|
|
188
134
|
self.fields,
|
|
189
|
-
self.parent_field,
|
|
190
|
-
self.parent_value,
|
|
191
135
|
)
|
|
192
136
|
|
|
193
137
|
|
|
@@ -196,54 +140,36 @@ class _DefaultSqlTable(SqlTable[ItemT]):
|
|
|
196
140
|
table_name: str
|
|
197
141
|
formatter: Formatter[dict[str, Any], ItemT]
|
|
198
142
|
fields: list[SqliteField]
|
|
199
|
-
parent_key: str | None
|
|
200
|
-
parent_value: Any | None
|
|
201
143
|
|
|
202
144
|
def count_all(self) -> DatabaseCommand:
|
|
203
|
-
where_statement = ""
|
|
204
|
-
if self.parent_key is not None:
|
|
205
|
-
where_statement += (
|
|
206
|
-
"WHERE " + self.parent_key + " = " + self._parent_value_sql
|
|
207
|
-
)
|
|
208
|
-
|
|
209
145
|
return DatabaseCommand(f"""
|
|
210
146
|
SELECT count(*) as n_items
|
|
211
|
-
FROM {self.table_name.
|
|
212
|
-
{
|
|
213
|
-
""")
|
|
147
|
+
FROM {self.table_name.upper()}
|
|
148
|
+
{self._where_statement(include_id=False)};
|
|
149
|
+
""").with_data(self._data_with_replaced_parent({}))
|
|
214
150
|
|
|
215
151
|
def insert(self, item: ItemT) -> DatabaseCommand:
|
|
216
|
-
dumped = self.formatter.dump(item)
|
|
217
|
-
if self.parent_key is not None:
|
|
218
|
-
dumped[self.parent_key] = self.parent_value
|
|
219
|
-
|
|
220
152
|
columns = ", ".join([field.name for field in self.fields])
|
|
221
153
|
placeholders = ", ".join([f":{key.name}" for key in self.fields])
|
|
222
154
|
|
|
223
155
|
return DatabaseCommand(f"""
|
|
224
|
-
INSERT INTO {self.table_name.
|
|
156
|
+
INSERT INTO {self.table_name.upper()} (
|
|
225
157
|
{columns}
|
|
226
158
|
) VALUES (
|
|
227
159
|
{placeholders}
|
|
228
160
|
)
|
|
229
161
|
RETURNING {columns};
|
|
230
|
-
""").with_data(
|
|
162
|
+
""").with_data(self._data_with_replaced_parent(self.formatter.dump(item)))
|
|
231
163
|
|
|
232
164
|
def select(self, item_id: str) -> DatabaseCommand:
|
|
233
|
-
raw: dict[str, Any] = {self._id: item_id}
|
|
234
|
-
where_statement = f"WHERE {self._id} = :{self._id}"
|
|
235
|
-
if self.parent_key is not None:
|
|
236
|
-
raw[self.parent_key] = self.parent_value
|
|
237
|
-
where_statement += " AND " + self.parent_key + " = :" + self.parent_key
|
|
238
|
-
|
|
239
165
|
columns = ", ".join([field.name for field in self.fields])
|
|
240
166
|
|
|
241
167
|
return DatabaseCommand(f"""
|
|
242
168
|
SELECT
|
|
243
169
|
{columns}
|
|
244
|
-
FROM {self.table_name.
|
|
245
|
-
{
|
|
246
|
-
""").with_data(
|
|
170
|
+
FROM {self.table_name.upper()}
|
|
171
|
+
{self._where_statement(include_id=True)};
|
|
172
|
+
""").with_data(self._data_with_replaced_parent({self._id: item_id}))
|
|
247
173
|
|
|
248
174
|
def select_duplicate(self, item: ItemT) -> DatabaseCommand:
|
|
249
175
|
raw = self.formatter.dump(item)
|
|
@@ -254,75 +180,49 @@ class _DefaultSqlTable(SqlTable[ItemT]):
|
|
|
254
180
|
return DatabaseCommand(f"""
|
|
255
181
|
SELECT
|
|
256
182
|
{columns}
|
|
257
|
-
FROM {self.table_name.
|
|
183
|
+
FROM {self.table_name.upper()}
|
|
258
184
|
WHERE {duplicates};
|
|
259
185
|
""").with_data({key: raw[key] for key in raw if key in self._composite})
|
|
260
186
|
|
|
261
187
|
def select_all(self) -> DatabaseCommand:
|
|
262
|
-
where_statement = ""
|
|
263
|
-
if self.parent_key is not None:
|
|
264
|
-
where_statement += (
|
|
265
|
-
"WHERE " + self.parent_key + " = " + self._parent_value_sql
|
|
266
|
-
)
|
|
267
|
-
|
|
268
188
|
columns = ", ".join([field.name for field in self.fields])
|
|
269
189
|
|
|
270
190
|
return DatabaseCommand(f"""
|
|
271
191
|
SELECT
|
|
272
192
|
{columns}
|
|
273
193
|
FROM {self.table_name.capitalize()}
|
|
274
|
-
{
|
|
275
|
-
""")
|
|
194
|
+
{self._where_statement(include_id=False)};
|
|
195
|
+
""").with_data(self._data_with_replaced_parent({}))
|
|
276
196
|
|
|
277
197
|
def update(self, item: ItemT) -> DatabaseCommand:
|
|
278
|
-
dumped = self.formatter.dump(item)
|
|
279
|
-
if self.parent_key is not None:
|
|
280
|
-
dumped[self.parent_key] = self.parent_value
|
|
281
|
-
|
|
282
|
-
where_statement = f"WHERE {self._id} = :{self._id}"
|
|
283
|
-
if self.parent_key is not None:
|
|
284
|
-
where_statement += " AND " + self.parent_key + " = :" + self.parent_key
|
|
285
|
-
|
|
286
198
|
updates = ", ".join(
|
|
287
199
|
[
|
|
288
200
|
f"{field.name} = :{field.name}"
|
|
289
201
|
for field in self.fields
|
|
290
|
-
if not field.is_id and field.
|
|
202
|
+
if not field.is_id and not field.is_parent
|
|
291
203
|
]
|
|
292
204
|
)
|
|
293
205
|
|
|
294
206
|
return DatabaseCommand(f"""
|
|
295
|
-
UPDATE {self.table_name.
|
|
207
|
+
UPDATE {self.table_name.upper()}
|
|
296
208
|
SET
|
|
297
209
|
{updates}
|
|
298
|
-
{
|
|
299
|
-
""").with_data(
|
|
210
|
+
{self._where_statement(include_id=True)};
|
|
211
|
+
""").with_data(self._data_with_replaced_parent(self.formatter.dump(item)))
|
|
300
212
|
|
|
301
213
|
def delete(self, item_id: str) -> DatabaseCommand:
|
|
302
|
-
raw: dict[str, Any] = {self._id: item_id}
|
|
303
|
-
where_statement = f"WHERE {self._id} = :{self._id}"
|
|
304
|
-
if self.parent_key is not None:
|
|
305
|
-
raw[self.parent_key] = self.parent_value
|
|
306
|
-
where_statement += " AND " + self.parent_key + " = :" + self.parent_key
|
|
307
|
-
|
|
308
214
|
return DatabaseCommand(f"""
|
|
309
215
|
DELETE
|
|
310
|
-
FROM {self.table_name.
|
|
311
|
-
{
|
|
312
|
-
""").with_data(
|
|
216
|
+
FROM {self.table_name.upper()}
|
|
217
|
+
{self._where_statement(include_id=True)};
|
|
218
|
+
""").with_data(self._data_with_replaced_parent({self._id: item_id}))
|
|
313
219
|
|
|
314
220
|
def delete_all(self) -> DatabaseCommand:
|
|
315
|
-
where_statement = ""
|
|
316
|
-
if self.parent_key is not None:
|
|
317
|
-
where_statement += (
|
|
318
|
-
"WHERE " + self.parent_key + " = " + self._parent_value_sql
|
|
319
|
-
)
|
|
320
|
-
|
|
321
221
|
return DatabaseCommand(f"""
|
|
322
222
|
DELETE
|
|
323
|
-
FROM {self.table_name.
|
|
324
|
-
{
|
|
325
|
-
""")
|
|
223
|
+
FROM {self.table_name.upper()}
|
|
224
|
+
{self._where_statement(include_id=False)};
|
|
225
|
+
""").with_data(self._data_with_replaced_parent({}))
|
|
326
226
|
|
|
327
227
|
def load(self, data: dict[str, Any]) -> ItemT:
|
|
328
228
|
return self.formatter.load(data)
|
|
@@ -335,6 +235,22 @@ class _DefaultSqlTable(SqlTable[ItemT]):
|
|
|
335
235
|
)
|
|
336
236
|
)
|
|
337
237
|
|
|
238
|
+
def _where_statement(self, include_id: bool = False) -> str:
|
|
239
|
+
result = next((field for field in self.fields if field.is_parent), None)
|
|
240
|
+
if result is None:
|
|
241
|
+
return f"WHERE {self._id} = :{self._id}" if include_id else ""
|
|
242
|
+
else:
|
|
243
|
+
statement = "WHERE " + result.name + " = :" + result.name
|
|
244
|
+
if include_id:
|
|
245
|
+
statement += f" AND {self._id} = :{self._id}"
|
|
246
|
+
return statement
|
|
247
|
+
|
|
248
|
+
def _data_with_replaced_parent(self, data: dict[str, Any]) -> dict[str, Any]:
|
|
249
|
+
result = next((field for field in self.fields if field.is_parent), None)
|
|
250
|
+
if result is not None:
|
|
251
|
+
data[result.name] = result.fixed_value
|
|
252
|
+
return data
|
|
253
|
+
|
|
338
254
|
@property
|
|
339
255
|
def _id(self) -> str:
|
|
340
256
|
result = next((field for field in self.fields if field.is_id), None)
|
|
@@ -347,16 +263,12 @@ class _DefaultSqlTable(SqlTable[ItemT]):
|
|
|
347
263
|
names = [field.name for field in self.fields if field.is_composite]
|
|
348
264
|
return [self._id] if len(names) == 0 else names
|
|
349
265
|
|
|
350
|
-
@property
|
|
351
|
-
def _parent_value_sql(self) -> str:
|
|
352
|
-
if isinstance(self.parent_value, str):
|
|
353
|
-
return "'" + self.parent_value + "'"
|
|
354
|
-
else:
|
|
355
|
-
return str(self.parent_value)
|
|
356
|
-
|
|
357
266
|
|
|
358
267
|
@dataclass(frozen=True)
|
|
359
268
|
class SqliteField:
|
|
360
269
|
name: str
|
|
361
|
-
is_id: bool
|
|
362
|
-
is_composite: bool
|
|
270
|
+
is_id: bool = False
|
|
271
|
+
is_composite: bool = False
|
|
272
|
+
|
|
273
|
+
is_parent: bool = False
|
|
274
|
+
fixed_value: Any | None = None
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|