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
@@ -0,0 +1,21 @@
1
+ from __future__ import annotations
2
+ import abc
3
+
4
+
5
+ from .IQueryCommand import IQuery
6
+
7
+
8
+ class IJoinSelector[TLeft, TRight](IQuery):
9
+ @abc.abstractmethod
10
+ def sort_join_selectors(cls, joins: set[IJoinSelector]) -> tuple[IJoinSelector]: ...
11
+
12
+ @property
13
+ def left_table(self) -> str: ...
14
+ @property
15
+ def right_table(self) -> str: ...
16
+ @property
17
+ def left_col(self) -> str: ...
18
+ @property
19
+ def right_col(self) -> str: ...
20
+ @property
21
+ def alias(self) -> str: ...
@@ -1,7 +1,5 @@
1
- from .IQueryCommand import IQuery as IQuery
2
- from .INonQueryCommand import INonQueryCommand as INonQueryCommand
3
- from .IRepositoryBase import IRepositoryBase as IRepositoryBase
4
- from .IStatements import IStatements as IStatements, IStatements_two_generic as IStatements_two_generic
5
- from .IDecompositionQuery import IDecompositionQuery as IDecompositionQuery
6
- from .IAggregate import IAggregate as IAggregate
7
1
  from .ICustomAlias import ICustomAlias as ICustomAlias
2
+ from .IDecompositionQuery import IDecompositionQuery as IDecompositionQuery
3
+ from .IJoinSelector import IJoinSelector as IJoinSelector
4
+ from .INonQueryCommand import INonQueryCommand as INonQueryCommand
5
+ from .IQueryCommand import IQuery as IQuery
@@ -0,0 +1,4 @@
1
+ from .select import ISelect # noqa: F401
2
+ from .delete import IDelete # noqa: F401
3
+ from .insert import IInsert # noqa: F401
4
+ from .update import IUpdate # noqa: F401
@@ -4,7 +4,7 @@ from typing import TYPE_CHECKING
4
4
 
5
5
  if TYPE_CHECKING:
6
6
  from ormlambda import Table
7
- from ormlambda import IRepositoryBase
7
+ from ormlambda.repository import IRepositoryBase
8
8
 
9
9
  from ormlambda.common.abstract_classes import NonQueryBase
10
10
  from .IInsert import IInsert
@@ -0,0 +1,17 @@
1
+ from __future__ import annotations
2
+ import abc
3
+ from ormlambda.common.interfaces import IQuery
4
+ from typing import TYPE_CHECKING
5
+
6
+ if TYPE_CHECKING:
7
+ from ormlambda.sql.clause_info import ClauseInfo
8
+
9
+ class ISelect(IQuery):
10
+ @property
11
+ @abc.abstractmethod
12
+ def FROM(self)->ClauseInfo: ...
13
+
14
+ @property
15
+ @abc.abstractmethod
16
+ def COLUMNS(self)->str: ...
17
+
@@ -0,0 +1 @@
1
+ from .ISelect import ISelect # noqa: F401
@@ -2,20 +2,20 @@ from __future__ import annotations
2
2
  from abc import abstractmethod
3
3
  from typing import Any, Optional, TYPE_CHECKING
4
4
 
5
- from ormlambda.components.where import AbstractWhere
6
5
  from ormlambda.common.abstract_classes import NonQueryBase
6
+ from ormlambda.databases.my_sql.clauses.where import Where
7
7
 
8
8
  if TYPE_CHECKING:
9
- from ormlambda import IRepositoryBase
9
+ from ormlambda.repository import IRepositoryBase
10
10
  from ormlambda import Table
11
11
 
12
12
  from .IUpdate import IUpdate
13
13
 
14
14
 
15
15
  class UpdateQueryBase[T: Table, TRepo: IRepositoryBase](NonQueryBase[T, TRepo], IUpdate):
16
- def __init__(self, model: T, repository: TRepo, where: AbstractWhere = list[AbstractWhere]) -> None:
16
+ def __init__(self, model: T, repository: TRepo, where: list[Where] = list[Where]) -> None:
17
17
  super().__init__(model, repository)
18
- self._where: Optional[AbstractWhere] = where
18
+ self._where: Optional[list[Where]] = where
19
19
 
20
20
  @abstractmethod
21
21
  def update(self, dicc: dict[str | property, Any]) -> None:
@@ -3,7 +3,7 @@ from abc import abstractmethod
3
3
  from typing import TYPE_CHECKING
