ormlambda 1.5.0__py3-none-any.whl → 2.0.2__py3-none-any.whl
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.
- ormlambda/__init__.py +9 -2
- ormlambda/common/__init__.py +0 -1
- ormlambda/common/abstract_classes/__init__.py +1 -1
- ormlambda/common/abstract_classes/abstract_model.py +13 -228
- ormlambda/common/abstract_classes/non_query_base.py +7 -5
- ormlambda/common/abstract_classes/query_base.py +5 -2
- ormlambda/common/enums/__init__.py +1 -1
- ormlambda/common/enums/join_type.py +2 -1
- ormlambda/common/interfaces/IQueryCommand.py +2 -1
- ormlambda/common/interfaces/IRepositoryBase.py +4 -18
- ormlambda/common/interfaces/IStatements.py +33 -15
- ormlambda/common/interfaces/__init__.py +1 -1
- ormlambda/components/delete/abstract_delete.py +6 -3
- ormlambda/components/insert/IInsert.py +1 -1
- ormlambda/components/insert/abstract_insert.py +8 -4
- ormlambda/components/select/ISelect.py +1 -1
- ormlambda/components/select/table_column.py +5 -1
- ormlambda/components/update/IUpdate.py +1 -1
- ormlambda/components/update/__init__.py +1 -1
- ormlambda/components/update/abstract_update.py +9 -5
- ormlambda/components/upsert/__init__.py +1 -1
- ormlambda/components/upsert/abstract_upsert.py +8 -4
- ormlambda/components/where/abstract_where.py +6 -2
- ormlambda/databases/my_sql/clauses/__init__.py +1 -0
- ormlambda/databases/my_sql/clauses/count.py +35 -0
- ormlambda/databases/my_sql/clauses/create_database.py +17 -10
- ormlambda/databases/my_sql/clauses/delete.py +7 -4
- ormlambda/databases/my_sql/clauses/drop_database.py +1 -1
- ormlambda/databases/my_sql/clauses/drop_table.py +1 -1
- ormlambda/databases/my_sql/clauses/insert.py +4 -3
- ormlambda/databases/my_sql/clauses/joins.py +8 -7
- ormlambda/databases/my_sql/clauses/limit.py +1 -1
- ormlambda/databases/my_sql/clauses/offset.py +1 -1
- ormlambda/databases/my_sql/clauses/order.py +3 -3
- ormlambda/databases/my_sql/clauses/select.py +5 -5
- ormlambda/databases/my_sql/clauses/update.py +3 -3
- ormlambda/databases/my_sql/clauses/upsert.py +3 -3
- ormlambda/databases/my_sql/clauses/where_condition.py +5 -5
- ormlambda/databases/my_sql/repository.py +57 -27
- ormlambda/databases/my_sql/statements.py +200 -43
- ormlambda/model_base.py +2 -4
- ormlambda/utils/column.py +4 -3
- ormlambda/utils/dtypes.py +6 -8
- ormlambda/utils/foreign_key.py +55 -10
- ormlambda/utils/lambda_disassembler/__init__.py +1 -1
- ormlambda/utils/lambda_disassembler/dis_types.py +22 -25
- ormlambda/utils/lambda_disassembler/tree_instruction.py +1 -1
- ormlambda/utils/module_tree/dynamic_module.py +6 -4
- ormlambda/utils/table_constructor.py +39 -22
- {ormlambda-1.5.0.dist-info → ormlambda-2.0.2.dist-info}/METADATA +13 -9
- ormlambda-2.0.2.dist-info/RECORD +71 -0
- ormlambda-1.5.0.dist-info/RECORD +0 -70
- {ormlambda-1.5.0.dist-info → ormlambda-2.0.2.dist-info}/LICENSE +0 -0
- {ormlambda-1.5.0.dist-info → ormlambda-2.0.2.dist-info}/WHEEL +0 -0
ormlambda/__init__.py
CHANGED
@@ -1,4 +1,11 @@
|
|
1
|
-
|
1
|
+
# enums
|
2
|
+
from .common.enums import ( # noqa: F401
|
3
|
+
JoinType,
|
4
|
+
ConditionType,
|
5
|
+
)
|
6
|
+
|
7
|
+
from .common.abstract_classes import AbstractSQLStatements # noqa: F401
|
8
|
+
from .common.interfaces import IRepositoryBase # noqa: F401
|
2
9
|
from .utils import Table, Column, ForeignKey # noqa: F401
|
3
10
|
from .utils.lambda_disassembler import Disassembler, nameof # noqa: F401
|
4
|
-
from .
|
11
|
+
from .model_base import BaseModel # noqa: F401 # COMMENT: to avoid relative import we need to import BaseModel after import Table,Column, ForeignKey, IRepositoryBase and Disassembler
|
ormlambda/common/__init__.py
CHANGED
@@ -1,31 +1,14 @@
|
|
1
|
-
from
|
2
|
-
from
|
1
|
+
from __future__ import annotations
|
2
|
+
from typing import Any, Type, override, Iterable, Literal, TYPE_CHECKING
|
3
3
|
from collections import defaultdict
|
4
|
-
from abc import abstractmethod
|
5
|
-
import inspect
|
6
4
|
|
7
|
-
from ...utils import ForeignKey, Table
|
8
5
|
|
9
|
-
from
|
10
|
-
from
|
6
|
+
from ormlambda.utils import Table
|
7
|
+
from ormlambda.common.interfaces import IQuery, IRepositoryBase, IStatements_two_generic
|
11
8
|
|
12
|
-
|
13
|
-
from
|
14
|
-
from
|
15
|
-
from ...components.upsert import UpsertQueryBase
|
16
|
-
from ...components.select import TableColumn
|
17
|
-
from ...components.insert import InsertQueryBase
|
18
|
-
from ...components.where.abstract_where import AbstractWhere
|
19
|
-
|
20
|
-
|
21
|
-
class JoinType(Enum):
|
22
|
-
RIGHT_INCLUSIVE = "RIGHT JOIN"
|
23
|
-
LEFT_INCLUSIVE = "LEFT JOIN"
|
24
|
-
RIGHT_EXCLUSIVE = "RIGHT JOIN"
|
25
|
-
LEFT_EXCLUSIVE = "LEFT JOIN"
|
26
|
-
FULL_OUTER_INCLUSIVE = "RIGHT JOIN"
|
27
|
-
FULL_OUTER_EXCLUSIVE = "RIGHT JOIN"
|
28
|
-
INNER_JOIN = "INNER JOIN"
|
9
|
+
if TYPE_CHECKING:
|
10
|
+
from ormlambda.components.select import ISelect
|
11
|
+
from ormlambda.components.select import TableColumn
|
29
12
|
|
30
13
|
|
31
14
|
ORDER_QUERIES = Literal["select", "join", "where", "order", "with", "group by", "limit", "offset"]
|
@@ -36,7 +19,7 @@ class AbstractSQLStatements[T: Table, TRepo](IStatements_two_generic[T, TRepo]):
|
|
36
19
|
__order__: tuple[str, ...] = ("select", "join", "where", "order", "with", "group by", "limit", "offset")
|
37
20
|
|
38
21
|
def __init__(self, model: T, repository: IRepositoryBase[TRepo]) -> None:
|
39
|
-
self.
|
22
|
+
self.__valid_repository(repository)
|
40
23
|
|
41
24
|
self._model: T = model
|
42
25
|
self._repository: IRepositoryBase[TRepo] = repository
|
@@ -48,149 +31,17 @@ class AbstractSQLStatements[T: Table, TRepo](IStatements_two_generic[T, TRepo]):
|
|
48
31
|
raise Exception(f"'{model}' class does not inherit from Table class")
|
49
32
|
|
50
33
|
@staticmethod
|
51
|
-
def
|
34
|
+
def __valid_repository(repository: Any) -> bool:
|
52
35
|
if not isinstance(repository, IRepositoryBase):
|
53
36
|
raise ValueError(f"'repository' attribute does not instance of '{IRepositoryBase.__name__}'")
|
54
37
|
return True
|
55
38
|
|
56
|
-
|
57
|
-
|
58
|
-
def INSERT_QUERY(self) -> Type[InsertQueryBase[T, TRepo]]: ...
|
59
|
-
@property
|
60
|
-
@abstractmethod
|
61
|
-
def UPSERT_QUERY(self) -> Type[UpsertQueryBase[T, TRepo]]: ...
|
62
|
-
@property
|
63
|
-
@abstractmethod
|
64
|
-
def UPDATE_QUERY(self) -> Type[UpdateQueryBase[T, TRepo]]: ...
|
65
|
-
@property
|
66
|
-
@abstractmethod
|
67
|
-
def DELETE_QUERY(self) -> Type[DeleteQueryBase[T, TRepo]]: ...
|
68
|
-
@property
|
69
|
-
@abstractmethod
|
70
|
-
def LIMIT_QUERY(self) -> Type[IQuery]: ...
|
71
|
-
@property
|
72
|
-
@abstractmethod
|
73
|
-
def OFFSET_QUERY(self) -> Type[IQuery]: ...
|
74
|
-
@property
|
75
|
-
@abstractmethod
|
76
|
-
def JOIN_QUERY(self) -> Type[IQuery]: ...
|
77
|
-
@property
|
78
|
-
@abstractmethod
|
79
|
-
def WHERE_QUERY(self) -> Type[IQuery]: ...
|
80
|
-
@property
|
81
|
-
@abstractmethod
|
82
|
-
def ORDER_QUERY(self) -> Type[IQuery]: ...
|
83
|
-
@property
|
84
|
-
@abstractmethod
|
85
|
-
def SELECT_QUERY(self) -> Type[ISelect]: ...
|
86
|
-
|
87
|
-
@override
|
88
|
-
def create_table(self) -> None:
|
89
|
-
if not self._repository.table_exists(self._model.__table_name__):
|
90
|
-
self._repository.execute(self._model.create_table_query())
|
91
|
-
return None
|
92
|
-
|
93
|
-
@override
|
94
|
-
def table_exists(self) -> bool:
|
95
|
-
return self._repository.table_exists(self._model.__table_name__)
|
96
|
-
|
97
|
-
@override
|
98
|
-
def insert(self, instances: T | list[T]) -> None:
|
99
|
-
insert = self.INSERT_QUERY(self._model, self._repository)
|
100
|
-
insert.insert(instances)
|
101
|
-
insert.execute()
|
102
|
-
self._query_list.clear()
|
103
|
-
return None
|
104
|
-
|
105
|
-
@override
|
106
|
-
def delete(self, instances: Optional[T | list[T]] = None) -> None:
|
107
|
-
if instances is None:
|
108
|
-
response = self.select()
|
109
|
-
if len(response) == 0:
|
110
|
-
return None
|
111
|
-
# [0] because if we do not select anything, we retrieve all columns of the unic model, stored in tuple[tuple[model]] structure.
|
112
|
-
# We always going to have a tuple of one element
|
113
|
-
return self.delete(response)
|
114
|
-
|
115
|
-
delete = self.DELETE_QUERY(self._model, self._repository)
|
116
|
-
delete.delete(instances)
|
117
|
-
delete.execute()
|
118
|
-
# not necessary to call self._query_list.clear() because select() method already call it
|
119
|
-
return None
|
120
|
-
|
121
|
-
@override
|
122
|
-
def upsert(self, instances: T | list[T]) -> None:
|
123
|
-
upsert = self.UPSERT_QUERY(self._model, self._repository)
|
124
|
-
upsert.upsert(instances)
|
125
|
-
upsert.execute()
|
126
|
-
self._query_list.clear()
|
127
|
-
return None
|
128
|
-
|
129
|
-
@override
|
130
|
-
def update(self, dicc: dict[str, Any] | list[dict[str, Any]]) -> None:
|
131
|
-
update = self.UPDATE_QUERY(self._model, self._repository, self._query_list["where"])
|
132
|
-
update.update(dicc)
|
133
|
-
update.execute()
|
134
|
-
self._query_list.clear()
|
135
|
-
return None
|
136
|
-
|
137
|
-
@override
|
138
|
-
def limit(self, number: int) -> "IStatements_two_generic[T,TRepo]":
|
139
|
-
limit = self.LIMIT_QUERY(number)
|
140
|
-
# Only can be one LIMIT SQL parameter. We only use the last LimitQuery
|
141
|
-
limit_list = self._query_list["limit"]
|
142
|
-
if len(limit_list) > 0:
|
143
|
-
self._query_list["limit"] = [limit]
|
144
|
-
else:
|
145
|
-
self._query_list["limit"].append(limit)
|
146
|
-
return self
|
147
|
-
|
148
|
-
@override
|
149
|
-
def offset(self, number: int) -> "IStatements_two_generic[T,TRepo]":
|
150
|
-
offset = self.OFFSET_QUERY(number)
|
151
|
-
self._query_list["offset"].append(offset)
|
152
|
-
return self
|
153
|
-
|
154
|
-
@override
|
155
|
-
def join(self, table_left: Table, table_right: Table, *, by: str) -> "IStatements_two_generic[T,TRepo]":
|
156
|
-
where = ForeignKey.MAPPED[table_left][table_right]
|
157
|
-
join_query = self.JOIN_QUERY[table_left, Table](table_left, table_right, JoinType(by), where=where)
|
158
|
-
self._query_list["join"].append(join_query)
|
159
|
-
return self
|
160
|
-
|
161
|
-
@override
|
162
|
-
def where(self, lambda_: Callable[[T], bool] = lambda: None, **kwargs) -> "IStatements_two_generic[T,TRepo]":
|
163
|
-
# FIXME [x]: I've wrapped self._model into tuple to pass it instance attr. Idk if it's correct
|
164
|
-
where_query = self.WHERE_QUERY[T](function=lambda_, instances=(self._model,), **kwargs)
|
165
|
-
self._query_list["where"].append(where_query)
|
166
|
-
return self
|
167
|
-
|
168
|
-
@override
|
169
|
-
def order[TValue](self, _lambda_col: Callable[[T], TValue], order_type: OrderType) -> "IStatements_two_generic[T,TRepo]":
|
170
|
-
order = self.ORDER_QUERY[T](self._model, _lambda_col, order_type)
|
171
|
-
self._query_list["order"].append(order)
|
172
|
-
return self
|
39
|
+
def __repr__(self):
|
40
|
+
return f"<Model: {self.__class__.__name__}>"
|
173
41
|
|
42
|
+
@property
|
174
43
|
@override
|
175
|
-
def
|
176
|
-
if len(inspect.signature(selector).parameters) == 0:
|
177
|
-
# COMMENT: if we do not specify any lambda function we assumed the user want to retreive only elements of the Model itself avoiding other models
|
178
|
-
result = self.select(selector=lambda x: (x,), flavour=flavour, by=by)
|
179
|
-
# COMMENT: Always we want to retrieve tuple[tuple[Any]]. That's the reason to return result[0] when we ensure the user want only objects of the first table.
|
180
|
-
# Otherwise, we wil return the result itself
|
181
|
-
if flavour:
|
182
|
-
return result
|
183
|
-
return () if not result else result[0]
|
184
|
-
select: ISelect = self.SELECT_QUERY(self._model, select_lambda=selector, by=by)
|
185
|
-
self._query_list["select"].append(select)
|
186
|
-
|
187
|
-
query: str = self.build()
|
188
|
-
if flavour:
|
189
|
-
result = self._return_flavour(query, flavour)
|
190
|
-
if issubclass(flavour, tuple) and isinstance(selector(self._model), property):
|
191
|
-
return tuple([x[0] for x in result])
|
192
|
-
return result
|
193
|
-
return self._return_model(select, query)
|
44
|
+
def repository(self) -> IRepositoryBase[TRepo]: ...
|
194
45
|
|
195
46
|
def _return_flavour[TValue](self, query, flavour: Type[TValue]) -> tuple[TValue]:
|
196
47
|
return self._repository.read_sql(query, flavour=flavour)
|
@@ -203,72 +54,6 @@ class AbstractSQLStatements[T: Table, TRepo](IStatements_two_generic[T, TRepo]):
|
|
203
54
|
|
204
55
|
return response_sql
|
205
56
|
|
206
|
-
@override
|
207
|
-
def select_one[TValue, TFlavour, *Ts](self, selector: Optional[Callable[[T], tuple[TValue, *Ts]]] = lambda: None, *, flavour: Optional[Type[TFlavour]] = None, by: JoinType = JoinType.INNER_JOIN):
|
208
|
-
self.limit(1)
|
209
|
-
if len(inspect.signature(selector).parameters) == 0:
|
210
|
-
response = self.select(selector=lambda x: (x,), flavour=flavour, by=by)
|
211
|
-
else:
|
212
|
-
response = self.select(selector=selector, flavour=flavour, by=by)
|
213
|
-
|
214
|
-
if flavour:
|
215
|
-
return response[0]
|
216
|
-
|
217
|
-
# response var could be return more than one element when we work with models an we
|
218
|
-
# select columns from different tables using a join query
|
219
|
-
if len(response) == 1 and len(response[0]) == 1:
|
220
|
-
return response[0][0]
|
221
|
-
return tuple([res[0] for res in response])
|
222
|
-
|
223
|
-
@override
|
224
|
-
def build(self) -> str:
|
225
|
-
query: str = ""
|
226
|
-
|
227
|
-
self._create_necessary_inner_join()
|
228
|
-
for x in self.__order__:
|
229
|
-
if sub_query := self._query_list.get(x, None):
|
230
|
-
if isinstance(sub_query[0], self.WHERE_QUERY):
|
231
|
-
query_ = self.__build_where_clause(sub_query)
|
232
|
-
|
233
|
-
# we must check if any join already exists on query string
|
234
|
-
elif isinstance(sub_query[0], self.JOIN_QUERY):
|
235
|
-
select_query: str = self._query_list["select"][0].query
|
236
|
-
query_ = ""
|
237
|
-
for join in sub_query:
|
238
|
-
if join.query not in select_query:
|
239
|
-
query_ += f"\n{join.query}"
|
240
|
-
else:
|
241
|
-
query_ = "\n".join([x.query for x in sub_query])
|
242
|
-
|
243
|
-
query += f"\n{query_}" if query != "" else query_
|
244
|
-
self._query_list.clear()
|
245
|
-
return query
|
246
|
-
|
247
|
-
def __build_where_clause(self, where_condition: list[AbstractWhere]) -> str:
|
248
|
-
query: str = where_condition[0].query
|
249
|
-
|
250
|
-
for where in where_condition[1:]:
|
251
|
-
q = where.query.replace(where.WHERE, "AND")
|
252
|
-
and_, clause = q.split(" ", maxsplit=1)
|
253
|
-
query += f" {and_} ({clause})"
|
254
|
-
return query
|
255
|
-
|
256
|
-
def _create_necessary_inner_join(self) -> None:
|
257
|
-
# When we applied filters in any table that we wont select any column, we need to add manually all neccessary joins to achieve positive result.
|
258
|
-
if "where" not in self._query_list:
|
259
|
-
return None
|
260
|
-
|
261
|
-
where: AbstractWhere = self._query_list["where"][0]
|
262
|
-
involved_tables = where.get_involved_tables()
|
263
|
-
|
264
|
-
select: ISelect = self._query_list["select"][0]
|
265
|
-
if not involved_tables or (set(involved_tables) == set(select.tables_heritage)):
|
266
|
-
return None
|
267
|
-
|
268
|
-
for l_tbl, r_tbl in involved_tables:
|
269
|
-
# FIXME [ ]: Checked what function was called by the self.join method before the change
|
270
|
-
self.join(l_tbl, r_tbl, by="INNER JOIN")
|
271
|
-
|
272
57
|
|
273
58
|
class ClusterQuery:
|
274
59
|
def __init__(self, select: ISelect, response_sql: tuple[dict[str, Any]]) -> None:
|
@@ -1,13 +1,15 @@
|
|
1
|
+
from __future__ import annotations
|
1
2
|
from abc import abstractmethod
|
2
|
-
from typing import Any, Optional, override
|
3
|
+
from typing import Any, Optional, Type, override, TYPE_CHECKING
|
3
4
|
|
4
|
-
from
|
5
|
+
from ormlambda.common.interfaces.INonQueryCommand import INonQueryCommand
|
5
6
|
|
6
|
-
|
7
|
-
from
|
7
|
+
if TYPE_CHECKING:
|
8
|
+
from ormlambda import IRepositoryBase
|
9
|
+
from ormlambda import Table
|
8
10
|
|
9
11
|
|
10
|
-
class NonQueryBase[T: Table, TRepo: IRepositoryBase](INonQueryCommand):
|
12
|
+
class NonQueryBase[T: Type[Table], TRepo: IRepositoryBase](INonQueryCommand):
|
11
13
|
__slots__: tuple[str, ...] = ("_model", "_repository", "_values", "_query")
|
12
14
|
|
13
15
|
def __init__(self, model: T, repository: TRepo) -> None:
|
@@ -1,7 +1,10 @@
|
|
1
1
|
from abc import abstractmethod
|
2
|
+
from typing import TYPE_CHECKING
|
2
3
|
|
3
|
-
from
|
4
|
-
|
4
|
+
from ormlambda.common.interfaces import IQuery
|
5
|
+
|
6
|
+
if TYPE_CHECKING:
|
7
|
+
from ormlambda import Table
|
5
8
|
|
6
9
|
|
7
10
|
class QueryBase[T: Table](IQuery):
|
@@ -1,2 +1,2 @@
|
|
1
1
|
from .join_type import JoinType # noqa: F401
|
2
|
-
from .condition_types import ConditionType # noqa: F401
|
2
|
+
from .condition_types import ConditionType # noqa: F401
|
@@ -1,5 +1,6 @@
|
|
1
1
|
from enum import Enum
|
2
2
|
|
3
|
+
|
3
4
|
class JoinType(Enum):
|
4
5
|
RIGHT_INCLUSIVE = "RIGHT JOIN"
|
5
6
|
LEFT_INCLUSIVE = "LEFT JOIN"
|
@@ -7,4 +8,4 @@ class JoinType(Enum):
|
|
7
8
|
LEFT_EXCLUSIVE = "LEFT JOIN"
|
8
9
|
FULL_OUTER_INCLUSIVE = "RIGHT JOIN"
|
9
10
|
FULL_OUTER_EXCLUSIVE = "RIGHT JOIN"
|
10
|
-
INNER_JOIN = "INNER JOIN"
|
11
|
+
INNER_JOIN = "INNER JOIN"
|
@@ -2,7 +2,8 @@ from abc import abstractmethod, ABC
|
|
2
2
|
|
3
3
|
|
4
4
|
class IQuery(ABC):
|
5
|
-
"""
|
5
|
+
"""Interface to queries that retrieve any element such as select, limit, offset, where, group by, etc..."""
|
6
|
+
|
6
7
|
@property
|
7
8
|
@abstractmethod
|
8
9
|
def query(self) -> str: ...
|
@@ -1,23 +1,10 @@
|
|
1
1
|
from abc import ABC, abstractmethod
|
2
|
-
import
|
3
|
-
from typing import Any, Callable, Literal, Optional, Type
|
2
|
+
from typing import Any, Literal, Optional, Type
|
4
3
|
|
5
4
|
TypeExists = Literal["fail", "replace", "append"]
|
6
5
|
|
7
6
|
|
8
7
|
class IRepositoryBase[T](ABC):
|
9
|
-
def check_connection(func: Callable[..., Any]):
|
10
|
-
@functools.wraps(func)
|
11
|
-
def wrapper(self: "IRepositoryBase[T]", *args, **kwargs):
|
12
|
-
if not self.is_connected():
|
13
|
-
self.connect()
|
14
|
-
|
15
|
-
foo = func(self, *args, **kwargs)
|
16
|
-
self.close_connection()
|
17
|
-
return foo
|
18
|
-
|
19
|
-
return wrapper
|
20
|
-
|
21
8
|
def __repr__(self) -> str:
|
22
9
|
return f"{IRepositoryBase.__name__}: {self.__class__.__name__}"
|
23
10
|
|
@@ -25,7 +12,7 @@ class IRepositoryBase[T](ABC):
|
|
25
12
|
def is_connected(self) -> bool: ...
|
26
13
|
|
27
14
|
@abstractmethod
|
28
|
-
def connect(self, **kwargs: Any) ->
|
15
|
+
def connect(self, **kwargs: Any) -> None: ...
|
29
16
|
|
30
17
|
@abstractmethod
|
31
18
|
def close_connection(self) -> None: ...
|
@@ -61,7 +48,6 @@ class IRepositoryBase[T](ABC):
|
|
61
48
|
@abstractmethod
|
62
49
|
def connection(self) -> T: ...
|
63
50
|
|
51
|
+
@property
|
64
52
|
@abstractmethod
|
65
|
-
def
|
66
|
-
"""Method to update database config"""
|
67
|
-
...
|
53
|
+
def database(self) -> Optional[str]: ...
|
@@ -1,17 +1,23 @@
|
|
1
|
-
from
|
1
|
+
from __future__ import annotations
|
2
|
+
from typing import Any, Callable, Iterable, Optional, Literal, Type, overload, TYPE_CHECKING
|
2
3
|
from enum import Enum
|
3
4
|
from abc import abstractmethod, ABC
|
4
5
|
|
5
6
|
from .IRepositoryBase import IRepositoryBase
|
6
|
-
from
|
7
|
-
|
7
|
+
from ormlambda.common.enums import JoinType
|
8
|
+
|
9
|
+
if TYPE_CHECKING:
|
10
|
+
from ormlambda import Table
|
8
11
|
|
9
12
|
OrderType = Literal["ASC", "DESC"]
|
10
13
|
|
14
|
+
# TODOH: This var is duplicated from 'src\ormlambda\databases\my_sql\clauses\create_database.py'
|
15
|
+
TypeExists = Literal["fail", "replace", "append"]
|
16
|
+
|
11
17
|
|
12
18
|
class IStatements[T: Table](ABC):
|
13
19
|
@abstractmethod
|
14
|
-
def create_table(self) -> None: ...
|
20
|
+
def create_table(self, if_exists: TypeExists) -> None: ...
|
15
21
|
|
16
22
|
@abstractmethod
|
17
23
|
def table_exists(self) -> bool: ...
|
@@ -38,6 +44,8 @@ class IStatements[T: Table](ABC):
|
|
38
44
|
@abstractmethod
|
39
45
|
def insert(self, values: T | list[T]) -> None: ...
|
40
46
|
|
47
|
+
# endregion
|
48
|
+
|
41
49
|
# region upsert
|
42
50
|
@overload
|
43
51
|
def upsert(self, values: T) -> None:
|
@@ -71,13 +79,19 @@ class IStatements[T: Table](ABC):
|
|
71
79
|
|
72
80
|
# region limit
|
73
81
|
@abstractmethod
|
74
|
-
def limit(self, number: int) ->
|
82
|
+
def limit(self, number: int) -> IStatements[T]: ...
|
75
83
|
|
76
84
|
# endregion
|
77
85
|
|
78
86
|
# region offset
|
79
87
|
@abstractmethod
|
80
|
-
def offset(self, number: int) ->
|
88
|
+
def offset(self, number: int) -> IStatements[T]: ...
|
89
|
+
|
90
|
+
# endregion
|
91
|
+
|
92
|
+
# region count
|
93
|
+
@abstractmethod
|
94
|
+
def count(self) -> int: ...
|
81
95
|
|
82
96
|
# endregion
|
83
97
|
|
@@ -97,13 +111,13 @@ class IStatements[T: Table](ABC):
|
|
97
111
|
|
98
112
|
# region join
|
99
113
|
@abstractmethod
|
100
|
-
def join(self, table_left: Table, table_right: Table, *, by: str) ->
|
114
|
+
def join(self, table_left: Table, table_right: Table, *, by: str) -> IStatements[T]: ...
|
101
115
|
|
102
116
|
# endregion
|
103
117
|
|
104
118
|
# region where
|
105
119
|
@overload
|
106
|
-
def where(self, lambda_: Callable[[T], bool]) ->
|
120
|
+
def where(self, lambda_: Callable[[T], bool]) -> IStatements[T]:
|
107
121
|
"""
|
108
122
|
This method creates where clause by passing the lambda's condition
|
109
123
|
|
@@ -115,7 +129,7 @@ class IStatements[T: Table](ABC):
|
|
115
129
|
...
|
116
130
|
|
117
131
|
@overload
|
118
|
-
def where(self, lambda_: Callable[[T], Iterable]) ->
|
132
|
+
def where(self, lambda_: Callable[[T], Iterable]) -> IStatements[T]:
|
119
133
|
"""
|
120
134
|
This method creates where clause by passing the Iterable in lambda function
|
121
135
|
EXAMPLE
|
@@ -126,7 +140,7 @@ class IStatements[T: Table](ABC):
|
|
126
140
|
...
|
127
141
|
|
128
142
|
@overload
|
129
|
-
def where(self, lambda_: Callable[[T], bool], **kwargs) ->
|
143
|
+
def where(self, lambda_: Callable[[T], bool], **kwargs) -> IStatements[T]:
|
130
144
|
"""
|
131
145
|
PARAM
|
132
146
|
-
|
@@ -143,17 +157,17 @@ class IStatements[T: Table](ABC):
|
|
143
157
|
...
|
144
158
|
|
145
159
|
@abstractmethod
|
146
|
-
def where(self, lambda_: Callable[[T], bool] = lambda: None, **kwargs) ->
|
160
|
+
def where(self, lambda_: Callable[[T], bool] = lambda: None, **kwargs) -> IStatements[T]: ...
|
147
161
|
|
148
162
|
# endregion
|
149
163
|
|
150
164
|
# region order
|
151
165
|
@overload
|
152
|
-
def order[TValue](self, _lambda_col: Callable[[T], TValue]) ->
|
166
|
+
def order[TValue](self, _lambda_col: Callable[[T], TValue]) -> IStatements[T]: ...
|
153
167
|
@overload
|
154
|
-
def order[TValue](self, _lambda_col: Callable[[T], TValue], order_type: OrderType) ->
|
168
|
+
def order[TValue](self, _lambda_col: Callable[[T], TValue], order_type: OrderType) -> IStatements[T]: ...
|
155
169
|
@abstractmethod
|
156
|
-
def order[TValue](self, _lambda_col: Callable[[T], TValue], order_type: OrderType) ->
|
170
|
+
def order[TValue](self, _lambda_col: Callable[[T], TValue], order_type: OrderType) -> IStatements[T]: ...
|
157
171
|
|
158
172
|
# endregion
|
159
173
|
|
@@ -203,12 +217,16 @@ class IStatements[T: Table](ABC):
|
|
203
217
|
@overload
|
204
218
|
def select_one(self) -> T: ...
|
205
219
|
@overload
|
206
|
-
def select_one(self, *, by: Optional[Enum] = JoinType.INNER_JOIN, flavour: Type[
|
220
|
+
def select_one[TFlavour](self, *, by: Optional[Enum] = JoinType.INNER_JOIN, flavour: Type[TFlavour]) -> TFlavour: ...
|
207
221
|
@overload
|
208
222
|
def select_one[T1](self, selector: Callable[[T], tuple[T1]], *, by: Optional[Enum] = JoinType.INNER_JOIN) -> T1: ...
|
209
223
|
@overload
|
210
224
|
def select_one[*Ts](self, selector: Callable[[T], tuple[*Ts]], *, by: Optional[Enum] = JoinType.INNER_JOIN) -> tuple[*Ts]: ...
|
211
225
|
@overload
|
226
|
+
def select_one[T1](self, selector: Callable[[T], tuple[T1]], *, by: Optional[Enum] = JoinType.INNER_JOIN, flavour: Type) -> T1: ...
|
227
|
+
@overload
|
228
|
+
def select_one[T1, TFlavour](self, selector: Callable[[T], T1], *, by: Optional[Enum] = JoinType.INNER_JOIN, flavour: Type[TFlavour]) -> T1: ...
|
229
|
+
@overload
|
212
230
|
def select_one[*Ts](self, selector: Callable[[T], tuple[*Ts]], *, by: Optional[Enum] = JoinType.INNER_JOIN, flavour: Type[tuple]) -> tuple[*Ts]: ...
|
213
231
|
@overload
|
214
232
|
def select_one[TFlavour](self, selector: Callable[[T], tuple], *, by: Optional[Enum] = JoinType.INNER_JOIN, flavour: Type[TFlavour]) -> TFlavour: ...
|
@@ -1,4 +1,4 @@
|
|
1
1
|
from .IQueryCommand import IQuery # noqa: F401
|
2
2
|
from .INonQueryCommand import INonQueryCommand # noqa: F401
|
3
3
|
from .IRepositoryBase import IRepositoryBase # noqa: F401
|
4
|
-
from .IStatements import IStatements,IStatements_two_generic # noqa: F401
|
4
|
+
from .IStatements import IStatements, IStatements_two_generic # noqa: F401
|
@@ -1,9 +1,12 @@
|
|
1
|
+
from __future__ import annotations
|
1
2
|
from abc import abstractmethod
|
3
|
+
from typing import TYPE_CHECKING
|
4
|
+
|
5
|
+
if TYPE_CHECKING:
|
6
|
+
from ormlambda import Table, IRepositoryBase
|
7
|
+
from ormlambda.common.abstract_classes import NonQueryBase
|
2
8
|
|
3
9
|
from .IDelete import IDelete
|
4
|
-
from ...utils import Table
|
5
|
-
from ...common.interfaces import IRepositoryBase
|
6
|
-
from ...common.abstract_classes import NonQueryBase
|
7
10
|
|
8
11
|
|
9
12
|
class DeleteQueryBase[T: Table, TRepo: IRepositoryBase](NonQueryBase[T, TRepo], IDelete[T]):
|
@@ -1,12 +1,16 @@
|
|
1
|
+
from __future__ import annotations
|
1
2
|
from abc import abstractmethod
|
2
|
-
from
|
3
|
+
from typing import TYPE_CHECKING
|
3
4
|
|
5
|
+
if TYPE_CHECKING:
|
6
|
+
from ormlambda import Table
|
7
|
+
from ormlambda import IRepositoryBase
|
8
|
+
|
9
|
+
from ormlambda.common.abstract_classes import NonQueryBase
|
4
10
|
from .IInsert import IInsert
|
5
|
-
from ...common.interfaces import IRepositoryBase
|
6
|
-
from ...common.abstract_classes import NonQueryBase
|
7
11
|
|
8
12
|
|
9
|
-
class InsertQueryBase[T: Table, TRepo: IRepositoryBase](NonQueryBase[T,
|
13
|
+
class InsertQueryBase[T: Table, TRepo: IRepositoryBase](NonQueryBase[T, TRepo], IInsert[T]):
|
10
14
|
def __init__(self, model: T, repository: TRepo) -> None:
|
11
15
|
super().__init__(model, repository)
|
12
16
|
|
@@ -1,2 +1,2 @@
|
|
1
1
|
from .abstract_update import UpdateQueryBase # noqa: F401
|
2
|
-
from .IUpdate import IUpdate # noqa: F401
|
2
|
+
from .IUpdate import IUpdate # noqa: F401
|
@@ -1,11 +1,15 @@
|
|
1
|
+
from __future__ import annotations
|
1
2
|
from abc import abstractmethod
|
2
|
-
from typing import Any, Optional
|
3
|
+
from typing import Any, Optional, TYPE_CHECKING
|
4
|
+
|
5
|
+
from ormlambda.components.where import AbstractWhere
|
6
|
+
from ormlambda.common.abstract_classes import NonQueryBase
|
7
|
+
|
8
|
+
if TYPE_CHECKING:
|
9
|
+
from ormlambda import IRepositoryBase
|
10
|
+
from ormlambda import Table
|
3
11
|
|
4
12
|
from .IUpdate import IUpdate
|
5
|
-
from ..where import AbstractWhere
|
6
|
-
from ...common.interfaces import IRepositoryBase
|
7
|
-
from ...common.abstract_classes import NonQueryBase
|
8
|
-
from ...utils import Table
|
9
13
|
|
10
14
|
|
11
15
|
class UpdateQueryBase[T: Table, TRepo: IRepositoryBase](NonQueryBase[T, TRepo], IUpdate):
|
@@ -1,2 +1,2 @@
|
|
1
1
|
from .abstract_upsert import UpsertQueryBase # noqa: F401
|
2
|
-
from .IUpsert import IUpsert # noqa: F401
|
2
|
+
from .IUpsert import IUpsert # noqa: F401
|