apexdevkit 1.17.6__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.6 → apexdevkit-1.17.8}/PKG-INFO +1 -1
- {apexdevkit-1.17.6 → apexdevkit-1.17.8}/apexdevkit/repository/mssql.py +47 -151
- {apexdevkit-1.17.6 → apexdevkit-1.17.8}/apexdevkit/repository/sqlite.py +55 -58
- {apexdevkit-1.17.6 → apexdevkit-1.17.8}/pyproject.toml +1 -1
- {apexdevkit-1.17.6 → apexdevkit-1.17.8}/LICENSE +0 -0
- {apexdevkit-1.17.6 → apexdevkit-1.17.8}/README.md +0 -0
- {apexdevkit-1.17.6 → apexdevkit-1.17.8}/apexdevkit/__init__.py +0 -0
- {apexdevkit-1.17.6 → apexdevkit-1.17.8}/apexdevkit/annotation/__init__.py +0 -0
- {apexdevkit-1.17.6 → apexdevkit-1.17.8}/apexdevkit/annotation/deprecate.py +0 -0
- {apexdevkit-1.17.6 → apexdevkit-1.17.8}/apexdevkit/environment.py +0 -0
- {apexdevkit-1.17.6 → apexdevkit-1.17.8}/apexdevkit/error.py +0 -0
- {apexdevkit-1.17.6 → apexdevkit-1.17.8}/apexdevkit/fastapi/__init__.py +0 -0
- {apexdevkit-1.17.6 → apexdevkit-1.17.8}/apexdevkit/fastapi/builder.py +0 -0
- {apexdevkit-1.17.6 → apexdevkit-1.17.8}/apexdevkit/fastapi/dependable.py +0 -0
- {apexdevkit-1.17.6 → apexdevkit-1.17.8}/apexdevkit/fastapi/docs.py +0 -0
- {apexdevkit-1.17.6 → apexdevkit-1.17.8}/apexdevkit/fastapi/name.py +0 -0
- {apexdevkit-1.17.6 → apexdevkit-1.17.8}/apexdevkit/fastapi/request.py +0 -0
- {apexdevkit-1.17.6 → apexdevkit-1.17.8}/apexdevkit/fastapi/resource.py +0 -0
- {apexdevkit-1.17.6 → apexdevkit-1.17.8}/apexdevkit/fastapi/response.py +0 -0
- {apexdevkit-1.17.6 → apexdevkit-1.17.8}/apexdevkit/fastapi/router.py +0 -0
- {apexdevkit-1.17.6 → apexdevkit-1.17.8}/apexdevkit/fastapi/schema.py +0 -0
- {apexdevkit-1.17.6 → apexdevkit-1.17.8}/apexdevkit/fastapi/service.py +0 -0
- {apexdevkit-1.17.6 → apexdevkit-1.17.8}/apexdevkit/fluent.py +0 -0
- {apexdevkit-1.17.6 → apexdevkit-1.17.8}/apexdevkit/formatter.py +0 -0
- {apexdevkit-1.17.6 → apexdevkit-1.17.8}/apexdevkit/http/__init__.py +0 -0
- {apexdevkit-1.17.6 → apexdevkit-1.17.8}/apexdevkit/http/fake.py +0 -0
- {apexdevkit-1.17.6 → apexdevkit-1.17.8}/apexdevkit/http/fluent.py +0 -0
- {apexdevkit-1.17.6 → apexdevkit-1.17.8}/apexdevkit/http/httpx.py +0 -0
- {apexdevkit-1.17.6 → apexdevkit-1.17.8}/apexdevkit/http/json.py +0 -0
- {apexdevkit-1.17.6 → apexdevkit-1.17.8}/apexdevkit/http/url.py +0 -0
- {apexdevkit-1.17.6 → apexdevkit-1.17.8}/apexdevkit/key_fn.py +0 -0
- {apexdevkit-1.17.6 → apexdevkit-1.17.8}/apexdevkit/py.typed +0 -0
- {apexdevkit-1.17.6 → apexdevkit-1.17.8}/apexdevkit/repository/__init__.py +0 -0
- {apexdevkit-1.17.6 → apexdevkit-1.17.8}/apexdevkit/repository/base.py +0 -0
- {apexdevkit-1.17.6 → apexdevkit-1.17.8}/apexdevkit/repository/connector.py +0 -0
- {apexdevkit-1.17.6 → apexdevkit-1.17.8}/apexdevkit/repository/database.py +0 -0
- {apexdevkit-1.17.6 → apexdevkit-1.17.8}/apexdevkit/repository/decorator.py +0 -0
- {apexdevkit-1.17.6 → apexdevkit-1.17.8}/apexdevkit/repository/in_memory.py +0 -0
- {apexdevkit-1.17.6 → apexdevkit-1.17.8}/apexdevkit/repository/interface.py +0 -0
- {apexdevkit-1.17.6 → apexdevkit-1.17.8}/apexdevkit/repository/mongo.py +0 -0
- {apexdevkit-1.17.6 → apexdevkit-1.17.8}/apexdevkit/server.py +0 -0
- {apexdevkit-1.17.6 → apexdevkit-1.17.8}/apexdevkit/synchronization.py +0 -0
- {apexdevkit-1.17.6 → apexdevkit-1.17.8}/apexdevkit/testing/__init__.py +0 -0
- {apexdevkit-1.17.6 → apexdevkit-1.17.8}/apexdevkit/testing/database.py +0 -0
- {apexdevkit-1.17.6 → apexdevkit-1.17.8}/apexdevkit/testing/fake.py +0 -0
- {apexdevkit-1.17.6 → apexdevkit-1.17.8}/apexdevkit/testing/rest.py +0 -0
- {apexdevkit-1.17.6 → 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
|
-
", [" + 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
|
-
", [" + 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
|
-
", [" + 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
|
|
@@ -112,51 +112,28 @@ class SqliteTableBuilder(Generic[ItemT]):
|
|
|
112
112
|
) -> SqliteTableBuilder[ItemT]:
|
|
113
113
|
return SqliteTableBuilder[ItemT](self.table_name, value, self.fields)
|
|
114
114
|
|
|
115
|
-
def with_fields(self,
|
|
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.")
|
|
116
121
|
return SqliteTableBuilder[ItemT](
|
|
117
122
|
self.table_name,
|
|
118
123
|
self.formatter,
|
|
119
|
-
|
|
124
|
+
field_list,
|
|
120
125
|
)
|
|
121
126
|
|
|
122
|
-
def
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
raise ValueError("Missing fields in the table.")
|
|
126
|
-
|
|
127
|
-
return SqliteTableBuilder[ItemT](
|
|
128
|
-
self.table_name,
|
|
129
|
-
self.formatter,
|
|
130
|
-
[
|
|
131
|
-
SqliteField(field.name, field.name == identifier, field.is_composite)
|
|
132
|
-
for field in self.fields
|
|
133
|
-
],
|
|
134
|
-
)
|
|
135
|
-
|
|
136
|
-
def with_composite_key(
|
|
137
|
-
self, composites: Iterable[str]
|
|
138
|
-
) -> SqliteTableBuilder[ItemT]:
|
|
139
|
-
assert self.fields is not None, "Set fields first."
|
|
140
|
-
|
|
141
|
-
names = [field.name for field in self.fields]
|
|
142
|
-
if not all(field in names for field in list(composites)):
|
|
143
|
-
raise ValueError("Missing fields in the table.")
|
|
127
|
+
def build(self) -> SqlTable[ItemT]:
|
|
128
|
+
if not self.table_name or not self.formatter or not self.fields:
|
|
129
|
+
raise ValueError("Parameter missing.")
|
|
144
130
|
|
|
145
|
-
return
|
|
131
|
+
return _DefaultSqlTable(
|
|
146
132
|
self.table_name,
|
|
147
133
|
self.formatter,
|
|
148
|
-
|
|
149
|
-
SqliteField(field.name, field.is_id, field.name in list(composites))
|
|
150
|
-
for field in self.fields
|
|
151
|
-
],
|
|
134
|
+
self.fields,
|
|
152
135
|
)
|
|
153
136
|
|
|
154
|
-
def build(self) -> SqlTable[ItemT]:
|
|
155
|
-
if not self.table_name or not self.formatter or not self.fields:
|
|
156
|
-
raise ValueError("Cannot build sql table.")
|
|
157
|
-
|
|
158
|
-
return _DefaultSqlTable(self.table_name, self.formatter, self.fields)
|
|
159
|
-
|
|
160
137
|
|
|
161
138
|
@dataclass(frozen=True)
|
|
162
139
|
class _DefaultSqlTable(SqlTable[ItemT]):
|
|
@@ -167,21 +144,22 @@ class _DefaultSqlTable(SqlTable[ItemT]):
|
|
|
167
144
|
def count_all(self) -> DatabaseCommand:
|
|
168
145
|
return DatabaseCommand(f"""
|
|
169
146
|
SELECT count(*) as n_items
|
|
170
|
-
FROM {self.table_name.
|
|
171
|
-
|
|
147
|
+
FROM {self.table_name.upper()}
|
|
148
|
+
{self._where_statement(include_id=False)};
|
|
149
|
+
""").with_data(self._data_with_replaced_parent({}))
|
|
172
150
|
|
|
173
151
|
def insert(self, item: ItemT) -> DatabaseCommand:
|
|
174
152
|
columns = ", ".join([field.name for field in self.fields])
|
|
175
153
|
placeholders = ", ".join([f":{key.name}" for key in self.fields])
|
|
176
154
|
|
|
177
155
|
return DatabaseCommand(f"""
|
|
178
|
-
INSERT INTO {self.table_name.
|
|
156
|
+
INSERT INTO {self.table_name.upper()} (
|
|
179
157
|
{columns}
|
|
180
158
|
) VALUES (
|
|
181
159
|
{placeholders}
|
|
182
160
|
)
|
|
183
161
|
RETURNING {columns};
|
|
184
|
-
""").with_data(self.formatter.dump(item))
|
|
162
|
+
""").with_data(self._data_with_replaced_parent(self.formatter.dump(item)))
|
|
185
163
|
|
|
186
164
|
def select(self, item_id: str) -> DatabaseCommand:
|
|
187
165
|
columns = ", ".join([field.name for field in self.fields])
|
|
@@ -189,9 +167,9 @@ class _DefaultSqlTable(SqlTable[ItemT]):
|
|
|
189
167
|
return DatabaseCommand(f"""
|
|
190
168
|
SELECT
|
|
191
169
|
{columns}
|
|
192
|
-
FROM {self.table_name.
|
|
193
|
-
|
|
194
|
-
""").with_data({self._id: item_id})
|
|
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}))
|
|
195
173
|
|
|
196
174
|
def select_duplicate(self, item: ItemT) -> DatabaseCommand:
|
|
197
175
|
raw = self.formatter.dump(item)
|
|
@@ -202,7 +180,7 @@ class _DefaultSqlTable(SqlTable[ItemT]):
|
|
|
202
180
|
return DatabaseCommand(f"""
|
|
203
181
|
SELECT
|
|
204
182
|
{columns}
|
|
205
|
-
FROM {self.table_name.
|
|
183
|
+
FROM {self.table_name.upper()}
|
|
206
184
|
WHERE {duplicates};
|
|
207
185
|
""").with_data({key: raw[key] for key in raw if key in self._composite})
|
|
208
186
|
|
|
@@ -212,39 +190,39 @@ class _DefaultSqlTable(SqlTable[ItemT]):
|
|
|
212
190
|
return DatabaseCommand(f"""
|
|
213
191
|
SELECT
|
|
214
192
|
{columns}
|
|
215
|
-
FROM {self.table_name.capitalize()}
|
|
216
|
-
|
|
193
|
+
FROM {self.table_name.capitalize()}
|
|
194
|
+
{self._where_statement(include_id=False)};
|
|
195
|
+
""").with_data(self._data_with_replaced_parent({}))
|
|
217
196
|
|
|
218
197
|
def update(self, item: ItemT) -> DatabaseCommand:
|
|
219
198
|
updates = ", ".join(
|
|
220
199
|
[
|
|
221
200
|
f"{field.name} = :{field.name}"
|
|
222
201
|
for field in self.fields
|
|
223
|
-
if not field.is_id
|
|
202
|
+
if not field.is_id and not field.is_parent
|
|
224
203
|
]
|
|
225
204
|
)
|
|
226
205
|
|
|
227
206
|
return DatabaseCommand(f"""
|
|
228
|
-
UPDATE {self.table_name.
|
|
207
|
+
UPDATE {self.table_name.upper()}
|
|
229
208
|
SET
|
|
230
209
|
{updates}
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
""").with_data(self.formatter.dump(item))
|
|
210
|
+
{self._where_statement(include_id=True)};
|
|
211
|
+
""").with_data(self._data_with_replaced_parent(self.formatter.dump(item)))
|
|
234
212
|
|
|
235
213
|
def delete(self, item_id: str) -> DatabaseCommand:
|
|
236
214
|
return DatabaseCommand(f"""
|
|
237
215
|
DELETE
|
|
238
|
-
FROM {self.table_name.
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
""").with_data({self._id: item_id})
|
|
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}))
|
|
242
219
|
|
|
243
220
|
def delete_all(self) -> DatabaseCommand:
|
|
244
221
|
return DatabaseCommand(f"""
|
|
245
222
|
DELETE
|
|
246
|
-
FROM {self.table_name.
|
|
247
|
-
|
|
223
|
+
FROM {self.table_name.upper()}
|
|
224
|
+
{self._where_statement(include_id=False)};
|
|
225
|
+
""").with_data(self._data_with_replaced_parent({}))
|
|
248
226
|
|
|
249
227
|
def load(self, data: dict[str, Any]) -> ItemT:
|
|
250
228
|
return self.formatter.load(data)
|
|
@@ -257,6 +235,22 @@ class _DefaultSqlTable(SqlTable[ItemT]):
|
|
|
257
235
|
)
|
|
258
236
|
)
|
|
259
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
|
+
|
|
260
254
|
@property
|
|
261
255
|
def _id(self) -> str:
|
|
262
256
|
result = next((field for field in self.fields if field.is_id), None)
|
|
@@ -273,5 +267,8 @@ class _DefaultSqlTable(SqlTable[ItemT]):
|
|
|
273
267
|
@dataclass(frozen=True)
|
|
274
268
|
class SqliteField:
|
|
275
269
|
name: str
|
|
276
|
-
is_id: bool
|
|
277
|
-
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
|