4
4
 
5
5
  if TYPE_CHECKING:
6
- from ormlambda import IRepositoryBase
6
+ from ormlambda.repository import IRepositoryBase
7
7
  from ormlambda import Table
8
8
 
9
9
  from ormlambda.common.abstract_classes import NonQueryBase
@@ -0,0 +1,5 @@
1
+ from .my_sql import (
2
+ MySQLCaster as MySQLCaster,
3
+ MySQLRepository as MySQLRepository,
4
+ MySQLStatements as MySQLStatements,
5
+ )
@@ -1,2 +1,4 @@
1
- from .repository import MySQLRepository, Error # noqa: F401
1
+ from mysql.connector import MySQLConnection # noqa: F401
2
+ from .repository import MySQLRepository # noqa: F401
2
3
  from .statements import MySQLStatements # noqa: F401
4
+ from .caster import MySQLCaster # noqa: F401
@@ -0,0 +1 @@
1
+ from .caster import MySQLCaster as MySQLCaster
@@ -0,0 +1,38 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Optional, get_args
4
+ from ormlambda.caster import BaseCaster
5
+ from ormlambda.caster import ICaster
6
+
7
+
8
+ from .types import StringCaster, IntegerCaster, FloatCaster, PointCaster, NoneTypeCaster, DatetimeCaster, BytesCaster, IterableCaster
9
+
10
+ from shapely import Point
11
+ from types import NoneType
12
+ from datetime import datetime
13
+
14
+
15
+ class MySQLCaster(ICaster):
16
+ @classmethod
17
+ def CASTER_SELECTOR(cls):
18
+ return {
19
+ str: StringCaster,
20
+ int: IntegerCaster,
21
+ float: FloatCaster,
22
+ Point: PointCaster,
23
+ NoneType: NoneTypeCaster,
24
+ datetime: DatetimeCaster,
25
+ bytes: BytesCaster,
26
+ tuple: IterableCaster,
27
+ list: IterableCaster,
28
+ }
29
+
30
+ @classmethod
31
+ def cast[TProp, TType](cls, value: TProp, type_value: Optional[TType] = None) -> BaseCaster[TProp, TType]:
32
+ if len(args := get_args(type_value)) > 1:
33
+ args = [x for x in args if x != NoneType]
34
+
35
+ type_value = args[0]
36
+
37
+ column_type = type_value if type_value else type(value)
38
+ return cls.CASTER_SELECTOR()[column_type](value, column_type)
@@ -0,0 +1,39 @@
1
+ from datetime import datetime
2
+ from typing import Optional
3
+ from shapely import Point
4
+ from types import NoneType
5
+ from ormlambda.common.abstract_classes.caster.cast_base import ReadCastBase
6
+
7
+
8
+ from .types.datetime import MySQLReadDatetime
9
+ from .types.string import MySQLReadString
10
+ from .types.int import MySQLReadInt
11
+ from .types.float import MySQLReadFloat
12
+ from .types.point import MySQLReadPoint
13
+ from .types.none import MySQLReadNoneType
14
+
15
+
16
+ class MySQLReadCastBase(ReadCastBase):
17
+ @staticmethod
18
+ def cast_str(value: str) -> str:
19
+ return MySQLReadString.cast(value)
20
+
21
+ @staticmethod
22
+ def cast_int(value: str) -> int:
23
+ return MySQLReadInt.cast(value)
24
+
25
+ @staticmethod
26
+ def cast_float(value: str) -> float:
27
+ return MySQLReadFloat.cast(value)
28
+
29
+ @staticmethod
30
+ def cast_Point(value: str) -> Point:
31
+ return MySQLReadPoint.cast(value)
32
+
33
+ @staticmethod
34
+ def cast_NoneType(value: str) -> NoneType:
35
+ return MySQLReadNoneType.cast(value)
36
+
37
+ @staticmethod
38
+ def cast_datetime(value: str) -> datetime:
39
+ return MySQLReadDatetime.cast(value)
@@ -0,0 +1,8 @@
1
+ from .string import StringCaster as StringCaster
2
+ from .int import IntegerCaster as IntegerCaster
3
+ from .float import FloatCaster as FloatCaster
4
+ from .point import PointCaster as PointCaster
5
+ from .none import NoneTypeCaster as NoneTypeCaster
6
+ from .datetime import DatetimeCaster as DatetimeCaster
7
+ from .bytes import BytesCaster as BytesCaster
8
+ from .iterable import IterableCaster as IterableCaster
@@ -0,0 +1,31 @@
1
+ from typing import Optional
2
+ from ormlambda.caster import BaseCaster, PLACEHOLDER
3
+
4
+
5
+ class BytesCaster[TType](BaseCaster[bytes, TType]):
6
+ def __init__(self, value: bytes, type_value: TType):
7
+ super().__init__(value, type_value)
8
+
9
+ def wildcard_to_select(self, value:str = PLACEHOLDER) -> str:
10
+ return value
11
+
12
+ def wildcard_to_where(self, value:str = PLACEHOLDER) -> str:
13
+ return value
14
+
15
+ def wildcard_to_insert(self, value:str = PLACEHOLDER) -> str:
16
+ return value
17
+
18
+ @property
19
+ @BaseCaster.return_value_if_exists
20
+ def to_database(self) -> Optional[bytes]:
21
+ return bytes(self.value)
22
+
23
+ @property
24
+ @BaseCaster.return_value_if_exists
25
+ def from_database(self) -> Optional[bytes]:
26
+ return bytes(self.value)
27
+
28
+ @property
29
+ @BaseCaster.return_value_if_exists
30
+ def string_data(self) -> Optional[str]:
31
+ return str(self.value)
@@ -0,0 +1,34 @@
1
+ from typing import Optional
2
+ from ormlambda.caster import BaseCaster, PLACEHOLDER
3
+ from datetime import datetime
4
+ from .string import StringCaster
5
+
6
+
7
+ class DatetimeCaster[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:str=PLACEHOLDER) -> str:
12
+ return value
13
+
14
+ def wildcard_to_where(self, value:str=PLACEHOLDER) -> str:
15
+ return value
16
+
17
+ def wildcard_to_insert(self, value:str=PLACEHOLDER) -> str:
18
+ return 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 %H:%M:%S")
34
+ return StringCaster(datetime_string, str).string_data
@@ -0,0 +1,31 @@
1
+ from typing import Optional
2
+ from ormlambda.caster import BaseCaster, PLACEHOLDER
3
+
4
+
5
+ class FloatCaster[TType](BaseCaster[float, TType]):
6
+ def __init__(self, value: float, type_value: TType):
7
+ super().__init__(value, type_value)
8
+
9
+ def wildcard_to_select(self, value:str=PLACEHOLDER) -> str:
10
+ return value
11
+
12
+ def wildcard_to_where(self, value:str=PLACEHOLDER) -> str:
13
+ return value
14
+
15
+ def wildcard_to_insert(self, value:str=PLACEHOLDER) -> str:
16
+ return value
17
+
18
+ @property
19
+ @BaseCaster.return_value_if_exists
20
+ def to_database(self) -> Optional[float]:
21
+ return float(self.value)
22
+
23
+ @property
24
+ @BaseCaster.return_value_if_exists
25
+ def from_database(self) -> Optional[float]:
26
+ return float(self.value)
27
+
28
+ @property
29
+ @BaseCaster.return_value_if_exists
30
+ def string_data(self) -> Optional[str]:
31
+ return str(self.value)
@@ -0,0 +1,31 @@
1
+ from typing import Optional
2
+ from ormlambda.caster import BaseCaster, PLACEHOLDER
3
+
4
+
5
+ class IntegerCaster[TType](BaseCaster[int, TType]):
6
+ def __init__(self, value: int, type_value: TType):
7
+ super().__init__(value, type_value)
8
+
9
+ def wildcard_to_select(self, value:str=PLACEHOLDER) -> str:
10
+ return value
11
+
12
+ def wildcard_to_where(self, value:str=PLACEHOLDER) -> str:
13
+ return value
14
+
15
+ def wildcard_to_insert(self, value:str=PLACEHOLDER) -> str:
16
+ return value
17
+
18
+ @property
19
+ @BaseCaster.return_value_if_exists
20
+ def to_database(self) -> Optional[int]:
21
+ return int(self.value)
22
+
23
+ @property
24
+ @BaseCaster.return_value_if_exists
25
+ def from_database(self) -> Optional[int]:
26
+ return int(self.value)
27
+
28
+ @property
29
+ @BaseCaster.return_value_if_exists
30
+ def string_data(self) -> Optional[str]:
31
+ return str(self.value)
@@ -0,0 +1,31 @@
1
+ from typing import Optional
2
+ from ormlambda.caster import BaseCaster, PLACEHOLDER
3
+
4
+
5
+ class IterableCaster[TType](BaseCaster[bytes, TType]):
6
+ def __init__(self, value: bytes, type_value: TType):
7
+ super().__init__(value, type_value)
8
+
9
+ def wildcard_to_select(self, value:str=PLACEHOLDER) -> str:
10
+ return value
11
+
12
+ def wildcard_to_where(self, value:str=PLACEHOLDER) -> str:
13
+ return value
14
+
15
+ def wildcard_to_insert(self, value:str=PLACEHOLDER) -> str:
16
+ return value
17
+
18
+ @property
19
+ @BaseCaster.return_value_if_exists
20
+ def to_database(self) -> Optional[bytes]:
21
+ return tuple(self.value)
22
+
23
+ @property
24
+ @BaseCaster.return_value_if_exists
25
+ def from_database(self) -> Optional[bytes]:
26
+ return tuple(self.value)
27
+
28
+ @property
29
+ @BaseCaster.return_value_if_exists
30
+ def string_data(self) -> Optional[str]:
31
+ return str(self.value)
@@ -0,0 +1,30 @@
1
+ from types import NoneType
2
+ from ormlambda.caster import BaseCaster, PLACEHOLDER
3
+
4
+
5
+ class NoneTypeCaster[TType](BaseCaster[NoneType, TType]):
6
+ def __init__(self, value: NoneType, type_value: TType):
7
+ super().__init__(value, type_value)
8
+
9
+ def wildcard_to_select(self, value:str=PLACEHOLDER) -> str:
10
+ return value
11
+
12
+ def wildcard_to_where(self, value:str=PLACEHOLDER) -> str:
13
+ return value
14
+
15
+ def wildcard_to_insert(self, value:str=PLACEHOLDER) -> str:
16
+ return value
17
+
18
+ # TODOL: cheched if it's right
19
+ @property
20
+ def to_database(self) -> None:
21
+ return None
22
+
23
+ # TODOL: cheched if it's right
24
+ @property
25
+ def from_database(self) -> None:
26
+ return None
27
+
28
+ @property
29
+ def string_data(self) -> str:
30
+ return "NULL"
@@ -0,0 +1,43 @@
1
+ from typing import Optional
2
+ from ormlambda.caster import BaseCaster, PLACEHOLDER
3
+ from shapely import Point
4
+ import shapely.wkt as wkt
5
+ from shapely import wkb
6
+
7
+
8
+ class PointCaster[TType](BaseCaster[Point, TType]):
9
+ def __init__(self, value: bytes | str, type_value: TType):
10
+ super().__init__(value, type_value)
11
+
12
+ def wildcard_to_select(self, value: str = PLACEHOLDER) -> str:
13
+ return f"ST_AsText({value})"
14
+
15
+ def wildcard_to_where(self, value: str = PLACEHOLDER) -> str:
16
+ return f"ST_AsText({value})"
17
+
18
+ def wildcard_to_insert(self, value: str = PLACEHOLDER) -> str:
19
+ return f"ST_GeomFromText({value})"
20
+
21
+ @property
22
+ @BaseCaster.return_value_if_exists
23
+ def to_database(self) -> Optional[str]:
24
+ if isinstance(self.value, Point):
25
+ return self.value.wkt
26
+ return self.value
27
+
28
+ @property
29
+ @BaseCaster.return_value_if_exists
30
+ def from_database(self) -> Optional[Point]:
31
+ """
32
+ Always should get string because we're using 'ST_AsText' when calling wildcard_to_select prop.
33
+ """
34
+ if isinstance(self.value, bytes):
35
+ return wkb.loads(self.value)
36
+ elif isinstance(self.value, str):
37
+ return wkt.loads(self.value)
38
+ return self.value
39
+
40
+ @property
41
+ @BaseCaster.return_value_if_exists
42
+ def string_data(self) -> Optional[str]:
43
+ return type(self)(str(self.value), str).wildcard_to_select()
@@ -0,0 +1,31 @@
1
+ from typing import Optional
2
+ from ormlambda.caster import BaseCaster, PLACEHOLDER
3
+
4
+
5
+ class StringCaster[TType](BaseCaster[str, TType]):
6
+ def __init__(self, value: str, type_value: TType):
7
+ super().__init__(value, type_value)
8
+
9
+ def wildcard_to_select(self, value:str = PLACEHOLDER) -> str:
10
+ return value
11
+
12
+ def wildcard_to_where(self, value:str = PLACEHOLDER) -> str:
13
+ return value
14
+
15
+ def wildcard_to_insert(self, value:str = PLACEHOLDER) -> str:
16
+ return value
17
+
18
+ @property
19
+ @BaseCaster.return_value_if_exists
20
+ def to_database(self) -> Optional[str]:
21
+ return str(self.value)
22
+
23
+ @property
24
+ @BaseCaster.return_value_if_exists
25
+ def from_database(self) -> Optional[str]:
26
+ return str(self.value)
27
+
28
+ @property
29
+ @BaseCaster.return_value_if_exists
30
+ def string_data(self) -> Optional[str]:
31
+ return f"'{self.value}'"
@@ -0,0 +1,37 @@
1
+ from datetime import datetime
2
+ from shapely import Point
3
+ from types import NoneType
4
+ from ormlambda.common.abstract_classes.caster.cast_base import WriteCastBase
5
+
6
+ from .types.datetime import MySQLWriteDatetime
7
+ from .types.string import MySQLWriteString
8
+ from .types.int import MySQLWriteInt
9
+ from .types.float import MySQLWriteFloat
10
+ from .types.point import MySQLWritePoint
11
+ from .types.none import MySQLWriteNoneType
12
+
13
+
14
+ class MySQLWriteCastBase(WriteCastBase):
15
+ @staticmethod
16
+ def cast_str(value: str, insert_data: bool = False) -> str:
17
+ return MySQLWriteString.cast(value, insert_data)
18
+
19
+ @staticmethod
20
+ def cast_int(value: int, insert_data: bool = False) -> str:
21
+ return MySQLWriteInt.cast(value, insert_data)
22
+
23
+ @staticmethod
24
+ def cast_float(value: float, insert_data: bool = False) -> str:
25
+ return MySQLWriteFloat.cast(value, insert_data)
26
+
27
+ @staticmethod
28
+ def cast_Point(value: Point, insert_data: bool = False) -> str:
29
+ return MySQLWritePoint.cast(value, insert_data)
30
+
31
+ @staticmethod
32
+ def cast_NoneType(value: NoneType, insert_data: bool = False) -> str:
33
+ return MySQLWriteNoneType.cast(value, insert_data)
34
+
35
+ @staticmethod
36
+ def cast_datetime(value: datetime, insert_data: bool = False) -> str:
37
+ return MySQLWriteDatetime.cast(value, insert_data)
@@ -0,0 +1,36 @@
1
+ from ormlambda.sql.clause_info import AggregateFunctionBase
2
+ from ormlambda.sql.types import ColumnType, AliasType
3
+ from ormlambda.sql.clause_info.clause_info_context import ClauseContextType
4
+
5
+
6
+ class ST_AsText[T, TProp](AggregateFunctionBase[None]):
7
+ """
8
+ https://dev.mysql.com/doc/refman/8.4/en/fetching-spatial-data.html
9
+
10
+ The ST_AsText() function converts a geometry from internal format to a WKT string.
11
+ """
12
+
13
+ @staticmethod
14
+ def FUNCTION_NAME() -> str:
15
+ return "ST_AsText"
16
+
17
+ def __init__(
18
+ self,
19
+ point: ColumnType[TProp],
20
+ alias_table: AliasType[ColumnType[TProp]] = None,
21
+ alias_clause: AliasType[ColumnType[TProp]] = None,
22
+ context: ClauseContextType = None,
23
+ ) -> None:
24
+ default_alias_clause = self.create_alias_from(point) if not alias_clause else alias_clause
25
+
26
+ super().__init__(
27
+ table=point.table,
28
+ column=point,
29
+ alias_table=alias_table,
30
+ alias_clause=default_alias_clause,
31
+ context=context,
32
+ )
33
+
34
+ @staticmethod
35
+ def create_alias_from(element: ColumnType[TProp]) -> str:
36
+ return element.column_name
@@ -0,0 +1,31 @@
1
+ import typing as tp
2
+
3
+ from shapely import Point
4
+
5
+ from ormlambda import Column
6
+ from ormlambda.sql.types import ColumnType, AliasType
7
+ from ormlambda.sql.clause_info import ClauseInfo, IAggregate
8
+
9
+
10
+ class ST_Contains(IAggregate):
11
+ FUNCTION_NAME: str = "ST_Contains"
12
+
13
+ def __init__[TProp: Column](
14
+ self,
15
+ column: ColumnType[TProp],
16
+ point: Point,
17
+ alias_table: tp.Optional[AliasType[ColumnType[TProp]]] = None,
18
+ alias_clause: tp.Optional[AliasType[ColumnType[TProp]]] = None,
19
+ ):
20
+ self.attr1: ClauseInfo[Point] = ClauseInfo(column.table, column, alias_table)
21
+ self.attr2: ClauseInfo[Point] = ClauseInfo[Point](None, point)
22
+
23
+ self._alias_clause: AliasType[ColumnType[TProp]] = alias_clause
24
+
25
+ @property
26
+ def query(self) -> str:
27
+ return f"{self.FUNCTION_NAME}({self.attr1.query}, {self.attr2.query})"
28
+
29
+ @property
30
+ def alias_clause(self) -> tp.Optional[str]:
31
+ return self._alias_clause
@@ -6,12 +6,14 @@ from .drop_table import DropTable as DropTable
6
6
  from .insert import InsertQuery as InsertQuery
