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,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:
@@ -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[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
- parser_data = self.parser_data(clause_info, data)
109
- new_row.append(parser_data)
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(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
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
- return wrapper
145
+ # return wrapper
142
146
 
143
- def __init__(self, **kwargs: Any) -> None:
144
- self._data_config: dict[str, Any] = kwargs
145
- self._pool: MySQLConnectionPool = self.__create_MySQLConnectionPool()
147
+ #
146
148
 
147
- def __create_MySQLConnectionPool(self):
148
- return MySQLConnectionPool(pool_name="mypool", pool_size=10, **self._data_config)
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
- @get_connection
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 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)
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
- @get_connection
180
- def create_tables_code_first(self, cnx: MySQLConnection, path: str | Path) -> None:
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 cnx.cursor(buffered=True) as cursor:
196
- cursor.execute(query)
197
- cnx.commit()
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
- @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()
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
- @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()
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
- @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()
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
- @get_connection
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
- with cnx.cursor(buffered=True) as cursor:
233
- cursor.execute(query, (name,))
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
- @get_connection
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 cnx.cursor(buffered=True) as cursor:
249
- cursor.execute(query, (name,))
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
- return CreateDatabase(self).execute(name, if_exists)
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 = self.__create_MySQLConnectionPool()
295
+ self._pool.set_config(**self._data_config)