ormlambda 2.11.2__py3-none-any.whl → 3.7.1__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 -319
  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} +114 -74
  66. ormlambda/databases/my_sql/statements.py +249 -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 +331 -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.2.dist-info → ormlambda-3.7.1.dist-info}/METADATA +132 -68
  99. ormlambda-3.7.1.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.2.dist-info/RECORD +0 -81
  117. /ormlambda/{utils → sql}/dtypes.py +0 -0
  118. {ormlambda-2.11.2.dist-info → ormlambda-3.7.1.dist-info}/LICENSE +0 -0
  119. {ormlambda-2.11.2.dist-info → ormlambda-3.7.1.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, Callable, TYPE_CHECKING
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, Error # noqa: F401
9
- from mysql.connector.pooling import PooledMySQLConnection, MySQLConnectionPool # noqa: F401
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.utils.module_tree.dynamic_module import ModuleTree
13
+ from ormlambda.repository import IRepositoryBase
14
+ from ormlambda.caster import Caster
14
15
 
15
- from .clauses import CreateDatabase, TypeExists
16
- from .clauses import DropDatabase
17
- from .clauses import DropTable
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 src.ormlambda.common.abstract_classes.decomposition_query import ClauseInfo
22
+ from ormlambda.common.abstract_classes.decomposition_query import ClauseInfo
22
23
  from ormlambda import Table
23
- from src.ormlambda.databases.my_sql.clauses.select import Select
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:
@@ -83,7 +86,16 @@ class Response[TFlavour, *Ts]:
83
86
  return [list(x) for x in data]
84
87
 
85
88
  def _default(**kwargs) -> list[TFlavour]:
86
- return self._flavour(data, **kwargs)
89
+ replacer_dicc: dict[str, str] = {x.alias_clause: x.column for x in self._select.all_clauses}
90
+
91
+ cleaned_column_names = [replacer_dicc[col] for col in self._columns]
92
+
93
+ result = []
94
+ for attr in data:
95
+ dicc_attr = dict(zip(cleaned_column_names, attr))
96
+ result.append(self._flavour(**dicc_attr, **kwargs))
97
+
98
+ return result
87
99
 
88
100
  selector: dict[Type[object], Any] = {
89
101
  dict: _dict,
@@ -92,10 +104,11 @@ class Response[TFlavour, *Ts]:
92
104
  list: _list,
93
105
  }
94
106
 
107
+ selector.get(dict)()
95
108
  return selector.get(self._flavour, _default)(**kwargs)
96
109
 
97
110
  def _parser_response(self) -> TFlavour:
98
- new_response: list[list] = []
111
+ new_response: list[tuple] = []
99
112
  for row in self._response_values:
100
113
  new_row: list = []
101
114
  for i, data in enumerate(row):
@@ -105,8 +118,9 @@ class Response[TFlavour, *Ts]:
105
118
  new_row = row
106
119
  break
107
120
  else:
108
- parser_data = self.parser_data(clause_info, data)
109
- new_row.append(parser_data)
121
+ parse_data = self._caster.for_value(data, value_type=clause_info.dtype).from_database
122
+ new_row.append(parse_data)
123
+ new_row = tuple(new_row)
110
124
  if not isinstance(new_row, tuple):
111
125
  new_row = tuple(new_row)
112
126
 
@@ -127,33 +141,38 @@ class Response[TFlavour, *Ts]:
127
141
  return data
128
142
 
129
143
 
130
- class MySQLRepository(IRepositoryBase[MySQLConnection]):
131
- def get_connection(func: Callable[..., Any]):
132
- @functools.wraps(func)
133
- def wrapper(self: MySQLRepository, *args, **kwargs):
134
- with self._pool.get_connection() as cnx:
135
- try:
136
- return func(self, cnx._cnx, *args, **kwargs)
137
- except Exception as e:
138
- cnx._cnx.rollback()
139
- raise e
144
+ class MySQLRepository(BaseRepository[MySQLConnectionPool]):
145
+ # def get_connection[**P, TReturn](func: Callable[Concatenate[MySQLRepository, MySQLConnection, P], TReturn]) -> Callable[P, TReturn]:
146
+ # def wrapper(self: MySQLRepository, *args: P.args, **kwargs: P.kwargs):
147
+ # with self.get_connection() as cnx:
148
+ # try:
149
+ # return func(self, cnx._cnx, *args, **kwargs)
150
+ # except Exception as e:
151
+ # cnx._cnx.rollback()
152
+ # raise e
140
153
 
141
- return wrapper
154
+ # return wrapper
142
155
 
143
- def __init__(self, **kwargs: Any) -> None:
144
- self._data_config: dict[str, Any] = kwargs
145
- self._pool: MySQLConnectionPool = self.__create_MySQLConnectionPool()
156
+ #
146
157
 
147
- def __create_MySQLConnectionPool(self):
148
- return MySQLConnectionPool(pool_name="mypool", pool_size=10, **self._data_config)
158
+ def __init__(self, **kwargs):
159
+ super().__init__(MySQLConnectionPool, **kwargs)
160
+
161
+ @contextlib.contextmanager
162
+ def get_connection(self) -> Generator[MySQLConnection, None, None]:
163
+ with self._pool.get_connection() as cnx:
164
+ try:
165
+ yield cnx._cnx
166
+ cnx._cnx.commit()
167
+ except Exception as exc:
168
+ cnx._cnx.rollback()
169
+ raise exc
149
170
 
150
171
  @override
151
- @get_connection
152
- def read_sql[TFlavour](
172
+ def read_sql[TFlavour: Iterable](
153
173
  self,
154
- cnx: MySQLConnection,
155
174
  query: str,
156
- flavour: Type[TFlavour] = tuple,
175
+ flavour: tuple | Type[TFlavour] = tuple,
157
176
  **kwargs,
158
177
  ) -> tuple[TFlavour]:
159
178
  """
@@ -169,15 +188,25 @@ class MySQLRepository(IRepositoryBase[MySQLConnection]):
169
188
  select: Select = kwargs.pop("select", None)
170
189
  cast_to_tuple: bool = kwargs.pop("cast_to_tuple", True)
171
190
 
172
- with cnx.cursor(buffered=True) as cursor:
173
- cursor.execute(query)
174
- values: list[tuple] = cursor.fetchall()
175
- columns: tuple[str] = cursor.column_names
176
- return Response[TFlavour](model=model, response_values=values, columns=columns, flavour=flavour, select=select).response(_tuple=cast_to_tuple, **kwargs)
191
+ with self.get_connection() as cnx:
192
+ with cnx.cursor(buffered=True) as cursor:
193
+ cursor.execute(query)
194
+ values: list[tuple] = cursor.fetchall()
195
+ columns: tuple[str] = cursor.column_names
196
+ return Response[TFlavour](
197
+ repository=self,
198
+ model=model,
199
+ response_values=values,
200
+ columns=columns,
201
+ flavour=flavour,
202
+ select=select,
203
+ ).response(_tuple=cast_to_tuple, **kwargs)
177
204
 
178
205
  # FIXME [ ]: this method does not comply with the implemented interface
179
- @get_connection
180
- def create_tables_code_first(self, cnx: MySQLConnection, path: str | Path) -> None:
206
+ def create_tables_code_first(self, path: str | Path) -> None:
207
+ return
208
+ from ormlambda.utils.module_tree.dynamic_module import ModuleTree
209
+
181
210
  if not isinstance(path, Path | str):
182
211
  raise ValueError
183
212
 
@@ -192,33 +221,30 @@ class MySQLRepository(IRepositoryBase[MySQLConnection]):
192
221
  queries_list: list[str] = module_tree.get_queries()
193
222
 
194
223
  for query in queries_list:
195
- with cnx.cursor(buffered=True) as cursor:
196
- cursor.execute(query)
197
- cnx.commit()
224
+ with self.get_connection() as cnx:
225
+ with cnx.cursor(buffered=True) as cursor:
226
+ cursor.execute(query)
198
227
  return None
199
228
 
200
229
  @override
201
- @get_connection
202
- def executemany_with_values(self, cnx: MySQLConnection, query: str, values) -> None:
203
- with cnx.cursor(buffered=True) as cursor:
204
- cursor.executemany(query, values)
205
- cnx.commit()
230
+ def executemany_with_values(self, query: str, values) -> None:
231
+ with self.get_connection() as cnx:
232
+ with cnx.cursor(buffered=True) as cursor:
233
+ cursor.executemany(query, values)
206
234
  return None
207
235
 
208
236
  @override
209
- @get_connection
210
- def execute_with_values(self, cnx: MySQLConnection, query: str, values) -> None:
211
- with cnx.cursor(buffered=True) as cursor:
212
- cursor.execute(query, values)
213
- cnx.commit()
237
+ def execute_with_values(self, query: str, values) -> None:
238
+ with self.get_connection() as cnx:
239
+ with cnx.cursor(buffered=True) as cursor:
240
+ cursor.execute(query, values)
214
241
  return None
215
242
 
216
243
  @override
217
- @get_connection
218
- def execute(self, cnx: MySQLConnection, query: str) -> None:
219
- with cnx.cursor(buffered=True) as cursor:
220
- cursor.execute(query)
221
- cnx.commit()
244
+ def execute(self, query: str) -> None:
245
+ with self.get_connection() as cnx:
246
+ with cnx.cursor(buffered=True) as cursor:
247
+ cursor.execute(query)
222
248
  return None
223
249
 
224
250
  @override
@@ -226,12 +252,21 @@ class MySQLRepository(IRepositoryBase[MySQLConnection]):
226
252
  return DropTable(self).execute(name)
227
253
 
228
254
  @override
229
- @get_connection
230
- def database_exists(self, cnx: MySQLConnection, name: str) -> bool:
255
+ def database_exists(self, name: str) -> bool:
231
256
  query = "SHOW DATABASES LIKE %s;"
232
- with cnx.cursor(buffered=True) as cursor:
233
- cursor.execute(query, (name,))
257
+ temp_config = self._pool._cnx_config
258
+
259
+ config_without_db = temp_config.copy()
260
+
261
+ if "database" in config_without_db:
262
+ config_without_db.pop("database")
263
+ self._pool.set_config(**config_without_db)
264
+ with self.get_connection() as cnx:
265
+ with cnx.cursor(buffered=True) as cursor:
266
+ cursor.execute(query, (name,))
234
267
  res = cursor.fetchmany(1)
268
+
269
+ self._pool.set_config(**temp_config)
235
270
  return len(res) > 0
236
271
 
237
272
  @override
@@ -239,20 +274,25 @@ class MySQLRepository(IRepositoryBase[MySQLConnection]):
239
274
  return DropDatabase(self).execute(name)
240
275
 
241
276
  @override
242
- @get_connection
243
- def table_exists(self, cnx: MySQLConnection, name: str) -> bool:
244
- if not cnx.database:
245
- raise Exception("No database selected")
246
-
277
+ def table_exists(self, name: str) -> bool:
247
278
  query = "SHOW TABLES LIKE %s;"
248
- with cnx.cursor(buffered=True) as cursor:
249
- cursor.execute(query, (name,))
279
+ with self.get_connection() as cnx:
280
+ if not cnx.database:
281
+ raise Exception("No database selected")
282
+ with cnx.cursor(buffered=True) as cursor:
283
+ cursor.execute(query, (name,))
250
284
  res = cursor.fetchmany(1)
251
285
  return len(res) > 0
252
286
 
253
287
  @override
254
288
  def create_database(self, name: str, if_exists: TypeExists = "fail") -> None:
255
- return CreateDatabase(self).execute(name, if_exists)
289
+ temp_config = self._pool._cnx_config
290
+
291
+ config_without_db = temp_config.copy()
292
+
293
+ if "database" in config_without_db:
294
+ config_without_db.pop("database")
295
+ return CreateDatabase(type(self)(**config_without_db)).execute(name, if_exists)
256
296
 
257
297
  @property
258
298
  def database(self) -> Optional[str]:
@@ -261,4 +301,4 @@ class MySQLRepository(IRepositoryBase[MySQLConnection]):
261
301
  @database.setter
262
302
  def database(self, value: str) -> None:
263
303
  self._data_config["database"] = value
264
- self._pool = self.__create_MySQLConnectionPool()
304
+ self._pool.set_config(**self._data_config)