ormlambda 3.34.6__py3-none-any.whl → 3.34.7__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.
@@ -0,0 +1,119 @@
1
+ from __future__ import annotations
2
+ from collections import defaultdict
3
+ from typing import override, Optional, TYPE_CHECKING, Type
4
+
5
+
6
+ from ormlambda.util.module_tree.dfs_traversal import DFSTraversal
7
+ from ormlambda.common.interfaces.IQueryCommand import IQuery
8
+ from ormlambda import JoinType
9
+ from ormlambda.sql.clause_info import ClauseInfo
10
+ from ormlambda.sql.comparer import Comparer
11
+ from ormlambda.sql.elements import ClauseElement
12
+
13
+
14
+ # TODOL [x]: Try to import Table module without circular import Error
15
+ if TYPE_CHECKING:
16
+ from ormlambda.dialects import Dialect
17
+
18
+
19
+ class Join(ClauseElement):
20
+ __visit_name__ = "join"
21
+ __slots__: tuple = (
22
+ "comparer",
23
+ "alias",
24
+ "from_clause",
25
+ "left_clause",
26
+ "right_clause",
27
+ "by",
28
+ "_dialect",
29
+ )
30
+
31
+ DEFAULT_TABLE: str = "{table}"
32
+
33
+ @override
34
+ def __repr__(self) -> str:
35
+ return f"{IQuery.__name__}: {self.query(self._dialect)}"
36
+
37
+ def __init__(
38
+ self,
39
+ comparer: Comparer,
40
+ right_alias: Optional[str] = DEFAULT_TABLE,
41
+ left_alias: Optional[str] = DEFAULT_TABLE,
42
+ by: JoinType = JoinType.LEFT_EXCLUSIVE,
43
+ *,
44
+ dialect: Dialect,
45
+ **kw,
46
+ ) -> None:
47
+ self.comparer = comparer
48
+ self._dialect = dialect
49
+ self.by = by
50
+
51
+ # COMMENT: When multiple columns reference the same table, we need to create an alias to maintain clear references.
52
+ self.alias: Optional[str] = right_alias
53
+ self.left_clause: ClauseInfo = comparer.left_condition(dialect)
54
+ self.left_clause.alias_table = left_alias if left_alias is not None else self.DEFAULT_TABLE
55
+
56
+ self.right_clause: ClauseInfo = comparer.right_condition(dialect)
57
+ self.right_clause.alias_table = right_alias if right_alias is not None else self.DEFAULT_TABLE
58
+ self.from_clause = ClauseInfo(self.right_clause.table, None, alias_table=self.alias, dialect=dialect)
59
+
60
+ def __eq__(self, __value: Join) -> bool:
61
+ return isinstance(__value, Join) and self.__hash__() == __value.__hash__()
62
+
63
+ def __hash__(self) -> int:
64
+ return hash(
65
+ (
66
+ self.by,
67
+ self.left_clause.query(self._dialect),
68
+ self.right_clause.query(self._dialect),
69
+ self.from_clause.query(self._dialect),
70
+ )
71
+ )
72
+
73
+ @classmethod
74
+ def join_selectors(cls, dialect: Dialect, *args: Join) -> str:
75
+ return "\n".join([x.query(dialect) for x in args])
76
+
77
+ def query(self, dialect: Dialect) -> str:
78
+ list_ = [
79
+ self.by.value, # inner join
80
+ self.from_clause.query(dialect),
81
+ "ON",
82
+ self.left_clause.query(dialect),
83
+ "=",
84
+ self.right_clause.query(dialect),
85
+ ]
86
+ return " ".join([x for x in list_ if x is not None])
87
+
88
+ @classmethod
89
+ def sort_join_selectors(cls, joins: set[Join]) -> tuple[Join]:
90
+ # FIXME [x]: How to sort when needed because it's not necessary at this point. It is for testing purpouse
91
+ if len(joins) == 1:
92
+ return tuple(joins)
93
+
94
+ # create graph and sort it using 'Depth First Search' algorithm
95
+ graph: dict[str, list[str]] = defaultdict(list)
96
+ for join in joins:
97
+ graph[join.left_clause.alias_table].append(join.right_clause.alias_table)
98
+
99
+ sorted_graph = DFSTraversal.sort(graph)[::-1]
100
+
101
+ if not sorted_graph:
102
+ return tuple(joins)
103
+
104
+ # Mapped Join class using his unique alias
105
+ join_object_map: dict[str, Join] = {}
106
+ for obj in joins:
107
+ join_object_map[obj.alias] = obj
108
+
109
+ res = []
110
+ for table in sorted_graph:
111
+ tables = join_object_map.get(table, None)
112
+
113
+ if not tables:
114
+ continue
115
+ res.append(tables)
116
+ return res
117
+
118
+
119
+ __all__ = ["Join"]
@@ -159,14 +159,10 @@ class Table(metaclass=TableMeta):
159
159
  return [ForeignKey.MAPPED[x].table_object for x in order_table]
160
160
 
161
161
  def __eq__(self, __value: Any) -> bool:
162
- if isinstance(__value, Table):
163
- return all(
164
- (
165
- self.__table_name__ == __value.__table_name__,
166
- tuple(self.to_dict().items()),
167
- )
168
- )
169
- return False
162
+ return hash(self) == hash(__value)
163
+
164
+ def __hash__(self):
165
+ return hash((self.__table_name__, *list(self.to_dict().items())))
170
166
 
