ormlambda 1.2.1__tar.gz → 1.3.0__tar.gz

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 (72) hide show
  1. {ormlambda-1.2.1 → ormlambda-1.3.0}/PKG-INFO +2 -2
  2. {ormlambda-1.2.1 → ormlambda-1.3.0}/pyproject.toml +2 -2
  3. {ormlambda-1.2.1 → ormlambda-1.3.0}/src/ormlambda/__init__.py +1 -0
  4. ormlambda-1.3.0/src/ormlambda/common/abstract_classes/abstract_model.py +87 -0
  5. {ormlambda-1.2.1 → ormlambda-1.3.0}/src/ormlambda/common/interfaces/IRepositoryBase.py +1 -1
  6. {ormlambda-1.2.1 → ormlambda-1.3.0}/src/ormlambda/databases/my_sql/repository.py +1 -1
  7. ormlambda-1.2.1/src/ormlambda/common/abstract_classes/abstract_model.py → ormlambda-1.3.0/src/ormlambda/databases/my_sql/statements.py +47 -139
  8. {ormlambda-1.2.1 → ormlambda-1.3.0}/src/ormlambda/model_base.py +2 -2
  9. ormlambda-1.2.1/src/ormlambda/databases/my_sql/statements.py +0 -95
  10. {ormlambda-1.2.1 → ormlambda-1.3.0}/LICENSE +0 -0
  11. {ormlambda-1.2.1 → ormlambda-1.3.0}/README.md +0 -0
  12. {ormlambda-1.2.1 → ormlambda-1.3.0}/src/ormlambda/common/__init__.py +0 -0
  13. {ormlambda-1.2.1 → ormlambda-1.3.0}/src/ormlambda/common/abstract_classes/__init__.py +0 -0
  14. {ormlambda-1.2.1 → ormlambda-1.3.0}/src/ormlambda/common/abstract_classes/non_query_base.py +0 -0
  15. {ormlambda-1.2.1 → ormlambda-1.3.0}/src/ormlambda/common/abstract_classes/query_base.py +0 -0
  16. {ormlambda-1.2.1 → ormlambda-1.3.0}/src/ormlambda/common/enums/__init__.py +0 -0
  17. {ormlambda-1.2.1 → ormlambda-1.3.0}/src/ormlambda/common/enums/condition_types.py +0 -0
  18. {ormlambda-1.2.1 → ormlambda-1.3.0}/src/ormlambda/common/enums/join_type.py +0 -0
  19. {ormlambda-1.2.1 → ormlambda-1.3.0}/src/ormlambda/common/interfaces/INonQueryCommand.py +0 -0
  20. {ormlambda-1.2.1 → ormlambda-1.3.0}/src/ormlambda/common/interfaces/IQueryCommand.py +0 -0
  21. {ormlambda-1.2.1 → ormlambda-1.3.0}/src/ormlambda/common/interfaces/IStatements.py +0 -0
  22. {ormlambda-1.2.1 → ormlambda-1.3.0}/src/ormlambda/common/interfaces/__init__.py +0 -0
  23. {ormlambda-1.2.1 → ormlambda-1.3.0}/src/ormlambda/components/__init__.py +0 -0
  24. {ormlambda-1.2.1 → ormlambda-1.3.0}/src/ormlambda/components/delete/IDelete.py +0 -0
  25. {ormlambda-1.2.1 → ormlambda-1.3.0}/src/ormlambda/components/delete/__init__.py +0 -0
  26. {ormlambda-1.2.1 → ormlambda-1.3.0}/src/ormlambda/components/delete/abstract_delete.py +0 -0
  27. {ormlambda-1.2.1 → ormlambda-1.3.0}/src/ormlambda/components/insert/IInsert.py +0 -0
  28. {ormlambda-1.2.1 → ormlambda-1.3.0}/src/ormlambda/components/insert/__init__.py +0 -0
  29. {ormlambda-1.2.1 → ormlambda-1.3.0}/src/ormlambda/components/insert/abstract_insert.py +0 -0
  30. {ormlambda-1.2.1 → ormlambda-1.3.0}/src/ormlambda/components/select/ISelect.py +0 -0
  31. {ormlambda-1.2.1 → ormlambda-1.3.0}/src/ormlambda/components/select/__init__.py +0 -0
  32. {ormlambda-1.2.1 → ormlambda-1.3.0}/src/ormlambda/components/select/table_column.py +0 -0
  33. {ormlambda-1.2.1 → ormlambda-1.3.0}/src/ormlambda/components/update/IUpdate.py +0 -0
  34. {ormlambda-1.2.1 → ormlambda-1.3.0}/src/ormlambda/components/update/__init__.py +0 -0
  35. {ormlambda-1.2.1 → ormlambda-1.3.0}/src/ormlambda/components/update/abstract_update.py +0 -0
  36. {ormlambda-1.2.1 → ormlambda-1.3.0}/src/ormlambda/components/upsert/IUpsert.py +0 -0
  37. {ormlambda-1.2.1 → ormlambda-1.3.0}/src/ormlambda/components/upsert/__init__.py +0 -0
  38. {ormlambda-1.2.1 → ormlambda-1.3.0}/src/ormlambda/components/upsert/abstract_upsert.py +0 -0
  39. {ormlambda-1.2.1 → ormlambda-1.3.0}/src/ormlambda/components/where/__init__.py +0 -0
  40. {ormlambda-1.2.1 → ormlambda-1.3.0}/src/ormlambda/components/where/abstract_where.py +0 -0
  41. {ormlambda-1.2.1 → ormlambda-1.3.0}/src/ormlambda/databases/__init__.py +0 -0
  42. {ormlambda-1.2.1 → ormlambda-1.3.0}/src/ormlambda/databases/my_sql/__init__.py +0 -0
  43. {ormlambda-1.2.1 → ormlambda-1.3.0}/src/ormlambda/databases/my_sql/clauses/__init__.py +0 -0
  44. {ormlambda-1.2.1 → ormlambda-1.3.0}/src/ormlambda/databases/my_sql/clauses/count.py +0 -0
  45. {ormlambda-1.2.1 → ormlambda-1.3.0}/src/ormlambda/databases/my_sql/clauses/create_database.py +0 -0
  46. {ormlambda-1.2.1 → ormlambda-1.3.0}/src/ormlambda/databases/my_sql/clauses/delete.py +0 -0
  47. {ormlambda-1.2.1 → ormlambda-1.3.0}/src/ormlambda/databases/my_sql/clauses/drop_database.py +0 -0
  48. {ormlambda-1.2.1 → ormlambda-1.3.0}/src/ormlambda/databases/my_sql/clauses/drop_table.py +0 -0
  49. {ormlambda-1.2.1 → ormlambda-1.3.0}/src/ormlambda/databases/my_sql/clauses/insert.py +0 -0
  50. {ormlambda-1.2.1 → ormlambda-1.3.0}/src/ormlambda/databases/my_sql/clauses/joins.py +0 -0
  51. {ormlambda-1.2.1 → ormlambda-1.3.0}/src/ormlambda/databases/my_sql/clauses/limit.py +0 -0
  52. {ormlambda-1.2.1 → ormlambda-1.3.0}/src/ormlambda/databases/my_sql/clauses/offset.py +0 -0
  53. {ormlambda-1.2.1 → ormlambda-1.3.0}/src/ormlambda/databases/my_sql/clauses/order.py +0 -0
  54. {ormlambda-1.2.1 → ormlambda-1.3.0}/src/ormlambda/databases/my_sql/clauses/select.py +0 -0
  55. {ormlambda-1.2.1 → ormlambda-1.3.0}/src/ormlambda/databases/my_sql/clauses/update.py +0 -0
  56. {ormlambda-1.2.1 → ormlambda-1.3.0}/src/ormlambda/databases/my_sql/clauses/upsert.py +0 -0
  57. {ormlambda-1.2.1 → ormlambda-1.3.0}/src/ormlambda/databases/my_sql/clauses/where_condition.py +0 -0
  58. {ormlambda-1.2.1 → ormlambda-1.3.0}/src/ormlambda/utils/__init__.py +0 -0
  59. {ormlambda-1.2.1 → ormlambda-1.3.0}/src/ormlambda/utils/column.py +0 -0
  60. {ormlambda-1.2.1 → ormlambda-1.3.0}/src/ormlambda/utils/dtypes.py +0 -0
  61. {ormlambda-1.2.1 → ormlambda-1.3.0}/src/ormlambda/utils/foreign_key.py +0 -0
  62. {ormlambda-1.2.1 → ormlambda-1.3.0}/src/ormlambda/utils/lambda_disassembler/__init__.py +0 -0
  63. {ormlambda-1.2.1 → ormlambda-1.3.0}/src/ormlambda/utils/lambda_disassembler/dis_types.py +0 -0
  64. {ormlambda-1.2.1 → ormlambda-1.3.0}/src/ormlambda/utils/lambda_disassembler/disassembler.py +0 -0
  65. {ormlambda-1.2.1 → ormlambda-1.3.0}/src/ormlambda/utils/lambda_disassembler/dtypes.py +0 -0
  66. {ormlambda-1.2.1 → ormlambda-1.3.0}/src/ormlambda/utils/lambda_disassembler/name_of.py +0 -0
  67. {ormlambda-1.2.1 → ormlambda-1.3.0}/src/ormlambda/utils/lambda_disassembler/nested_element.py +0 -0
  68. {ormlambda-1.2.1 → ormlambda-1.3.0}/src/ormlambda/utils/lambda_disassembler/tree_instruction.py +0 -0
  69. {ormlambda-1.2.1 → ormlambda-1.3.0}/src/ormlambda/utils/module_tree/__init__.py +0 -0
  70. {ormlambda-1.2.1 → ormlambda-1.3.0}/src/ormlambda/utils/module_tree/dfs_traversal.py +0 -0
  71. {ormlambda-1.2.1 → ormlambda-1.3.0}/src/ormlambda/utils/module_tree/dynamic_module.py +0 -0
  72. {ormlambda-1.2.1 → ormlambda-1.3.0}/src/ormlambda/utils/table_constructor.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ormlambda
