ormlambda 1.5.0__tar.gz → 2.0.2__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 (77) hide show
  1. {ormlambda-1.5.0 → ormlambda-2.0.2}/PKG-INFO +13 -9
  2. {ormlambda-1.5.0 → ormlambda-2.0.2}/README.md +10 -6
  3. {ormlambda-1.5.0 → ormlambda-2.0.2}/pyproject.toml +3 -4
  4. ormlambda-2.0.2/src/ormlambda/__init__.py +11 -0
  5. {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/common/__init__.py +0 -1
  6. {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/common/abstract_classes/__init__.py +1 -1
  7. ormlambda-2.0.2/src/ormlambda/common/abstract_classes/abstract_model.py +87 -0
  8. {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/common/abstract_classes/non_query_base.py +7 -5
  9. {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/common/abstract_classes/query_base.py +5 -2
  10. ormlambda-2.0.2/src/ormlambda/common/enums/__init__.py +2 -0
  11. {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/common/enums/join_type.py +2 -1
  12. {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/common/interfaces/IQueryCommand.py +2 -1
  13. {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/common/interfaces/IRepositoryBase.py +4 -18
  14. {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/common/interfaces/IStatements.py +33 -15
  15. {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/common/interfaces/__init__.py +1 -1
  16. {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/components/delete/abstract_delete.py +6 -3
  17. {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/components/insert/IInsert.py +1 -1
  18. {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/components/insert/abstract_insert.py +8 -4
  19. {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/components/select/ISelect.py +1 -1
  20. {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/components/select/table_column.py +5 -1
  21. {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/components/update/IUpdate.py +1 -1
  22. {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/components/update/__init__.py +1 -1
  23. {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/components/update/abstract_update.py +9 -5
  24. {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/components/upsert/__init__.py +1 -1
  25. {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/components/upsert/abstract_upsert.py +8 -4
  26. {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/components/where/abstract_where.py +6 -2
  27. {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/databases/my_sql/clauses/__init__.py +1 -0
  28. ormlambda-2.0.2/src/ormlambda/databases/my_sql/clauses/count.py +35 -0
  29. ormlambda-2.0.2/src/ormlambda/databases/my_sql/clauses/create_database.py +36 -0
  30. {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/databases/my_sql/clauses/delete.py +7 -4
  31. {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/databases/my_sql/clauses/drop_database.py +1 -1
  32. {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/databases/my_sql/clauses/drop_table.py +1 -1
  33. {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/databases/my_sql/clauses/insert.py +4 -3
  34. {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/databases/my_sql/clauses/joins.py +8 -7
  35. {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/databases/my_sql/clauses/limit.py +1 -1
  36. {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/databases/my_sql/clauses/offset.py +1 -1
  37. {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/databases/my_sql/clauses/order.py +3 -3
  38. {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/databases/my_sql/clauses/select.py +5 -5
  39. {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/databases/my_sql/clauses/update.py +3 -3
  40. {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/databases/my_sql/clauses/upsert.py +3 -3
  41. {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/databases/my_sql/clauses/where_condition.py +5 -5
  42. {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/databases/my_sql/repository.py +57 -27
  43. ormlambda-2.0.2/src/ormlambda/databases/my_sql/statements.py +243 -0
  44. {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/model_base.py +2 -4
  45. {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/utils/column.py +4 -3
  46. {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/utils/dtypes.py +6 -8
  47. ormlambda-2.0.2/src/ormlambda/utils/foreign_key.py +81 -0
  48. {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/utils/lambda_disassembler/__init__.py +1 -1
  49. {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/utils/lambda_disassembler/dis_types.py +22 -25
  50. {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/utils/lambda_disassembler/tree_instruction.py +1 -1
  51. {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/utils/module_tree/dynamic_module.py +6 -4
  52. {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/utils/table_constructor.py +39 -22
  53. ormlambda-1.5.0/src/ormlambda/__init__.py +0 -4
  54. ormlambda-1.5.0/src/ormlambda/common/abstract_classes/abstract_model.py +0 -302
  55. ormlambda-1.5.0/src/ormlambda/common/enums/__init__.py +0 -2
  56. ormlambda-1.5.0/src/ormlambda/databases/my_sql/clauses/create_database.py +0 -29
  57. ormlambda-1.5.0/src/ormlambda/databases/my_sql/statements.py +0 -86
  58. ormlambda-1.5.0/src/ormlambda/utils/foreign_key.py +0 -36
  59. {ormlambda-1.5.0 → ormlambda-2.0.2}/LICENSE +0 -0
  60. {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/common/enums/condition_types.py +0 -0
  61. {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/common/interfaces/INonQueryCommand.py +0 -0
  62. {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/components/__init__.py +0 -0
  63. {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/components/delete/IDelete.py +0 -0
  64. {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/components/delete/__init__.py +0 -0
  65. {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/components/insert/__init__.py +0 -0
  66. {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/components/select/__init__.py +0 -0
  67. {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/components/upsert/IUpsert.py +0 -0
  68. {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/components/where/__init__.py +0 -0
  69. {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/databases/__init__.py +0 -0
  70. {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/databases/my_sql/__init__.py +0 -0
  71. {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/utils/__init__.py +0 -0
  72. {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/utils/lambda_disassembler/disassembler.py +0 -0
  73. {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/utils/lambda_disassembler/dtypes.py +0 -0
  74. {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/utils/lambda_disassembler/name_of.py +0 -0
  75. {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/utils/lambda_disassembler/nested_element.py +0 -0
  76. {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/utils/module_tree/__init__.py +0 -0
  77. {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/utils/module_tree/dfs_traversal.py +0 -0
@@ -1,16 +1,20 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ormlambda
3
- Version: 1.5.0
3
+ Version: 2.0.2
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
7
7
  Requires-Python: >=3.12,<4.0
8
8
  Classifier: Programming Language :: Python :: 3
9
9
  Classifier: Programming Language :: Python :: 3.12
10
- Requires-Dist: mysql-connector (>=2.2.9,<3.0.0)
11
- Requires-Dist: ruff (>=0.4.5,<0.5.0)
10
+ Requires-Dist: fluent-validation (>=3.1.0,<4.0.0)
11
+ Requires-Dist: mysql-connector-python (>=9.0.0,<10.0.0)
12
12
  Description-Content-Type: text/markdown
13
13
 
14
+ ![PyPI version](https://img.shields.io/pypi/v/ormlambda.svg)
15
+ ![downloads](https://img.shields.io/pypi/dm/ormlambda?label=downloads)
16
+ ![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)
17
+
14
18
  # ormMySQL
15
19
  This ORM is designed to connect with a MySQL server, facilitating the management of various database queries. Built with flexibility and efficiency in mind, this ORM empowers developers to interact with the database using lambda functions, allowing for concise and expressive query construction.
16
20
 
@@ -19,7 +23,7 @@ This ORM is designed to connect with a MySQL server, facilitating the management
19
23
  ## Initialize MySQLRepository
20
24
  ```python
21
25
  from decouple import config
22
- from src.ormmysql.databases.my_sql import MySQLRepository
26
+ from ormlambda.databases.my_sql import MySQLRepository
23
27
 
24
28
  USERNAME = config("USERNAME")
25
29
  PASSWORD = config("PASSWORD")
@@ -31,7 +35,7 @@ database = MySQLRepository(user=USERNAME, password=PASSWORD, database="sakila",
31
35
 
32
36
  ## Select all columns
33
37
  ```python
34
- from src.test.models.address import AddressModel
38
+ from models.address import AddressModel
35
39
 
36
40
  result = AddressModel(database).select()
37
41
  ```
@@ -41,8 +45,8 @@ The `result` var will be of type `tuple[Address, ...]`
41
45
  Once the `AddressModel` class is created, we will not only be able to access all the information in that table, but also all the information in all the tables that have foreign keys related to it."
42
46
 
43
47
  ```python
44
- from src.ormmysql.common.enums import ConditionType
45
- from src.test.models.address import AddressModel
48
+ from ormlambda import ConditionType
49
+ from models.address import AddressModel
46
50
 
47
51
 
48
52
  result = AddressModel(database).where(lambda x: (x.City.Country, ConditionType.REGEXP, r"^[aA]")).select(
@@ -135,13 +139,13 @@ The easiest way to map your tables is:
135
139
  ```python
136
140
  from datetime import datetime
137
141
 
138
- from src.ormmysql import (
142
+ from ormlambda import (
139
143
  Column,
140
144
  Table,
141
145
  BaseModel,
142
146
  ForeignKey,
143
147
  )
144
- from src.ormmysql.common.interfaces import IStatements_two_generic, IRepositoryBase
148
+ from ormlambda.common.interfaces import IStatements_two_generic, IRepositoryBase
145
149
 
146
150
 
147
151
  class Country(Table):
@@ -1,3 +1,7 @@
1
+ ![PyPI version](https://img.shields.io/pypi/v/ormlambda.svg)
2
+ ![downloads](https://img.shields.io/pypi/dm/ormlambda?label=downloads)
3
+ ![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)
4
+
1
5
  # ormMySQL
2
6
  This ORM is designed to connect with a MySQL server, facilitating the management of various database queries. Built with flexibility and efficiency in mind, this ORM empowers developers to interact with the database using lambda functions, allowing for concise and expressive query construction.
3
7
 
@@ -6,7 +10,7 @@ This ORM is designed to connect with a MySQL server, facilitating the management
6
10
  ## Initialize MySQLRepository
7
11
  ```python
8
12
  from decouple import config
9
- from src.ormmysql.databases.my_sql import MySQLRepository
13
+ from ormlambda.databases.my_sql import MySQLRepository
10
14
 
11
15
  USERNAME = config("USERNAME")
12
16
  PASSWORD = config("PASSWORD")
@@ -18,7 +22,7 @@ database = MySQLRepository(user=USERNAME, password=PASSWORD, database="sakila",
18
22
 
19
23
  ## Select all columns
20
24
  ```python
21
- from src.test.models.address import AddressModel
25
+ from models.address import AddressModel
22
26
 
23
27
  result = AddressModel(database).select()
24
28
  ```
@@ -28,8 +32,8 @@ The `result` var will be of type `tuple[Address, ...]`
28
32
  Once the `AddressModel` class is created, we will not only be able to access all the information in that table, but also all the information in all the tables that have foreign keys related to it."
29
33
 
30
34
  ```python
31
- from src.ormmysql.common.enums import ConditionType
32
- from src.test.models.address import AddressModel
35
+ from ormlambda import ConditionType
36
+ from models.address import AddressModel
33
37
 
34
38
 
35
39
  result = AddressModel(database).where(lambda x: (x.City.Country, ConditionType.REGEXP, r"^[aA]")).select(
@@ -122,13 +126,13 @@ The easiest way to map your tables is:
122
126
  ```python
123
127
  from datetime import datetime
124
128
 
125
- from src.ormmysql import (
129
+ from ormlambda import (
126
130
  Column,
127
131
  Table,
128
132
  BaseModel,
129
133
  ForeignKey,
130
134
  )
131
- from src.ormmysql.common.interfaces import IStatements_two_generic, IRepositoryBase
135
+ from ormlambda.common.interfaces import IStatements_two_generic, IRepositoryBase
132
136
 
133
137
 
134
138
  class Country(Table):
@@ -3,19 +3,18 @@ line-length = 320
3
3
 
4
4
  [tool.poetry]
5
5
  name = "ormlambda"
6
- version = "1.5.0"
6
+ version = "2.0.2"
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 = "^2.2.9"
14
- ruff = "^0.4.5"
13
+ mysql-connector-python= "^9.0.0"
14
+ fluent-validation = "^3.1.0"
15
15
 
16
16
  [tool.poetry.group.test.dependencies]
17
17
  pandas = "^2.2.2"
18
- mysql-connector = "^2.2.9"
19
18
  ruff = "^0.4.5"
20
19
  python-decouple = "^3.8"
21
20
 
@@ -0,0 +1,11 @@
1
+ # enums
2
+ from .common.enums import ( # noqa: F401
3
+ JoinType,
4
+ ConditionType,
5
+ )
6
+
7
+ from .common.abstract_classes import AbstractSQLStatements # noqa: F401
8
+ from .common.interfaces import IRepositoryBase # noqa: F401
9
+ from .utils import Table, Column, ForeignKey # noqa: F401
10
+ from .utils.lambda_disassembler import Disassembler, nameof # noqa: F401
11
+ from .model_base import BaseModel # noqa: F401 # COMMENT: to avoid relative import we need to import BaseModel after import Table,Column, ForeignKey, IRepositoryBase and Disassembler
@@ -1,3 +1,3 @@
1
1
  from .non_query_base import NonQueryBase # noqa: F401
2
2
  from .abstract_model import AbstractSQLStatements # noqa: F401
3
- from .query_base import QueryBase # noqa: F401
3
+ from .query_base import QueryBase # 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())
@@ -1,13 +1,15 @@
1
+ from __future__ import annotations
1
2
  from abc import abstractmethod
2
- from typing import Any, Optional, override
3
+ from typing import Any, Optional, Type, override, TYPE_CHECKING
3
4
 
4
- from ..interfaces.INonQueryCommand import INonQueryCommand
5
+ from ormlambda.common.interfaces.INonQueryCommand import INonQueryCommand
5
6
 
6
- from ..interfaces import IRepositoryBase
7
- from ...utils import Table
7
+ if TYPE_CHECKING:
8
+ from ormlambda import IRepositoryBase
9
+ from ormlambda import Table
8
10
 
9
11
 
10
- class NonQueryBase[T: Table, TRepo: IRepositoryBase](INonQueryCommand):
12
+ class NonQueryBase[T: Type[Table], TRepo: IRepositoryBase](INonQueryCommand):
11
13
  __slots__: tuple[str, ...] = ("_model", "_repository", "_values", "_query")
12
14
 
13
15
  def __init__(self, model: T, repository: TRepo) -> None:
@@ -1,7 +1,10 @@
1
1
  from abc import abstractmethod
2
+ from typing import TYPE_CHECKING
2
3
 
3
- from ...utils import Table
4
- from ..interfaces import IQuery
4
+ from ormlambda.common.interfaces import IQuery
5
+
6
+ if TYPE_CHECKING:
7
+ from ormlambda import Table
5
8
 
6
9
 
7
10
  class QueryBase[T: Table](IQuery):
@@ -0,0 +1,2 @@
1
+ from .join_type import JoinType # noqa: F401
2
+ from .condition_types import ConditionType # noqa: F401
@@ -1,5 +1,6 @@
1
1
  from enum import Enum
2
2
 
3
+
3
4
  class JoinType(Enum):
4
5
  RIGHT_INCLUSIVE = "RIGHT JOIN"
5
6
  LEFT_INCLUSIVE = "LEFT JOIN"
@@ -7,4 +8,4 @@ class JoinType(Enum):
7
8
  LEFT_EXCLUSIVE = "LEFT JOIN"
8
9
  FULL_OUTER_INCLUSIVE = "RIGHT JOIN"
9
10
  FULL_OUTER_EXCLUSIVE = "RIGHT JOIN"
10
- INNER_JOIN = "INNER JOIN"
11
+ INNER_JOIN = "INNER JOIN"
@@ -2,7 +2,8 @@ from abc import abstractmethod, ABC
2
2
 
3
3
 
4
4
  class IQuery(ABC):
5
- """ Interface to queries that retrieve any element such as select, limit, offset, where, group by, etc..."""
5
+ """Interface to queries that retrieve any element such as select, limit, offset, where, group by, etc..."""
6
+
6
7
  @property
7
8
  @abstractmethod
8
9
  def query(self) -> str: ...
@@ -1,23 +1,10 @@
1
1
  from abc import ABC, abstractmethod
2
- import functools
3
- from typing import Any, Callable, Literal, Optional, Type
2
+ from typing import Any, Literal, Optional, Type
4
3
 
5
4
  TypeExists = Literal["fail", "replace", "append"]
6
5
 
7
6
 
8
7
  class IRepositoryBase[T](ABC):
9
- def check_connection(func: Callable[..., Any]):
10
- @functools.wraps(func)
11
- def wrapper(self: "IRepositoryBase[T]", *args, **kwargs):
12
- if not self.is_connected():
13
- self.connect()
14
-
15
- foo = func(self, *args, **kwargs)
16
- self.close_connection()
17
- return foo
18
-
19
- return wrapper
20
-
21
8
  def __repr__(self) -> str:
22
9
  return f"{IRepositoryBase.__name__}: {self.__class__.__name__}"
23
10
 
@@ -25,7 +12,7 @@ class IRepositoryBase[T](ABC):
25
12
  def is_connected(self) -> bool: ...
26
13
 
27
14
  @abstractmethod
28
- def connect(self, **kwargs: Any) -> "IRepositoryBase[T]": ...
15
+ def connect(self, **kwargs: Any) -> None: ...
29
16
 
30
17
  @abstractmethod
31
18
  def close_connection(self) -> None: ...
@@ -61,7 +48,6 @@ class IRepositoryBase[T](ABC):
61
48
  @abstractmethod
62
49
  def connection(self) -> T: ...
63
50
 
51
+ @property
64
52
  @abstractmethod
65
- def set_config(self, value: dict[str, Any]) -> dict[str, Any]:
66
- """Method to update database config"""
67
- ...
53
+ def database(self) -> Optional[str]: ...
@@ -1,17 +1,23 @@
1
- from typing import Any, Callable, Iterable, Optional, Literal, Type, overload
1
+ from __future__ import annotations
2
+ from typing import Any, Callable, Iterable, Optional, Literal, Type, overload, TYPE_CHECKING
2
3
  from enum import Enum
3
4
  from abc import abstractmethod, ABC
4
5
 
5
6
  from .IRepositoryBase import IRepositoryBase
6
- from ..enums import JoinType
7
- from ...utils import Table
7
+ from ormlambda.common.enums import JoinType
8
+
9
+ if TYPE_CHECKING:
10
+ from ormlambda import Table
8
11
 
9
12
  OrderType = Literal["ASC", "DESC"]
10
13
 
14
+ # TODOH: This var is duplicated from 'src\ormlambda\databases\my_sql\clauses\create_database.py'
15
+ TypeExists = Literal["fail", "replace", "append"]
16
+
11
17
 
12
18
  class IStatements[T: Table](ABC):
13
19
  @abstractmethod
14
- def create_table(self) -> None: ...
20
+ def create_table(self, if_exists: TypeExists) -> None: ...
15
21
 
16
22
  @abstractmethod
17
23
  def table_exists(self) -> bool: ...
@@ -38,6 +44,8 @@ class IStatements[T: Table](ABC):
38
44
  @abstractmethod
39
45
  def insert(self, values: T | list[T]) -> None: ...
40
46
 
47
+ # endregion
48
+
41
49
  # region upsert
42
50
  @overload
43
51
  def upsert(self, values: T) -> None:
@@ -71,13 +79,19 @@ class IStatements[T: Table](ABC):
71
79
 
72
80
  # region limit
73
81
  @abstractmethod
74
- def limit(self, number: int) -> "IStatements[T]": ...
82
+ def limit(self, number: int) -> IStatements[T]: ...
75
83
 
76
84
  # endregion
77
85
 
78
86
  # region offset
79
87
  @abstractmethod
80
- def offset(self, number: int) -> "IStatements[T]": ...
88
+ def offset(self, number: int) -> IStatements[T]: ...
89
+
90
+ # endregion
91
+
92
+ # region count
93
+ @abstractmethod
94
+ def count(self) -> int: ...
81
95
 
82
96
  # endregion
83
97
 
@@ -97,13 +111,13 @@ class IStatements[T: Table](ABC):
97
111
 
98
112
  # region join
99
113
  @abstractmethod
100
- def join(self, table_left: Table, table_right: Table, *, by: str) -> "IStatements[T]": ...
114
+ def join(self, table_left: Table, table_right: Table, *, by: str) -> IStatements[T]: ...
101
115
 
102
116
  # endregion
103
117
 
104
118
  # region where
105
119
  @overload
106
- def where(self, lambda_: Callable[[T], bool]) -> "IStatements[T]":
120
+ def where(self, lambda_: Callable[[T], bool]) -> IStatements[T]:
107
121
  """
108
122
  This method creates where clause by passing the lambda's condition
109
123
 
@@ -115,7 +129,7 @@ class IStatements[T: Table](ABC):
115
129
  ...
116
130
 
117
131
  @overload
118
- def where(self, lambda_: Callable[[T], Iterable]) -> "IStatements[T]":
132
+ def where(self, lambda_: Callable[[T], Iterable]) -> IStatements[T]:
119
133
  """
120
134
  This method creates where clause by passing the Iterable in lambda function
121
135
  EXAMPLE
@@ -126,7 +140,7 @@ class IStatements[T: Table](ABC):
126
140
  ...
127
141
 
128
142
  @overload
129
- def where(self, lambda_: Callable[[T], bool], **kwargs) -> "IStatements[T]":
143
+ def where(self, lambda_: Callable[[T], bool], **kwargs) -> IStatements[T]:
130
144
  """
131
145
  PARAM
132
146
  -
@@ -143,17 +157,17 @@ class IStatements[T: Table](ABC):
143
157
  ...
144
158
 
145
159
  @abstractmethod
146
- def where(self, lambda_: Callable[[T], bool] = lambda: None, **kwargs) -> "IStatements[T]": ...
160
+ def where(self, lambda_: Callable[[T], bool] = lambda: None, **kwargs) -> IStatements[T]: ...
147
161
 
148
162
  # endregion
149
163
 
150
164
  # region order
151
165
  @overload
152
- def order[TValue](self, _lambda_col: Callable[[T], TValue]) -> "IStatements[T]": ...
166
+ def order[TValue](self, _lambda_col: Callable[[T], TValue]) -> IStatements[T]: ...
153
167
  @overload
154
- def order[TValue](self, _lambda_col: Callable[[T], TValue], order_type: OrderType) -> "IStatements[T]": ...
168
+ def order[TValue](self, _lambda_col: Callable[[T], TValue], order_type: OrderType) -> IStatements[T]: ...
155
169
  @abstractmethod
156
- def order[TValue](self, _lambda_col: Callable[[T], TValue], order_type: OrderType) -> "IStatements[T]": ...
170
+ def order[TValue](self, _lambda_col: Callable[[T], TValue], order_type: OrderType) -> IStatements[T]: ...
157
171
 
158
172
  # endregion
159
173
 
@@ -203,12 +217,16 @@ class IStatements[T: Table](ABC):
203
217
  @overload
204
218
  def select_one(self) -> T: ...
205
219
  @overload
206
- def select_one(self, *, by: Optional[Enum] = JoinType.INNER_JOIN, flavour: Type[tuple]) -> tuple: ...
220
+ def select_one[TFlavour](self, *, by: Optional[Enum] = JoinType.INNER_JOIN, flavour: Type[TFlavour]) -> TFlavour: ...
207
221
  @overload
208
222
  def select_one[T1](self, selector: Callable[[T], tuple[T1]], *, by: Optional[Enum] = JoinType.INNER_JOIN) -> T1: ...
209
223
  @overload
210
224
  def select_one[*Ts](self, selector: Callable[[T], tuple[*Ts]], *, by: Optional[Enum] = JoinType.INNER_JOIN) -> tuple[*Ts]: ...
211
225
  @overload
226
+ def select_one[T1](self, selector: Callable[[T], tuple[T1]], *, by: Optional[Enum] = JoinType.INNER_JOIN, flavour: Type) -> T1: ...
227
+ @overload
228
+ def select_one[T1, TFlavour](self, selector: Callable[[T], T1], *, by: Optional[Enum] = JoinType.INNER_JOIN, flavour: Type[TFlavour]) -> T1: ...
229
+ @overload
212
230
  def select_one[*Ts](self, selector: Callable[[T], tuple[*Ts]], *, by: Optional[Enum] = JoinType.INNER_JOIN, flavour: Type[tuple]) -> tuple[*Ts]: ...
213
231
  @overload
214
232
  def select_one[TFlavour](self, selector: Callable[[T], tuple], *, by: Optional[Enum] = JoinType.INNER_JOIN, flavour: Type[TFlavour]) -> TFlavour: ...
@@ -1,4 +1,4 @@
1
1
  from .IQueryCommand import IQuery # noqa: F401
2
2
  from .INonQueryCommand import INonQueryCommand # noqa: F401
3
3
  from .IRepositoryBase import IRepositoryBase # noqa: F401
4
- from .IStatements import IStatements,IStatements_two_generic # noqa: F401
4
+ from .IStatements import IStatements, IStatements_two_generic # noqa: F401
@@ -1,9 +1,12 @@
1
+ from __future__ import annotations
1
2
  from abc import abstractmethod
3
+ from typing import TYPE_CHECKING
4
+
5
+ if TYPE_CHECKING:
6
+ from ormlambda import Table, IRepositoryBase
7
+ from ormlambda.common.abstract_classes import NonQueryBase
2
8
 
3
9
  from .IDelete import IDelete
4
- from ...utils import Table
5
- from ...common.interfaces import IRepositoryBase
6
- from ...common.abstract_classes import NonQueryBase
7
10
 
8
11
 
9
12
  class DeleteQueryBase[T: Table, TRepo: IRepositoryBase](NonQueryBase[T, TRepo], IDelete[T]):
@@ -3,4 +3,4 @@ from abc import ABC, abstractmethod
3
3
 
4
4
  class IInsert[T](ABC):
5
5
  @abstractmethod
6
- def insert(self, instances: T | list[T])->None: ...
6
+ def insert(self, instances: T | list[T]) -> None: ...
@@ -1,12 +1,16 @@
1
+ from __future__ import annotations
1
2
  from abc import abstractmethod
2
- from ...utils import Table
3
+ from typing import TYPE_CHECKING
3
4
 
5
+ if TYPE_CHECKING:
6
+ from ormlambda import Table
7
+ from ormlambda import IRepositoryBase
8
+
9
+ from ormlambda.common.abstract_classes import NonQueryBase
4
10
  from .IInsert import IInsert
5
- from ...common.interfaces import IRepositoryBase
6
- from ...common.abstract_classes import NonQueryBase
7
11
 
8
12
 
9
- class InsertQueryBase[T: Table, TRepo: IRepositoryBase](NonQueryBase[T, IRepositoryBase], IInsert[T]):
13
+ class InsertQueryBase[T: Table, TRepo: IRepositoryBase](NonQueryBase[T, TRepo], IInsert[T]):
10
14
  def __init__(self, model: T, repository: TRepo) -> None:
11
15
  super().__init__(model, repository)
12
16
 
@@ -1,6 +1,6 @@
1
1
  from abc import abstractmethod
2
2
 
3
- from ...common.interfaces import IQuery
3
+ from ormlambda.common.interfaces import IQuery
4
4
  from .table_column import TableColumn
5
5
 
6
6
 
@@ -1,5 +1,9 @@
1
+ from __future__ import annotations
1
2
  from typing import Any, Iterator
2
- from ...utils import Table
3
+ from typing import TYPE_CHECKING
4
+
5
+ if TYPE_CHECKING:
6
+ from ormlambda import Table
3
7
 
4
8
 
5
9
  class TableColumn:
@@ -4,4 +4,4 @@ from typing import Any
4
4
 
5
5
  class IUpdate(ABC):
6
6
  @abstractmethod
7
- def update(self, dicc: dict[str|property, Any]) -> None: ...
7
+ def update(self, dicc: dict[str | property, Any]) -> None: ...
@@ -1,2 +1,2 @@
1
1
  from .abstract_update import UpdateQueryBase # noqa: F401
2
- from .IUpdate import IUpdate # noqa: F401
2
+ from .IUpdate import IUpdate # noqa: F401
@@ -1,11 +1,15 @@
1
+ from __future__ import annotations
1
2
  from abc import abstractmethod
2
- from typing import Any, Optional
3
+ from typing import Any, Optional, TYPE_CHECKING
4
+
5
+ from ormlambda.components.where import AbstractWhere
6
+ from ormlambda.common.abstract_classes import NonQueryBase
7
+
8
+ if TYPE_CHECKING:
9
+ from ormlambda import IRepositoryBase
10
+ from ormlambda import Table
3
11
 
4
12
  from .IUpdate import IUpdate
5
- from ..where import AbstractWhere
6
- from ...common.interfaces import IRepositoryBase
7
- from ...common.abstract_classes import NonQueryBase
8
- from ...utils import Table
9
13
 
10
14
 
11
15
  class UpdateQueryBase[T: Table, TRepo: IRepositoryBase](NonQueryBase[T, TRepo], IUpdate):
@@ -1,2 +1,2 @@
1
1
  from .abstract_upsert import UpsertQueryBase # noqa: F401
2
- from .IUpsert import IUpsert # noqa: F401
2
+ from .IUpsert import IUpsert # noqa: F401
@@ -1,9 +1,13 @@
1
+ from __future__ import annotations
1
2
  from abc import abstractmethod
2
- from .IUpsert import IUpsert
3
- from ...common.interfaces import IRepositoryBase
4
- from ...common.abstract_classes import NonQueryBase
3
+ from typing import TYPE_CHECKING
4
+
5
+ if TYPE_CHECKING:
6
+ from ormlambda import IRepositoryBase
7
+ from ormlambda import Table
5
8
 
6
- from ...utils import Table
9
+ from ormlambda.common.abstract_classes import NonQueryBase
10
+ from .IUpsert import IUpsert
7
11
 
8
12
 
9
13
  class UpsertQueryBase[T: Table, TRepo: IRepositoryBase](NonQueryBase[T, TRepo], IUpsert[T]):
@@ -1,7 +1,11 @@
1
+ from __future__ import annotations
1
2
  from abc import abstractmethod
2
- from ...utils import Table
3
+ from typing import TYPE_CHECKING
3
4
 
4
- from ...common.interfaces import IQuery
5
+ if TYPE_CHECKING:
6
+ from ormlambda import Table
7
+
8
+ from ormlambda.common.interfaces import IQuery
5
9
 
6
10
 
7
11
  class AbstractWhere(IQuery):
@@ -11,3 +11,4 @@ from .select import SelectQuery # noqa: F401
11
11
  from .update import UpdateQuery # noqa: F401
12
12
  from .upsert import UpsertQuery # noqa: F401
13
13
  from .where_condition import WhereCondition # noqa: F401
14
+ from .count import CountQuery # noqa: F401