ormlambda 3.12.2__py3-none-any.whl → 3.34.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.
- ormlambda/__init__.py +2 -0
- ormlambda/caster/__init__.py +1 -1
- ormlambda/caster/caster.py +29 -12
- ormlambda/common/abstract_classes/clause_info_converter.py +4 -12
- ormlambda/common/abstract_classes/decomposition_query.py +17 -2
- ormlambda/common/abstract_classes/non_query_base.py +9 -7
- ormlambda/common/abstract_classes/query_base.py +3 -1
- ormlambda/common/errors/__init__.py +29 -0
- ormlambda/common/interfaces/IQueryCommand.py +6 -2
- ormlambda/databases/__init__.py +0 -1
- ormlambda/databases/my_sql/__init__.py +0 -1
- ormlambda/databases/my_sql/caster/caster.py +23 -19
- ormlambda/databases/my_sql/caster/types/__init__.py +3 -0
- ormlambda/databases/my_sql/caster/types/boolean.py +35 -0
- ormlambda/databases/my_sql/caster/types/bytes.py +7 -7
- ormlambda/databases/my_sql/caster/types/date.py +34 -0
- ormlambda/databases/my_sql/caster/types/datetime.py +7 -7
- ormlambda/databases/my_sql/caster/types/decimal.py +32 -0
- ormlambda/databases/my_sql/caster/types/float.py +7 -7
- ormlambda/databases/my_sql/caster/types/int.py +7 -7
- ormlambda/databases/my_sql/caster/types/iterable.py +7 -7
- ormlambda/databases/my_sql/caster/types/none.py +8 -7
- ormlambda/databases/my_sql/caster/types/point.py +4 -4
- ormlambda/databases/my_sql/caster/types/string.py +7 -7
- ormlambda/databases/my_sql/clauses/ST_AsText.py +8 -7
- ormlambda/databases/my_sql/clauses/ST_Contains.py +10 -5
- ormlambda/databases/my_sql/clauses/__init__.py +4 -10
- ormlambda/databases/my_sql/clauses/count.py +5 -15
- ormlambda/databases/my_sql/clauses/delete.py +3 -50
- ormlambda/databases/my_sql/clauses/group_by.py +3 -16
- ormlambda/databases/my_sql/clauses/having.py +2 -6
- ormlambda/databases/my_sql/clauses/insert.py +4 -92
- ormlambda/databases/my_sql/clauses/joins.py +5 -140
- ormlambda/databases/my_sql/clauses/limit.py +4 -15
- ormlambda/databases/my_sql/clauses/offset.py +4 -15
- ormlambda/databases/my_sql/clauses/order.py +4 -61
- ormlambda/databases/my_sql/clauses/update.py +4 -67
- ormlambda/databases/my_sql/clauses/upsert.py +3 -66
- ormlambda/databases/my_sql/clauses/where.py +4 -42
- ormlambda/databases/my_sql/repository.py +217 -0
- 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 +8 -0
- ormlambda/dialects/mysql/base.py +387 -0
- ormlambda/dialects/mysql/mysqlconnector.py +46 -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 +58 -0
- ormlambda/engine/create.py +9 -23
- ormlambda/engine/url.py +31 -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 +121 -7
- ormlambda/repository/response.py +134 -0
- ormlambda/sql/clause_info/aggregate_function_base.py +19 -9
- ormlambda/sql/clause_info/clause_info.py +34 -17
- ormlambda/sql/clauses/__init__.py +14 -0
- ormlambda/{databases/my_sql → sql}/clauses/alias.py +23 -6
- ormlambda/sql/clauses/count.py +57 -0
- ormlambda/sql/clauses/delete.py +71 -0
- ormlambda/sql/clauses/group_by.py +30 -0
- ormlambda/sql/clauses/having.py +21 -0
- ormlambda/sql/clauses/insert.py +104 -0
- ormlambda/sql/clauses/interfaces/__init__.py +5 -0
- ormlambda/{components → sql/clauses}/join/join_context.py +15 -7
- ormlambda/sql/clauses/joins.py +159 -0
- ormlambda/sql/clauses/limit.py +15 -0
- ormlambda/sql/clauses/offset.py +15 -0
- ormlambda/sql/clauses/order.py +55 -0
- ormlambda/{databases/my_sql → sql}/clauses/select.py +12 -13
- ormlambda/sql/clauses/update.py +84 -0
- ormlambda/sql/clauses/upsert.py +77 -0
- ormlambda/sql/clauses/where.py +65 -0
- ormlambda/sql/column/__init__.py +1 -0
- ormlambda/sql/{column.py → column/column.py} +82 -22
- ormlambda/sql/comparer.py +51 -37
- ormlambda/sql/compiler.py +427 -0
- ormlambda/sql/ddl.py +68 -0
- ormlambda/sql/elements.py +36 -0
- ormlambda/sql/foreign_key.py +43 -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 +179 -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 +28 -38
- ormlambda/statements/interfaces/IStatements.py +5 -4
- ormlambda/{databases/my_sql → statements}/query_builder.py +35 -30
- ormlambda/{databases/my_sql → statements}/statements.py +50 -60
- ormlambda/statements/types.py +2 -2
- ormlambda/types/__init__.py +24 -0
- ormlambda/types/metadata.py +42 -0
- ormlambda/util/__init__.py +88 -0
- ormlambda/util/load_module.py +21 -0
- ormlambda/util/plugin_loader.py +32 -0
- ormlambda/util/typing.py +6 -0
- ormlambda-3.34.1.dist-info/AUTHORS +32 -0
- {ormlambda-3.12.2.dist-info → ormlambda-3.34.1.dist-info}/METADATA +2 -3
- ormlambda-3.34.1.dist-info/RECORD +157 -0
- {ormlambda-3.12.2.dist-info → ormlambda-3.34.1.dist-info}/WHEEL +1 -1
- 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/my_sql/clauses/create_database.py +0 -35
- ormlambda/databases/my_sql/clauses/drop_database.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.12.2.dist-info/RECORD +0 -125
- /ormlambda/databases/my_sql/{types.py → 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/{components → sql/clauses}/join/__init__.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/{utils → util}/module_tree/dynamic_module.py +0 -0
- {ormlambda-3.12.2.dist-info → ormlambda-3.34.1.dist-info}/LICENSE +0 -0
ormlambda/__init__.py
CHANGED
ormlambda/caster/__init__.py
CHANGED
ormlambda/caster/caster.py
CHANGED
@@ -1,24 +1,26 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
3
|
|
4
|
-
from typing import Optional, Type, TYPE_CHECKING, Callable, overload
|
5
|
-
|
4
|
+
from typing import ClassVar, Optional, Type, TYPE_CHECKING, Callable, overload, get_args
|
5
|
+
from types import NoneType
|
6
|
+
from ormlambda.caster.interfaces import ICaster
|
6
7
|
from ormlambda.common.global_checker import GlobalChecker
|
7
8
|
from ormlambda.sql.types import ColumnType
|
8
|
-
from ormlambda.
|
9
|
+
from ormlambda.caster import BaseCaster
|
10
|
+
from ormlambda.sql.sqltypes import TypeEngine
|
11
|
+
|
9
12
|
|
10
13
|
if TYPE_CHECKING:
|
11
14
|
from ormlambda.caster import BaseCaster
|
12
|
-
from ormlambda.repository import IRepositoryBase
|
13
15
|
|
14
16
|
|
15
|
-
|
17
|
+
class Caster(ICaster):
|
18
|
+
PLACEHOLDER: ClassVar[str] = "%s"
|
16
19
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
self._caster = RepositoryTemplateDict().get(repository).caster
|
20
|
+
@classmethod
|
21
|
+
def set_placeholder(cls, char: str) -> None:
|
22
|
+
cls.PLACEHOLDER = char
|
23
|
+
return None
|
22
24
|
|
23
25
|
@overload
|
24
26
|
def for_column[T, TProp](self, column: Callable[[T], TProp], instance: T) -> BaseCaster[TProp, Type[TProp]]: ...
|
@@ -36,7 +38,7 @@ class Caster:
|
|
36
38
|
column_type = column.dtype
|
37
39
|
value = instance[column]
|
38
40
|
|
39
|
-
return self.
|
41
|
+
return self.cast(value, column_type)
|
40
42
|
|
41
43
|
@overload
|
42
44
|
def for_value[TProp](self, value: TProp) -> BaseCaster[TProp, Type[TProp]]: ...
|
@@ -45,4 +47,19 @@ class Caster:
|
|
45
47
|
|
46
48
|
def for_value[TProp, TType](self, value: TProp, value_type: Optional[TType] = None) -> BaseCaster[TProp, TType]:
|
47
49
|
column_type = value_type if value_type else type(value)
|
48
|
-
return self.
|
50
|
+
return self.cast(value, column_type)
|
51
|
+
|
52
|
+
@classmethod
|
53
|
+
def cast[TProp, TType](cls, value: TProp, type_value: Optional[TypeEngine[TType]] = None) -> BaseCaster[TProp, TType]:
|
54
|
+
if len(args := get_args(type_value)) > 1:
|
55
|
+
args = [x for x in args if x != NoneType]
|
56
|
+
|
57
|
+
type_value = args[0]
|
58
|
+
|
59
|
+
if isinstance(type_value, TypeEngine):
|
60
|
+
column_type = type_value.python_type
|
61
|
+
elif not type_value:
|
62
|
+
column_type = type(value)
|
63
|
+
else:
|
64
|
+
column_type = type_value
|
65
|
+
return cls.CASTER_SELECTOR()[column_type](value, column_type)
|
@@ -17,21 +17,13 @@ class ClauseInfoConverter[T, TProp](tp.Protocol):
|
|
17
17
|
class ConvertFromAnyType(ClauseInfoConverter[None, None]):
|
18
18
|
@classmethod
|
19
19
|
def convert(cls, data: tp.Any, alias_table: AliasType = "{table}", context: ClauseContextType = None, **kwargs) -> list[ClauseInfo[None]]:
|
20
|
-
return [
|
21
|
-
ClauseInfo[None](
|
22
|
-
table=None,
|
23
|
-
column=data,
|
24
|
-
alias_table=alias_table,
|
25
|
-
alias_clause=kwargs.get("alias", None),
|
26
|
-
context=context,
|
27
|
-
)
|
28
|
-
]
|
20
|
+
return [ClauseInfo[None](table=None, column=data, alias_table=alias_table, alias_clause=kwargs.get("alias", None), context=context, **kwargs)]
|
29
21
|
|
30
22
|
|
31
23
|
class ConvertFromForeignKey[LT: Table, RT: Table](ClauseInfoConverter[RT, None]):
|
32
24
|
@classmethod
|
33
25
|
def convert(cls, data: ForeignKey[LT, RT], alias_table=None, context: ClauseContextType = None, **kwargs) -> list[ClauseInfo[RT]]:
|
34
|
-
return ConvertFromTable[RT].convert(data.tright, data.
|
26
|
+
return ConvertFromTable[RT].convert(data.tright, data.get_alias(kwargs["dialect"]), context, **kwargs)
|
35
27
|
|
36
28
|
|
37
29
|
class ConvertFromColumn[TProp](ClauseInfoConverter[None, TProp]):
|
@@ -44,9 +36,9 @@ class ConvertFromColumn[TProp](ClauseInfoConverter[None, TProp]):
|
|
44
36
|
"alias_table": alias_table,
|
45
37
|
"alias_clause": "{table}_{column}",
|
46
38
|
"context": context,
|
47
|
-
**kwargs,
|
48
39
|
}
|
49
|
-
|
40
|
+
attributes.update(**kwargs)
|
41
|
+
clause_info = ClauseInfo(**attributes)
|
50
42
|
return [clause_info]
|
51
43
|
|
52
44
|
|
@@ -27,6 +27,9 @@ type ValueType = tp.Union[
|
|
27
27
|
tp.Type[ICustomAlias],
|
28
28
|
]
|
29
29
|
|
30
|
+
if tp.TYPE_CHECKING:
|
31
|
+
from ormlambda.dialects import Dialect
|
32
|
+
|
30
33
|
|
31
34
|
class DecompositionQueryBase[T: Table, *Ts](IDecompositionQuery[T, *Ts]):
|
32
35
|
@tp.overload
|
@@ -36,10 +39,20 @@ class DecompositionQueryBase[T: Table, *Ts](IDecompositionQuery[T, *Ts]):
|
|
36
39
|
@tp.overload
|
37
40
|
def __init__(self, tables: tuple[TableType[T]], columns: tuple[ColumnType], alias_table: str, context: ClauseContextType = ...) -> None: ...
|
38
41
|
|
39
|
-
def __init__(
|
42
|
+
def __init__(
|
43
|
+
self,
|
44
|
+
tables: tuple[TableType[T]],
|
45
|
+
columns: tuple[ColumnType],
|
46
|
+
alias_table: str = "{table}",
|
47
|
+
*,
|
48
|
+
context: ClauseContextType = ClauseInfoContext(),
|
49
|
+
dialect: Dialect,
|
50
|
+
**kwargs,
|
51
|
+
) -> None:
|
40
52
|
self.kwargs = kwargs
|
41
53
|
self._tables: tuple[TableType[T]] = tables if isinstance(tables, tp.Iterable) else (tables,)
|
42
54
|
|
55
|
+
self._dialect = dialect
|
43
56
|
self._columns: tp.Callable[[T], tuple] = columns
|
44
57
|
self._all_clauses: list[ClauseInfo | AggregateFunctionBase] = []
|
45
58
|
self._context: ClauseContextType = context if context else ClauseInfoContext()
|
@@ -88,7 +101,9 @@ class DecompositionQueryBase[T: Table, *Ts](IDecompositionQuery[T, *Ts]):
|
|
88
101
|
Table: ConvertFromTable[T],
|
89
102
|
}
|
90
103
|
classConverter = next((converter for obj, converter in VALUE_TYPE_MAPPED.items() if validation(data, obj)), ConvertFromAnyType)
|
91
|
-
|
104
|
+
self.kwargs.setdefault("dialect", self._dialect)
|
105
|
+
if "dialect" not in self.kwargs:
|
106
|
+
raise ValueError("You must specified 'dialect' variable")
|
92
107
|
return classConverter.convert(data, alias_table=self._alias_table, context=self._context, **self.kwargs)
|
93
108
|
|
94
109
|
def __add_clause[TTable: TableType](self, clauses: list[ClauseInfo[TTable]] | ClauseInfo[TTable]) -> None:
|
@@ -1,22 +1,26 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
from abc import abstractmethod
|
3
|
-
from typing import Any, Optional, Type,
|
3
|
+
from typing import Any, Optional, Type, TYPE_CHECKING
|
4
4
|
|
5
5
|
from ormlambda.common.interfaces.INonQueryCommand import INonQueryCommand
|
6
6
|
|
7
7
|
if TYPE_CHECKING:
|
8
8
|
from ormlambda.repository import BaseRepository
|
9
|
+
from ormlambda.dialects import Dialect
|
9
10
|
from ormlambda import Table
|
11
|
+
from ormlambda.engine import Engine
|
10
12
|
|
11
13
|
|
12
|
-
class NonQueryBase[T: Type[Table], TRepo
|
14
|
+
class NonQueryBase[T: Type[Table], TRepo](INonQueryCommand):
|
13
15
|
__slots__: tuple[str, ...] = ("_model", "_repository", "_values", "_query")
|
14
16
|
|
15
|
-
def __init__(self, model: T, repository: TRepo) -> None:
|
17
|
+
def __init__(self, model: T, repository: TRepo, **kwargs) -> None:
|
16
18
|
self._model: T = model
|
17
|
-
self._repository: TRepo = repository
|
19
|
+
self._repository: BaseRepository[TRepo] = repository
|
18
20
|
self._values: list[tuple[Any]] = []
|
19
21
|
self._query: Optional[str] = None
|
22
|
+
self._dialect: Dialect = kwargs.get("dialect", None)
|
23
|
+
self._engine: Optional[Engine] = kwargs.get("engine", None)
|
20
24
|
|
21
25
|
@property
|
22
26
|
@abstractmethod
|
@@ -25,9 +29,7 @@ class NonQueryBase[T: Type[Table], TRepo: BaseRepository](INonQueryCommand):
|
|
25
29
|
@abstractmethod
|
26
30
|
def execute(self) -> None: ...
|
27
31
|
|
28
|
-
|
29
|
-
@override
|
30
|
-
def query(self) -> str:
|
32
|
+
def query(self, dialect: Dialect, **kwargs) -> str:
|
31
33
|
return self._query
|
32
34
|
|
33
35
|
@property
|
@@ -1,3 +1,4 @@
|
|
1
|
+
from __future__ import annotations
|
1
2
|
from abc import abstractmethod
|
2
3
|
from typing import TYPE_CHECKING
|
3
4
|
|
@@ -5,9 +6,10 @@ from ormlambda.common.interfaces import IQuery
|
|
5
6
|
|
6
7
|
if TYPE_CHECKING:
|
7
8
|
from ormlambda import Table
|
9
|
+
from ormlambda.dialects import Dialect
|
8
10
|
|
9
11
|
|
10
12
|
class QueryBase[T: Table](IQuery):
|
11
13
|
@property
|
12
14
|
@abstractmethod
|
13
|
-
def query(self) -> str: ...
|
15
|
+
def query(self, dialect: Dialect, **kwargs) -> str: ...
|
@@ -1,7 +1,12 @@
|
|
1
|
+
from __future__ import annotations
|
1
2
|
import inspect
|
2
3
|
import typing as tp
|
3
4
|
|
4
5
|
|
6
|
+
if tp.TYPE_CHECKING:
|
7
|
+
from ormlambda.sql.clause_info import ClauseInfo
|
8
|
+
|
9
|
+
|
5
10
|
class UnmatchedLambdaParameterError(Exception):
|
6
11
|
def __init__(self, expected_params: int, function: tp.Callable[..., tp.Any], *args: object) -> None:
|
7
12
|
super().__init__(*args)
|
@@ -19,3 +24,27 @@ class NotKeysInIAggregateError(Exception):
|
|
19
24
|
|
20
25
|
def __str__(self) -> str:
|
21
26
|
return f"We cannot use placeholders in IAggregate class. You used {self._match_regex}"
|
27
|
+
|
28
|
+
|
29
|
+
class AggregateFunctionError[T](Exception):
|
30
|
+
def __init__(self, clause: ClauseInfo[T], *args):
|
31
|
+
self.clause = clause
|
32
|
+
super().__init__(*args)
|
33
|
+
|
34
|
+
def __str__(self):
|
35
|
+
agg_methods = self.__get_all_aggregate_method(self.clause)
|
36
|
+
return f"You cannot use aggregation method like '{agg_methods}' to return model objects. Try specifying 'flavour' attribute as 'dict'."
|
37
|
+
|
38
|
+
def __get_all_aggregate_method(self, clauses: list[ClauseInfo]) -> str:
|
39
|
+
"""
|
40
|
+
Get the class name of those classes that inherit from 'AggregateFunctionBase' class in order to create a better error message.
|
41
|
+
"""
|
42
|
+
from ormlambda.sql.clause_info import AggregateFunctionBase
|
43
|
+
|
44
|
+
res: set[str] = set()
|
45
|
+
if not isinstance(clauses, tp.Iterable):
|
46
|
+
return clauses.__class__.__name__
|
47
|
+
for clause in clauses:
|
48
|
+
if isinstance(clause, AggregateFunctionBase):
|
49
|
+
res.add(clause.__class__.__name__)
|
50
|
+
return ", ".join(res)
|
@@ -1,12 +1,16 @@
|
|
1
|
+
from __future__ import annotations
|
1
2
|
from abc import abstractmethod, ABC
|
3
|
+
from typing import TYPE_CHECKING
|
4
|
+
|
5
|
+
if TYPE_CHECKING:
|
6
|
+
from ormlambda.dialects import Dialect
|
2
7
|
|
3
8
|
|
4
9
|
class IQuery(ABC):
|
5
10
|
"""Interface to queries that retrieve any element such as select, limit, offset, where, group by, etc..."""
|
6
11
|
|
7
|
-
@property
|
8
12
|
@abstractmethod
|
9
|
-
def query(self) -> str: ...
|
13
|
+
def query(self, dialect: Dialect, **kwargs) -> str: ...
|
10
14
|
|
11
15
|
def __repr__(self) -> str:
|
12
16
|
return f"{IQuery.__name__}: {self.__class__.__name__}"
|
ormlambda/databases/__init__.py
CHANGED
@@ -1,18 +1,29 @@
|
|
1
1
|
from __future__ import annotations
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
from
|
6
|
-
|
7
|
-
|
8
|
-
|
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
|
+
DecimalCaster,
|
16
|
+
)
|
9
17
|
|
10
18
|
from shapely import Point
|
11
19
|
from types import NoneType
|
12
|
-
from datetime import datetime
|
20
|
+
from datetime import datetime, date
|
21
|
+
from decimal import Decimal
|
22
|
+
|
13
23
|
|
24
|
+
class MySQLCaster(Caster):
|
25
|
+
PLACEHOLDER = "%s"
|
14
26
|
|
15
|
-
class MySQLCaster(ICaster):
|
16
27
|
@classmethod
|
17
28
|
def CASTER_SELECTOR(cls):
|
18
29
|
return {
|
@@ -22,18 +33,11 @@ class MySQLCaster(ICaster):
|
|
22
33
|
Point: PointCaster,
|
23
34
|
NoneType: NoneTypeCaster,
|
24
35
|
datetime: DatetimeCaster,
|
36
|
+
date: DatetimeCaster,
|
25
37
|
bytes: BytesCaster,
|
26
38
|
bytearray: BytesCaster,
|
27
39
|
tuple: IterableCaster,
|
28
40
|
list: IterableCaster,
|
41
|
+
bool: BooleanCaster,
|
42
|
+
Decimal: DecimalCaster,
|
29
43
|
}
|
30
|
-
|
31
|
-
@classmethod
|
32
|
-
def cast[TProp, TType](cls, value: TProp, type_value: Optional[TType] = None) -> BaseCaster[TProp, TType]:
|
33
|
-
if len(args := get_args(type_value)) > 1:
|
34
|
-
args = [x for x in args if x != NoneType]
|
35
|
-
|
36
|
-
type_value = args[0]
|
37
|
-
|
38
|
-
column_type = type_value if type_value else type(value)
|
39
|
-
return cls.CASTER_SELECTOR()[column_type](value, column_type)
|
@@ -6,3 +6,6 @@ from .none import NoneTypeCaster as NoneTypeCaster
|
|
6
6
|
from .datetime import DatetimeCaster as DatetimeCaster
|
7
7
|
from .bytes import BytesCaster as BytesCaster
|
8
8
|
from .iterable import IterableCaster as IterableCaster
|
9
|
+
from .boolean import BooleanCaster as BooleanCaster
|
10
|
+
from .date import DateCaster as DateCaster
|
11
|
+
from .decimal import DecimalCaster as DecimalCaster
|
@@ -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
|
@@ -0,0 +1,34 @@
|
|
1
|
+
from typing import Optional
|
2
|
+
from ormlambda.caster import BaseCaster, Caster
|
3
|
+
from datetime import datetime
|
4
|
+
from .string import StringCaster
|
5
|
+
|
6
|
+
|
7
|
+
class DateCaster[TType](BaseCaster[datetime, TType]):
|
8
|
+
def __init__(self, value: datetime, type_value: TType):
|
9
|
+
super().__init__(value, type_value)
|
10
|
+
|
11
|
+
def wildcard_to_select(self, value: Optional[str] = None) -> str:
|
12
|
+
return Caster.PLACEHOLDER if value is None else value
|
13
|
+
|
14
|
+
def wildcard_to_where(self, value: Optional[str] = None) -> str:
|
15
|
+
return Caster.PLACEHOLDER if value is None else value
|
16
|
+
|
17
|
+
def wildcard_to_insert(self, value: Optional[str] = None) -> str:
|
18
|
+
return Caster.PLACEHOLDER if value is None else value
|
19
|
+
|
20
|
+
@property
|
21
|
+
@BaseCaster.return_value_if_exists
|
22
|
+
def to_database(self) -> Optional[datetime]:
|
23
|
+
return self.value
|
24
|
+
|
25
|
+
@property
|
26
|
+
@BaseCaster.return_value_if_exists
|
27
|
+
def from_database(self) -> Optional[datetime]:
|
28
|
+
return self.value
|
29
|
+
|
30
|
+
@property
|
31
|
+
@BaseCaster.return_value_if_exists
|
32
|
+
def string_data(self) -> Optional[str]:
|
33
|
+
datetime_string = self.value.strftime(r"%Y-%m-%d")
|
34
|
+
return StringCaster(datetime_string, str).string_data
|
@@ -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
|
@@ -0,0 +1,32 @@
|
|
1
|
+
from typing import Optional
|
2
|
+
from ormlambda.caster import BaseCaster, Caster
|
3
|
+
from decimal import Decimal
|
4
|
+
|
5
|
+
|
6
|
+
class DecimalCaster[TType](BaseCaster[Decimal, TType]):
|
7
|
+
def __init__(self, value: Decimal, type_value: TType):
|
8
|
+
super().__init__(value, type_value)
|
9
|
+
|
10
|
+
def wildcard_to_select(self, value: Optional[str] = None) -> str:
|
11
|
+
return Caster.PLACEHOLDER if value is None else value
|
12
|
+
|
13
|
+
def wildcard_to_where(self, value: Optional[str] = None) -> str:
|
14
|
+
return Caster.PLACEHOLDER if value is None else value
|
15
|
+
|
16
|
+
def wildcard_to_insert(self, value: Optional[str] = None) -> str:
|
17
|
+
return Caster.PLACEHOLDER if value is None else value
|
18
|
+
|
19
|
+
@property
|
20
|
+
@BaseCaster.return_value_if_exists
|
21
|
+
def to_database(self) -> Optional[Decimal]:
|
22
|
+
return Decimal(self.value)
|
23
|
+
|
24
|
+
@property
|
25
|
+
@BaseCaster.return_value_if_exists
|
26
|
+
def from_database(self) -> Optional[Decimal]:
|
27
|
+
return Decimal(self.value)
|
28
|
+
|
29
|
+
@property
|
30
|
+
@BaseCaster.return_value_if_exists
|
31
|
+
def string_data(self) -> Optional[str]:
|
32
|
+
return str(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 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
|