3
- Version: 1.2.1
3
+ Version: 1.3.0
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
@@ -8,7 +8,7 @@ Requires-Python: >=3.12,<4.0
8
8
  Classifier: Programming Language :: Python :: 3
9
9
  Classifier: Programming Language :: Python :: 3.12
10
10
  Requires-Dist: fluent-validation (>=3.1.0,<4.0.0)
11
- Requires-Dist: mysql-connector-python (>=2.2.9,<3.0.0)
11
+ Requires-Dist: mysql-connector-python (>=9.0.0,<10.0.0)
12
12
  Description-Content-Type: text/markdown
13
13
 
14
14
  ![PyPI version](https://img.shields.io/pypi/v/ormlambda.svg)
@@ -3,14 +3,14 @@ line-length = 320
3
3
 
4
4
  [tool.poetry]
5
5
  name = "ormlambda"
6
- version = "1.2.1"
6
+ version = "1.3.0"
7
7
  description = "ORM designed to interact with the database (currently with MySQL) using lambda functions and nested functions"
8
8
  authors = ["p-hzamora <p.hzamora@icloud.com>"]
9
9
  readme = "README.md"
10
10
 
11
11
  [tool.poetry.dependencies]
12
12
  python = "^3.12"
13
- mysql-connector-python= "^2.2.9"
13
+ mysql-connector-python= "^9.0.0"
14
14
  fluent-validation = "^3.1.0"
15
15
 
16
16
  [tool.poetry.group.test.dependencies]
@@ -4,6 +4,7 @@ from .common.enums import ( # noqa: F401
4
4
  ConditionType,
5
5
  )
6
6
 
7
+ from .common.abstract_classes import AbstractSQLStatements # noqa: F401
7
8
  from .common.interfaces import IRepositoryBase # noqa: F401
8
9
  from .utils import Table, Column, ForeignKey # noqa: F401
9
10
  from .utils.lambda_disassembler import Disassembler, nameof # noqa: F401
@@ -0,0 +1,87 @@
1
+ from __future__ import annotations
2
+ from typing import Any, Type, override, Iterable, Literal, TYPE_CHECKING
3
+ from collections import defaultdict
4
+
5
+
6
+ from ormlambda.utils import Table
7
+ from ormlambda.common.interfaces import IQuery, IRepositoryBase, IStatements_two_generic
8
+
9
+ if TYPE_CHECKING:
10
+ from ormlambda.components.select import ISelect
11
+ from ormlambda.components.select import TableColumn
12
+
13
+
14
+ ORDER_QUERIES = Literal["select", "join", "where", "order", "with", "group by", "limit", "offset"]
15
+
16
+
17
+ class AbstractSQLStatements[T: Table, TRepo](IStatements_two_generic[T, TRepo]):
18
+ __slots__ = ("_model", "_repository", "_query_list")
19
+ __order__: tuple[str, ...] = ("select", "join", "where", "order", "with", "group by", "limit", "offset")
20
+
21
+ def __init__(self, model: T, repository: IRepositoryBase[TRepo]) -> None:
22
+ self.__valid_repository(repository)
23
+
24
+ self._model: T = model
25
+ self._repository: IRepositoryBase[TRepo] = repository
26
+ self._query_list: dict[ORDER_QUERIES, list[IQuery]] = defaultdict(list)
27
+
28
+ if not issubclass(self._model, Table):
29
+ # Deben heredar de Table ya que es la forma que tenemos para identificar si estamos pasando una instancia del tipo que corresponde o no cuando llamamos a insert o upsert.
30
+ # Si no heredase de Table no sabriamos identificar el tipo de dato del que se trata porque al llamar a isinstance, obtendriamos el nombre de la clase que mapea a la tabla, Encargo, Edificio, Presupuesto y no podriamos crear una clase generica
31
+ raise Exception(f"'{model}' class does not inherit from Table class")
32
+
33
+ @staticmethod
34
+ def __valid_repository(repository: Any) -> bool:
35
+ if not isinstance(repository, IRepositoryBase):
36
+ raise ValueError(f"'repository' attribute does not instance of '{IRepositoryBase.__name__}'")
37
+ return True
38
+
39
+ def __repr__(self):
40
+ return f"<Model: {self.__class__.__name__}>"
41
+
42
+ @property
43
+ @override
44
+ def repository(self) -> IRepositoryBase[TRepo]: ...
45
+
46
+ def _return_flavour[TValue](self, query, flavour: Type[TValue]) -> tuple[TValue]:
47
+ return self._repository.read_sql(query, flavour=flavour)
48
+
49
+ def _return_model(self, select: ISelect, query: str):
50
+ response_sql = self._repository.read_sql(query, flavour=dict) # store all columns of the SQL query
51
+
52
+ if isinstance(response_sql, Iterable):
53
+ return ClusterQuery(select, response_sql).clean_response()
54
+
55
+ return response_sql
56
+
57
+
58
+ class ClusterQuery:
59
+ def __init__(self, select: ISelect, response_sql: tuple[dict[str, Any]]) -> None:
60
+ self._select: ISelect = select
61
+ self._response_sql: tuple[dict[str, Any]] = response_sql
62
+
63
+ def loop_foo(self) -> dict[Type[Table], list[Table]]:
64
+ # We must ensure to get the valid attributes for each instance
65
+ table_initialize = defaultdict(list)
66
+
67
+ unic_table: dict[Table, list[TableColumn]] = defaultdict(list)
68
+ for table_col in self._select.select_list:
69
+ unic_table[table_col._table].append(table_col)
70
+
71
+ for table_, table_col in unic_table.items():
72
+ for dicc_cols in self._response_sql:
73
+ valid_attr: dict[str, Any] = {}
74
+ for col in table_col:
75
+ valid_attr[col.real_column] = dicc_cols[col.alias]
76
+ # COMMENT: At this point we are going to instantiate Table class with specific attributes getting directly from database
77
+ table_initialize[table_].append(table_(**valid_attr))
78
+ return table_initialize
79
+
80
+ def clean_response(self) -> tuple[dict[Type[Table], tuple[Table]]]:
81
+ tbl_dicc: dict[Type[Table], list[Table]] = self.loop_foo()
82
+
83
+ # it not depend of flavour attr
84
+ for key, val in tbl_dicc.items():
85
+ tbl_dicc[key] = tuple(val)
86
+
87
+ return tuple(tbl_dicc.values())
@@ -25,7 +25,7 @@ class IRepositoryBase[T](ABC):
25
25
  def is_connected(self) -> bool: ...
26
26
 
27
27
  @abstractmethod
28
- def connect(self, **kwargs: Any) -> "IRepositoryBase[T]": ...
28
+ def connect(self, **kwargs: Any) -> None: ...
29
29
 
30
30
  @abstractmethod
31
31
  def close_connection(self) -> None: ...
@@ -85,7 +85,7 @@ class MySQLRepository(IRepositoryBase[MySQLConnection]):
85
85
  return self._connection.is_connected()
86
86
 
87
87
  @override
88
- def connect(self) -> IRepositoryBase[MySQLConnection]:
88
+ def connect(self) -> None:
89
89
  # return MySQLConnectionPool(pool_name="mypool", pool_size=5, **kwargs)
90
90
  self._connection.connect(**self._data_config)
91
91
  return None
@@ -1,98 +1,49 @@
1
1
  from __future__ import annotations
2
- from typing import Any, Callable, Optional, Type, override, Iterable, Literal, TYPE_CHECKING
3
- from enum import Enum
4
- from collections import defaultdict
5
- from abc import abstractmethod
6
- import inspect
7
-
8
- from ormlambda.utils import ForeignKey, Table
9
-
10
- from ormlambda.common.interfaces import IQuery, IRepositoryBase, IStatements_two_generic
2
+ from typing import override, Type, TYPE_CHECKING, Any, Callable, Optional
11
3
 
12
4
  if TYPE_CHECKING:
13
- from ormlambda.common.interfaces.IStatements import OrderType
14
-
15
- from ormlambda.components.update import UpdateQueryBase
5
+ from ormlambda import Table
16
6
  from ormlambda.components.select import ISelect
17
- from ormlambda.components.delete import DeleteQueryBase
18
- from ormlambda.components.upsert import UpsertQueryBase
19
- from ormlambda.components.select import TableColumn
20
- from ormlambda.components.insert import InsertQueryBase
21
7
  from ormlambda.components.where.abstract_where import AbstractWhere
22
-
8
+ from ormlambda.common.interfaces.IStatements import OrderType
9
+ from ormlambda.common.interfaces import IQuery, IRepositoryBase, IStatements_two_generic
10
+
23
11
  from ormlambda.databases.my_sql.clauses.select import SelectQuery
24
12
  from ormlambda.databases.my_sql.clauses.count import CountQuery
25
13
 
26
14
 
27
- class JoinType(Enum):
28
- RIGHT_INCLUSIVE = "RIGHT JOIN"
29
- LEFT_INCLUSIVE = "LEFT JOIN"
30
- RIGHT_EXCLUSIVE = "RIGHT JOIN"
31
- LEFT_EXCLUSIVE = "LEFT JOIN"
32
- FULL_OUTER_INCLUSIVE = "RIGHT JOIN"
33
- FULL_OUTER_EXCLUSIVE = "RIGHT JOIN"
34
- INNER_JOIN = "INNER JOIN"
35
-
15
+ from ormlambda import AbstractSQLStatements
16
+ from .clauses import DeleteQuery
17
+ from .clauses import InsertQuery
18
+ from .clauses import JoinSelector
19
+ from .clauses import LimitQuery
20
+ from .clauses import OffsetQuery
21
+ from .clauses import OrderQuery
22
+ from .clauses import SelectQuery
23
+ from .clauses import UpsertQuery
24
+ from .clauses import UpdateQuery
25
+ from .clauses import WhereCondition
26
+ from .clauses import CountQuery
36
27
 
37
- ORDER_QUERIES = Literal["select", "join", "where", "order", "with", "group by", "limit", "offset"]
28
+ from mysql.connector import MySQLConnection
38
29
 
39
30
 
40
- class AbstractSQLStatements[T: Table, TRepo](IStatements_two_generic[T, TRepo]):
41
- __slots__ = ("_model", "_repository", "_query_list")
42
- __order__: tuple[str, ...] = ("select", "join", "where", "order", "with", "group by", "limit", "offset")
43
31
 
44
- def __init__(self, model: T, repository: IRepositoryBase[TRepo]) -> None:
45
- self.valid_repository(repository)
32
+ import inspect
46
33
 
47
- self._model: T = model
48
- self._repository: IRepositoryBase[TRepo] = repository
49
- self._query_list: dict[ORDER_QUERIES, list[IQuery]] = defaultdict(list)
34
+ from ormlambda.utils import ForeignKey, Table
35
+ from ormlambda.common.enums import JoinType
50
36
 
51
- if not issubclass(self._model, Table):
52
- # Deben heredar de Table ya que es la forma que tenemos para identificar si estamos pasando una instancia del tipo que corresponde o no cuando llamamos a insert o upsert.
53
- # Si no heredase de Table no sabriamos identificar el tipo de dato del que se trata porque al llamar a isinstance, obtendriamos el nombre de la clase que mapea a la tabla, Encargo, Edificio, Presupuesto y no podriamos crear una clase generica
54
- raise Exception(f"'{model}' class does not inherit from Table class")
55
37
 
56
- @staticmethod
57
- def valid_repository(repository: Any) -> bool:
58
- if not isinstance(repository, IRepositoryBase):
59
- raise ValueError(f"'repository' attribute does not instance of '{IRepositoryBase.__name__}'")
60
- return True
61
38
 
62
- @property
63
- @abstractmethod
64
- def INSERT_QUERY(self) -> Type[InsertQueryBase[T, TRepo]]: ...
65
- @property
66
- @abstractmethod
67
- def UPSERT_QUERY(self) -> Type[UpsertQueryBase[T, TRepo]]: ...
68
- @property
69
- @abstractmethod
70
- def UPDATE_QUERY(self) -> Type[UpdateQueryBase[T, TRepo]]: ...
71
- @property
72
- @abstractmethod
73
- def DELETE_QUERY(self) -> Type[DeleteQueryBase[T, TRepo]]: ...
74
- @property
75
- @abstractmethod
76
- def LIMIT_QUERY(self) -> Type[IQuery]: ...
77
- @property
78
- @abstractmethod
79
- def OFFSET_QUERY(self) -> Type[IQuery]: ...
80
- @property
81
- @abstractmethod
82
- def JOIN_QUERY(self) -> Type[IQuery]: ...
83
- @property
84
- @abstractmethod
85
- def WHERE_QUERY(self) -> Type[IQuery]: ...
86
- @property
87
- @abstractmethod
88
- def ORDER_QUERY(self) -> Type[IQuery]: ...
89
- @property
90
- @abstractmethod
91
- def SELECT_QUERY(self) -> Type[SelectQuery]: ...
39
+ class MySQLStatements[T: Table](AbstractSQLStatements[T, MySQLConnection]):
40
+ def __init__(self, model: T, repository: IRepositoryBase[MySQLConnection]) -> None:
41
+ super().__init__(model, repository=repository)
92
42
 
93
43
  @property
94
- @abstractmethod
95
- def COUNT(self) -> Type[CountQuery]: ...
44
+ @override
45
+ def repository(self) -> IRepositoryBase[MySQLConnection]:
46
+ return self._repository
96
47
 
97
48
  @override
98
49
  def create_table(self) -> None:
@@ -106,7 +57,7 @@ class AbstractSQLStatements[T: Table, TRepo](IStatements_two_generic[T, TRepo]):
106
57
 
107
58
  @override
108
59
  def insert(self, instances: T | list[T]) -> None:
109
- insert = self.INSERT_QUERY(self._model, self._repository)
60
+ insert = InsertQuery(self._model, self._repository)
110
61
  insert.insert(instances)
111
62
  insert.execute()
112
63
  self._query_list.clear()
@@ -122,7 +73,7 @@ class AbstractSQLStatements[T: Table, TRepo](IStatements_two_generic[T, TRepo]):
122
73
  # We always going to have a tuple of one element
123
74
  return self.delete(response)
124
75
 
125
- delete = self.DELETE_QUERY(self._model, self._repository)
76
+ delete = DeleteQuery(self._model, self._repository)
126
77
  delete.delete(instances)
127
78
  delete.execute()
128
79
  # not necessary to call self._query_list.clear() because select() method already call it
@@ -130,7 +81,7 @@ class AbstractSQLStatements[T: Table, TRepo](IStatements_two_generic[T, TRepo]):
130
81
 
131
82
  @override
132
83
  def upsert(self, instances: T | list[T]) -> None:
133
- upsert = self.UPSERT_QUERY(self._model, self._repository)
84
+ upsert = UpsertQuery(self._model, self._repository)
134
85
  upsert.upsert(instances)
135
86
  upsert.execute()
136
87
  self._query_list.clear()
@@ -138,15 +89,15 @@ class AbstractSQLStatements[T: Table, TRepo](IStatements_two_generic[T, TRepo]):
138
89
 
139
90
  @override
140
91
  def update(self, dicc: dict[str, Any] | list[dict[str, Any]]) -> None:
141
- update = self.UPDATE_QUERY(self._model, self._repository, self._query_list["where"])
92
+ update = UpdateQuery(self._model, self._repository, self._query_list["where"])
142
93
  update.update(dicc)
143
94
  update.execute()
144
95
  self._query_list.clear()
145
96
  return None
146
97
 
147
98
  @override
148
- def limit(self, number: int) -> "IStatements_two_generic[T,TRepo]":
149
- limit = self.LIMIT_QUERY(number)
99
+ def limit(self, number: int) -> IStatements_two_generic[T, MySQLConnection]:
100
+ limit = LimitQuery(number)
150
101
  # Only can be one LIMIT SQL parameter. We only use the last LimitQuery
151
102
  limit_list = self._query_list["limit"]
152
103
  if len(limit_list) > 0:
@@ -156,35 +107,35 @@ class AbstractSQLStatements[T: Table, TRepo](IStatements_two_generic[T, TRepo]):
156
107
  return self
157
108
 
158
109
  @override
159
- def offset(self, number: int) -> "IStatements_two_generic[T,TRepo]":
160
- offset = self.OFFSET_QUERY(number)
110
+ def offset(self, number: int) -> IStatements_two_generic[T, MySQLConnection]:
111
+ offset = OffsetQuery(number)
161
112
  self._query_list["offset"].append(offset)
162
113
  return self
163
114
 
164
115
  @override
165
116
  def count(self) -> int:
166
- count_select: IQuery = self.COUNT(self._model)
117
+ count_select: IQuery = CountQuery(self._model)
167
118
  self._query_list["select"].append(count_select)
168
119
  query = self.build()
169
120
  return self.repository.read_sql(query)[0][0]
170
121
 
171
122
  @override
172
- def join(self, table_left: Table, table_right: Table, *, by: str) -> "IStatements_two_generic[T,TRepo]":
123
+ def join(self, table_left: Table, table_right: Table, *, by: str) -> IStatements_two_generic[T, MySQLConnection]:
173
124
  where = ForeignKey.MAPPED[table_left.__table_name__][table_right.__table_name__]
174
- join_query = self.JOIN_QUERY[table_left, Table](table_left, table_right, JoinType(by), where=where)
125
+ join_query = JoinSelector[table_left, Table](table_left, table_right, JoinType(by), where=where)
175
126
  self._query_list["join"].append(join_query)
176
127
  return self
177
128
 
178
129
  @override
179
- def where(self, lambda_: Callable[[T], bool] = lambda: None, **kwargs) -> "IStatements_two_generic[T,TRepo]":
130
+ def where(self, lambda_: Callable[[T], bool] = lambda: None, **kwargs) -> IStatements_two_generic[T, MySQLConnection]:
180
131
  # FIXME [x]: I've wrapped self._model into tuple to pass it instance attr. Idk if it's correct
181
- where_query = self.WHERE_QUERY[T](function=lambda_, instances=(self._model,), **kwargs)
132
+ where_query = WhereCondition[T](function=lambda_, instances=(self._model,), **kwargs)
182
133
  self._query_list["where"].append(where_query)
183
134
  return self
184
135
 
185
136
  @override
186
- def order[TValue](self, _lambda_col: Callable[[T], TValue], order_type: OrderType) -> "IStatements_two_generic[T,TRepo]":
187
- order = self.ORDER_QUERY[T](self._model, _lambda_col, order_type)
137
+ def order[TValue](self, _lambda_col: Callable[[T], TValue], order_type: OrderType) -> IStatements_two_generic[T, MySQLConnection]:
138
+ order = OrderQuery[T](self._model, _lambda_col, order_type)
188
139
  self._query_list["order"].append(order)
189
140
  return self
190
141
 
@@ -198,7 +149,7 @@ class AbstractSQLStatements[T: Table, TRepo](IStatements_two_generic[T, TRepo]):
198
149
  if flavour:
199
150
  return result
200
151
  return () if not result else result[0]
201
- select: ISelect = self.SELECT_QUERY(self._model, select_lambda=selector, by=by)
152
+ select: ISelect = SelectQuery(self._model, select_lambda=selector, by=by)
202
153
  self._query_list["select"].append(select)
203
154
 
204
155
  query: str = self.build()
@@ -209,17 +160,6 @@ class AbstractSQLStatements[T: Table, TRepo](IStatements_two_generic[T, TRepo]):
209
160
  return result
210
161
  return self._return_model(select, query)
211
162
 
212
- def _return_flavour[TValue](self, query, flavour: Type[TValue]) -> tuple[TValue]:
213
- return self._repository.read_sql(query, flavour=flavour)
214
-
215
- def _return_model(self, select: ISelect, query: str):
216
- response_sql = self._repository.read_sql(query, flavour=dict) # store all columns of the SQL query
217
-
218
- if isinstance(response_sql, Iterable):
219
- return ClusterQuery(select, response_sql).clean_response()
220
-
221
- return response_sql
222
-
223
163
  @override
224
164
  def select_one[TValue, TFlavour, *Ts](self, selector: Optional[Callable[[T], tuple[TValue, *Ts]]] = lambda: None, *, flavour: Optional[Type[TFlavour]] = None, by: JoinType = JoinType.INNER_JOIN):
225
165
  self.limit(1)
@@ -241,14 +181,14 @@ class AbstractSQLStatements[T: Table, TRepo](IStatements_two_generic[T, TRepo]):
241
181
  def build(self) -> str:
242
182
  query: str = ""
243
183
 
244
- self._create_necessary_inner_join()
184
+ self.__create_necessary_inner_join()
245
185
  for x in self.__order__:
246
186
  if sub_query := self._query_list.get(x, None):
247
- if isinstance(sub_query[0], self.WHERE_QUERY):
187
+ if isinstance(sub_query[0], WhereCondition):
248
188
  query_ = self.__build_where_clause(sub_query)
249
189
 
250
190
  # we must check if any join already exists on query string
251
- elif isinstance(sub_query[0], self.JOIN_QUERY):
191
+ elif isinstance(sub_query[0], JoinSelector):
252
192
  select_query: str = self._query_list["select"][0].query
253
193
  query_ = ""
254
194
  for join in sub_query:
@@ -270,7 +210,7 @@ class AbstractSQLStatements[T: Table, TRepo](IStatements_two_generic[T, TRepo]):
270
210
  query += f" {and_} ({clause})"
271
211
  return query
272
212
 
273
- def _create_necessary_inner_join(self) -> None:
213
+ def __create_necessary_inner_join(self) -> None:
274
214
  # When we applied filters in any table that we wont select any column, we need to add manually all neccessary joins to achieve positive result.
275
215
  if "where" not in self._query_list:
276
216
  return None
@@ -285,35 +225,3 @@ class AbstractSQLStatements[T: Table, TRepo](IStatements_two_generic[T, TRepo]):
285
225
  for l_tbl, r_tbl in involved_tables:
286
226
  # FIXME [ ]: Checked what function was called by the self.join method before the change
287
227
  self.join(l_tbl, r_tbl, by="INNER JOIN")
288
-
289
-
290
- class ClusterQuery:
291
- def __init__(self, select: ISelect, response_sql: tuple[dict[str, Any]]) -> None:
292
- self._select: ISelect = select
293
- self._response_sql: tuple[dict[str, Any]] = response_sql
294
-
295
- def loop_foo(self) -> dict[Type[Table], list[Table]]:
296
- # We must ensure to get the valid attributes for each instance
297
- table_initialize = defaultdict(list)
298
-
299
- unic_table: dict[Table, list[TableColumn]] = defaultdict(list)
300
- for table_col in self._select.select_list:
301
- unic_table[table_col._table].append(table_col)
302
-
303
- for table_, table_col in unic_table.items():
304
- for dicc_cols in self._response_sql:
305
- valid_attr: dict[str, Any] = {}
306
- for col in table_col:
307
- valid_attr[col.real_column] = dicc_cols[col.alias]
308
- # COMMENT: At this point we are going to instantiate Table class with specific attributes getting directly from database
309
- table_initialize[table_].append(table_(**valid_attr))
310
- return table_initialize
311
-
312
- def clean_response(self) -> tuple[dict[Type[Table], tuple[Table]]]:
313
- tbl_dicc: dict[Type[Table], list[Table]] = self.loop_foo()
314
-
315
- # it not depend of flavour attr
316
- for key, val in tbl_dicc.items():
317
- tbl_dicc[key] = tuple(val)
318
-
319
- return tuple(tbl_dicc.values())
@@ -10,7 +10,7 @@ from .databases.my_sql import MySQLStatements, MySQLRepository
10
10
  # endregion
11
11
 
12
12
 
13
- class BaseModel[T: Table]:
13
+ class BaseModel[T: Type[Table]]:
14
14
  """
15
15
  Class to select the correct AbstractSQLStatements class depends on the repository.
16
16
 
@@ -27,7 +27,7 @@ class BaseModel[T: Table]:
27
27
  cls: AbstractSQLStatements[T, TRepo] = cls.statements_dicc.get(type(repository), None)
28
28
 
29
29
  if not cls:
30
- raise Exception(f"Repository selected does not exits '{repository}'")
30
+ raise Exception(f"The selected repository '{repository}' does not exist.")
31
31
 
32
32
  self = object().__new__(cls)
33
33
  cls.__init__(self, model, repository)
@@ -1,95 +0,0 @@
1
- from __future__ import annotations
2
- from typing import override, Type, TYPE_CHECKING
3
-
4
- if TYPE_CHECKING:
5
- from ormlambda import Table
6
- from ormlambda.components.select import ISelect
7
-
8
- from ormlambda.common.abstract_classes import AbstractSQLStatements
9
-
10
- from ormlambda.common.interfaces import IQuery, IRepositoryBase
11
-
12
- from .clauses import DeleteQuery
13
- from .clauses import InsertQuery
14
- from .clauses import JoinSelector
15
- from .clauses import LimitQuery
16
- from .clauses import OffsetQuery
17
- from .clauses import OrderQuery
18
- from .clauses import SelectQuery
19
- from .clauses import UpsertQuery
20
- from .clauses import UpdateQuery
21
- from .clauses import WhereCondition
22
- from .clauses import CountQuery
23
-
24
- from mysql.connector import MySQLConnection
25
-
26
-
27
- class MySQLStatements[T: Table](AbstractSQLStatements[T, MySQLConnection]):
28
- def __init__(self, model: T, repository: IRepositoryBase[MySQLConnection]) -> None:
29
- super().__init__(model, repository=repository)
30
-
31
- # region Private methods
32
- def __repr__(self):
33
- return f"<Model: {self.__class__.__name__}>"
34
-
35
- # endregion
36
-
37
- @property
38
- @override
39
- def INSERT_QUERY(self) -> Type[InsertQuery]:
40
- return InsertQuery
41
-
42
- @property
43
- @override
44
- def UPSERT_QUERY(self) -> Type[UpsertQuery]:
45
- return UpsertQuery
46
-
47
- @property
48
- @override
49
- def UPDATE_QUERY(self) -> Type[UpsertQuery]:
50
- return UpdateQuery
51
-
52
- @override
53
- @property
54
- def DELETE_QUERY(self) -> Type[DeleteQuery]:
55
- return DeleteQuery
56
-
57
- @property
58
- @override
59
- def LIMIT_QUERY(self) -> Type[IQuery]:
60
- return LimitQuery
61
-
62
- @property
63
- @override
64
- def OFFSET_QUERY(self) -> Type[IQuery]:
65
- return OffsetQuery
66
-
67
- @property
68
- @override
69
- def COUNT(self) -> int:
70
- return CountQuery
71
-
72
- @property
73
- @override
74
- def JOIN_QUERY(self) -> Type[IQuery]:
75
- return JoinSelector
76
-
77
- @property
78
- @override
79
- def WHERE_QUERY(self) -> Type[IQuery]:
80
- return WhereCondition
81
-
82
- @property
83
- @override
84
- def ORDER_QUERY(self) -> Type[IQuery]:
85
- return OrderQuery
86
-
87
- @property
88
- @override
89
- def SELECT_QUERY(self) -> Type[ISelect]:
90
- return SelectQuery
91
-
92
- @property
93
- @override
94
- def repository(self) -> IRepositoryBase[MySQLConnection]:
95
- return self._repository
File without changes
File without changes