ormlambda 3.35.3__py3-none-any.whl → 4.0.4__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 (130) hide show
  1. ormlambda/__init__.py +79 -51
  2. ormlambda/caster/caster.py +6 -1
  3. ormlambda/common/abstract_classes/__init__.py +0 -2
  4. ormlambda/common/enums/__init__.py +1 -0
  5. ormlambda/common/enums/order_type.py +9 -0
  6. ormlambda/common/errors/__init__.py +13 -3
  7. ormlambda/common/global_checker.py +86 -8
  8. ormlambda/common/interfaces/IQueryCommand.py +2 -2
  9. ormlambda/common/interfaces/__init__.py +0 -2
  10. ormlambda/dialects/__init__.py +75 -3
  11. ormlambda/dialects/default/base.py +1 -1
  12. ormlambda/dialects/mysql/__init__.py +35 -78
  13. ormlambda/dialects/mysql/base.py +226 -40
  14. ormlambda/dialects/mysql/clauses/ST_AsText.py +26 -0
  15. ormlambda/dialects/mysql/clauses/ST_Contains.py +30 -0
  16. ormlambda/dialects/mysql/clauses/__init__.py +1 -0
  17. ormlambda/dialects/mysql/repository/__init__.py +1 -0
  18. ormlambda/{databases/my_sql → dialects/mysql/repository}/repository.py +0 -5
  19. ormlambda/dialects/mysql/types.py +6 -0
  20. ormlambda/engine/base.py +26 -4
  21. ormlambda/errors.py +9 -0
  22. ormlambda/model/base_model.py +3 -10
  23. ormlambda/repository/base_repository.py +1 -1
  24. ormlambda/repository/interfaces/IRepositoryBase.py +0 -7
  25. ormlambda/repository/response.py +21 -8
  26. ormlambda/sql/__init__.py +12 -3
  27. ormlambda/sql/clause_info/__init__.py +0 -2
  28. ormlambda/sql/clause_info/clause_info.py +94 -76
  29. ormlambda/sql/clause_info/interface/IAggregate.py +14 -4
  30. ormlambda/sql/clause_info/interface/IClauseInfo.py +6 -11
  31. ormlambda/sql/clauses/alias.py +6 -37
  32. ormlambda/sql/clauses/count.py +21 -36
  33. ormlambda/sql/clauses/group_by.py +13 -19
  34. ormlambda/sql/clauses/having.py +2 -6
  35. ormlambda/sql/clauses/insert.py +3 -3
  36. ormlambda/sql/clauses/interfaces/__init__.py +0 -1
  37. ormlambda/sql/clauses/join/join_context.py +5 -12
  38. ormlambda/sql/clauses/joins.py +34 -52
  39. ormlambda/sql/clauses/limit.py +1 -2
  40. ormlambda/sql/clauses/offset.py +1 -2
  41. ormlambda/sql/clauses/order.py +17 -21
  42. ormlambda/sql/clauses/select.py +56 -28
  43. ormlambda/sql/clauses/update.py +13 -10
  44. ormlambda/sql/clauses/where.py +20 -39
  45. ormlambda/sql/column/__init__.py +1 -0
  46. ormlambda/sql/column/column.py +19 -12
  47. ormlambda/sql/column/column_proxy.py +117 -0
  48. ormlambda/sql/column_table_proxy.py +23 -0
  49. ormlambda/sql/comparer.py +31 -65
  50. ormlambda/sql/compiler.py +248 -58
  51. ormlambda/sql/context/__init__.py +304 -0
  52. ormlambda/sql/ddl.py +19 -5
  53. ormlambda/sql/elements.py +3 -0
  54. ormlambda/sql/foreign_key.py +42 -64
  55. ormlambda/sql/functions/__init__.py +0 -1
  56. ormlambda/sql/functions/concat.py +35 -38
  57. ormlambda/sql/functions/max.py +12 -36
  58. ormlambda/sql/functions/min.py +13 -28
  59. ormlambda/sql/functions/sum.py +17 -33
  60. ormlambda/sql/sqltypes.py +2 -0
  61. ormlambda/sql/table/__init__.py +1 -0
  62. ormlambda/sql/table/table.py +31 -45
  63. ormlambda/sql/table/table_proxy.py +88 -0
  64. ormlambda/sql/type_api.py +4 -1
  65. ormlambda/sql/types.py +15 -12
  66. ormlambda/statements/__init__.py +0 -2
  67. ormlambda/statements/base_statement.py +53 -91
  68. ormlambda/statements/interfaces/IStatements.py +77 -123
  69. ormlambda/statements/interfaces/__init__.py +1 -1
  70. ormlambda/statements/query_builder.py +296 -128
  71. ormlambda/statements/statements.py +122 -115
  72. ormlambda/statements/types.py +5 -25
  73. ormlambda/util/__init__.py +7 -100
  74. ormlambda/util/langhelpers.py +102 -0
  75. ormlambda/util/module_tree/dynamic_module.py +1 -1
  76. ormlambda/util/preloaded.py +80 -0
  77. ormlambda/util/typing.py +12 -3
  78. {ormlambda-3.35.3.dist-info → ormlambda-4.0.4.dist-info}/METADATA +56 -79
  79. ormlambda-4.0.4.dist-info/RECORD +139 -0
  80. ormlambda/common/abstract_classes/clause_info_converter.py +0 -65
  81. ormlambda/common/abstract_classes/decomposition_query.py +0 -141
  82. ormlambda/common/abstract_classes/query_base.py +0 -15
  83. ormlambda/common/interfaces/ICustomAlias.py +0 -7
  84. ormlambda/common/interfaces/IDecompositionQuery.py +0 -33
  85. ormlambda/databases/__init__.py +0 -4
  86. ormlambda/databases/my_sql/__init__.py +0 -3
  87. ormlambda/databases/my_sql/clauses/ST_AsText.py +0 -37
  88. ormlambda/databases/my_sql/clauses/ST_Contains.py +0 -36
  89. ormlambda/databases/my_sql/clauses/__init__.py +0 -14
  90. ormlambda/databases/my_sql/clauses/count.py +0 -33
  91. ormlambda/databases/my_sql/clauses/delete.py +0 -9
  92. ormlambda/databases/my_sql/clauses/drop_table.py +0 -26
  93. ormlambda/databases/my_sql/clauses/group_by.py +0 -17
  94. ormlambda/databases/my_sql/clauses/having.py +0 -12
  95. ormlambda/databases/my_sql/clauses/insert.py +0 -9
  96. ormlambda/databases/my_sql/clauses/joins.py +0 -14
  97. ormlambda/databases/my_sql/clauses/limit.py +0 -6
  98. ormlambda/databases/my_sql/clauses/offset.py +0 -6
  99. ormlambda/databases/my_sql/clauses/order.py +0 -8
  100. ormlambda/databases/my_sql/clauses/update.py +0 -8
  101. ormlambda/databases/my_sql/clauses/upsert.py +0 -9
  102. ormlambda/databases/my_sql/clauses/where.py +0 -7
  103. ormlambda/dialects/interface/__init__.py +0 -1
  104. ormlambda/dialects/interface/dialect.py +0 -78
  105. ormlambda/sql/clause_info/aggregate_function_base.py +0 -96
  106. ormlambda/sql/clause_info/clause_info_context.py +0 -87
  107. ormlambda/sql/clauses/interfaces/ISelect.py +0 -17
  108. ormlambda/sql/clauses/new_join.py +0 -119
  109. ormlambda/util/load_module.py +0 -21
  110. ormlambda/util/plugin_loader.py +0 -32
  111. ormlambda-3.35.3.dist-info/RECORD +0 -159
  112. /ormlambda/{databases/my_sql → dialects/mysql}/caster/__init__.py +0 -0
  113. /ormlambda/{databases/my_sql → dialects/mysql}/caster/caster.py +0 -0
  114. /ormlambda/{databases/my_sql → dialects/mysql}/caster/types/__init__.py +0 -0
  115. /ormlambda/{databases/my_sql → dialects/mysql}/caster/types/boolean.py +0 -0
  116. /ormlambda/{databases/my_sql → dialects/mysql}/caster/types/bytes.py +0 -0
  117. /ormlambda/{databases/my_sql → dialects/mysql}/caster/types/date.py +0 -0
  118. /ormlambda/{databases/my_sql → dialects/mysql}/caster/types/datetime.py +0 -0
  119. /ormlambda/{databases/my_sql → dialects/mysql}/caster/types/decimal.py +0 -0
  120. /ormlambda/{databases/my_sql → dialects/mysql}/caster/types/float.py +0 -0
  121. /ormlambda/{databases/my_sql → dialects/mysql}/caster/types/int.py +0 -0
  122. /ormlambda/{databases/my_sql → dialects/mysql}/caster/types/iterable.py +0 -0
  123. /ormlambda/{databases/my_sql → dialects/mysql}/caster/types/json.py +0 -0
  124. /ormlambda/{databases/my_sql → dialects/mysql}/caster/types/none.py +0 -0
  125. /ormlambda/{databases/my_sql → dialects/mysql}/caster/types/point.py +0 -0
  126. /ormlambda/{databases/my_sql → dialects/mysql}/caster/types/string.py +0 -0
  127. /ormlambda/{databases/my_sql → dialects/mysql/repository}/pool_types.py +0 -0
  128. {ormlambda-3.35.3.dist-info → ormlambda-4.0.4.dist-info}/AUTHORS +0 -0
  129. {ormlambda-3.35.3.dist-info → ormlambda-4.0.4.dist-info}/LICENSE +0 -0
  130. {ormlambda-3.35.3.dist-info → ormlambda-4.0.4.dist-info}/WHEEL +0 -0
