ormlambda 2.11.2__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 -319
- 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.2.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.2.dist-info/RECORD +0 -81
- /ormlambda/{utils → sql}/dtypes.py +0 -0
- {ormlambda-2.11.2.dist-info → ormlambda-3.7.0.dist-info}/LICENSE +0 -0
- {ormlambda-2.11.2.dist-info → ormlambda-3.7.0.dist-info}/WHEEL +0 -0
@@ -1,32 +1,34 @@
|
|
1
1
|
from __future__ import annotations
|
2
|
+
import contextlib
|
2
3
|
from pathlib import Path
|
3
|
-
from typing import Any, Optional, Type, override,
|
4
|
-
import functools
|
4
|
+
from typing import Any, Generator, Iterable, Optional, Type, override, TYPE_CHECKING
|
5
5
|
import shapely as shp
|
6
6
|
|
7
7
|
# from mysql.connector.pooling import MySQLConnectionPool
|
8
|
-
from mysql.connector import MySQLConnection
|
9
|
-
from mysql.connector.pooling import
|
8
|
+
from mysql.connector import MySQLConnection # noqa: F401
|
9
|
+
from mysql.connector.pooling import MySQLConnectionPool # noqa: F401
|
10
|
+
from ormlambda.repository import BaseRepository
|
10
11
|
|
11
12
|
# Custom libraries
|
12
|
-
from ormlambda import IRepositoryBase
|
13
|
-
from ormlambda.
|
13
|
+
from ormlambda.repository import IRepositoryBase
|
14
|
+
from ormlambda.caster import Caster
|
14
15
|
|
15
|
-
from
|
16
|
-
from
|
17
|
-
from
|
16
|
+
from ..clauses import CreateDatabase, TypeExists
|
17
|
+
from ..clauses import DropDatabase
|
18
|
+
from ..clauses import DropTable
|
18
19
|
|
19
20
|
|
20
21
|
if TYPE_CHECKING:
|
21
|
-
from
|
22
|
+
from ormlambda.common.abstract_classes.decomposition_query import ClauseInfo
|
22
23
|
from ormlambda import Table
|
23
|
-
from
|
24
|
+
from ormlambda.databases.my_sql.clauses.select import Select
|
24
25
|
|
25
26
|
type TResponse[TFlavour, *Ts] = TFlavour | tuple[dict[str, tuple[*Ts]]] | tuple[tuple[*Ts]] | tuple[TFlavour]
|
26
27
|
|
27
28
|
|
28
29
|
class Response[TFlavour, *Ts]:
|
29
|
-
def __init__(self, response_values: list[tuple[*Ts]], columns: tuple[str], flavour: Type[TFlavour], model: Optional[Table] = None, select: Optional[Select] = None) -> None:
|
30
|
+
def __init__(self, repository: IRepositoryBase, response_values: list[tuple[*Ts]], columns: tuple[str], flavour: Type[TFlavour], model: Optional[Table] = None, select: Optional[Select] = None) -> None:
|
31
|
+
self._repository: IRepositoryBase = repository
|
30
32
|
self._response_values: list[tuple[*Ts]] = response_values
|
31
33
|
self._columns: tuple[str] = columns
|
32
34
|
self._flavour: Type[TFlavour] = flavour
|
@@ -35,6 +37,7 @@ class Response[TFlavour, *Ts]:
|
|
35
37
|
|
36
38
|
self._response_values_index: int = len(self._response_values)
|
37
39
|
# self.select_values()
|
40
|
+
self._caster = Caster(repository)
|
38
41
|
|
39
42
|
@property
|
40
43
|
def is_one(self) -> bool:
|
@@ -92,10 +95,11 @@ class Response[TFlavour, *Ts]:
|
|
92
95
|
list: _list,
|
93
96
|
}
|
94
97
|
|
98
|
+
selector.get(dict)()
|
95
99
|
return selector.get(self._flavour, _default)(**kwargs)
|
96
100
|
|
97
101
|
def _parser_response(self) -> TFlavour:
|
98
|
-
new_response: list[
|
102
|
+
new_response: list[tuple] = []
|
99
103
|
for row in self._response_values:
|
100
104
|
new_row: list = []
|
101
105
|
for i, data in enumerate(row):
|
@@ -105,8 +109,9 @@ class Response[TFlavour, *Ts]:
|
|
105
109
|
new_row = row
|
106
110
|
break
|
107
111
|
else:
|
108
|
-
|
109
|
-
new_row.append(
|
112
|
+
parse_data = self._caster.for_value(data, value_type=clause_info.dtype).from_database
|
113
|
+
new_row.append(parse_data)
|
114
|
+
new_row = tuple(new_row)
|
110
115
|
if not isinstance(new_row, tuple):
|
111
116
|
new_row = tuple(new_row)
|
112
117
|
|
@@ -127,33 +132,38 @@ class Response[TFlavour, *Ts]:
|
|
127
132
|
return data
|
128
133
|
|
129
134
|
|
130
|
-
class MySQLRepository(
|
131
|
-
def get_connection(func: Callable[
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
raise e
|
135
|
+
class MySQLRepository(BaseRepository[MySQLConnectionPool]):
|
136
|
+
# def get_connection[**P, TReturn](func: Callable[Concatenate[MySQLRepository, MySQLConnection, P], TReturn]) -> Callable[P, TReturn]:
|
137
|
+
# def wrapper(self: MySQLRepository, *args: P.args, **kwargs: P.kwargs):
|
138
|
+
# with self.get_connection() as cnx:
|
139
|
+
# try:
|
140
|
+
# return func(self, cnx._cnx, *args, **kwargs)
|
141
|
+
# except Exception as e:
|
142
|
+
# cnx._cnx.rollback()
|
143
|
+
# raise e
|
140
144
|
|
141
|
-
|
145
|
+
# return wrapper
|
142
146
|
|
143
|
-
|
144
|
-
self._data_config: dict[str, Any] = kwargs
|
145
|
-
self._pool: MySQLConnectionPool = self.__create_MySQLConnectionPool()
|
147
|
+
#
|
146
148
|
|
147
|
-
def
|
148
|
-
|
149
|
+
def __init__(self, **kwargs):
|
150
|
+
super().__init__(MySQLConnectionPool, **kwargs)
|
151
|
+
|
152
|
+
@contextlib.contextmanager
|
153
|
+
def get_connection(self) -> Generator[MySQLConnection, None, None]:
|
154
|
+
with self._pool.get_connection() as cnx:
|
155
|
+
try:
|
156
|
+
yield cnx._cnx
|
157
|
+
cnx._cnx.commit()
|
158
|
+
except Exception as exc:
|
159
|
+
cnx._cnx.rollback()
|
160
|
+
raise exc
|
149
161
|
|
150
162
|
@override
|
151
|
-
|
152
|
-
def read_sql[TFlavour](
|
163
|
+
def read_sql[TFlavour: Iterable](
|
153
164
|
self,
|
154
|
-
cnx: MySQLConnection,
|
155
165
|
query: str,
|
156
|
-
flavour: Type[TFlavour] = tuple,
|
166
|
+
flavour: tuple | Type[TFlavour] = tuple,
|
157
167
|
**kwargs,
|
158
168
|
) -> tuple[TFlavour]:
|
159
169
|
"""
|
@@ -169,15 +179,25 @@ class MySQLRepository(IRepositoryBase[MySQLConnection]):
|
|
169
179
|
select: Select = kwargs.pop("select", None)
|
170
180
|
cast_to_tuple: bool = kwargs.pop("cast_to_tuple", True)
|
171
181
|
|
172
|
-
with
|
173
|
-
cursor
|
174
|
-
|
175
|
-
|
176
|
-
|
182
|
+
with self.get_connection() as cnx:
|
183
|
+
with cnx.cursor(buffered=True) as cursor:
|
184
|
+
cursor.execute(query)
|
185
|
+
values: list[tuple] = cursor.fetchall()
|
186
|
+
columns: tuple[str] = cursor.column_names
|
187
|
+
return Response[TFlavour](
|
188
|
+
repository=self,
|
189
|
+
model=model,
|
190
|
+
response_values=values,
|
191
|
+
columns=columns,
|
192
|
+
flavour=flavour,
|
193
|
+
select=select,
|
194
|
+
).response(_tuple=cast_to_tuple, **kwargs)
|
177
195
|
|
178
196
|
# FIXME [ ]: this method does not comply with the implemented interface
|
179
|
-
|
180
|
-
|
197
|
+
def create_tables_code_first(self, path: str | Path) -> None:
|
198
|
+
return
|
199
|
+
from ormlambda.utils.module_tree.dynamic_module import ModuleTree
|
200
|
+
|
181
201
|
if not isinstance(path, Path | str):
|
182
202
|
raise ValueError
|
183
203
|
|
@@ -192,33 +212,30 @@ class MySQLRepository(IRepositoryBase[MySQLConnection]):
|
|
192
212
|
queries_list: list[str] = module_tree.get_queries()
|
193
213
|
|
194
214
|
for query in queries_list:
|
195
|
-
with
|
196
|
-
cursor
|
197
|
-
|
215
|
+
with self.get_connection() as cnx:
|
216
|
+
with cnx.cursor(buffered=True) as cursor:
|
217
|
+
cursor.execute(query)
|
198
218
|
return None
|
199
219
|
|
200
220
|
@override
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
cnx.commit()
|
221
|
+
def executemany_with_values(self, query: str, values) -> None:
|
222
|
+
with self.get_connection() as cnx:
|
223
|
+
with cnx.cursor(buffered=True) as cursor:
|
224
|
+
cursor.executemany(query, values)
|
206
225
|
return None
|
207
226
|
|
208
227
|
@override
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
cnx.commit()
|
228
|
+
def execute_with_values(self, query: str, values) -> None:
|
229
|
+
with self.get_connection() as cnx:
|
230
|
+
with cnx.cursor(buffered=True) as cursor:
|
231
|
+
cursor.execute(query, values)
|
214
232
|
return None
|
215
233
|
|
216
234
|
@override
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
cnx.commit()
|
235
|
+
def execute(self, query: str) -> None:
|
236
|
+
with self.get_connection() as cnx:
|
237
|
+
with cnx.cursor(buffered=True) as cursor:
|
238
|
+
cursor.execute(query)
|
222
239
|
return None
|
223
240
|
|
224
241
|
@override
|
@@ -226,12 +243,21 @@ class MySQLRepository(IRepositoryBase[MySQLConnection]):
|
|
226
243
|
return DropTable(self).execute(name)
|
227
244
|
|
228
245
|
@override
|
229
|
-
|
230
|
-
def database_exists(self, cnx: MySQLConnection, name: str) -> bool:
|
246
|
+
def database_exists(self, name: str) -> bool:
|
231
247
|
query = "SHOW DATABASES LIKE %s;"
|
232
|
-
|
233
|
-
|
248
|
+
temp_config = self._pool._cnx_config
|
249
|
+
|
250
|
+
config_without_db = temp_config.copy()
|
251
|
+
|
252
|
+
if "database" in config_without_db:
|
253
|
+
config_without_db.pop("database")
|
254
|
+
self._pool.set_config(**config_without_db)
|
255
|
+
with self.get_connection() as cnx:
|
256
|
+
with cnx.cursor(buffered=True) as cursor:
|
257
|
+
cursor.execute(query, (name,))
|
234
258
|
res = cursor.fetchmany(1)
|
259
|
+
|
260
|
+
self._pool.set_config(**temp_config)
|
235
261
|
return len(res) > 0
|
236
262
|
|
237
263
|
@override
|
@@ -239,20 +265,25 @@ class MySQLRepository(IRepositoryBase[MySQLConnection]):
|
|
239
265
|
return DropDatabase(self).execute(name)
|
240
266
|
|
241
267
|
@override
|
242
|
-
|
243
|
-
def table_exists(self, cnx: MySQLConnection, name: str) -> bool:
|
244
|
-
if not cnx.database:
|
245
|
-
raise Exception("No database selected")
|
246
|
-
|
268
|
+
def table_exists(self, name: str) -> bool:
|
247
269
|
query = "SHOW TABLES LIKE %s;"
|
248
|
-
with
|
249
|
-
|
270
|
+
with self.get_connection() as cnx:
|
271
|
+
if not cnx.database:
|
272
|
+
raise Exception("No database selected")
|
273
|
+
with cnx.cursor(buffered=True) as cursor:
|
274
|
+
cursor.execute(query, (name,))
|
250
275
|
res = cursor.fetchmany(1)
|
251
276
|
return len(res) > 0
|
252
277
|
|
253
278
|
@override
|
254
279
|
def create_database(self, name: str, if_exists: TypeExists = "fail") -> None:
|
255
|
-
|
280
|
+
temp_config = self._pool._cnx_config
|
281
|
+
|
282
|
+
config_without_db = temp_config.copy()
|
283
|
+
|
284
|
+
if "database" in config_without_db:
|
285
|
+
config_without_db.pop("database")
|
286
|
+
return CreateDatabase(type(self)(**config_without_db)).execute(name, if_exists)
|
256
287
|
|
257
288
|
@property
|
258
289
|
def database(self) -> Optional[str]:
|
@@ -261,4 +292,4 @@ class MySQLRepository(IRepositoryBase[MySQLConnection]):
|
|
261
292
|
@database.setter
|
262
293
|
def database(self, value: str) -> None:
|
263
294
|
self._data_config["database"] = value
|
264
|
-
self._pool
|
295
|
+
self._pool.set_config(**self._data_config)
|