7
7
  from .joins import JoinSelector as JoinSelector
8
8
  from .joins import JoinType as JoinType
9
- from .limit import LimitQuery as LimitQuery
10
- from .offset import OffsetQuery as OffsetQuery
11
- from .order import OrderQuery as OrderQuery
9
+ from .limit import Limit as Limit
10
+ from .offset import Offset as Offset
11
+ from .order import Order as Order
12
12
  from .update import UpdateQuery as UpdateQuery
13
13
  from .upsert import UpsertQuery as UpsertQuery
14
- from .where_condition import WhereCondition as WhereCondition
14
+ from .where import Where as Where
15
15
  from .count import Count as Count
16
16
  from .group_by import GroupBy as GroupBy
17
17
  from .alias import Alias as Alias
18
+ from .ST_AsText import ST_AsText as ST_AsText
19
+ from .select import Select as Select
@@ -1,31 +1,34 @@
1
+ from __future__ import annotations
1
2
  import typing as tp
2
- from ormlambda.common.abstract_classes.decomposition_query import ClauseInfo, DecompositionQueryBase
3
- from ormlambda import Table
4
3
 
5
- from ormlambda.common.interfaces import ICustomAlias
4
+ from ormlambda import Table, Column
5
+ from ormlambda.sql.clause_info import ClauseInfo
6
+ from ormlambda.common.interfaces.IQueryCommand import IQuery
7
+ from ormlambda.sql.clause_info import ClauseInfoContext, IAggregate
6
8
 