@@ -1,141 +0,0 @@
1
- from __future__ import annotations
2
- import typing as tp
3
- from ormlambda import Table, Column
4
-
5
- from ormlambda.common.interfaces import IDecompositionQuery, ICustomAlias
6
- from ormlambda.sql.clause_info import IAggregate
7
- from ormlambda.sql.clause_info import ClauseInfo, AggregateFunctionBase
8
- from ormlambda.sql.clause_info.clause_info_context import ClauseInfoContext, ClauseContextType
9
- from ormlambda import ForeignKey
10
- from ormlambda.common.global_checker import GlobalChecker
11
-
12
- from ormlambda.sql.types import TableType, ColumnType
13
- from .clause_info_converter import (
14
- ClauseInfoConverter,
15
- ConvertFromAnyType,
16
- ConvertFromForeignKey,
17
- ConvertFromColumn,
18
- ConvertFromIAggregate,
19
- ConvertFromTable,
20
- )
21
-
22
- type TableTupleType[T, *Ts] = tuple[T:TableType, *Ts]
23
- type ValueType = tp.Union[
24
- tp.Type[IAggregate],
25
- tp.Type[Table],
26
- tp.Type[str],
27
- tp.Type[ICustomAlias],
28
- ]
29
-
30
- if tp.TYPE_CHECKING:
31
- from ormlambda.dialects import Dialect
32
-
33
-
34
- class DecompositionQueryBase[T: Table, *Ts](IDecompositionQuery[T, *Ts]):
35
- @tp.overload
36
- def __init__(self, tables: tuple[TableType[T]], columns: tuple[ColumnType]) -> None: ...
37
- @tp.overload
38
- def __init__(self, tables: tuple[TableType[T]], columns: tuple[ColumnType], context: ClauseContextType = ...) -> None: ...
39
- @tp.overload
40
- def __init__(self, tables: tuple[TableType[T]], columns: tuple[ColumnType], alias_table: str, context: ClauseContextType = ...) -> None: ...
41
-
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:
52
- self.kwargs = kwargs
53
- self._tables: tuple[TableType[T]] = tables if isinstance(tables, tp.Iterable) else (tables,)
54
-
55
- self._dialect = dialect
56
- self._columns: tp.Callable[[T], tuple] = columns
57
- self._all_clauses: list[ClauseInfo | AggregateFunctionBase] = []
58
- self._context: ClauseContextType = context if context else ClauseInfoContext()
59
- self._alias_table: str = alias_table
60
- self.__clauses_list_generetor()
61
-
62
- def __getitem__(self, key: str) -> ClauseInfo | AggregateFunctionBase:
63
- for clause in self._all_clauses:
64
- is_agg_function = isinstance(clause, AggregateFunctionBase)
65
- is_clause_info = isinstance(clause, ClauseInfo)
66
- if (is_agg_function and clause._alias_aggregate == key) or (is_clause_info and clause.alias_clause == key):
67
- return clause
68
-
69
- def __clauses_list_generetor(self) -> None:
70
- # Clean self._all_clauses if we update the context
71
- self._all_clauses.clear() if self._all_clauses else None
72
-
73
- resolved_function = GlobalChecker.resolved_callback_object(self._columns, self.tables)
74
-
75
- # Python treats string objects as iterable, so we need to prevent this behavior
76
- if isinstance(resolved_function, str) or not isinstance(resolved_function, tp.Iterable):
77
- resolved_function = (self.table,) if ClauseInfo.is_asterisk(resolved_function) else (resolved_function,)
78
-
79
- for data in resolved_function:
80
- if not isinstance(data, ClauseInfo):
81
- values = self.__convert_into_ClauseInfo(data)
82
- else:
83
- values = [data]
84
- self.__add_clause(values)
85
-
86
- return None
87
-
88
- def __convert_into_ClauseInfo[TProp](self, data: TProp) -> list[ClauseInfo[T]]:
89
- """
90
- A method that behaves based on the variable's type
91
- """
92
-
93
- def validation(data: TProp, type_: ValueType) -> bool:
94
- is_valid_type: bool = isinstance(data, type) and issubclass(data, type_)
95
- return isinstance(data, type_) or is_valid_type
96
-
97
- VALUE_TYPE_MAPPED: dict[tp.Type[ValueType], ClauseInfoConverter[T, TProp]] = {
98
- ForeignKey: ConvertFromForeignKey[T, Table],
99
- Column: ConvertFromColumn[TProp],
100
- IAggregate: ConvertFromIAggregate,
101
- Table: ConvertFromTable[T],
102
- }
103
- classConverter = next((converter for obj, converter in VALUE_TYPE_MAPPED.items() if validation(data, obj)), ConvertFromAnyType)
104
- self.kwargs.setdefault("dialect", self._dialect)
105
- if "dialect" not in self.kwargs:
106
- raise ValueError("You must specified 'dialect' variable")
107
- return classConverter.convert(data, alias_table=self._alias_table, context=self._context, **self.kwargs)
108
-
109
- def __add_clause[TTable: TableType](self, clauses: list[ClauseInfo[TTable]] | ClauseInfo[TTable]) -> None:
110
- if not isinstance(clauses, tp.Iterable):
111
- raise ValueError(f"Iterable expected. '{type(clauses)}' got instead.")
112
-
113
- for clause in clauses:
114
- self._all_clauses.append(clause)
115
- return None
116
-
117
- @property
118
- def table(self) -> T:
119
- return self.tables[0] if isinstance(self.tables, tp.Iterable) else self.tables
120
-
121
- @property
122
- def tables(self) -> T:
123
- return self._tables
124
-
125
- @property
126
- def columns[*Ts](self) -> tp.Callable[[T], tuple[*Ts]]:
127
- return self._columns
128
-
129
- @property
130
- def all_clauses(self) -> list[ClauseInfo[T]]:
131
- return self._all_clauses
132
-
133
- @property
134
- def context(self) -> tp.Optional[ClauseInfoContext]:
135
- return self._context
136
-
137
- @context.setter
138
- def context(self, value: ClauseInfoContext) -> None:
139
- self._context = value
140
- self.__clauses_list_generetor()
141
- return None
@@ -1,15 +0,0 @@
1
- from __future__ import annotations
2
- from abc import abstractmethod
3
- from typing import TYPE_CHECKING
4
-
5
- from ormlambda.common.interfaces import IQuery
6
-
7
- if TYPE_CHECKING:
8
- from ormlambda import Table
9
- from ormlambda.dialects import Dialect
10
-
11
-
12
- class QueryBase[T: Table](IQuery):
13
- @property
14
- @abstractmethod
15
- def query(self, dialect: Dialect, **kwargs) -> str: ...
@@ -1,7 +0,0 @@
1
- # from ormlambda.common.interfaces import IDecompositionQuery
2
-
3
-
4
- class ICustomAlias[T, *Ts]: ...
5
-
6
-
7
- # class ICustomAlias[T, *Ts](IDecompositionQuery[T, *Ts]): ...
@@ -1,33 +0,0 @@
1
- from __future__ import annotations
2
- import abc
3
- import typing as tp
4
-
5
-
6
- if tp.TYPE_CHECKING:
7
- # TODOH: Changed to avoid mysql dependency
8
- from ormlambda.sql.clause_info import ClauseInfo, TableType
9
- from ormlambda.sql.clause_info.clause_info_context import ClauseInfoContext
10
-
11
-
12
- class IDecompositionQuery_one_arg[T: TableType]:
13
- @property
14
- @abc.abstractmethod
15
- def table(self) -> T: ...
16
-
17
- @property
18
- @abc.abstractmethod
19
- def context(self) -> tp.Optional[ClauseInfoContext]: ...
20
-
21
- @context.setter
22
- @abc.abstractmethod
23
- def context(self) -> tp.Optional[ClauseInfoContext]: ...
24
-
25
-
26
- class IDecompositionQuery[T: TableType, *Ts](IDecompositionQuery_one_arg[T]):
27
- @property
28
- @abc.abstractmethod
29
- def tables(self) -> tuple[*Ts]: ...
30
-
31
- @property
32
- @abc.abstractmethod
33
- def all_clauses(self) -> list[ClauseInfo]: ...
@@ -1,4 +0,0 @@
1
- from .my_sql import (
2
- MySQLCaster as MySQLCaster,
3
- MySQLRepository as MySQLRepository,
4
- )
@@ -1,3 +0,0 @@
1
- from mysql.connector import MySQLConnection # noqa: F401
2
- from .repository import MySQLRepository # noqa: F401
3
- from .caster import MySQLCaster # noqa: F401
@@ -1,37 +0,0 @@
1
- from __future__ import annotations
2
- from typing import TYPE_CHECKING
3
- from ormlambda.sql.clause_info import AggregateFunctionBase
4
- from ormlambda.sql.types import ColumnType, AliasType
5
- from ormlambda.sql.clause_info.clause_info_context import ClauseContextType
6
-
7
- if TYPE_CHECKING:
8
- from ormlambda.dialects import Dialect
9
-
10
-
11
- class ST_AsText[T, TProp](AggregateFunctionBase[None]):
12
- """
13
- https://dev.mysql.com/doc/refman/8.4/en/fetching-spatial-data.html
14
-
15
- The ST_AsText() function converts a geometry from internal format to a WKT string.
16
- """
17
-
18
- @staticmethod
19
- def FUNCTION_NAME() -> str:
20
- return "ST_AsText"
21
-
22
- def __init__(
23
- self,
24
- point: ColumnType[TProp],
25
- alias_table: AliasType[ColumnType[TProp]] = None,
26
- alias_clause: AliasType[ColumnType[TProp]] = None,
27
- context: ClauseContextType = None,
28
- *,
29
- dialect: Dialect,
30
- ) -> None:
31
- default_alias_clause = self.create_alias_from(point) if not alias_clause else alias_clause
32
-
33
- super().__init__(table=point.table, column=point, alias_table=alias_table, alias_clause=default_alias_clause, context=context, dialect=dialect)
34
-
35
- @staticmethod
36
- def create_alias_from(element: ColumnType[TProp]) -> str:
37
- return element.column_name
@@ -1,36 +0,0 @@
1
- from __future__ import annotations
2
- import typing as tp
3
-
4
- from shapely import Point
5
-
6
- from ormlambda import Column
7
- from ormlambda.sql.types import ColumnType, AliasType
8
- from ormlambda.sql.clause_info import ClauseInfo, IAggregate
9
-
10
- if tp.TYPE_CHECKING:
11
- from ormlambda.dialects import Dialect
12
-
13
-
14
- class ST_Contains(IAggregate):
15
- FUNCTION_NAME: str = "ST_Contains"
16
-
17
- def __init__[TProp: Column](
18
- self,
19
- column: ColumnType[TProp],
20
- point: Point,
21
- alias_table: tp.Optional[AliasType[ColumnType[TProp]]] = None,
22
- alias_clause: tp.Optional[AliasType[ColumnType[TProp]]] = None,
23
- *,
24
- dialect: Dialect,
25
- ):
26
- self.attr1: ClauseInfo[Point] = ClauseInfo(column.table, column, alias_table, dialect=dialect)
27
- self.attr2: ClauseInfo[Point] = ClauseInfo[Point](None, point, dialect=dialect)
28
-
29
- self._alias_clause: AliasType[ColumnType[TProp]] = alias_clause
30
-
31
- def query(self, dialect: Dialect, **kwargs) -> str:
32
- return f"{self.FUNCTION_NAME}({self.attr1.query(dialect,**kwargs)}, {self.attr2.query(dialect,**kwargs)})"
33
-
34
- @property
35
- def alias_clause(self) -> tp.Optional[str]:
36
- return self._alias_clause
@@ -1,14 +0,0 @@
1
- from .delete import DeleteQuery as Delete
2
- from .drop_table import DropTable as DropTable
3
- from .insert import InsertQuery as Insert
4
- from .joins import JoinSelector as JoinSelector
5
- from .limit import Limit as Limit
6
- from .offset import Offset as Offset
7
- from .order import Order as Order
8
- from .update import Update as Update
9
- from .upsert import UpsertQuery as Upsert
10
- from .where import Where as Where
11
- from .having import Having as Having
12
- from .count import Count as Count
13
- from .group_by import GroupBy as GroupBy
14
- from .ST_AsText import ST_AsText as ST_AsText
@@ -1,33 +0,0 @@
1
- from __future__ import annotations
2
- from ormlambda.sql.clauses import Count
3
- from ormlambda.sql.clause_info.clause_info_context import ClauseContextType
4
-
5
- from ormlambda.sql.types import AliasType, ColumnType
6
-
7
- from ormlambda import Table
8
-
9
- from typing import TYPE_CHECKING
10
-
11
- if TYPE_CHECKING:
12
- from ormlambda import Table
13
- from ormlambda.sql.types import ColumnType, AliasType, TableType
14
-
15
-
16
- class Count[T: Table](Count[T]):
17
- def __init__[TProp: Table](
18
- self,
19
- element: ColumnType[T] | TableType[TProp],
20
- alias_table: AliasType[ColumnType[TProp]] = None,
21
- alias_clause: AliasType[ColumnType[TProp]] = "count",
22
- context: ClauseContextType = None,
23
- keep_asterisk: bool = True,
24
- preserve_context: bool = True,
25
- ) -> None:
26
- super().__init__(
27
- element=element,
28
- alias_table=alias_table,
29
- alias_clause=alias_clause,
30
- context=context,
31
- keep_asterisk=keep_asterisk,
32
- preserve_context=preserve_context,
33
- )
@@ -1,9 +0,0 @@
1
- from ormlambda import Table
2
- from ormlambda.repository import IRepositoryBase
3
- from ormlambda.sql.clauses import Delete
4
- from mysql.connector import MySQLConnection
5
-
6
-
7
- class DeleteQuery[T: Table](Delete[T, MySQLConnection]):
8
- def __init__(self, model: T, repository: IRepositoryBase) -> None:
9
- super().__init__(model, repository)
@@ -1,26 +0,0 @@
1
- from __future__ import annotations
2
- from typing import Literal, override, TYPE_CHECKING
3
-
4
- if TYPE_CHECKING:
5
- from mysql.connector import MySQLConnection
6
-
7
- from ormlambda.repository import BaseRepository
8
-
9
-
10
- TypeExists = Literal["fail", "replace", "append"]
11
-
12
-
13
- class DropTable:
14
- def __init__(self, repository: BaseRepository[MySQLConnection]) -> None:
15
- self._repository: BaseRepository[MySQLConnection] = repository
16
-
17
- @override
18
- def execute(self, name: str = None) -> None:
19
- query = rf"{self.CLAUSE} {name}"
20
- self._repository.execute(query)
21
- return None
22
-
23
- @property
24
- @override
25
- def CLAUSE(self) -> str:
26
- return "DROP TABLE"
@@ -1,17 +0,0 @@
1
- from ormlambda.sql.clause_info import ClauseInfoContext
2
- from ormlambda.sql.clauses import GroupBy
3
- from ormlambda.sql.types import ColumnType
4
-
5
-
6
- class GroupBy(GroupBy):
7
- def __init__(
8
- self,
9
- column: ColumnType,
10
- context: ClauseInfoContext,
11
- **kwargs,
12
- ):
13
- super().__init__(
14
- column=column,
15
- context=context,
16
- **kwargs,
17
- )
@@ -1,12 +0,0 @@
1
- from __future__ import annotations
2
-
3
- from ormlambda.sql.clauses import Having
4
-
5
-
6
- class Having(Having):
7
- """
8
- The purpose of this class is to create 'WHERE' condition queries properly.
9
- """
10
-
11
- def __init__(self, *comparer, restrictive=True, context=None):
12
- super().__init__(*comparer, restrictive=restrictive, context=context)
@@ -1,9 +0,0 @@
1
- from __future__ import annotations
2
- from ormlambda import Table
3
- from ormlambda.sql.clauses import Insert
4
- from mysql.connector import MySQLConnection
5
-
6
-
7
- class InsertQuery[T: Table](Insert[T, MySQLConnection]):
8
- def __init__(self, model, repository):
9
- super().__init__(model, repository)
@@ -1,14 +0,0 @@
1
- from __future__ import annotations
2
- from typing import TYPE_CHECKING
3
-
4
-
5
- from ormlambda.sql.clauses import JoinSelector
6
-
7
- # TODOL [x]: Try to import Table module without circular import Error
8
- if TYPE_CHECKING:
9
- from ormlambda import Table
10
-
11
-
12
- class JoinSelector[TLeft: Table, TRight: Table](JoinSelector[TLeft, TRight]):
13
- def __init__(self, where, by, alias="{table}", context=None, **kw):
14
- super().__init__(where, by, alias, context, **kw)
@@ -1,6 +0,0 @@
1
- from ormlambda.sql.clauses import Limit
2
-
3
-
4
- class Limit(Limit):
5
- def __init__(self, number):
6
- super().__init__(number)
@@ -1,6 +0,0 @@
1
- from ormlambda.sql.clauses import Offset
2
-
3
-
4
- class Offset(Offset):
5
- def __init__(self, number):
6
- super().__init__(number)
@@ -1,8 +0,0 @@
1
- from __future__ import annotations
2
-
3
- from ormlambda.sql.clauses import Order
4
-
5
-
6
- class Order(Order):
7
- def __init__(self, column, order_type, context=None):
8
- super().__init__(column, order_type, context)
@@ -1,8 +0,0 @@
1
- from mysql.connector import MySQLConnection
2
-
3
- from ormlambda.sql.clauses import Update
4
-
5
-
6
- class Update[T](Update[T, MySQLConnection]):
7
- def __init__(self, model, repository, where):
8
- super().__init__(model, repository, where)
@@ -1,9 +0,0 @@
1
- from __future__ import annotations
2
-
3
- from ormlambda import Table
4
- from ormlambda.sql.clauses.upsert import Upsert
5
-
6
-
7
- class UpsertQuery[T: Table](Upsert):
8
- def __init__(self, model, repository):
9
- super().__init__(model, repository)
@@ -1,7 +0,0 @@
1
- from __future__ import annotations
2
- from ormlambda.sql.clauses import Where
3
-
4
-
5
- class Where(Where):
6
- def __init__(self, *comparer, restrictive=True, context=None):
7
- super().__init__(*comparer, restrictive=restrictive, context=context)
@@ -1 +0,0 @@
1
- from .dialect import Dialect # noqa: F401
@@ -1,78 +0,0 @@
1
- from __future__ import annotations
2
- import abc
3
- from typing import ClassVar, Optional, Type, TYPE_CHECKING
4
-
5
-
6
- if TYPE_CHECKING:
7
- from ormlambda.caster.caster import Caster
8
- from ormlambda.repository.interfaces.IRepositoryBase import DBAPIConnection
9
- from ormlambda.sql.types import DDLCompiler, SQLCompiler, TypeCompiler
10
- from ormlambda import BaseRepository
11
-
12
-
13
- class Dialect(abc.ABC):
14
- """
15
- Abstract base class for all database dialects.
16
- """
17
-
18
- dbapi: Optional[DBAPIConnection]
19
- """A reference to the DBAPI module object itself.
20
-
21
- Ormlambda dialects import DBAPI modules using the classmethod
22
- :meth:`.Dialect.import_dbapi`. The rationale is so that any dialect
23
- module can be imported and used to generate SQL statements without the
24
- need for the actual DBAPI driver to be installed. Only when an
25
- :class:`.Engine` is constructed using :func:`.create_engine` does the
26
- DBAPI get imported; at that point, the creation process will assign
27
- the DBAPI module to this attribute.
28
-
29
- Dialects should therefore implement :meth:`.Dialect.import_dbapi`
30
- which will import the necessary module and return it, and then refer
31
- to ``self.dbapi`` in dialect code in order to refer to the DBAPI module
32
- contents.
33
-
34
- .. versionchanged:: The :attr:`.Dialect.dbapi` attribute is exclusively
35
- used as the per-:class:`.Dialect`-instance reference to the DBAPI
36
- module. The previous not-fully-documented ``.Dialect.dbapi()``
37
- classmethod is deprecated and replaced by :meth:`.Dialect.import_dbapi`.
38
-
39
- """
40
-
41
- name: ClassVar[str]
42
- """The name of the dialect, e.g. 'sqlite', 'postgresql', etc."""
43
- driver: ClassVar[str]
44
- """The driver used by the dialect, e.g. 'sqlite3', 'psycopg2', etc."""
45
-
46
- ddl_compiler: ClassVar[Type[DDLCompiler]]
47
- """The DDL compiler class used by the dialect."""
48
-
49
- statement_compiler: ClassVar[Type[SQLCompiler]]
50
- """The statement compiler class used by the dialect."""
51
-
52
- type_compiler_cls: ClassVar[Type[TypeCompiler]]
53
- """The type compiler class used by the dialect."""
54
-
55
- type_compiler_instance: ClassVar[TypeCompiler]
56
- """The instance of the type compiler class used by the dialect."""
57
-
58
- repository_cls: ClassVar[Type[BaseRepository]]
59
- """The repository class used by the dialect."""
60
-
61
- caster: ClassVar[Type[Caster]]
62
-
63
- @classmethod
64
- def get_dialect_cls(cls) -> Type[Dialect]:
65
- return cls
66
-
67
- @classmethod
68
- @abc.abstractmethod
69
- def import_dbapi(cls) -> DBAPIConnection:
70
- """
71
- Import the DB API module for the dialect.
72
- This method should be implemented by subclasses to import the
73
- appropriate DB API module for the dialect.
74
- """
75
- ...
76
-
77
- def __repr__(self):
78
- return f"{Dialect.__name__}: {type(self).__name__}"
@@ -1,96 +0,0 @@
1
- from __future__ import annotations
2
- import abc
3
- import typing as tp
4
-
5
- from ormlambda import Table
6
- from ormlambda import Column
7
- from ormlambda.sql.types import (
8
- TableType,
9
- ColumnType,
10
- AliasType,
11
- )
12
- from .interface import IAggregate
13
- from ormlambda.common.errors import NotKeysInIAggregateError
14
- from ormlambda.sql import ForeignKey
15
- from ormlambda.sql.table import TableMeta
16
- from .clause_info import ClauseInfo
17
- from .clause_info_context import ClauseContextType
18
-
19
- if tp.TYPE_CHECKING:
20
- from ormlambda.dialects import Dialect
21
-
22
-
23
- class AggregateFunctionBase[T: Table](ClauseInfo[T], IAggregate):
24
- def __init__[TProp: Column](
25
- self,
26
- table: TableType[T],
27
- column: tp.Optional[ColumnType[TProp]] = None,
28
- alias_table: tp.Optional[AliasType[ClauseInfo[T]]] = None,
29
- alias_clause: tp.Optional[AliasType[ClauseInfo[T]]] = None,
30
- context: ClauseContextType = None,
31
- keep_asterisk: bool = False,
32
- preserve_context: bool = False,
33
- dtype: TProp = None,
34
- *,
35
- dialect: Dialect,
36
- **kw,
37
- ):
38
- self._alias_aggregate = alias_clause
39
- super().__init__(
40
- table=table,
41
- column=column,
42
- alias_table=alias_table,
43
- context=context,
44
- keep_asterisk=keep_asterisk,
45
- preserve_context=preserve_context,
46
- dtype=dtype,
47
- dialect=dialect,
48
- **kw,
49
- )
50
-
51
- @staticmethod
52
- @abc.abstractmethod
53
- def FUNCTION_NAME() -> str: ...
54
-
55
- @classmethod
56
- def _convert_into_clauseInfo[TypeColumns, TProp](cls, columns: ClauseInfo | ColumnType[TProp], context: ClauseContextType, dialect: Dialect) -> list[ClauseInfo]:
57
- type DEFAULT = tp.Literal["default"]
58
- type ClusterType = ColumnType | ForeignKey | DEFAULT
59
-
60
- dicc_type: dict[ClusterType, tp.Callable[[ClusterType], ClauseInfo]] = {
61
- Column: lambda column: ClauseInfo(column.table, column, context=context, dialect=dialect),
62
- ClauseInfo: lambda column: column,
63
- ForeignKey: lambda tbl: ClauseInfo(tbl.tright, tbl.tright, context=context, dialect=dialect),
64
- TableMeta: lambda tbl: ClauseInfo(tbl, tbl, context=context, dialect=dialect),
65
- "default": lambda column: ClauseInfo(table=None, column=column, context=context, dialect=dialect),
66
- }
67
- all_clauses: list[ClauseInfo] = []
68
- if isinstance(columns, str) or not isinstance(columns, tp.Iterable):
69
- columns = (columns,)
70
- for value in columns:
71
- all_clauses.append(dicc_type.get(type(value), dicc_type["default"])(value))
72
-
73
- return all_clauses
74
-
75
- @tp.override
76
- def query(self, dialect: Dialect, **kwargs) -> str:
77
- wrapped_ci = self.wrapped_clause_info(self)
78
- if not self._alias_aggregate:
79
- return wrapped_ci
80
-
81
- return ClauseInfo(
82
- table=None,
83
- column=wrapped_ci,
84
- alias_clause=self._alias_aggregate,
85
- context=self._context,
86
- keep_asterisk=self._keep_asterisk,
87
- preserve_context=self._preserve_context,
88
- dialect=self._dialect,
89
- ).query(dialect, **kwargs)
90
-
91
- def wrapped_clause_info(self, ci: ClauseInfo[T]) -> str:
92
- # avoid use placeholder when using IAggregate because no make sense.
93
- if self._alias_aggregate and (found := self._keyRegex.findall(self._alias_aggregate)):
94
- raise NotKeysInIAggregateError(found)
95
-
96
- return f"{self.FUNCTION_NAME()}({ci._create_query(self._dialect)})"