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.
Files changed (119) hide show
  1. ormlambda/__init__.py +11 -9
  2. ormlambda/caster/__init__.py +3 -0
  3. ormlambda/caster/base_caster.py +69 -0
  4. ormlambda/caster/caster.py +48 -0
  5. ormlambda/caster/interfaces/ICaster.py +26 -0
  6. ormlambda/caster/interfaces/__init__.py +1 -0
  7. ormlambda/common/__init__.py +1 -1
  8. ormlambda/common/abstract_classes/__init__.py +3 -3
  9. ormlambda/common/abstract_classes/decomposition_query.py +117 -315
  10. ormlambda/common/abstract_classes/non_query_base.py +1 -1
  11. ormlambda/common/enums/condition_types.py +2 -1
  12. ormlambda/common/enums/join_type.py +4 -1
  13. ormlambda/common/errors/__init__.py +15 -2
  14. ormlambda/common/global_checker.py +28 -0
  15. ormlambda/common/interfaces/ICustomAlias.py +4 -1
  16. ormlambda/common/interfaces/IDecompositionQuery.py +9 -34
  17. ormlambda/common/interfaces/IJoinSelector.py +21 -0
  18. ormlambda/common/interfaces/__init__.py +4 -6
  19. ormlambda/components/__init__.py +4 -0
  20. ormlambda/components/insert/abstract_insert.py +1 -1
  21. ormlambda/components/select/ISelect.py +17 -0
  22. ormlambda/components/select/__init__.py +1 -0
  23. ormlambda/components/update/abstract_update.py +4 -4
  24. ormlambda/components/upsert/abstract_upsert.py +1 -1
  25. ormlambda/databases/__init__.py +5 -0
  26. ormlambda/databases/my_sql/__init__.py +3 -1
  27. ormlambda/databases/my_sql/caster/__init__.py +1 -0
  28. ormlambda/databases/my_sql/caster/caster.py +38 -0
  29. ormlambda/databases/my_sql/caster/read.py +39 -0
  30. ormlambda/databases/my_sql/caster/types/__init__.py +8 -0
  31. ormlambda/databases/my_sql/caster/types/bytes.py +31 -0
  32. ormlambda/databases/my_sql/caster/types/datetime.py +34 -0
  33. ormlambda/databases/my_sql/caster/types/float.py +31 -0
  34. ormlambda/databases/my_sql/caster/types/int.py +31 -0
  35. ormlambda/databases/my_sql/caster/types/iterable.py +31 -0
  36. ormlambda/databases/my_sql/caster/types/none.py +30 -0
  37. ormlambda/databases/my_sql/caster/types/point.py +43 -0
  38. ormlambda/databases/my_sql/caster/types/string.py +31 -0
  39. ormlambda/databases/my_sql/caster/write.py +37 -0
  40. ormlambda/databases/my_sql/clauses/ST_AsText.py +36 -0
  41. ormlambda/databases/my_sql/clauses/ST_Contains.py +31 -0
  42. ormlambda/databases/my_sql/clauses/__init__.py +6 -4
  43. ormlambda/databases/my_sql/clauses/alias.py +24 -21
  44. ormlambda/databases/my_sql/clauses/count.py +32 -28
  45. ormlambda/databases/my_sql/clauses/create_database.py +3 -4
  46. ormlambda/databases/my_sql/clauses/delete.py +10 -10
  47. ormlambda/databases/my_sql/clauses/drop_database.py +3 -5
  48. ormlambda/databases/my_sql/clauses/drop_table.py +3 -3
  49. ormlambda/databases/my_sql/clauses/group_by.py +4 -7
  50. ormlambda/databases/my_sql/clauses/insert.py +33 -19
  51. ormlambda/databases/my_sql/clauses/joins.py +66 -59
  52. ormlambda/databases/my_sql/clauses/limit.py +1 -1
  53. ormlambda/databases/my_sql/clauses/offset.py +1 -1
  54. ormlambda/databases/my_sql/clauses/order.py +36 -23
  55. ormlambda/databases/my_sql/clauses/select.py +25 -36
  56. ormlambda/databases/my_sql/clauses/update.py +38 -13
  57. ormlambda/databases/my_sql/clauses/upsert.py +2 -2
  58. ormlambda/databases/my_sql/clauses/where.py +45 -0
  59. ormlambda/databases/my_sql/functions/concat.py +24 -27
  60. ormlambda/databases/my_sql/functions/max.py +32 -28
  61. ormlambda/databases/my_sql/functions/min.py +32 -28
  62. ormlambda/databases/my_sql/functions/sum.py +32 -28
  63. ormlambda/databases/my_sql/join_context.py +75 -0
  64. ormlambda/databases/my_sql/repository/__init__.py +1 -0
  65. ormlambda/databases/my_sql/{repository.py → repository/repository.py} +104 -73
  66. ormlambda/databases/my_sql/statements.py +231 -153
  67. ormlambda/engine/__init__.py +0 -0
  68. ormlambda/engine/template.py +47 -0
  69. ormlambda/model/__init__.py +0 -0
  70. ormlambda/model/base_model.py +37 -0
  71. ormlambda/repository/__init__.py +2 -0
  72. ormlambda/repository/base_repository.py +14 -0
  73. ormlambda/repository/interfaces/IDatabaseConnection.py +12 -0
  74. ormlambda/{common → repository}/interfaces/IRepositoryBase.py +6 -5
  75. ormlambda/repository/interfaces/__init__.py +2 -0
  76. ormlambda/sql/__init__.py +3 -0
  77. ormlambda/sql/clause_info/__init__.py +3 -0
  78. ormlambda/sql/clause_info/clause_info.py +434 -0
  79. ormlambda/sql/clause_info/clause_info_context.py +87 -0
  80. ormlambda/sql/clause_info/interface/IAggregate.py +10 -0
  81. ormlambda/sql/clause_info/interface/__init__.py +1 -0
  82. ormlambda/sql/column.py +126 -0
  83. ormlambda/sql/comparer.py +156 -0
  84. ormlambda/sql/foreign_key.py +115 -0
  85. ormlambda/sql/interfaces/__init__.py +0 -0
  86. ormlambda/sql/table/__init__.py +1 -0
  87. ormlambda/{utils → sql/table}/fields.py +6 -5
  88. ormlambda/{utils → sql/table}/table_constructor.py +43 -91
  89. ormlambda/sql/types.py +25 -0
  90. ormlambda/statements/__init__.py +2 -0
  91. ormlambda/statements/base_statement.py +129 -0
  92. ormlambda/statements/interfaces/IStatements.py +309 -0
  93. ormlambda/statements/interfaces/__init__.py +1 -0
  94. ormlambda/statements/types.py +51 -0
  95. ormlambda/utils/__init__.py +1 -3
  96. ormlambda/utils/module_tree/__init__.py +1 -0
  97. ormlambda/utils/module_tree/dynamic_module.py +20 -14
  98. {ormlambda-2.11.1.dist-info → ormlambda-3.7.0.dist-info}/METADATA +132 -68
  99. ormlambda-3.7.0.dist-info/RECORD +117 -0
  100. ormlambda/common/abstract_classes/abstract_model.py +0 -115
  101. ormlambda/common/interfaces/IAggregate.py +0 -10
  102. ormlambda/common/interfaces/IStatements.py +0 -348
  103. ormlambda/components/where/__init__.py +0 -1
  104. ormlambda/components/where/abstract_where.py +0 -15
  105. ormlambda/databases/my_sql/clauses/where_condition.py +0 -222
  106. ormlambda/model_base.py +0 -36
  107. ormlambda/utils/column.py +0 -105
  108. ormlambda/utils/foreign_key.py +0 -81
  109. ormlambda/utils/lambda_disassembler/__init__.py +0 -4
  110. ormlambda/utils/lambda_disassembler/dis_types.py +0 -133
  111. ormlambda/utils/lambda_disassembler/disassembler.py +0 -69
  112. ormlambda/utils/lambda_disassembler/dtypes.py +0 -103
  113. ormlambda/utils/lambda_disassembler/name_of.py +0 -41
  114. ormlambda/utils/lambda_disassembler/nested_element.py +0 -44
  115. ormlambda/utils/lambda_disassembler/tree_instruction.py +0 -145
  116. ormlambda-2.11.1.dist-info/RECORD +0 -81
  117. /ormlambda/{utils → sql}/dtypes.py +0 -0
  118. {ormlambda-2.11.1.dist-info → ormlambda-3.7.0.dist-info}/LICENSE +0 -0
  119. {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