171
167
  @classmethod
172
168
  def table_alias(cls, column: Optional[str] = None) -> str:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ormlambda
3
- Version: 3.34.6
3
+ Version: 3.34.7
4
4
  Summary: ORM designed to interact with the database (currently with MySQL) using lambda functions and nested functions
5
5
  Author: p-hzamora
6
6
  Author-email: p.hzamora@icloud.com
@@ -107,6 +107,7 @@ ormlambda/sql/clauses/join/__init__.py,sha256=7hwAB-nKaMirTT6uNZ1JtYNkkIx5zMSa6j
107
107
  ormlambda/sql/clauses/join/join_context.py,sha256=69R_X_RoWO2kXPgJ94Wck6s-sJjTIqFXpOifmLsYC9c,3497
108
108
  ormlambda/sql/clauses/joins.py,sha256=w0c_uHNe3BNqL9-rAdQaAFeM6ExJXTNENG_sO7I2HWI,5505
109
109
  ormlambda/sql/clauses/limit.py,sha256=NX9qUp_8Zd-0myZ80PhD2tbF72N5jsx_SaYakf7lNbU,345
110
+ ormlambda/sql/clauses/new_join.py,sha256=e-tLvSQJJpTEQURYgLLoKZ6TrVsY8xGphBnqlEGg76A,3859
110
111
  ormlambda/sql/clauses/offset.py,sha256=FibzDho7Bc1UQchrPHjOakW_0BfZVupbuI62lHoha94,350
111
112
  ormlambda/sql/clauses/order.py,sha256=qOcz2T0NQNY0H7vt-jbvBRjTy3X5Lw-kGSuISTGfAPA,1609
112
113
  ormlambda/sql/clauses/select.py,sha256=gJfTqTCi32Knyp-rox_qo-JeoVYr6YWTEPl9FF8FsFg,1670
@@ -129,7 +130,7 @@ ormlambda/sql/interfaces/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZ
129
130
  ormlambda/sql/sqltypes.py,sha256=1Ir_Wxz1VjnNOh2zzIf7P7w4tbY0ljlubZMoAEiUkYU,14333
130
131
  ormlambda/sql/table/__init__.py,sha256=LLZcMLjwFxgBCPhdm5UQYYZDIbtYWCKPO9CbcXsy5zI,50
131
132
  ormlambda/sql/table/fields.py,sha256=ovNR3bJ473aKW-2NhbKr0iJlVpgW06jurHLob2IyZU8,2116
132
- ormlambda/sql/table/table.py,sha256=U8ByMDEEXIOwfPykDcjzoyNV1WEieN40Zk18EXveX60,6594
133
+ ormlambda/sql/table/table.py,sha256=l_oXhTHid09IaG-eapBxZTdaNrWCVgGHWLDHnIrrEqY,6484
133
134
  ormlambda/sql/table/table_constructor.py,sha256=c3Z-1El0onSClYBmAatoUBYUOT70tITVqtsDJMxZ9QU,1092
134
135
  ormlambda/sql/type_api.py,sha256=vepqMw6hR4zVhhNIYbtX491iVsxAfwHiSiD3uYQUGTE,1067
135
136
  ormlambda/sql/types.py,sha256=lQxC5gbhDPRckGSRJZ4rYSZr-XUvIMMH8WfkN1wtM1g,844
@@ -150,8 +151,8 @@ ormlambda/util/module_tree/dfs_traversal.py,sha256=lSF03G63XtJFLp03ueAmsHMBvhUkj
150
151
  ormlambda/util/module_tree/dynamic_module.py,sha256=vJOqvm5-WKksudXBK1IcTn4WsuLxt1qXNISq-_21sy4,8705
151
152
  ormlambda/util/plugin_loader.py,sha256=p6WLn-MF1bQd2i2GHy98WQjNKmbQdqIUyTFIcBIHC5M,1034
152
153
  ormlambda/util/typing.py,sha256=Z7irz53ui0hoFnJTe06NX4JPl60_thgdjJIxh5gjGGk,169
153
- ormlambda-3.34.6.dist-info/AUTHORS,sha256=uWpOHaCPTOLbVkk5x9McoLwbgzSeCg7yILeDRyMGWGM,606
154
- ormlambda-3.34.6.dist-info/LICENSE,sha256=xBprFw8GJLdHMOoUqDk0427EvjIcbEREvXXVFULuuXU,1080
155
- ormlambda-3.34.6.dist-info/METADATA,sha256=dLX5_MrsxoSEMj42Ummw8Cnv7E8829nPkqxLQCH6V4o,13326
156
- ormlambda-3.34.6.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
157
- ormlambda-3.34.6.dist-info/RECORD,,
154
+ ormlambda-3.34.7.dist-info/AUTHORS,sha256=uWpOHaCPTOLbVkk5x9McoLwbgzSeCg7yILeDRyMGWGM,606
155
+ ormlambda-3.34.7.dist-info/LICENSE,sha256=xBprFw8GJLdHMOoUqDk0427EvjIcbEREvXXVFULuuXU,1080
156
+ ormlambda-3.34.7.dist-info/METADATA,sha256=KY00nCr8bLYuTDA0h70RF6PeYZ2Kt-NOcN3Nd5UfR18,13326
157
+ ormlambda-3.34.7.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
158
+ ormlambda-3.34.7.dist-info/RECORD,,