9
+ if tp.TYPE_CHECKING:
10
+ from ormlambda.sql.types import ColumnType
11
+ from ormlambda import Table
12
+ from ormlambda.sql.types import AliasType
7
13
 
8
- class Alias[T: tp.Type[Table], *Ts](DecompositionQueryBase[T, *Ts], ICustomAlias[T, *Ts]):
14
+
15
+ class Alias[T: Table, TProp](ClauseInfo, IQuery):
9
16
  def __init__(
10
17
  self,
11
- table: T,
12
- query: tp.Callable[[T, *Ts], tp.Any],
13
- *,
14
- alias: bool = True,
15
- alias_name: str | None = None,
16
- ) -> None:
17
- super().__init__(
18
- table,
19
- lambda_query=query,
20
- alias=alias,
21
- alias_name=alias_name,
22
- )
18
+ element: IAggregate | ClauseInfo[T] | ColumnType[TProp],
19
+ alias_clause: tp.Optional[AliasType[ClauseInfo[T]]],
20
+ ):
21
+ if isinstance(element, Column):
22
+ context = ClauseInfoContext()
23
+ element = ClauseInfo(table=element.table, column=element, alias_clause=alias_clause)
24
+ else:
25
+ context = ClauseInfoContext(table_context=element.context._table_context, clause_context={})
26
+ element.context = context
27
+ element._alias_clause = alias_clause
23
28
 
24
- def alias_children_resolver[Tclause: tp.Type[Table]](self, clause_info: ClauseInfo[Tclause]):
25
- return self.alias_name
29
+ self._element = element
26
30
 
31
+ @tp.override
27
32
  @property
28
33
  def query(self) -> str:
29
- assert len(self.all_clauses) == 1
30
-
31
- return self.all_clauses[0].query
34
+ return self._element.query