ormlambda 3.11.2__py3-none-any.whl → 3.34.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 +3 -1
- ormlambda/caster/__init__.py +1 -1
- ormlambda/caster/caster.py +29 -12
- ormlambda/common/abstract_classes/clause_info_converter.py +65 -0
- ormlambda/common/abstract_classes/decomposition_query.py +27 -68
- ormlambda/common/abstract_classes/non_query_base.py +10 -8
- ormlambda/common/abstract_classes/query_base.py +3 -1
- ormlambda/common/errors/__init__.py +29 -0
- ormlambda/common/interfaces/ICustomAlias.py +1 -1
- ormlambda/common/interfaces/IQueryCommand.py +6 -2
- ormlambda/dialects/__init__.py +39 -0
- ormlambda/dialects/default/__init__.py +1 -0
- ormlambda/dialects/default/base.py +39 -0
- ormlambda/dialects/interface/__init__.py +1 -0
- ormlambda/dialects/interface/dialect.py +78 -0
- ormlambda/dialects/mysql/__init__.py +38 -0
- ormlambda/dialects/mysql/base.py +388 -0
- ormlambda/dialects/mysql/caster/caster.py +39 -0
- ormlambda/{databases/my_sql → dialects/mysql}/caster/types/__init__.py +1 -0
- ormlambda/dialects/mysql/caster/types/boolean.py +35 -0
- ormlambda/{databases/my_sql → dialects/mysql}/caster/types/bytes.py +7 -7
- ormlambda/{databases/my_sql → dialects/mysql}/caster/types/datetime.py +7 -7
- ormlambda/{databases/my_sql → dialects/mysql}/caster/types/float.py +7 -7
- ormlambda/{databases/my_sql → dialects/mysql}/caster/types/int.py +7 -7
- ormlambda/{databases/my_sql → dialects/mysql}/caster/types/iterable.py +7 -7
- ormlambda/{databases/my_sql → dialects/mysql}/caster/types/none.py +8 -7
- ormlambda/{databases/my_sql → dialects/mysql}/caster/types/point.py +4 -4
- ormlambda/{databases/my_sql → dialects/mysql}/caster/types/string.py +7 -7
- ormlambda/{databases/my_sql → dialects/mysql}/clauses/ST_AsText.py +8 -7
- ormlambda/{databases/my_sql → dialects/mysql}/clauses/ST_Contains.py +10 -5
- ormlambda/dialects/mysql/clauses/__init__.py +13 -0
- ormlambda/dialects/mysql/clauses/count.py +33 -0
- ormlambda/dialects/mysql/clauses/delete.py +9 -0
- ormlambda/dialects/mysql/clauses/group_by.py +17 -0
- ormlambda/dialects/mysql/clauses/having.py +12 -0
- ormlambda/dialects/mysql/clauses/insert.py +9 -0
- ormlambda/dialects/mysql/clauses/joins.py +14 -0
- ormlambda/dialects/mysql/clauses/limit.py +6 -0
- ormlambda/dialects/mysql/clauses/offset.py +6 -0
- ormlambda/dialects/mysql/clauses/order.py +8 -0
- ormlambda/dialects/mysql/clauses/update.py +8 -0
- ormlambda/dialects/mysql/clauses/upsert.py +9 -0
- ormlambda/dialects/mysql/clauses/where.py +7 -0
- ormlambda/dialects/mysql/mysqlconnector.py +46 -0
- ormlambda/dialects/mysql/repository/__init__.py +1 -0
- ormlambda/dialects/mysql/repository/repository.py +212 -0
- ormlambda/dialects/mysql/types.py +732 -0
- ormlambda/dialects/sqlite/__init__.py +5 -0
- ormlambda/dialects/sqlite/base.py +47 -0
- ormlambda/dialects/sqlite/pysqlite.py +32 -0
- ormlambda/engine/__init__.py +1 -0
- ormlambda/engine/base.py +77 -0
- ormlambda/engine/create.py +9 -23
- ormlambda/engine/url.py +34 -19
- ormlambda/env.py +30 -0
- ormlambda/errors.py +17 -0
- ormlambda/model/base_model.py +7 -9
- ormlambda/repository/base_repository.py +36 -5
- ormlambda/repository/interfaces/IRepositoryBase.py +119 -12
- ormlambda/repository/response.py +134 -0
- ormlambda/sql/clause_info/__init__.py +2 -1
- ormlambda/sql/clause_info/aggregate_function_base.py +96 -0
- ormlambda/sql/clause_info/clause_info.py +35 -115
- ormlambda/sql/clause_info/interface/IClauseInfo.py +37 -0
- ormlambda/sql/clause_info/interface/__init__.py +1 -0
- ormlambda/sql/clauses/__init__.py +14 -0
- ormlambda/{databases/my_sql → sql}/clauses/alias.py +23 -6
- ormlambda/{databases/my_sql → sql}/clauses/count.py +15 -1
- ormlambda/{databases/my_sql → sql}/clauses/delete.py +22 -7
- ormlambda/sql/clauses/group_by.py +30 -0
- ormlambda/{databases/my_sql → sql}/clauses/having.py +7 -2
- ormlambda/{databases/my_sql → sql}/clauses/insert.py +16 -9
- ormlambda/sql/clauses/interfaces/__init__.py +5 -0
- ormlambda/sql/clauses/join/__init__.py +1 -0
- ormlambda/{databases/my_sql → sql/clauses/join}/join_context.py +15 -7
- ormlambda/{databases/my_sql → sql}/clauses/joins.py +29 -19
- ormlambda/sql/clauses/limit.py +15 -0
- ormlambda/sql/clauses/offset.py +15 -0
- ormlambda/{databases/my_sql → sql}/clauses/order.py +14 -24
- ormlambda/{databases/my_sql → sql}/clauses/select.py +14 -13
- ormlambda/{databases/my_sql → sql}/clauses/update.py +24 -11
- ormlambda/{databases/my_sql → sql}/clauses/upsert.py +19 -10
- ormlambda/{databases/my_sql → sql}/clauses/where.py +28 -8
- ormlambda/sql/column/__init__.py +1 -0
- ormlambda/sql/{column.py → column/column.py} +85 -22
- ormlambda/sql/comparer.py +51 -37
- ormlambda/sql/compiler.py +668 -0
- ormlambda/sql/ddl.py +82 -0
- ormlambda/sql/elements.py +36 -0
- ormlambda/sql/foreign_key.py +61 -39
- ormlambda/{databases/my_sql → sql}/functions/concat.py +13 -5
- ormlambda/{databases/my_sql → sql}/functions/max.py +9 -4
- ormlambda/{databases/my_sql → sql}/functions/min.py +9 -13
- ormlambda/{databases/my_sql → sql}/functions/sum.py +8 -10
- ormlambda/sql/sqltypes.py +647 -0
- ormlambda/sql/table/__init__.py +1 -1
- ormlambda/sql/table/table.py +175 -0
- ormlambda/sql/table/table_constructor.py +1 -208
- ormlambda/sql/type_api.py +35 -0
- ormlambda/sql/types.py +3 -1
- ormlambda/sql/visitors.py +74 -0
- ormlambda/statements/__init__.py +1 -0
- ormlambda/statements/base_statement.py +34 -40
- ormlambda/statements/interfaces/IStatements.py +28 -21
- ormlambda/statements/query_builder.py +163 -0
- ormlambda/{databases/my_sql → statements}/statements.py +68 -210
- ormlambda/statements/types.py +2 -2
- ormlambda/types/__init__.py +24 -0
- ormlambda/types/metadata.py +42 -0
- ormlambda/util/__init__.py +87 -0
- ormlambda/{utils → util}/module_tree/dynamic_module.py +4 -3
- ormlambda/util/plugin_loader.py +32 -0
- ormlambda/util/typing.py +6 -0
- ormlambda-3.34.0.dist-info/AUTHORS +32 -0
- {ormlambda-3.11.2.dist-info → ormlambda-3.34.0.dist-info}/METADATA +56 -10
- ormlambda-3.34.0.dist-info/RECORD +152 -0
- ormlambda/components/__init__.py +0 -4
- ormlambda/components/delete/__init__.py +0 -2
- ormlambda/components/delete/abstract_delete.py +0 -17
- ormlambda/components/insert/__init__.py +0 -2
- ormlambda/components/insert/abstract_insert.py +0 -25
- ormlambda/components/select/__init__.py +0 -1
- ormlambda/components/update/__init__.py +0 -2
- ormlambda/components/update/abstract_update.py +0 -29
- ormlambda/components/upsert/__init__.py +0 -2
- ormlambda/components/upsert/abstract_upsert.py +0 -25
- ormlambda/databases/__init__.py +0 -5
- ormlambda/databases/my_sql/__init__.py +0 -4
- ormlambda/databases/my_sql/caster/caster.py +0 -39
- ormlambda/databases/my_sql/clauses/__init__.py +0 -20
- ormlambda/databases/my_sql/clauses/create_database.py +0 -35
- ormlambda/databases/my_sql/clauses/drop_database.py +0 -17
- ormlambda/databases/my_sql/clauses/drop_table.py +0 -23
- ormlambda/databases/my_sql/clauses/group_by.py +0 -31
- ormlambda/databases/my_sql/clauses/limit.py +0 -17
- ormlambda/databases/my_sql/clauses/offset.py +0 -17
- ormlambda/databases/my_sql/repository/__init__.py +0 -1
- ormlambda/databases/my_sql/repository/repository.py +0 -351
- ormlambda/engine/template.py +0 -47
- ormlambda/sql/dtypes.py +0 -94
- ormlambda/utils/__init__.py +0 -1
- ormlambda-3.11.2.dist-info/RECORD +0 -120
- /ormlambda/{databases/my_sql → dialects/mysql}/caster/__init__.py +0 -0
- /ormlambda/{databases/my_sql/types.py → dialects/mysql/repository/pool_types.py} +0 -0
- /ormlambda/{components/delete → sql/clauses/interfaces}/IDelete.py +0 -0
- /ormlambda/{components/insert → sql/clauses/interfaces}/IInsert.py +0 -0
- /ormlambda/{components/select → sql/clauses/interfaces}/ISelect.py +0 -0
- /ormlambda/{components/update → sql/clauses/interfaces}/IUpdate.py +0 -0
- /ormlambda/{components/upsert → sql/clauses/interfaces}/IUpsert.py +0 -0
- /ormlambda/{databases/my_sql → sql}/functions/__init__.py +0 -0
- /ormlambda/{utils → util}/module_tree/__init__.py +0 -0
- /ormlambda/{utils → util}/module_tree/dfs_traversal.py +0 -0
- {ormlambda-3.11.2.dist-info → ormlambda-3.34.0.dist-info}/LICENSE +0 -0
- {ormlambda-3.11.2.dist-info → ormlambda-3.34.0.dist-info}/WHEEL +0 -0
@@ -0,0 +1,388 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
from types import ModuleType
|
3
|
+
from ormlambda.sql import compiler
|
4
|
+
from .. import default
|
5
|
+
from typing import TYPE_CHECKING, Any, Iterable
|
6
|
+
|
7
|
+
if TYPE_CHECKING:
|
8
|
+
from ormlambda.sql.column.column import Column
|
9
|
+
from mysql import connector
|
10
|
+
|
11
|
+
from .types import (
|
12
|
+
_NumericType,
|
13
|
+
_StringType,
|
14
|
+
NUMERIC,
|
15
|
+
DECIMAL,
|
16
|
+
DOUBLE,
|
17
|
+
REAL,
|
18
|
+
FLOAT,
|
19
|
+
INTEGER,
|
20
|
+
BIGINT,
|
21
|
+
MEDIUMINT,
|
22
|
+
TINYINT,
|
23
|
+
SMALLINT,
|
24
|
+
BIT,
|
25
|
+
TIME,
|
26
|
+
TIMESTAMP,
|
27
|
+
DATETIME,
|
28
|
+
YEAR,
|
29
|
+
TEXT,
|
30
|
+
TINYTEXT,
|
31
|
+
MEDIUMTEXT,
|
32
|
+
LONGTEXT,
|
33
|
+
NVARCHAR,
|
34
|
+
NCHAR,
|
35
|
+
TINYBLOB,
|
36
|
+
MEDIUMBLOB,
|
37
|
+
LONGBLOB,
|
38
|
+
)
|
39
|
+
from ormlambda.sql.sqltypes import BLOB
|
40
|
+
|
41
|
+
from .caster import MySQLCaster
|
42
|
+
from .repository import MySQLRepository
|
43
|
+
|
44
|
+
|
45
|
+
if TYPE_CHECKING:
|
46
|
+
from ormlambda.sql.clauses import (
|
47
|
+
Select,
|
48
|
+
Insert,
|
49
|
+
Delete,
|
50
|
+
Upsert,
|
51
|
+
Update,
|
52
|
+
Limit,
|
53
|
+
Offset,
|
54
|
+
Count,
|
55
|
+
Where,
|
56
|
+
Having,
|
57
|
+
Order,
|
58
|
+
GroupBy,
|
59
|
+
)
|
60
|
+
|
61
|
+
from ormlambda.sql.functions import (
|
62
|
+
Concat,
|
63
|
+
Max,
|
64
|
+
Min,
|
65
|
+
Sum,
|
66
|
+
)
|
67
|
+
|
68
|
+
|
69
|
+
from ormlambda.sql.clause_info.clause_info_context import ClauseInfoContext
|
70
|
+
|
71
|
+
|
72
|
+
class MySQLCompiler(compiler.SQLCompiler):
|
73
|
+
render_table_with_column_in_update_from = True
|
74
|
+
"""Overridden from base SQLCompiler value"""
|
75
|
+
|
76
|
+
def visit_select(self, select: Select, **kw):
|
77
|
+
return f"{select.CLAUSE} {select.COLUMNS} FROM {select.FROM.query(self.dialect,**kw)}"
|
78
|
+
|
79
|
+
def visit_group_by(self, groupby: GroupBy, **kw):
|
80
|
+
column = groupby._create_query(self.dialect, **kw)
|
81
|
+
return f"{groupby.FUNCTION_NAME()} {column}"
|
82
|
+
|
83
|
+
def visit_limit(self, limit: Limit, **kw):
|
84
|
+
return f"{limit.LIMIT} {limit._number}"
|
85
|
+
|
86
|
+
# TODOH []: include the rest of visit methods
|
87
|
+
def visit_insert(self, insert: Insert, **kw) -> Insert: ...
|
88
|
+
def visit_delete(self, delete: Delete, **kw) -> Delete: ...
|
89
|
+
def visit_upsert(self, upsert: Upsert, **kw) -> Upsert: ...
|
90
|
+
def visit_update(self, update: Update, **kw) -> Update: ...
|
91
|
+
def visit_offset(self, offset: Offset, **kw) -> Offset:
|
92
|
+
return f"{offset.OFFSET} {offset._number}"
|
93
|
+
|
94
|
+
def visit_count(self, count: Count, **kw) -> Count: ...
|
95
|
+
def visit_where(self, where: Where, **kw) -> Where: ...
|
96
|
+
def visit_having(self, having: Having, **kw) -> Having: ...
|
97
|
+
def visit_order(self, order: Order, **kw) -> Order:
|
98
|
+
string_columns: list[str] = []
|
99
|
+
columns = order.unresolved_column
|
100
|
+
|
101
|
+
# if this attr is not iterable means that we only pass one column without wrapped in a list or tuple
|
102
|
+
if isinstance(columns, str):
|
103
|
+
string_columns = f"{columns} {str(order._order_type[0])}"
|
104
|
+
return f"{order.FUNCTION_NAME()} {string_columns}"
|
105
|
+
|
106
|
+
if not isinstance(columns, Iterable):
|
107
|
+
columns = (columns,)
|
108
|
+
|
109
|
+
assert len(columns) == len(order._order_type)
|
110
|
+
|
111
|
+
context = ClauseInfoContext(table_context=order._context._table_context, clause_context=None) if order._context else None
|
112
|
+
for index, clause in enumerate(order._convert_into_clauseInfo(columns, context, dialect=self.dialect)):
|
113
|
+
clause.alias_clause = None
|
114
|
+
string_columns.append(f"{clause.query(self.dialect,**kw)} {str(order._order_type[index])}")
|
115
|
+
|
116
|
+
return f"{order.FUNCTION_NAME()} {', '.join(string_columns)}"
|
117
|
+
|
118
|
+
def visit_concat(self, concat: Concat, **kw) -> Concat: ...
|
119
|
+
def visit_max(self, max: Max, **kw) -> Max: ...
|
120
|
+
def visit_min(self, min: Min, **kw) -> Min: ...
|
121
|
+
def visit_sum(self, sum: Sum, **kw) -> Sum: ...
|
122
|
+
|
123
|
+
|
124
|
+
class MySQLDDLCompiler(compiler.DDLCompiler):
|
125
|
+
def get_column_specification(self, column: Column, **kwargs):
|
126
|
+
colspec = column.column_name + " " + self.dialect.type_compiler_instance.process(column.dtype)
|
127
|
+
default = self.get_column_default_string(column)
|
128
|
+
if default is not None:
|
129
|
+
colspec += " DEFAULT " + default
|
130
|
+
|
131
|
+
if column.is_not_null:
|
132
|
+
colspec += " NOT NULL"
|
133
|
+
|
134
|
+
if column.is_primary_key:
|
135
|
+
colspec += " PRIMARY KEY"
|
136
|
+
|
137
|
+
colspec += " AUTO_INCREMENT" if column.is_auto_increment else ""
|
138
|
+
|
139
|
+
return colspec
|
140
|
+
|
141
|
+
|
142
|
+
class MySQLTypeCompiler(compiler.GenericTypeCompiler):
|
143
|
+
def mysql_type(self, type_: Any) -> bool:
|
144
|
+
return isinstance(type_, (_StringType, _NumericType))
|
145
|
+
|
146
|
+
def _extend_numeric(self, type_: _NumericType, spec: str) -> str:
|
147
|
+
"Extend a numeric-type declaration with MySQL specific extensions."
|
148
|
+
|
149
|
+
if not self.mysql_type(type_):
|
150
|
+
return spec
|
151
|
+
|
152
|
+
if type_.unsigned:
|
153
|
+
spec += " UNSIGNED"
|
154
|
+
if type_.zerofill:
|
155
|
+
spec += " ZEROFILL"
|
156
|
+
return spec
|
157
|
+
|
158
|
+
def _extend_string(self, type_: _StringType, defaults, spec):
|
159
|
+
"""Extend a string-type declaration with standard SQL CHARACTER SET /
|
160
|
+
COLLATE annotations and MySQL specific extensions.
|
161
|
+
|
162
|
+
"""
|
163
|
+
|
164
|
+
def attr(name):
|
165
|
+
return getattr(type_, name, defaults.get(name))
|
166
|
+
|
167
|
+
if attr("charset"):
|
168
|
+
charset = f"CHARACTER SET {attr("charset")}"
|
169
|
+
elif attr("ascii"):
|
170
|
+
charset = "ASCII"
|
171
|
+
elif attr("unicode"):
|
172
|
+
charset = "UNICODE"
|
173
|
+
else:
|
174
|
+
charset = None
|
175
|
+
|
176
|
+
if attr("collation"):
|
177
|
+
collation = f"COLLATE {type_.collation}"
|
178
|
+
elif attr("binary"):
|
179
|
+
collation = "BINARY"
|
180
|
+
else:
|
181
|
+
collation = None
|
182
|
+
|
183
|
+
if attr("national"):
|
184
|
+
# NATIONAL (aka NCHAR/NVARCHAR) trumps charsets.
|
185
|
+
return " ".join([c for c in ("NATIONAL", spec, collation) if c is not None])
|
186
|
+
return " ".join([c for c in (spec, charset, collation) if c is not None])
|
187
|
+
|
188
|
+
def visit_INTEGER(self, type_: INTEGER, **kw):
|
189
|
+
if self.mysql_type(type_) and type_.display_width is not None:
|
190
|
+
return self._extend_numeric(
|
191
|
+
type_,
|
192
|
+
f"INTEGER(%({type_.display_width})s)",
|
193
|
+
)
|
194
|
+
else:
|
195
|
+
return self._extend_numeric(type_, "INTEGER")
|
196
|
+
|
197
|
+
def visit_VARCHAR(self, type_, **kw):
|
198
|
+
if type_.length is None:
|
199
|
+
raise ValueError("VARCHAR requires a length on dialect %s" % self.dialect.name)
|
200
|
+
return self._extend_string(type_, {}, "VARCHAR(%d)" % type_.length)
|
201
|
+
|
202
|
+
def visit_CHAR(self, type_, **kw):
|
203
|
+
if type_.length is not None:
|
204
|
+
return self._extend_string(type_, {}, "CHAR(%(length)s)" % {"length": type_.length})
|
205
|
+
else:
|
206
|
+
return self._extend_string(type_, {}, "CHAR")
|
207
|
+
|
208
|
+
def visit_NUMERIC(self, type_: NUMERIC, **kw):
|
209
|
+
return "NUMERIC"
|
210
|
+
|
211
|
+
def visit_DECIMAL(self, type_: DECIMAL, **kw):
|
212
|
+
return "DECIMAL"
|
213
|
+
|
214
|
+
def visit_DOUBLE(self, type_: DOUBLE, **kw):
|
215
|
+
return "DOUBLE"
|
216
|
+
|
217
|
+
def visit_REAL(self, type_: REAL, **kw):
|
218
|
+
return "REAL"
|
219
|
+
|
220
|
+
def visit_FLOAT(self, type_: FLOAT, **kw):
|
221
|
+
return "FLOAT"
|
222
|
+
|
223
|
+
def visit_BIGINT(self, type_: BIGINT, **kw):
|
224
|
+
return "BIGINT"
|
225
|
+
|
226
|
+
def visit_MEDIUMINT(self, type_: MEDIUMINT, **kw):
|
227
|
+
return "MEDIUMINT"
|
228
|
+
|
229
|
+
def visit_TINYINT(self, type_: TINYINT, **kw):
|
230
|
+
return "TINYINT"
|
231
|
+
|
232
|
+
def visit_SMALLINT(self, type_: SMALLINT, **kw):
|
233
|
+
return "SMALLINT"
|
234
|
+
|
235
|
+
def visit_BIT(self, type_: BIT, **kw):
|
236
|
+
return "BIT"
|
237
|
+
|
238
|
+
def visit_TIME(self, type_: TIME, **kw):
|
239
|
+
return "TIME"
|
240
|
+
|
241
|
+
def visit_TIMESTAMP(self, type_: TIMESTAMP, **kw):
|
242
|
+
return "TIMESTAMP"
|
243
|
+
|
244
|
+
def visit_DATETIME(self, type_: DATETIME, **kw):
|
245
|
+
return "DATETIME"
|
246
|
+
|
247
|
+
def visit_YEAR(self, type_: YEAR, **kw):
|
248
|
+
return "YEAR"
|
249
|
+
|
250
|
+
def visit_TEXT(self, type_: TEXT, **kw):
|
251
|
+
if type_.length is not None:
|
252
|
+
return self._extend_string(type_, {}, f"TEXT({type_.length})")
|
253
|
+
return self._extend_string(type_, {}, "TEXT")
|
254
|
+
|
255
|
+
def visit_TINYTEXT(self, type_: TINYTEXT, **kw):
|
256
|
+
return "TINYTEXT"
|
257
|
+
|
258
|
+
def visit_MEDIUMTEXT(self, type_: MEDIUMTEXT, **kw):
|
259
|
+
return "MEDIUMTEXT"
|
260
|
+
|
261
|
+
def visit_LONGTEXT(self, type_: LONGTEXT, **kw):
|
262
|
+
return "LONGTEXT"
|
263
|
+
|
264
|
+
def visit_NVARCHAR(self, type_: NVARCHAR, **kw):
|
265
|
+
return "NVARCHAR"
|
266
|
+
|
267
|
+
def visit_NCHAR(self, type_: NCHAR, **kw):
|
268
|
+
return "NCHAR"
|
269
|
+
|
270
|
+
def visit_TINYBLOB(self, type_: TINYBLOB, **kw):
|
271
|
+
return "TINYBLOB"
|
272
|
+
|
273
|
+
def visit_BLOB(self, type_: BLOB, **kw) -> str:
|
274
|
+
blob = "BLOB"
|
275
|
+
blob += f"({type_.length})" if type_.length is not None else ""
|
276
|
+
return blob
|
277
|
+
|
278
|
+
def visit_MEDIUMBLOB(self, type_: MEDIUMBLOB, **kw):
|
279
|
+
return "MEDIUMBLOB"
|
280
|
+
|
281
|
+
def visit_LONGBLOB(self, type_: LONGBLOB, **kw):
|
282
|
+
return "LONGBLOB"
|
283
|
+
|
284
|
+
# region visit lowercase
|
285
|
+
|
286
|
+
def visit_integer(self, type_: INTEGER, **kw):
|
287
|
+
return self.visit_INTEGER(type_, **kw)
|
288
|
+
|
289
|
+
def visit_varchar(self, type_, **kw):
|
290
|
+
return self.visit_VARCHAR(type_, **kw)
|
291
|
+
|
292
|
+
def visit_char(self, type_, **kw):
|
293
|
+
return self.visit_CHAR(type_, **kw)
|
294
|
+
|
295
|
+
def visit_numeric(self, type_: NUMERIC, **kw):
|
296
|
+
return self.visit_NUMERIC(type_, **kw)
|
297
|
+
|
298
|
+
def visit_decimal(self, type_: DECIMAL, **kw):
|
299
|
+
return self.visit_DECIMAL(type_, **kw)
|
300
|
+
|
301
|
+
def visit_double(self, type_: DOUBLE, **kw):
|
302
|
+
return self.visit_DOUBLE(type_, **kw)
|
303
|
+
|
304
|
+
def visit_real(self, type_: REAL, **kw):
|
305
|
+
return self.visit_REAL(type_, **kw)
|
306
|
+
|
307
|
+
def visit_float(self, type_: FLOAT, **kw):
|
308
|
+
return self.visit_FLOAT(type_, **kw)
|
309
|
+
|
310
|
+
def visit_bigint(self, type_: BIGINT, **kw):
|
311
|
+
return self.visit_BIGINT(type_, **kw)
|
312
|
+
|
313
|
+
def visit_mediumint(self, type_: MEDIUMINT, **kw):
|
314
|
+
return self.visit_MEDIUMINT(type_, **kw)
|
315
|
+
|
316
|
+
def visit_tinyint(self, type_: TINYINT, **kw):
|
317
|
+
return self.visit_TINYINT(type_, **kw)
|
318
|
+
|
319
|
+
def visit_smallint(self, type_: SMALLINT, **kw):
|
320
|
+
return self.visit_SMALLINT(type_, **kw)
|
321
|
+
|
322
|
+
def visit_bit(self, type_: BIT, **kw):
|
323
|
+
return self.visit_BIT(type_, **kw)
|
324
|
+
|
325
|
+
def visit_time(self, type_: TIME, **kw):
|
326
|
+
return self.visit_TIME(type_, **kw)
|
327
|
+
|
328
|
+
def visit_timestamp(self, type_: TIMESTAMP, **kw):
|
329
|
+
return self.visit_TIMESTAMP(type_, **kw)
|
330
|
+
|
331
|
+
def visit_datetime(self, type_: DATETIME, **kw):
|
332
|
+
return self.visit_DATETIME(type_, **kw)
|
333
|
+
|
334
|
+
def visit_year(self, type_: YEAR, **kw):
|
335
|
+
return self.visit_YEAR(type_, **kw)
|
336
|
+
|
337
|
+
def visit_text(self, type_: TEXT, **kw):
|
338
|
+
return self.visit_TEXT(type_, **kw)
|
339
|
+
|
340
|
+
def visit_tinytext(self, type_: TINYTEXT, **kw):
|
341
|
+
return self.visit_TINYTEXT(type_, **kw)
|
342
|
+
|
343
|
+
def visit_mediumtext(self, type_: MEDIUMTEXT, **kw):
|
344
|
+
return self.visit_MEDIUMTEXT(type_, **kw)
|
345
|
+
|
346
|
+
def visit_longtext(self, type_: LONGTEXT, **kw):
|
347
|
+
return self.visit_LONGTEXT(type_, **kw)
|
348
|
+
|
349
|
+
def visit_nvarchar(self, type_: NVARCHAR, **kw):
|
350
|
+
return self.visit_NVARCHAR(type_, **kw)
|
351
|
+
|
352
|
+
def visit_nchar(self, type_: NCHAR, **kw):
|
353
|
+
return self.visit_NCHAR(type_, **kw)
|
354
|
+
|
355
|
+
def visit_tinyblob(self, type_: TINYBLOB, **kw):
|
356
|
+
return self.visit_TINYBLOB(type_, **kw)
|
357
|
+
|
358
|
+
def visit_mediumblob(self, type_: MEDIUMBLOB, **kw):
|
359
|
+
return self.visit_MEDIUMBLOB(type_, **kw)
|
360
|
+
|
361
|
+
def visit_longblob(self, type_: LONGBLOB, **kw):
|
362
|
+
return self.visit_LONGBLOB(type_, **kw)
|
363
|
+
|
364
|
+
# endregion
|
365
|
+
|
366
|
+
|
367
|
+
class MySQLDialect(default.DefaultDialect):
|
368
|
+
"""Details of the MySQL dialect.
|
369
|
+
Not used directly in application code.
|
370
|
+
"""
|
371
|
+
|
372
|
+
dbapi: connector
|
373
|
+
name = "mysql"
|
374
|
+
|
375
|
+
statement_compiler = MySQLCompiler
|
376
|
+
ddl_compiler = MySQLDDLCompiler
|
377
|
+
type_compiler_cls = MySQLTypeCompiler
|
378
|
+
repository_cls = MySQLRepository
|
379
|
+
caster = MySQLCaster
|
380
|
+
|
381
|
+
def __init__(self, **kwargs):
|
382
|
+
super().__init__(**kwargs)
|
383
|
+
|
384
|
+
@classmethod
|
385
|
+
def import_dbapi(cls) -> ModuleType:
|
386
|
+
from mysql import connector
|
387
|
+
|
388
|
+
return connector
|
@@ -0,0 +1,39 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
from ormlambda.caster.caster import Caster
|
3
|
+
|
4
|
+
|
5
|
+
from .types import (
|
6
|
+
StringCaster,
|
7
|
+
IntegerCaster,
|
8
|
+
FloatCaster,
|
9
|
+
PointCaster,
|
10
|
+
NoneTypeCaster,
|
11
|
+
DatetimeCaster,
|
12
|
+
BytesCaster,
|
13
|
+
IterableCaster,
|
14
|
+
BooleanCaster,
|
15
|
+
)
|
16
|
+
|
17
|
+
from shapely import Point
|
18
|
+
from types import NoneType
|
19
|
+
from datetime import datetime
|
20
|
+
|
21
|
+
|
22
|
+
class MySQLCaster(Caster):
|
23
|
+
PLACEHOLDER = "%s"
|
24
|
+
|
25
|
+
@classmethod
|
26
|
+
def CASTER_SELECTOR(cls):
|
27
|
+
return {
|
28
|
+
str: StringCaster,
|
29
|
+
int: IntegerCaster,
|
30
|
+
float: FloatCaster,
|
31
|
+
Point: PointCaster,
|
32
|
+
NoneType: NoneTypeCaster,
|
33
|
+
datetime: DatetimeCaster,
|
34
|
+
bytes: BytesCaster,
|
35
|
+
bytearray: BytesCaster,
|
36
|
+
tuple: IterableCaster,
|
37
|
+
list: IterableCaster,
|
38
|
+
bool: BooleanCaster,
|
39
|
+
}
|
@@ -0,0 +1,35 @@
|
|
1
|
+
from typing import Optional
|
2
|
+
from ormlambda.caster import BaseCaster, Caster
|
3
|
+
|
4
|
+
|
5
|
+
class BooleanCaster[TType](BaseCaster[bool, TType]):
|
6
|
+
"""
|
7
|
+
MySQL uses 0/1 for booleans stored in TINYINT
|
8
|
+
"""
|
9
|
+
|
10
|
+
def __init__(self, value: bool, type_value: TType):
|
11
|
+
super().__init__(value, type_value)
|
12
|
+
|
13
|
+
def wildcard_to_select(self, value: Optional[str] = None) -> str:
|
14
|
+
return Caster.PLACEHOLDER if value is None else value
|
15
|
+
|
16
|
+
def wildcard_to_where(self, value: Optional[str] = None) -> str:
|
17
|
+
return Caster.PLACEHOLDER if value is None else value
|
18
|
+
|
19
|
+
def wildcard_to_insert(self, value: Optional[str] = None) -> str:
|
20
|
+
return Caster.PLACEHOLDER if value is None else value
|
21
|
+
|
22
|
+
@property
|
23
|
+
@BaseCaster.return_value_if_exists
|
24
|
+
def to_database(self) -> Optional[int]:
|
25
|
+
return 1 if self.value else 0
|
26
|
+
|
27
|
+
@property
|
28
|
+
@BaseCaster.return_value_if_exists
|
29
|
+
def from_database(self) -> Optional[bool]:
|
30
|
+
return bool(self.value)
|
31
|
+
|
32
|
+
@property
|
33
|
+
@BaseCaster.return_value_if_exists
|
34
|
+
def string_data(self) -> Optional[str]:
|
35
|
+
return str(bool(self.value))
|
@@ -1,19 +1,19 @@
|
|
1
1
|
from typing import Optional
|
2
|
-
from ormlambda.caster import BaseCaster,
|
2
|
+
from ormlambda.caster import BaseCaster, Caster
|
3
3
|
|
4
4
|
|
5
5
|
class BytesCaster[TType](BaseCaster[bytes, TType]):
|
6
6
|
def __init__(self, value: bytes, type_value: TType):
|
7
7
|
super().__init__(value, type_value)
|
8
8
|
|
9
|
-
def wildcard_to_select(self, value: str =
|
10
|
-
return value
|
9
|
+
def wildcard_to_select(self, value: Optional[str] = None) -> str:
|
10
|
+
return Caster.PLACEHOLDER if value is None else value
|
11
11
|
|
12
|
-
def wildcard_to_where(self, value: str =
|
13
|
-
return value
|
12
|
+
def wildcard_to_where(self, value: Optional[str] = None) -> str:
|
13
|
+
return Caster.PLACEHOLDER if value is None else value
|
14
14
|
|
15
|
-
def wildcard_to_insert(self, value: str =
|
16
|
-
return value
|
15
|
+
def wildcard_to_insert(self, value: Optional[str] = None) -> str:
|
16
|
+
return Caster.PLACEHOLDER if value is None else value
|
17
17
|
|
18
18
|
@property
|
19
19
|
@BaseCaster.return_value_if_exists
|
@@ -1,5 +1,5 @@
|
|
1
1
|
from typing import Optional
|
2
|
-
from ormlambda.caster import BaseCaster,
|
2
|
+
from ormlambda.caster import BaseCaster, Caster
|
3
3
|
from datetime import datetime
|
4
4
|
from .string import StringCaster
|
5
5
|
|
@@ -8,14 +8,14 @@ class DatetimeCaster[TType](BaseCaster[datetime, TType]):
|
|
8
8
|
def __init__(self, value: datetime, type_value: TType):
|
9
9
|
super().__init__(value, type_value)
|
10
10
|
|
11
|
-
def wildcard_to_select(self, value: str =
|
12
|
-
return value
|
11
|
+
def wildcard_to_select(self, value: Optional[str] = None) -> str:
|
12
|
+
return Caster.PLACEHOLDER if value is None else value
|
13
13
|
|
14
|
-
def wildcard_to_where(self, value: str =
|
15
|
-
return value
|
14
|
+
def wildcard_to_where(self, value: Optional[str] = None) -> str:
|
15
|
+
return Caster.PLACEHOLDER if value is None else value
|
16
16
|
|
17
|
-
def wildcard_to_insert(self, value: str =
|
18
|
-
return value
|
17
|
+
def wildcard_to_insert(self, value: Optional[str] = None) -> str:
|
18
|
+
return Caster.PLACEHOLDER if value is None else value
|
19
19
|
|
20
20
|
@property
|
21
21
|
@BaseCaster.return_value_if_exists
|
@@ -1,19 +1,19 @@
|
|
1
1
|
from typing import Optional
|
2
|
-
from ormlambda.caster import BaseCaster,
|
2
|
+
from ormlambda.caster import BaseCaster, Caster
|
3
3
|
|
4
4
|
|
5
5
|
class FloatCaster[TType](BaseCaster[float, TType]):
|
6
6
|
def __init__(self, value: float, type_value: TType):
|
7
7
|
super().__init__(value, type_value)
|
8
8
|
|
9
|
-
def wildcard_to_select(self, value: str =
|
10
|
-
return value
|
9
|
+
def wildcard_to_select(self, value: Optional[str] = None) -> str:
|
10
|
+
return Caster.PLACEHOLDER if value is None else value
|
11
11
|
|
12
|
-
def wildcard_to_where(self, value: str =
|
13
|
-
return value
|
12
|
+
def wildcard_to_where(self, value: Optional[str] = None) -> str:
|
13
|
+
return Caster.PLACEHOLDER if value is None else value
|
14
14
|
|
15
|
-
def wildcard_to_insert(self, value: str =
|
16
|
-
return value
|
15
|
+
def wildcard_to_insert(self, value: Optional[str] = None) -> str:
|
16
|
+
return Caster.PLACEHOLDER if value is None else value
|
17
17
|
|
18
18
|
@property
|
19
19
|
@BaseCaster.return_value_if_exists
|
@@ -1,19 +1,19 @@
|
|
1
1
|
from typing import Optional
|
2
|
-
from ormlambda.caster import BaseCaster,
|
2
|
+
from ormlambda.caster import BaseCaster, Caster
|
3
3
|
|
4
4
|
|
5
5
|
class IntegerCaster[TType](BaseCaster[int, TType]):
|
6
6
|
def __init__(self, value: int, type_value: TType):
|
7
7
|
super().__init__(value, type_value)
|
8
8
|
|
9
|
-
def wildcard_to_select(self, value: str =
|
10
|
-
return value
|
9
|
+
def wildcard_to_select(self, value: Optional[str] = None) -> str:
|
10
|
+
return Caster.PLACEHOLDER if value is None else value
|
11
11
|
|
12
|
-
def wildcard_to_where(self, value: str =
|
13
|
-
return value
|
12
|
+
def wildcard_to_where(self, value: Optional[str] = None) -> str:
|
13
|
+
return Caster.PLACEHOLDER if value is None else value
|
14
14
|
|
15
|
-
def wildcard_to_insert(self, value: str =
|
16
|
-
return value
|
15
|
+
def wildcard_to_insert(self, value: Optional[str] = None) -> str:
|
16
|
+
return Caster.PLACEHOLDER if value is None else value
|
17
17
|
|
18
18
|
@property
|
19
19
|
@BaseCaster.return_value_if_exists
|
@@ -1,19 +1,19 @@
|
|
1
1
|
from typing import Optional
|
2
|
-
from ormlambda.caster import BaseCaster,
|
2
|
+
from ormlambda.caster import BaseCaster, Caster
|
3
3
|
|
4
4
|
|
5
5
|
class IterableCaster[TType](BaseCaster[bytes, TType]):
|
6
6
|
def __init__(self, value: bytes, type_value: TType):
|
7
7
|
super().__init__(value, type_value)
|
8
8
|
|
9
|
-
def wildcard_to_select(self, value: str =
|
10
|
-
return value
|
9
|
+
def wildcard_to_select(self, value: Optional[str] = None) -> str:
|
10
|
+
return Caster.PLACEHOLDER if value is None else value
|
11
11
|
|
12
|
-
def wildcard_to_where(self, value: str =
|
13
|
-
return value
|
12
|
+
def wildcard_to_where(self, value: Optional[str] = None) -> str:
|
13
|
+
return Caster.PLACEHOLDER if value is None else value
|
14
14
|
|
15
|
-
def wildcard_to_insert(self, value: str =
|
16
|
-
return value
|
15
|
+
def wildcard_to_insert(self, value: Optional[str] = None) -> str:
|
16
|
+
return Caster.PLACEHOLDER if value is None else value
|
17
17
|
|
18
18
|
@property
|
19
19
|
@BaseCaster.return_value_if_exists
|
@@ -1,19 +1,20 @@
|
|
1
1
|
from types import NoneType
|
2
|
-
from
|
2
|
+
from typing import Optional
|
3
|
+
from ormlambda.caster import BaseCaster, Caster
|
3
4
|
|
4
5
|
|
5
6
|
class NoneTypeCaster[TType](BaseCaster[NoneType, TType]):
|
6
7
|
def __init__(self, value: NoneType, type_value: TType):
|
7
8
|
super().__init__(value, type_value)
|
8
9
|
|
9
|
-
def wildcard_to_select(self, value: str =
|
10
|
-
return value
|
10
|
+
def wildcard_to_select(self, value: Optional[str] = None) -> str:
|
11
|
+
return Caster.PLACEHOLDER if value is None else value
|
11
12
|
|
12
|
-
def wildcard_to_where(self, value: str =
|
13
|
-
return value
|
13
|
+
def wildcard_to_where(self, value: Optional[str] = None) -> str:
|
14
|
+
return Caster.PLACEHOLDER if value is None else value
|
14
15
|
|
15
|
-
def wildcard_to_insert(self, value: str =
|
16
|
-
return value
|
16
|
+
def wildcard_to_insert(self, value: Optional[str] = None) -> str:
|
17
|
+
return Caster.PLACEHOLDER if value is None else value
|
17
18
|
|
18
19
|
# TODOL: cheched if it's right
|
19
20
|
@property
|
@@ -1,5 +1,5 @@
|
|
1
1
|
from typing import Optional
|
2
|
-
from ormlambda.caster import BaseCaster,
|
2
|
+
from ormlambda.caster import BaseCaster, Caster
|
3
3
|
from shapely import Point
|
4
4
|
import shapely.wkt as wkt
|
5
5
|
from shapely import wkb
|
@@ -9,13 +9,13 @@ class PointCaster[TType](BaseCaster[Point, TType]):
|
|
9
9
|
def __init__(self, value: bytes | str, type_value: TType):
|
10
10
|
super().__init__(value, type_value)
|
11
11
|
|
12
|
-
def wildcard_to_select(self, value: str = PLACEHOLDER) -> str:
|
12
|
+
def wildcard_to_select(self, value: str = Caster.PLACEHOLDER) -> str:
|
13
13
|
return f"ST_AsText({value})"
|
14
14
|
|
15
|
-
def wildcard_to_where(self, value: str = PLACEHOLDER) -> str:
|
15
|
+
def wildcard_to_where(self, value: str = Caster.PLACEHOLDER) -> str:
|
16
16
|
return f"ST_AsText({value})"
|
17
17
|
|
18
|
-
def wildcard_to_insert(self, value: str = PLACEHOLDER) -> str:
|
18
|
+
def wildcard_to_insert(self, value: str = Caster.PLACEHOLDER) -> str:
|
19
19
|
return f"ST_GeomFromText({value})"
|
20
20
|
|
21
21
|
@property
|
@@ -1,19 +1,19 @@
|
|
1
1
|
from typing import Optional
|
2
|
-
from ormlambda.caster import BaseCaster,
|
2
|
+
from ormlambda.caster import BaseCaster, Caster
|
3
3
|
|
4
4
|
|
5
5
|
class StringCaster[TType](BaseCaster[str, TType]):
|
6
6
|
def __init__(self, value: str, type_value: TType):
|
7
7
|
super().__init__(value, type_value)
|
8
8
|
|
9
|
-
def wildcard_to_select(self, value: str =
|
10
|
-
return value
|
9
|
+
def wildcard_to_select(self, value: Optional[str] = None) -> str:
|
10
|
+
return Caster.PLACEHOLDER if value is None else value
|
11
11
|
|
12
|
-
def wildcard_to_where(self, value: str =
|
13
|
-
return value
|
12
|
+
def wildcard_to_where(self, value: Optional[str] = None) -> str:
|
13
|
+
return Caster.PLACEHOLDER if value is None else value
|
14
14
|
|
15
|
-
def wildcard_to_insert(self, value: str =
|
16
|
-
return value
|
15
|
+
def wildcard_to_insert(self, value: Optional[str] = None) -> str:
|
16
|
+
return Caster.PLACEHOLDER if value is None else value
|
17
17
|
|
18
18
|
@property
|
19
19
|
@BaseCaster.return_value_if_exists
|