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.
- {ormlambda-1.5.0 → ormlambda-2.0.2}/PKG-INFO +13 -9
- {ormlambda-1.5.0 → ormlambda-2.0.2}/README.md +10 -6
- {ormlambda-1.5.0 → ormlambda-2.0.2}/pyproject.toml +3 -4
- ormlambda-2.0.2/src/ormlambda/__init__.py +11 -0
- {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/common/__init__.py +0 -1
- {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/common/abstract_classes/__init__.py +1 -1
- ormlambda-2.0.2/src/ormlambda/common/abstract_classes/abstract_model.py +87 -0
- {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/common/abstract_classes/non_query_base.py +7 -5
- {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/common/abstract_classes/query_base.py +5 -2
- ormlambda-2.0.2/src/ormlambda/common/enums/__init__.py +2 -0
- {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/common/enums/join_type.py +2 -1
- {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/common/interfaces/IQueryCommand.py +2 -1
- {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/common/interfaces/IRepositoryBase.py +4 -18
- {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/common/interfaces/IStatements.py +33 -15
- {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/common/interfaces/__init__.py +1 -1
- {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/components/delete/abstract_delete.py +6 -3
- {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/components/insert/IInsert.py +1 -1
- {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/components/insert/abstract_insert.py +8 -4
- {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/components/select/ISelect.py +1 -1
- {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/components/select/table_column.py +5 -1
- {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/components/update/IUpdate.py +1 -1
- {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/components/update/__init__.py +1 -1
- {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/components/update/abstract_update.py +9 -5
- {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/components/upsert/__init__.py +1 -1
- {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/components/upsert/abstract_upsert.py +8 -4
- {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/components/where/abstract_where.py +6 -2
- {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/databases/my_sql/clauses/__init__.py +1 -0
- ormlambda-2.0.2/src/ormlambda/databases/my_sql/clauses/count.py +35 -0
- ormlambda-2.0.2/src/ormlambda/databases/my_sql/clauses/create_database.py +36 -0
- {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/databases/my_sql/clauses/delete.py +7 -4
- {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/databases/my_sql/clauses/drop_database.py +1 -1
- {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/databases/my_sql/clauses/drop_table.py +1 -1
- {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/databases/my_sql/clauses/insert.py +4 -3
- {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/databases/my_sql/clauses/joins.py +8 -7
- {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/databases/my_sql/clauses/limit.py +1 -1
- {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/databases/my_sql/clauses/offset.py +1 -1
- {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/databases/my_sql/clauses/order.py +3 -3
- {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/databases/my_sql/clauses/select.py +5 -5
- {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/databases/my_sql/clauses/update.py +3 -3
- {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/databases/my_sql/clauses/upsert.py +3 -3
- {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/databases/my_sql/clauses/where_condition.py +5 -5
- {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/databases/my_sql/repository.py +57 -27
- ormlambda-2.0.2/src/ormlambda/databases/my_sql/statements.py +243 -0
- {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/model_base.py +2 -4
- {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/utils/column.py +4 -3
- {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/utils/dtypes.py +6 -8
- ormlambda-2.0.2/src/ormlambda/utils/foreign_key.py +81 -0
- {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/utils/lambda_disassembler/__init__.py +1 -1
- {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/utils/lambda_disassembler/dis_types.py +22 -25
- {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/utils/lambda_disassembler/tree_instruction.py +1 -1
- {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/utils/module_tree/dynamic_module.py +6 -4
- {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/utils/table_constructor.py +39 -22
- ormlambda-1.5.0/src/ormlambda/__init__.py +0 -4
- ormlambda-1.5.0/src/ormlambda/common/abstract_classes/abstract_model.py +0 -302
- ormlambda-1.5.0/src/ormlambda/common/enums/__init__.py +0 -2
- ormlambda-1.5.0/src/ormlambda/databases/my_sql/clauses/create_database.py +0 -29
- ormlambda-1.5.0/src/ormlambda/databases/my_sql/statements.py +0 -86
- ormlambda-1.5.0/src/ormlambda/utils/foreign_key.py +0 -36
- {ormlambda-1.5.0 → ormlambda-2.0.2}/LICENSE +0 -0
- {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/common/enums/condition_types.py +0 -0
- {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/common/interfaces/INonQueryCommand.py +0 -0
- {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/components/__init__.py +0 -0
- {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/components/delete/IDelete.py +0 -0
- {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/components/delete/__init__.py +0 -0
- {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/components/insert/__init__.py +0 -0
- {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/components/select/__init__.py +0 -0
- {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/components/upsert/IUpsert.py +0 -0
- {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/components/where/__init__.py +0 -0
- {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/databases/__init__.py +0 -0
- {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/databases/my_sql/__init__.py +0 -0
- {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/utils/__init__.py +0 -0
- {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/utils/lambda_disassembler/disassembler.py +0 -0
- {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/utils/lambda_disassembler/dtypes.py +0 -0
- {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/utils/lambda_disassembler/name_of.py +0 -0
- {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/utils/lambda_disassembler/nested_element.py +0 -0
- {ormlambda-1.5.0 → ormlambda-2.0.2}/src/ormlambda/utils/module_tree/__init__.py +0 -0
- {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:
|
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:
|
11
|
-
Requires-Dist:
|
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
|
+

|
15
|
+

|
16
|
+

|
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
|
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
|
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
|
45
|
-
from
|
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
|
142
|
+
from ormlambda import (
|
139
143
|
Column,
|
140
144
|
Table,
|
141
145
|
BaseModel,
|
142
146
|
ForeignKey,
|
143
147
|
)
|
144
|
-
from
|
148
|
+
from ormlambda.common.interfaces import IStatements_two_generic, IRepositoryBase
|
145
149
|
|
146
150
|
|
147
151
|
class Country(Table):
|
@@ -1,3 +1,7 @@
|
|
1
|
+

|
2
|
+

|
3
|
+

|
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
|
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
|
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
|
32
|
-
from
|
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
|
129
|
+
from ormlambda import (
|
126
130
|
Column,
|
127
131
|
Table,
|
128
132
|
BaseModel,
|
129
133
|
ForeignKey,
|
130
134
|
)
|
131
|
-
from
|
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 = "
|
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
|
14
|
-
|
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
|
@@ -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
|
5
|
+
from ormlambda.common.interfaces.INonQueryCommand import INonQueryCommand
|
5
6
|
|
6
|
-
|
7
|
-
from
|
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
|
4
|
-
|
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):
|
@@ -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
|
-
"""
|
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
|
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) ->
|
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
|
66
|
-
"""Method to update database config"""
|
67
|
-
...
|
53
|
+
def database(self) -> Optional[str]: ...
|
@@ -1,17 +1,23 @@
|
|
1
|
-
from
|
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
|
7
|
-
|
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) ->
|
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) ->
|
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) ->
|
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]) ->
|
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]) ->
|
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) ->
|
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) ->
|
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]) ->
|
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) ->
|
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) ->
|
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[
|
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]):
|
@@ -1,12 +1,16 @@
|
|
1
|
+
from __future__ import annotations
|
1
2
|
from abc import abstractmethod
|
2
|
-
from
|
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,
|
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,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
|
3
|
-
|
4
|
-
|
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
|
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
|
3
|
+
from typing import TYPE_CHECKING
|
3
4
|
|
4
|
-
|
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):
|