ormlambda 2.11.1__py3-none-any.whl → 3.7.0__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 +11 -9
- ormlambda/caster/__init__.py +3 -0
- ormlambda/caster/base_caster.py +69 -0
- ormlambda/caster/caster.py +48 -0
- ormlambda/caster/interfaces/ICaster.py +26 -0
- ormlambda/caster/interfaces/__init__.py +1 -0
- ormlambda/common/__init__.py +1 -1
- ormlambda/common/abstract_classes/__init__.py +3 -3
- ormlambda/common/abstract_classes/decomposition_query.py +117 -315
- ormlambda/common/abstract_classes/non_query_base.py +1 -1
- ormlambda/common/enums/condition_types.py +2 -1
- ormlambda/common/enums/join_type.py +4 -1
- ormlambda/common/errors/__init__.py +15 -2
- ormlambda/common/global_checker.py +28 -0
- ormlambda/common/interfaces/ICustomAlias.py +4 -1
- ormlambda/common/interfaces/IDecompositionQuery.py +9 -34
- ormlambda/common/interfaces/IJoinSelector.py +21 -0
- ormlambda/common/interfaces/__init__.py +4 -6
- ormlambda/components/__init__.py +4 -0
- ormlambda/components/insert/abstract_insert.py +1 -1
- ormlambda/components/select/ISelect.py +17 -0
- ormlambda/components/select/__init__.py +1 -0
- ormlambda/components/update/abstract_update.py +4 -4
- ormlambda/components/upsert/abstract_upsert.py +1 -1
- ormlambda/databases/__init__.py +5 -0
- ormlambda/databases/my_sql/__init__.py +3 -1
- ormlambda/databases/my_sql/caster/__init__.py +1 -0
- ormlambda/databases/my_sql/caster/caster.py +38 -0
- ormlambda/databases/my_sql/caster/read.py +39 -0
- ormlambda/databases/my_sql/caster/types/__init__.py +8 -0
- ormlambda/databases/my_sql/caster/types/bytes.py +31 -0
- ormlambda/databases/my_sql/caster/types/datetime.py +34 -0
- ormlambda/databases/my_sql/caster/types/float.py +31 -0
- ormlambda/databases/my_sql/caster/types/int.py +31 -0
- ormlambda/databases/my_sql/caster/types/iterable.py +31 -0
- ormlambda/databases/my_sql/caster/types/none.py +30 -0
- ormlambda/databases/my_sql/caster/types/point.py +43 -0
- ormlambda/databases/my_sql/caster/types/string.py +31 -0
- ormlambda/databases/my_sql/caster/write.py +37 -0
- ormlambda/databases/my_sql/clauses/ST_AsText.py +36 -0
- ormlambda/databases/my_sql/clauses/ST_Contains.py +31 -0
- ormlambda/databases/my_sql/clauses/__init__.py +6 -4
- ormlambda/databases/my_sql/clauses/alias.py +24 -21
- ormlambda/databases/my_sql/clauses/count.py +32 -28
- ormlambda/databases/my_sql/clauses/create_database.py +3 -4
- ormlambda/databases/my_sql/clauses/delete.py +10 -10
- ormlambda/databases/my_sql/clauses/drop_database.py +3 -5
- ormlambda/databases/my_sql/clauses/drop_table.py +3 -3
- ormlambda/databases/my_sql/clauses/group_by.py +4 -7
- ormlambda/databases/my_sql/clauses/insert.py +33 -19
- ormlambda/databases/my_sql/clauses/joins.py +66 -59
- 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 +36 -23
- ormlambda/databases/my_sql/clauses/select.py +25 -36
- ormlambda/databases/my_sql/clauses/update.py +38 -13
- ormlambda/databases/my_sql/clauses/upsert.py +2 -2
- ormlambda/databases/my_sql/clauses/where.py +45 -0
- ormlambda/databases/my_sql/functions/concat.py +24 -27
- ormlambda/databases/my_sql/functions/max.py +32 -28
- ormlambda/databases/my_sql/functions/min.py +32 -28
- ormlambda/databases/my_sql/functions/sum.py +32 -28
- ormlambda/databases/my_sql/join_context.py +75 -0
- ormlambda/databases/my_sql/repository/__init__.py +1 -0
- ormlambda/databases/my_sql/{repository.py → repository/repository.py} +104 -73
- ormlambda/databases/my_sql/statements.py +231 -153
- ormlambda/engine/__init__.py +0 -0
- ormlambda/engine/template.py +47 -0
- ormlambda/model/__init__.py +0 -0
- ormlambda/model/base_model.py +37 -0
- ormlambda/repository/__init__.py +2 -0
- ormlambda/repository/base_repository.py +14 -0
- ormlambda/repository/interfaces/IDatabaseConnection.py +12 -0
- ormlambda/{common → repository}/interfaces/IRepositoryBase.py +6 -5
- ormlambda/repository/interfaces/__init__.py +2 -0
- ormlambda/sql/__init__.py +3 -0
- ormlambda/sql/clause_info/__init__.py +3 -0
- ormlambda/sql/clause_info/clause_info.py +434 -0
- ormlambda/sql/clause_info/clause_info_context.py +87 -0
- ormlambda/sql/clause_info/interface/IAggregate.py +10 -0
- ormlambda/sql/clause_info/interface/__init__.py +1 -0
- ormlambda/sql/column.py +126 -0
- ormlambda/sql/comparer.py +156 -0
- ormlambda/sql/foreign_key.py +115 -0
- ormlambda/sql/interfaces/__init__.py +0 -0
- ormlambda/sql/table/__init__.py +1 -0
- ormlambda/{utils → sql/table}/fields.py +6 -5
- ormlambda/{utils → sql/table}/table_constructor.py +43 -91
- ormlambda/sql/types.py +25 -0
- ormlambda/statements/__init__.py +2 -0
- ormlambda/statements/base_statement.py +129 -0
- ormlambda/statements/interfaces/IStatements.py +309 -0
- ormlambda/statements/interfaces/__init__.py +1 -0
- ormlambda/statements/types.py +51 -0
- ormlambda/utils/__init__.py +1 -3
- ormlambda/utils/module_tree/__init__.py +1 -0
- ormlambda/utils/module_tree/dynamic_module.py +20 -14
- {ormlambda-2.11.1.dist-info → ormlambda-3.7.0.dist-info}/METADATA +132 -68
- ormlambda-3.7.0.dist-info/RECORD +117 -0
- ormlambda/common/abstract_classes/abstract_model.py +0 -115
- ormlambda/common/interfaces/IAggregate.py +0 -10
- ormlambda/common/interfaces/IStatements.py +0 -348
- ormlambda/components/where/__init__.py +0 -1
- ormlambda/components/where/abstract_where.py +0 -15
- ormlambda/databases/my_sql/clauses/where_condition.py +0 -222
- ormlambda/model_base.py +0 -36
- ormlambda/utils/column.py +0 -105
- ormlambda/utils/foreign_key.py +0 -81
- ormlambda/utils/lambda_disassembler/__init__.py +0 -4
- ormlambda/utils/lambda_disassembler/dis_types.py +0 -133
- ormlambda/utils/lambda_disassembler/disassembler.py +0 -69
- ormlambda/utils/lambda_disassembler/dtypes.py +0 -103
- ormlambda/utils/lambda_disassembler/name_of.py +0 -41
- ormlambda/utils/lambda_disassembler/nested_element.py +0 -44
- ormlambda/utils/lambda_disassembler/tree_instruction.py +0 -145
- ormlambda-2.11.1.dist-info/RECORD +0 -81
- /ormlambda/{utils → sql}/dtypes.py +0 -0
- {ormlambda-2.11.1.dist-info → ormlambda-3.7.0.dist-info}/LICENSE +0 -0
- {ormlambda-2.11.1.dist-info → ormlambda-3.7.0.dist-info}/WHEEL +0 -0
@@ -1,348 +0,0 @@
|
|
1
|
-
from __future__ import annotations
|
2
|
-
from typing import Any, Callable, Iterable, Optional, Literal, Type, Union, overload, TYPE_CHECKING
|
3
|
-
from enum import Enum
|
4
|
-
from abc import abstractmethod, ABC
|
5
|
-
import enum
|
6
|
-
|
7
|
-
from .IRepositoryBase import IRepositoryBase
|
8
|
-
from ormlambda.common.enums import JoinType
|
9
|
-
|
10
|
-
if TYPE_CHECKING:
|
11
|
-
from ormlambda import Table
|
12
|
-
from .IAggregate import IAggregate
|
13
|
-
|
14
|
-
|
15
|
-
class OrderType(enum.Enum):
|
16
|
-
ASC = "ASC"
|
17
|
-
DESC = "DESC"
|
18
|
-
|
19
|
-
|
20
|
-
type OrderTypes = Literal["ASC", "DESC"] | OrderType | Iterable[OrderType]
|
21
|
-
|
22
|
-
|
23
|
-
type Tuple[T] = tuple[T, ...]
|
24
|
-
|
25
|
-
type SelectRes1[T1] = tuple[Tuple[T1]]
|
26
|
-
type SelectRes2[T1, T2] = tuple[*SelectRes1[T1], Tuple[T2]]
|
27
|
-
type SelectRes3[T1, T2, T3] = tuple[*SelectRes2[T1, T2], Tuple[T3]]
|
28
|
-
type SelectRes4[T1, T2, T3, T4] = tuple[*SelectRes3[T1, T2, T3], Tuple[T4]]
|
29
|
-
type SelectRes5[T1, T2, T3, T4, T5] = tuple[*SelectRes4[T1, T2, T3, T4], Tuple[T5]]
|
30
|
-
type SelectRes6[T1, T2, T3, T4, T5, T6] = tuple[*SelectRes5[T1, T2, T3, T4, T5], Tuple[T6]]
|
31
|
-
type SelectRes7[T1, T2, T3, T4, T5, T6, T7] = tuple[*SelectRes6[T1, T2, T3, T4, T5, T6], Tuple[T7]]
|
32
|
-
type SelectRes8[T1, T2, T3, T4, T5, T6, T7, T8] = tuple[*SelectRes7[T1, T2, T3, T4, T5, T6, T7], Tuple[T8]]
|
33
|
-
type SelectRes9[T1, T2, T3, T4, T5, T6, T7, T8, T9] = tuple[*SelectRes8[T1, T2, T3, T4, T5, T6, T7, T8], Tuple[T9]]
|
34
|
-
type SelectRes10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10] = tuple[*SelectRes9[T1, T2, T3, T4, T5, T6, T7, T8, T9], Tuple[T10]]
|
35
|
-
|
36
|
-
|
37
|
-
type WhereCondition[T, T1] = Callable[[T, T1], bool]
|
38
|
-
type JoinCondition[T, T1] = tuple[T1, WhereCondition[T, T1], Optional[JoinType]]
|
39
|
-
|
40
|
-
type TupleJoins1[T, T1] = tuple[JoinCondition[T, T1]]
|
41
|
-
type TupleJoins2[T, T1, T2] = tuple[*TupleJoins1[T, T1], JoinCondition[T, T2]]
|
42
|
-
type TupleJoins3[T, T1, T2, T3] = tuple[*TupleJoins2[T, T1, T2], JoinCondition[T, T3]]
|
43
|
-
type TupleJoins4[T, T1, T2, T3, T4] = tuple[*TupleJoins3[T, T1, T2, T3], JoinCondition[T, T4]]
|
44
|
-
type TupleJoins5[T, T1, T2, T3, T4, T5] = tuple[*TupleJoins4[T, T1, T2, T3, T4], JoinCondition[T, T5]]
|
45
|
-
type TupleJoins6[T, T1, T2, T3, T4, T5, T6] = tuple[*TupleJoins5[T, T1, T2, T3, T4, T5], JoinCondition[T, T6]]
|
46
|
-
|
47
|
-
|
48
|
-
# TODOH: This var is duplicated from 'src\ormlambda\databases\my_sql\clauses\create_database.py'
|
49
|
-
TypeExists = Literal["fail", "replace", "append"]
|
50
|
-
|
51
|
-
type WhereTypes[T, *Ts] = Union[Callable[[T, *Ts], bool], Iterable[Callable[[T, *Ts], bool]]]
|
52
|
-
|
53
|
-
|
54
|
-
class IStatements[T, *Ts](ABC):
|
55
|
-
@abstractmethod
|
56
|
-
def create_table(self, if_exists: TypeExists) -> None: ...
|
57
|
-
|
58
|
-
# #TODOL [ ]: We must to implement this mehtod
|
59
|
-
# @abstractmethod
|
60
|
-
# def drop_table(self)->None: ...
|
61
|
-
|
62
|
-
@abstractmethod
|
63
|
-
def table_exists(self) -> bool: ...
|
64
|
-
|
65
|
-
# region insert
|
66
|
-
@overload
|
67
|
-
def insert(self, values: T) -> None:
|
68
|
-
"""
|
69
|
-
PARAMS
|
70
|
-
------
|
71
|
-
- values: Recieves a single object that must match the model's type
|
72
|
-
"""
|
73
|
-
...
|
74
|
-
|
75
|
-
@overload
|
76
|
-
def insert(self, values: list[T]) -> None:
|
77
|
-
"""
|
78
|
-
PARAMS
|
79
|
-
------
|
80
|
-
- values: Recieves a list of the same objects as the model
|
81
|
-
"""
|
82
|
-
...
|
83
|
-
|
84
|
-
@abstractmethod
|
85
|
-
def insert(self, values: T | list[T]) -> None: ...
|
86
|
-
|
87
|
-
# endregion
|
88
|
-
# region upsert
|
89
|
-
@overload
|
90
|
-
def upsert(self, values: T) -> None:
|
91
|
-
"""
|
92
|
-
PARAMS
|
93
|
-
------
|
94
|
-
- values: Recieves a single object that must match the model's type
|
95
|
-
"""
|
96
|
-
...
|
97
|
-
|
98
|
-
@overload
|
99
|
-
def upsert(self, values: list[T]) -> None:
|
100
|
-
"""
|
101
|
-
PARAMS
|
102
|
-
------
|
103
|
-
- values: Recieves a list of the same objects as the model
|
104
|
-
"""
|
105
|
-
...
|
106
|
-
|
107
|
-
@abstractmethod
|
108
|
-
def upsert(self, values: list[T]) -> None:
|
109
|
-
"""
|
110
|
-
Try to insert new values in the table, if they exist, update them
|
111
|
-
"""
|
112
|
-
...
|
113
|
-
|
114
|
-
@abstractmethod
|
115
|
-
def update(self, dicc: dict[str | property, Any]) -> None: ...
|
116
|
-
|
117
|
-
# endregion
|
118
|
-
# region limit
|
119
|
-
@abstractmethod
|
120
|
-
def limit(self, number: int) -> IStatements[T]: ...
|
121
|
-
|
122
|
-
# endregion
|
123
|
-
# region offset
|
124
|
-
@abstractmethod
|
125
|
-
def offset(self, number: int) -> IStatements[T]: ...
|
126
|
-
|
127
|
-
# endregion
|
128
|
-
# region count
|
129
|
-
@abstractmethod
|
130
|
-
def count(
|
131
|
-
self,
|
132
|
-
selection: Callable[[T], property],
|
133
|
-
alias: bool = ...,
|
134
|
-
alias_name: Optional[str] = ...,
|
135
|
-
) -> int: ...
|
136
|
-
|
137
|
-
# endregion
|
138
|
-
# region delete
|
139
|
-
@overload
|
140
|
-
def delete(self) -> None: ...
|
141
|
-
|
142
|
-
@overload
|
143
|
-
def delete(self, instance: T) -> None: ...
|
144
|
-
|
145
|
-
@overload
|
146
|
-
def delete(self, instance: list[T]) -> None: ...
|
147
|
-
@abstractmethod
|
148
|
-
def delete(self, instance: Optional[T | list[T]] = ...) -> None: ...
|
149
|
-
|
150
|
-
# endregion
|
151
|
-
|
152
|
-
# region where
|
153
|
-
@overload
|
154
|
-
def where(self, conditions: Iterable[Callable[[T, *Ts], bool]]) -> IStatements[T, *Ts]:
|
155
|
-
"""
|
156
|
-
This method creates where clause by passing the Iterable in lambda function
|
157
|
-
EXAMPLE
|
158
|
-
-
|
159
|
-
mb = BaseModel()
|
160
|
-
mb.where(lambda a: (a.city, ConditionType.REGEXP, r"^B"))
|
161
|
-
"""
|
162
|
-
...
|
163
|
-
|
164
|
-
@overload
|
165
|
-
def where(self, conditions: Callable[[T, *Ts], bool], **kwargs) -> IStatements[T, *Ts]:
|
166
|
-
"""
|
167
|
-
PARAM
|
168
|
-
-
|
169
|
-
|
170
|
-
-kwargs: Use this when you need to replace variables inside a lambda method. When working with lambda methods, all variables will be replaced by their own variable names. To avoid this, we need to pass key-value parameters to specify which variables we want to replace with their values.
|
171
|
-
|
172
|
-
EXAMPLE
|
173
|
-
-
|
174
|
-
mb = BaseModel()
|
175
|
-
|
176
|
-
external_data = "
|
177
|
-
mb.where(lambda a: a.city_id > external_data)
|
178
|
-
"""
|
179
|
-
...
|
180
|
-
|
181
|
-
@abstractmethod
|
182
|
-
def where(self, conditions: WhereTypes[T, *Ts] = lambda: None, **kwargs) -> IStatements[T, *Ts]: ...
|
183
|
-
|
184
|
-
# endregion
|
185
|
-
# region order
|
186
|
-
@overload
|
187
|
-
def order[TValue](self, _lambda_col: Callable[[T], TValue]) -> IStatements[T]: ...
|
188
|
-
@overload
|
189
|
-
def order[TValue](self, _lambda_col: Callable[[T], TValue], order_type: OrderTypes) -> IStatements[T]: ...
|
190
|
-
@abstractmethod
|
191
|
-
def order[TValue](self, _lambda_col: Callable[[T], TValue], order_type: OrderTypes) -> IStatements[T]: ...
|
192
|
-
|
193
|
-
# endregion
|
194
|
-
# region concat
|
195
|
-
@overload
|
196
|
-
def concat[*Ts](self, selector: Callable[[T], tuple[*Ts]]) -> IAggregate[T]: ...
|
197
|
-
|
198
|
-
# endregion
|
199
|
-
# region max
|
200
|
-
@overload
|
201
|
-
def max[TProp](
|
202
|
-
self,
|
203
|
-
column: Callable[[T], TProp],
|
204
|
-
alias: bool = ...,
|
205
|
-
alias_name: Optional[str] = ...,
|
206
|
-
) -> TProp: ...
|
207
|
-
# endregion
|
208
|
-
# region min
|
209
|
-
@overload
|
210
|
-
def min[TProp](
|
211
|
-
self,
|
212
|
-
column: Callable[[T], TProp],
|
213
|
-
alias: bool = ...,
|
214
|
-
alias_name: Optional[str] = ...,
|
215
|
-
) -> TProp: ...
|
216
|
-
# endregion
|
217
|
-
# region sum
|
218
|
-
@overload
|
219
|
-
def sum[TProp](
|
220
|
-
self,
|
221
|
-
column: Callable[[T], TProp],
|
222
|
-
alias: bool = ...,
|
223
|
-
alias_name: Optional[str] = ...,
|
224
|
-
) -> TProp: ...
|
225
|
-
|
226
|
-
# endregion
|
227
|
-
# region join
|
228
|
-
|
229
|
-
@overload
|
230
|
-
def join[T1](self, table: T1, relation: WhereCondition[T, T1], join_type: Optional[JoinType]) -> IStatements[T, T1]: ...
|
231
|
-
@overload
|
232
|
-
def join[T1](self, table: JoinCondition[T, T1]) -> IStatements[T, T1]: ...
|
233
|
-
@overload
|
234
|
-
def join[T1](self, table: TupleJoins1[T, T1]) -> IStatements[T, T1]: ...
|
235
|
-
@overload
|
236
|
-
def join[T1, T2](self, table: TupleJoins2[T, T1, T2]) -> IStatements[T, T1, T2]: ...
|
237
|
-
@overload
|
238
|
-
def join[T1, T2, T3](self, table: TupleJoins3[T, T1, T2, T3]) -> IStatements[T, T1, T2, T3]: ...
|
239
|
-
@overload
|
240
|
-
def join[T1, T2, T3, T4](self, table: TupleJoins4[T, T1, T2, T3, T4]) -> IStatements[T, T1, T2, T3, T4]: ...
|
241
|
-
@overload
|
242
|
-
def join[T1, T2, T3, T4, T5](self, table: TupleJoins5[T, T1, T2, T3, T4, T5]) -> IStatements[T, T1, T2, T3, T4, T5]: ...
|
243
|
-
@overload
|
244
|
-
def join[T1, T2, T3, T4, T5, T6](self, table: TupleJoins6[T, T1, T2, T3, T4, T5, T6]) -> IStatements[T, T1, T2, T3, T4, T5, T6]: ...
|
245
|
-
|
246
|
-
@abstractmethod
|
247
|
-
def join[*FKTables](
|
248
|
-
self,
|
249
|
-
table: Optional[T] = ...,
|
250
|
-
relation: Optional[WhereCondition[T, FKTables]] = ...,
|
251
|
-
join_type: Optional[JoinType] = ...,
|
252
|
-
) -> IStatements[T, *FKTables]: ...
|
253
|
-
|
254
|
-
# endregion
|
255
|
-
# region select
|
256
|
-
@overload
|
257
|
-
def select(self) -> SelectRes1[T]: ...
|
258
|
-
@overload
|
259
|
-
def select[T1](self, selector: Callable[[T], T1], *, by: Optional[Enum] = ...) -> SelectRes1[T1]: ...
|
260
|
-
@overload
|
261
|
-
def select[T1](self, selector: Callable[[T], tuple[T1]], *, by: Optional[Enum] = ...) -> SelectRes1[T1]: ...
|
262
|
-
@overload
|
263
|
-
def select[T1, T2](self, selector: Callable[[T, *Ts], tuple[T1, T2]], *, by: Optional[Enum] = ...) -> SelectRes2[T1, T2]: ...
|
264
|
-
@overload
|
265
|
-
def select[T1, T2, T3](self, selector: Callable[[T, *Ts], tuple[T1, T2, T3]], *, by: Optional[Enum] = ...) -> SelectRes3[T1, T2, T3]: ...
|
266
|
-
@overload
|
267
|
-
def select[T1, T2, T3, T4](self, selector: Callable[[T, *Ts], tuple[T1, T2, T3, T4]], *, by: Optional[Enum] = ...) -> SelectRes4[T1, T2, T3, T4]: ...
|
268
|
-
@overload
|
269
|
-
def select[T1, T2, T3, T4, T5](self, selector: Callable[[T, *Ts], tuple[T1, T2, T3, T4, T5]], *, by: Optional[Enum] = ...) -> SelectRes5[T1, T2, T3, T4, T5]: ...
|
270
|
-
@overload
|
271
|
-
def select[T1, T2, T3, T4, T5, T6](self, selector: Callable[[T, *Ts], tuple[T1, T2, T3, T4, T5, T6]], *, by: Optional[Enum] = ...) -> SelectRes6[T1, T2, T3, T4, T5, T6]: ...
|
272
|
-
@overload
|
273
|
-
def select[T1, T2, T3, T4, T5, T6, T7](self, selector: Callable[[T, *Ts], tuple[T1, T2, T3, T4, T5, T6, T7]], *, by: Optional[Enum] = ...) -> SelectRes7[T1, T2, T3, T4, T5, T6, T7]: ...
|
274
|
-
@overload
|
275
|
-
def select[T1, T2, T3, T4, T5, T6, T7, T8](self, selector: Callable[[T, *Ts], tuple[T1, T2, T3, T4, T5, T6, T7, T8]], *, by: Optional[Enum] = ...) -> SelectRes8[T1, T2, T3, T4, T5, T6, T7, T8]: ...
|
276
|
-
@overload
|
277
|
-
def select[T1, T2, T3, T4, T5, T6, T7, T8, T9](self, selector: Callable[[T, *Ts], tuple[T1, T2, T3, T4, T5, T6, T7, T8, T9]], *, by: Optional[Enum] = ...) -> SelectRes9[T1, T2, T3, T4, T5, T6, T7, T8, T9]: ...
|
278
|
-
@overload
|
279
|
-
def select[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10](self, selector: Callable[[T, *Ts], tuple[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]], *, by: Optional[Enum] = ...) -> SelectRes10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]: ...
|
280
|
-
|
281
|
-
@overload
|
282
|
-
def select[TFlavour](self, selector: Optional[Callable[[T, *Ts], tuple]] = ..., *, cast_to_tuple: bool = ..., flavour: Type[TFlavour], by: Optional[Enum] = ..., **kwargs) -> TFlavour: ...
|
283
|
-
@overload
|
284
|
-
def select[TRes](self, selector: Optional[Callable[[T, *Ts], TRes]] = ..., *, flavour: Type[tuple], by: Optional[Enum] = ..., **kwargs) -> tuple[TRes, ...]: ...
|
285
|
-
@overload
|
286
|
-
def select[TRes](self, selector: Optional[Callable[[T, *Ts], tuple[TRes]]] = ..., *, flavour: Type[tuple], by: Optional[Enum] = ..., **kwargs) -> tuple[TRes, ...]: ...
|
287
|
-
@overload
|
288
|
-
def select[*TRes](self, selector: Optional[Callable[[T, *Ts], tuple[*TRes]]] = ..., *, flavour: Type[tuple], by: Optional[Enum] = ..., **kwargs) -> tuple[tuple[*TRes]]: ...
|
289
|
-
@overload
|
290
|
-
def select[TFlavour](self, selector: Optional[Callable[[T, *Ts], tuple]] = ..., *, flavour: Type[TFlavour], by: Optional[Enum] = ..., **kwargs) -> tuple[TFlavour]: ...
|
291
|
-
|
292
|
-
@abstractmethod
|
293
|
-
def select[TValue, TFlavour, *Ts](self, selector: Optional[Callable[[T, *Ts], tuple[TValue, *Ts]]] = ..., *, cast_to_tuple: bool = ..., flavour: Type[TFlavour] = ..., by: JoinType = ..., **kwargs): ...
|
294
|
-
|
295
|
-
# endregion
|
296
|
-
# region select_one
|
297
|
-
@overload
|
298
|
-
def select_one(self) -> T: ...
|
299
|
-
@overload
|
300
|
-
def select_one[TFlavour](self, *, by: Optional[Enum] = ..., flavour: Type[TFlavour]) -> TFlavour: ...
|
301
|
-
@overload
|
302
|
-
def select_one[T1](self, selector: Callable[[T, *Ts], tuple[T1]], *, by: Optional[Enum] = ...) -> T1: ...
|
303
|
-
@overload
|
304
|
-
def select_one[*TRes](self, selector: Callable[[T, *Ts], tuple[*TRes]], *, by: Optional[Enum] = ...) -> tuple[*TRes]: ...
|
305
|
-
@overload
|
306
|
-
def select_one[T1](self, selector: Callable[[T, *Ts], tuple[T1]], *, by: Optional[Enum] = ..., flavour: Type) -> T1: ...
|
307
|
-
@overload
|
308
|
-
def select_one[T1, TFlavour](self, selector: Callable[[T, *Ts], T1], *, by: Optional[Enum] = ..., flavour: Type[TFlavour]) -> T1: ...
|
309
|
-
@overload
|
310
|
-
def select_one[*Ts](self, selector: Callable[[T, *Ts], tuple[*Ts]], *, by: Optional[Enum] = ..., flavour: Type[tuple]) -> tuple[*Ts]: ...
|
311
|
-
@overload
|
312
|
-
def select_one[TFlavour](self, selector: Callable[[T, *Ts], tuple], *, by: Optional[Enum] = ..., flavour: Type[TFlavour]) -> TFlavour: ...
|
313
|
-
@abstractmethod
|
314
|
-
def select_one[TValue, TFlavour, *Ts](
|
315
|
-
self,
|
316
|
-
selector: Optional[Callable[[T, *Ts], tuple[TValue, *Ts]]] = lambda: None,
|
317
|
-
*,
|
318
|
-
flavour: Type[TFlavour] = ...,
|
319
|
-
by: Optional[Enum] = ...,
|
320
|
-
): ...
|
321
|
-
|
322
|
-
# endregion
|
323
|
-
# region group_by
|
324
|
-
@abstractmethod
|
325
|
-
def group_by[TRepo](self, column: Callable[[T, *Ts], TRepo]) -> IStatements[T, *Ts]: ...
|
326
|
-
|
327
|
-
# endregion
|
328
|
-
|
329
|
-
@abstractmethod
|
330
|
-
def _build(self) -> str: ...
|
331
|
-
|
332
|
-
@abstractmethod
|
333
|
-
def alias(self, column: Callable[[T, *Ts], Any], alias: str) -> IStatements[T, *Ts]: ...
|
334
|
-
|
335
|
-
|
336
|
-
class IStatements_two_generic[T: Table, *Ts, TRepo](IStatements[T, *Ts]):
|
337
|
-
@property
|
338
|
-
@abstractmethod
|
339
|
-
def repository(self) -> IRepositoryBase[TRepo]: ...
|
340
|
-
|
341
|
-
@property
|
342
|
-
def query(self) -> str: ...
|
343
|
-
|
344
|
-
@property
|
345
|
-
def model(self) -> Type[T]: ...
|
346
|
-
|
347
|
-
@property
|
348
|
-
def models(self) -> tuple[*Ts]: ...
|
@@ -1 +0,0 @@
|
|
1
|
-
from .abstract_where import AbstractWhere # noqa: F401
|
@@ -1,15 +0,0 @@
|
|
1
|
-
from __future__ import annotations
|
2
|
-
from abc import abstractmethod
|
3
|
-
from typing import TYPE_CHECKING
|
4
|
-
|
5
|
-
if TYPE_CHECKING:
|
6
|
-
from ormlambda import Table
|
7
|
-
|
8
|
-
from ormlambda.common.interfaces import IQuery
|
9
|
-
|
10
|
-
|
11
|
-
class AbstractWhere(IQuery):
|
12
|
-
WHERE: str = "WHERE"
|
13
|
-
|
14
|
-
@abstractmethod
|
15
|
-
def get_involved_tables(self) -> tuple[tuple[Table, Table]]: ...
|
@@ -1,222 +0,0 @@
|
|
1
|
-
from typing import Any, Callable, Optional, override, Type
|
2
|
-
import inspect
|
3
|
-
|
4
|
-
from ormlambda.common.enums import ConditionType
|
5
|
-
from ormlambda.utils.lambda_disassembler.tree_instruction import TreeInstruction, TupleInstruction
|
6
|
-
from ormlambda.common.interfaces.IQueryCommand import IQuery
|
7
|
-
from ormlambda.components.where.abstract_where import AbstractWhere
|
8
|
-
from ormlambda.common.errors import UnmatchedLambdaParameterError
|
9
|
-
from ormlambda import Table
|
10
|
-
|
11
|
-
|
12
|
-
class WhereConditionByArg[TProp1, TProp2](IQuery):
|
13
|
-
def __init__(self, cond1: TProp1, cond2: TProp2, symbol: ConditionType) -> None:
|
14
|
-
self.cond1: TProp1 = cond1
|
15
|
-
self.cond2: TProp2 = cond2
|
16
|
-
self.symbol: ConditionType = symbol
|
17
|
-
|
18
|
-
@property
|
19
|
-
def query(self) -> str:
|
20
|
-
return f"WHERE {self.cond1} {self.symbol.value} {self.cond2}"
|
21
|
-
|
22
|
-
|
23
|
-
class WhereCondition[T: Type[Table], *Inst](AbstractWhere):
|
24
|
-
"""
|
25
|
-
The purpose of this class is to create 'WHERE' condition queries properly.
|
26
|
-
|
27
|
-
Args.
|
28
|
-
- instances: tuple[*Inst],
|
29
|
-
- passed all instance that we are going to use inside of `function` arg
|
30
|
-
|
31
|
-
- function: Callable[[*Inst], bool] = lambda: None,
|
32
|
-
- lambda function to create condition between instance variables
|
33
|
-
- **kwargs: Any,
|
34
|
-
- We use this clause by passing all the variables that we want to replace inside the lambda function.
|
35
|
-
When we try to disassemble the lambda function, we see that the variables were not replaced by their values.
|
36
|
-
Instead, we only got the variable names, not the values.
|
37
|
-
Due to this problem, we need to specify the correct dictionary to map variable names to their values.
|
38
|
-
|
39
|
-
>>> var = 100
|
40
|
-
>>> _lambda = lambda a: a.city_id <= var
|
41
|
-
>>> ... #Dissamble _lambda method
|
42
|
-
>>> parts_of_lambda = [
|
43
|
-
>>> "city_id"
|
44
|
-
>>> "<="
|
45
|
-
>>> "var" <-------- We excepted 100
|
46
|
-
>>> ]
|
47
|
-
"""
|
48
|
-
|
49
|
-
__slots__ = [
|
50
|
-
"_instances",
|
51
|
-
"_function",
|
52
|
-
"_tree",
|
53
|
-
"_kwargs",
|
54
|
-
"_lambda_param_map",
|
55
|
-
]
|
56
|
-
|
57
|
-
def __init__(
|
58
|
-
self,
|
59
|
-
instances: tuple[*Inst],
|
60
|
-
function: Callable[[*Inst], bool] = lambda: None,
|
61
|
-
**kwargs: Any,
|
62
|
-
) -> None:
|
63
|
-
self._instances: tuple[Table] = instances
|
64
|
-
self._function: Callable[[*Inst], bool] = function
|
65
|
-
self._kwargs: dict[str, tuple[*Inst]] = kwargs
|
66
|
-
self._tree: TreeInstruction = TreeInstruction(function)
|
67
|
-
self._lambda_param_map: dict[str, Table] = self._create_lambda_param_map()
|
68
|
-
|
69
|
-
def _create_lambda_param_map(self) -> dict[str, Table]:
|
70
|
-
"""
|
71
|
-
The method is responsible for mapping the variables present in the lambda function so that they are replaced with the instance of the model Table.
|
72
|
-
"""
|
73
|
-
lamda_param = inspect.signature(self._function).parameters
|
74
|
-
if len(lamda_param) != (expected := len(self._instances)):
|
75
|
-
raise UnmatchedLambdaParameterError(expected, found_param=tuple(lamda_param))
|
76
|
-
|
77
|
-
_temp_instances = list(self._instances)[::-1] # we copied and translated tuple instance due to pop each value in order to param
|
78
|
-
new_dicc: dict[str, Table] = {}
|
79
|
-
for param in lamda_param.keys():
|
80
|
-
new_dicc[param] = _temp_instances.pop()
|
81
|
-
|
82
|
-
return new_dicc
|
83
|
-
|
84
|
-
@override
|
85
|
-
@property
|
86
|
-
def query(self) -> str:
|
87
|
-
if len(self._tree.compare_op) == 0:
|
88
|
-
return self._build_with_lambda_as_column_name()
|
89
|
-
return self._build_with_lambda_as_condition()
|
90
|
-
|
91
|
-
def _build_with_lambda_as_column_name(self) -> str:
|
92
|
-
conditions, compare_sign = self.create_conditions_list_and_compare_sign()
|
93
|
-
c1, c2 = conditions
|
94
|
-
return f"{self.WHERE} {c1} {compare_sign[0]} {c2}"
|
95
|
-
|
96
|
-
def _replace_values(self, ti: TupleInstruction) -> str:
|
97
|
-
instance: Any = self._kwargs[ti.var]
|
98
|
-
if isinstance(instance, Table):
|
99
|
-
data = getattr(instance, ti.nested_element.name)
|
100
|
-
else:
|
101
|
-
data = instance
|
102
|
-
|
103
|
-
return f"'{data}'" if isinstance(data, str) else data
|
104
|
-
|
105
|
-
def _build_with_lambda_as_condition(self) -> Callable[[], Any]:
|
106
|
-
n: int = len(self._tree.compare_op)
|
107
|
-
dicc_selector: dict[int, Callable[[], str]] = {
|
108
|
-
1: self.__one_sign,
|
109
|
-
2: self.__two_sign,
|
110
|
-
}
|
111
|
-
return dicc_selector[n]()
|
112
|
-
|
113
|
-
def __one_sign(self) -> str:
|
114
|
-
"""lambda x: x <= 10"""
|
115
|
-
(c1, c2), _ = self.create_conditions_list_and_compare_sign()
|
116
|
-
|
117
|
-
return f"{self.WHERE} {c1} {self._tree.compare_op[0]} {c2}"
|
118
|
-
|
119
|
-
def _get_table_for_tuple_instruction(self, ti: TupleInstruction) -> Optional[Table]:
|
120
|
-
if ti.var not in self._lambda_param_map:
|
121
|
-
return None
|
122
|
-
|
123
|
-
involved_tables: list[Table] = [self._lambda_param_map[ti.var]]
|
124
|
-
|
125
|
-
def get_attr_tbl(tbl: Table, class_var: str) -> Optional[Table]:
|
126
|
-
tbl_attrs = (tbl, class_var)
|
127
|
-
if hasattr(*tbl_attrs):
|
128
|
-
attr = getattr(*tbl_attrs)
|
129
|
-
|
130
|
-
if not isinstance(attr, property) and issubclass(attr, Table):
|
131
|
-
return attr
|
132
|
-
return None
|
133
|
-
|
134
|
-
for name in ti.nested_element.parents[1:]:
|
135
|
-
attr = get_attr_tbl(involved_tables[-1], name)
|
136
|
-
if attr is not None:
|
137
|
-
involved_tables.append(attr)
|
138
|
-
|
139
|
-
return involved_tables[-1].__table_name__
|
140
|
-
|
141
|
-
def __two_sign(self) -> str:
|
142
|
-
"""lambda x: 100 <= x <= 500"""
|
143
|
-
self.__valid_between_comparable_sign()
|
144
|
-
conds, _ = self.create_conditions_list_and_compare_sign()
|
145
|
-
c1, c2, c3 = conds
|
146
|
-
cond1 = WhereConditionByArg[str, str](c1, c2, ConditionType(self._tree.compare_op[0]))
|
147
|
-
cond2 = WhereConditionByArg[str, str](c2, c3, ConditionType(self._tree.compare_op[1]))
|
148
|
-
|
149
|
-
return WhereCondition.join_condition(cond1, cond2, restrictive=True)
|
150
|
-
|
151
|
-
def __valid_between_comparable_sign(self) -> bool:
|
152
|
-
if not len(self._tree.compare_op) == 2:
|
153
|
-
raise Exception("Number of comparable signs distinct from 2.")
|
154
|
-
return True
|
155
|
-
|
156
|
-
@classmethod
|
157
|
-
def join_condition(cls, *args: WhereConditionByArg, restrictive=False) -> str:
|
158
|
-
BY: str = "AND" if restrictive else "OR"
|
159
|
-
query: str = f"{cls.WHERE} "
|
160
|
-
|
161
|
-
n = len(args)
|
162
|
-
for i in range(n):
|
163
|
-
condition: IQuery = args[i]
|
164
|
-
query += "(" + condition.query.removeprefix(f"{cls.WHERE} ") + ")"
|
165
|
-
if i != n - 1:
|
166
|
-
query += f" {BY} "
|
167
|
-
|
168
|
-
return query
|
169
|
-
|
170
|
-
@override
|
171
|
-
def get_involved_tables(self) -> tuple[tuple[Table, Table]]:
|
172
|
-
return_involved_tables: list[tuple[Table, Table]] = []
|
173
|
-
involved_tables: list[Table] = [self._instances[0]]
|
174
|
-
|
175
|
-
def get_attr_tbl(instance: Table, tbl_name: str) -> Optional[Table]:
|
176
|
-
inst_tbl_name = (instance, tbl_name)
|
177
|
-
if hasattr(*inst_tbl_name):
|
178
|
-
attr = getattr(*inst_tbl_name)
|
179
|
-
|
180
|
-
if not isinstance(attr, property) and issubclass(attr, Table):
|
181
|
-
return attr
|
182
|
-
return None
|
183
|
-
|
184
|
-
tables: list[str] = self._tree.to_list()[0].nested_element.parents[1:] # Avoid lambda variable
|
185
|
-
for tbl_name in tables:
|
186
|
-
tbl = involved_tables[-1]
|
187
|
-
attr = get_attr_tbl(tbl, tbl_name)
|
188
|
-
if attr is not None:
|
189
|
-
involved_tables.append(attr)
|
190
|
-
return_involved_tables.append(tuple([tbl, attr]))
|
191
|
-
return tuple(return_involved_tables)
|
192
|
-
|
193
|
-
def create_conditions_list_and_compare_sign(self) -> tuple[list[str], list[str]]:
|
194
|
-
compare_sign: list[str] = []
|
195
|
-
conds: list[str] = []
|
196
|
-
for ti in self._tree.to_list():
|
197
|
-
key = ti.var
|
198
|
-
ne = ti.nested_element
|
199
|
-
|
200
|
-
if hasattr(ConditionType, str(ne.name)):
|
201
|
-
cond_type: ConditionType = getattr(ConditionType, ne.name)
|
202
|
-
compare_sign.append(cond_type.value)
|
203
|
-
|
204
|
-
elif key in self._kwargs:
|
205
|
-
conds.append(self._replace_values(ti))
|
206
|
-
else:
|
207
|
-
_name_table = self._get_table_for_tuple_instruction(ti)
|
208
|
-
_name_table_str = f"{_name_table}." if _name_table else ""
|
209
|
-
|
210
|
-
_name = ne.name
|
211
|
-
if not _name_table:
|
212
|
-
_name = self._wrapp_condition_id_str(ne.name)
|
213
|
-
|
214
|
-
conds.append(f"{_name_table_str}{_name}")
|
215
|
-
return conds, compare_sign
|
216
|
-
|
217
|
-
def _wrapp_condition_id_str(self, name: Any):
|
218
|
-
if not name:
|
219
|
-
return "NULL"
|
220
|
-
if not isinstance(name, str):
|
221
|
-
return name
|
222
|
-
return f"'{name}'"
|
ormlambda/model_base.py
DELETED
@@ -1,36 +0,0 @@
|
|
1
|
-
from typing import Type
|
2
|
-
|
3
|
-
|
4
|
-
from .utils import Table
|
5
|
-
from .common.interfaces import IRepositoryBase, IStatements_two_generic
|
6
|
-
from .common.abstract_classes import AbstractSQLStatements
|
7
|
-
from .databases.my_sql import MySQLStatements, MySQLRepository
|
8
|
-
|
9
|
-
|
10
|
-
# endregion
|
11
|
-
|
12
|
-
|
13
|
-
class BaseModel[T: Type[Table], *Ts]:
|
14
|
-
"""
|
15
|
-
Class to select the correct AbstractSQLStatements class depends on the repository.
|
16
|
-
|
17
|
-
Contiene los metodos necesarios para hacer consultas a una tabla
|
18
|
-
"""
|
19
|
-
|
20
|
-
statements_dicc: dict[Type[IRepositoryBase], Type[AbstractSQLStatements[T, *Ts, IRepositoryBase]]] = {
|
21
|
-
MySQLRepository: MySQLStatements,
|
22
|
-
}
|
23
|
-
|
24
|
-
# region Constructor
|
25
|
-
|
26
|
-
def __new__[TRepo](cls, model: tuple[T, *Ts], repository: IRepositoryBase[TRepo]) -> IStatements_two_generic[T, *Ts, TRepo]:
|
27
|
-
if repository is None:
|
28
|
-
raise ValueError("`None` cannot be passed to the `repository` attribute when calling the `BaseModel` class")
|
29
|
-
cls: AbstractSQLStatements[T, TRepo] = cls.statements_dicc.get(type(repository), None)
|
30
|
-
|
31
|
-
if not cls:
|
32
|
-
raise Exception(f"The selected repository '{repository}' does not exist.")
|
33
|
-
|
34
|
-
self = object().__new__(cls)
|
35
|
-
cls.__init__(self, model, repository)
|
36
|
-
return self
|