ormlambda 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. ormlambda/__init__.py +4 -0
  2. ormlambda/common/__init__.py +2 -0
  3. ormlambda/common/abstract_classes/__init__.py +3 -0
  4. ormlambda/common/abstract_classes/abstract_model.py +302 -0
  5. ormlambda/common/abstract_classes/non_query_base.py +33 -0
  6. ormlambda/common/abstract_classes/query_base.py +10 -0
  7. ormlambda/common/enums/__init__.py +2 -0
  8. ormlambda/common/enums/condition_types.py +16 -0
  9. ormlambda/common/enums/join_type.py +10 -0
  10. ormlambda/common/interfaces/INonQueryCommand.py +9 -0
  11. ormlambda/common/interfaces/IQueryCommand.py +11 -0
  12. ormlambda/common/interfaces/IRepositoryBase.py +67 -0
  13. ormlambda/common/interfaces/IStatements.py +227 -0
  14. ormlambda/common/interfaces/__init__.py +4 -0
  15. ormlambda/components/__init__.py +0 -0
  16. ormlambda/components/delete/IDelete.py +6 -0
  17. ormlambda/components/delete/__init__.py +2 -0
  18. ormlambda/components/delete/abstract_delete.py +14 -0
  19. ormlambda/components/insert/IInsert.py +6 -0
  20. ormlambda/components/insert/__init__.py +2 -0
  21. ormlambda/components/insert/abstract_insert.py +21 -0
  22. ormlambda/components/select/ISelect.py +14 -0
  23. ormlambda/components/select/__init__.py +2 -0
  24. ormlambda/components/select/table_column.py +39 -0
  25. ormlambda/components/update/IUpdate.py +7 -0
  26. ormlambda/components/update/__init__.py +2 -0
  27. ormlambda/components/update/abstract_update.py +25 -0
  28. ormlambda/components/upsert/IUpsert.py +6 -0
  29. ormlambda/components/upsert/__init__.py +2 -0
  30. ormlambda/components/upsert/abstract_upsert.py +21 -0
  31. ormlambda/components/where/__init__.py +1 -0
  32. ormlambda/components/where/abstract_where.py +11 -0
  33. ormlambda/databases/__init__.py +0 -0
  34. ormlambda/databases/my_sql/__init__.py +2 -0
  35. ormlambda/databases/my_sql/clauses/__init__.py +13 -0
  36. ormlambda/databases/my_sql/clauses/create_database.py +29 -0
  37. ormlambda/databases/my_sql/clauses/delete.py +54 -0
  38. ormlambda/databases/my_sql/clauses/drop_database.py +19 -0
  39. ormlambda/databases/my_sql/clauses/drop_table.py +23 -0
  40. ormlambda/databases/my_sql/clauses/insert.py +70 -0
  41. ormlambda/databases/my_sql/clauses/joins.py +103 -0
  42. ormlambda/databases/my_sql/clauses/limit.py +17 -0
  43. ormlambda/databases/my_sql/clauses/offset.py +17 -0
  44. ormlambda/databases/my_sql/clauses/order.py +29 -0
  45. ormlambda/databases/my_sql/clauses/select.py +172 -0
  46. ormlambda/databases/my_sql/clauses/update.py +52 -0
  47. ormlambda/databases/my_sql/clauses/upsert.py +68 -0
  48. ormlambda/databases/my_sql/clauses/where_condition.py +219 -0
  49. ormlambda/databases/my_sql/repository.py +192 -0
  50. ormlambda/databases/my_sql/statements.py +86 -0
  51. ormlambda/model_base.py +36 -0
  52. ormlambda/utils/__init__.py +3 -0
  53. ormlambda/utils/column.py +65 -0
  54. ormlambda/utils/dtypes.py +104 -0
  55. ormlambda/utils/foreign_key.py +36 -0
  56. ormlambda/utils/lambda_disassembler/__init__.py +4 -0
  57. ormlambda/utils/lambda_disassembler/dis_types.py +136 -0
  58. ormlambda/utils/lambda_disassembler/disassembler.py +69 -0
  59. ormlambda/utils/lambda_disassembler/dtypes.py +103 -0
  60. ormlambda/utils/lambda_disassembler/name_of.py +41 -0
  61. ormlambda/utils/lambda_disassembler/nested_element.py +44 -0
  62. ormlambda/utils/lambda_disassembler/tree_instruction.py +145 -0
  63. ormlambda/utils/module_tree/__init__.py +0 -0
  64. ormlambda/utils/module_tree/dfs_traversal.py +60 -0
  65. ormlambda/utils/module_tree/dynamic_module.py +237 -0
  66. ormlambda/utils/table_constructor.py +308 -0
  67. ormlambda-0.1.0.dist-info/LICENSE +21 -0
  68. ormlambda-0.1.0.dist-info/METADATA +268 -0
  69. ormlambda-0.1.0.dist-info/RECORD +70 -0
  70. ormlambda-0.1.0.dist-info/WHEEL +4 -0
ormlambda/__init__.py ADDED
@@ -0,0 +1,4 @@
1
+ from .model_base import BaseModel # noqa: F401
2
+ from .utils import Table, Column, ForeignKey # noqa: F401
3
+ from .utils.lambda_disassembler import Disassembler, nameof # noqa: F401
4
+ from .common.interfaces import IRepositoryBase # noqa: F401
@@ -0,0 +1,2 @@
1
+
2
+
@@ -0,0 +1,3 @@
1
+ from .non_query_base import NonQueryBase # noqa: F401
2
+ from .abstract_model import AbstractSQLStatements # noqa: F401
3
+ from .query_base import QueryBase # noqa: F401
@@ -0,0 +1,302 @@
1
+ from typing import Any, Callable, Optional, Type, override, Iterable, Literal
2
+ from enum import Enum
3
+ from collections import defaultdict
4
+ from abc import abstractmethod
5
+ import inspect
6
+
7
+ from ...utils import ForeignKey, Table
8
+
9
+ from ..interfaces import IQuery, IRepositoryBase, IStatements_two_generic
10
+ from ..interfaces.IStatements import OrderType
11
+
12
+ from ...components.update import UpdateQueryBase
13
+ from ...components.select import ISelect
14
+ from ...components.delete import DeleteQueryBase
15
+ from ...components.upsert import UpsertQueryBase
16
+ from ...components.select import TableColumn
17
+ from ...components.insert import InsertQueryBase
18
+ from ...components.where.abstract_where import AbstractWhere
19
+
20
+
21
+ class JoinType(Enum):
22
+ RIGHT_INCLUSIVE = "RIGHT JOIN"
23
+ LEFT_INCLUSIVE = "LEFT JOIN"
24
+ RIGHT_EXCLUSIVE = "RIGHT JOIN"
25
+ LEFT_EXCLUSIVE = "LEFT JOIN"
26
+ FULL_OUTER_INCLUSIVE = "RIGHT JOIN"
27
+ FULL_OUTER_EXCLUSIVE = "RIGHT JOIN"
28
+ INNER_JOIN = "INNER JOIN"
29
+
30
+
31
+ ORDER_QUERIES = Literal["select", "join", "where", "order", "with", "group by", "limit", "offset"]
32
+
33
+
34
+ class AbstractSQLStatements[T: Table, TRepo](IStatements_two_generic[T, TRepo]):
35
+ __slots__ = ("_model", "_repository", "_query_list")
36
+ __order__: tuple[str, ...] = ("select", "join", "where", "order", "with", "group by", "limit", "offset")
37
+
38
+ def __init__(self, model: T, repository: IRepositoryBase[TRepo]) -> None:
39
+ self.valid_repository(repository)
40
+
41
+ self._model: T = model
42
+ self._repository: IRepositoryBase[TRepo] = repository
43
+ self._query_list: dict[ORDER_QUERIES, list[IQuery]] = defaultdict(list)
44
+
45
+ if not issubclass(self._model, Table):
46
+ # 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.
47
+ # 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
48
+ raise Exception(f"'{model}' class does not inherit from Table class")
49
+
50
+ @staticmethod
51
+ def valid_repository(repository: Any) -> bool:
52
+ if not isinstance(repository, IRepositoryBase):
53
+ raise ValueError(f"'repository' attribute does not instance of '{IRepositoryBase.__name__}'")
54
+ return True
55
+
56
+ @property
57
+ @abstractmethod
58
+ def INSERT_QUERY(self) -> Type[InsertQueryBase[T, TRepo]]: ...
59
+ @property
60
+ @abstractmethod
61
+ def UPSERT_QUERY(self) -> Type[UpsertQueryBase[T, TRepo]]: ...
62
+ @property
63
+ @abstractmethod
64
+ def UPDATE_QUERY(self) -> Type[UpdateQueryBase[T, TRepo]]: ...
65
+ @property
66
+ @abstractmethod
67
+ def DELETE_QUERY(self) -> Type[DeleteQueryBase[T, TRepo]]: ...
68
+ @property
69
+ @abstractmethod
70
+ def LIMIT_QUERY(self) -> Type[IQuery]: ...
71
+ @property
72
+ @abstractmethod
73
+ def OFFSET_QUERY(self) -> Type[IQuery]: ...
74
+ @property
75
+ @abstractmethod
76
+ def JOIN_QUERY(self) -> Type[IQuery]: ...
77
+ @property
78
+ @abstractmethod
79
+ def WHERE_QUERY(self) -> Type[IQuery]: ...
80
+ @property
81
+ @abstractmethod
82
+ def ORDER_QUERY(self) -> Type[IQuery]: ...
83
+ @property
84
+ @abstractmethod
85
+ def SELECT_QUERY(self) -> Type[ISelect]: ...
86
+
87
+ @override
88
+ def create_table(self) -> None:
89
+ if not self._repository.table_exists(self._model.__table_name__):
90
+ self._repository.execute(self._model.create_table_query())
91
+ return None
92
+
93
+ @override
94
+ def table_exists(self) -> bool:
95
+ return self._repository.table_exists(self._model.__table_name__)
96
+
97
+ @override
98
+ def insert(self, instances: T | list[T]) -> None:
99
+ insert = self.INSERT_QUERY(self._model, self._repository)
100
+ insert.insert(instances)
101
+ insert.execute()
102
+ self._query_list.clear()
103
+ return None
104
+
105
+ @override
106
+ def delete(self, instances: Optional[T | list[T]] = None) -> None:
107
+ if instances is None:
108
+ response = self.select()
109
+ if len(response) == 0:
110
+ return None
111
+ # [0] because if we do not select anything, we retrieve all columns of the unic model, stored in tuple[tuple[model]] structure.
112
+ # We always going to have a tuple of one element
113
+ return self.delete(response)
114
+
115
+ delete = self.DELETE_QUERY(self._model, self._repository)
116
+ delete.delete(instances)
117
+ delete.execute()
118
+ # not necessary to call self._query_list.clear() because select() method already call it
119
+ return None
120
+
121
+ @override
122
+ def upsert(self, instances: T | list[T]) -> None:
123
+ upsert = self.UPSERT_QUERY(self._model, self._repository)
124
+ upsert.upsert(instances)
125
+ upsert.execute()
126
+ self._query_list.clear()
127
+ return None
128
+
129
+ @override
130
+ def update(self, dicc: dict[str, Any] | list[dict[str, Any]]) -> None:
131
+ update = self.UPDATE_QUERY(self._model, self._repository, self._query_list["where"])
132
+ update.update(dicc)
133
+ update.execute()
134
+ self._query_list.clear()
135
+ return None
136
+
137
+ @override
138
+ def limit(self, number: int) -> "IStatements_two_generic[T,TRepo]":
139
+ limit = self.LIMIT_QUERY(number)
140
+ # Only can be one LIMIT SQL parameter. We only use the last LimitQuery
141
+ limit_list = self._query_list["limit"]
142
+ if len(limit_list) > 0:
143
+ self._query_list["limit"] = [limit]
144
+ else:
145
+ self._query_list["limit"].append(limit)
146
+ return self
147
+
148
+ @override
149
+ def offset(self, number: int) -> "IStatements_two_generic[T,TRepo]":
150
+ offset = self.OFFSET_QUERY(number)
151
+ self._query_list["offset"].append(offset)
152
+ return self
153
+
154
+ @override
155
+ def join(self, table_left: Table, table_right: Table, *, by: str) -> "IStatements_two_generic[T,TRepo]":
156
+ where = ForeignKey.MAPPED[table_left][table_right]
157
+ join_query = self.JOIN_QUERY[table_left, Table](table_left, table_right, JoinType(by), where=where)
158
+ self._query_list["join"].append(join_query)
159
+ return self
160
+
161
+ @override
162
+ def where(self, lambda_: Callable[[T], bool] = lambda: None, **kwargs) -> "IStatements_two_generic[T,TRepo]":
163
+ # FIXME [x]: I've wrapped self._model into tuple to pass it instance attr. Idk if it's correct
164
+ where_query = self.WHERE_QUERY[T](function=lambda_, instances=(self._model,), **kwargs)
165
+ self._query_list["where"].append(where_query)
166
+ return self
167
+
168
+ @override
169
+ def order[TValue](self, _lambda_col: Callable[[T], TValue], order_type: OrderType) -> "IStatements_two_generic[T,TRepo]":
170
+ order = self.ORDER_QUERY[T](self._model, _lambda_col, order_type)
171
+ self._query_list["order"].append(order)
172
+ return self
173
+
174
+ @override
175
+ def select[TValue, TFlavour, *Ts](self, selector: Optional[Callable[[T], tuple[TValue, *Ts]]] = lambda: None, *, flavour: Optional[Type[TFlavour]] = None, by: JoinType = JoinType.INNER_JOIN):
176
+ if len(inspect.signature(selector).parameters) == 0:
177
+ # COMMENT: if we do not specify any lambda function we assumed the user want to retreive only elements of the Model itself avoiding other models
178
+ result = self.select(selector=lambda x: (x,), flavour=flavour, by=by)
179
+ # COMMENT: Always we want to retrieve tuple[tuple[Any]]. That's the reason to return result[0] when we ensure the user want only objects of the first table.
180
+ # Otherwise, we wil return the result itself
181
+ if flavour:
182
+ return result
183
+ return () if not result else result[0]
184
+ select: ISelect = self.SELECT_QUERY(self._model, select_lambda=selector, by=by)
185
+ self._query_list["select"].append(select)
186
+
187
+ query: str = self.build()
188
+ if flavour:
189
+ result = self._return_flavour(query, flavour)
190
+ if issubclass(flavour, tuple) and isinstance(selector(self._model), property):
191
+ return tuple([x[0] for x in result])
192
+ return result
193
+ return self._return_model(select, query)
194
+
195
+ def _return_flavour[TValue](self, query, flavour: Type[TValue]) -> tuple[TValue]:
196
+ return self._repository.read_sql(query, flavour=flavour)
197
+
198
+ def _return_model(self, select: ISelect, query: str):
199
+ response_sql = self._repository.read_sql(query, flavour=dict) # store all columns of the SQL query
200
+
201
+ if isinstance(response_sql, Iterable):
202
+ return ClusterQuery(select, response_sql).clean_response()
203
+
204
+ return response_sql
205
+
206
+ @override
207
+ 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):
208
+ self.limit(1)
209
+ if len(inspect.signature(selector).parameters) == 0:
210
+ response = self.select(selector=lambda x: (x,), flavour=flavour, by=by)
211
+ else:
212
+ response = self.select(selector=selector, flavour=flavour, by=by)
213
+
214
+ if flavour:
215
+ return response[0]
216
+
217
+ # response var could be return more than one element when we work with models an we
218
+ # select columns from different tables using a join query
219
+ if len(response) == 1 and len(response[0]) == 1:
220
+ return response[0][0]
221
+ return tuple([res[0] for res in response])
222
+
223
+ @override
224
+ def build(self) -> str:
225
+ query: str = ""
226
+
227
+ self._create_necessary_inner_join()
228
+ for x in self.__order__:
229
+ if sub_query := self._query_list.get(x, None):
230
+ if isinstance(sub_query[0], self.WHERE_QUERY):
231
+ query_ = self.__build_where_clause(sub_query)
232
+
233
+ # we must check if any join already exists on query string
234
+ elif isinstance(sub_query[0], self.JOIN_QUERY):
235
+ select_query: str = self._query_list["select"][0].query
236
+ query_ = ""
237
+ for join in sub_query:
238
+ if join.query not in select_query:
239
+ query_ += f"\n{join.query}"
240
+ else:
241
+ query_ = "\n".join([x.query for x in sub_query])
242
+
243
+ query += f"\n{query_}" if query != "" else query_
244
+ self._query_list.clear()
245
+ return query
246
+
247
+ def __build_where_clause(self, where_condition: list[AbstractWhere]) -> str:
248
+ query: str = where_condition[0].query
249
+
250
+ for where in where_condition[1:]:
251
+ q = where.query.replace(where.WHERE, "AND")
252
+ and_, clause = q.split(" ", maxsplit=1)
253
+ query += f" {and_} ({clause})"
254
+ return query
255
+
256
+ def _create_necessary_inner_join(self) -> None:
257
+ # 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.
258
+ if "where" not in self._query_list:
259
+ return None
260
+
261
+ where: AbstractWhere = self._query_list["where"][0]
262
+ involved_tables = where.get_involved_tables()
263
+
264
+ select: ISelect = self._query_list["select"][0]
265
+ if not involved_tables or (set(involved_tables) == set(select.tables_heritage)):
266
+ return None
267
+
268
+ for l_tbl, r_tbl in involved_tables:
269
+ # FIXME [ ]: Checked what function was called by the self.join method before the change
270
+ self.join(l_tbl, r_tbl, by="INNER JOIN")
271
+
272
+
273
+ class ClusterQuery:
274
+ def __init__(self, select: ISelect, response_sql: tuple[dict[str, Any]]) -> None:
275
+ self._select: ISelect = select
276
+ self._response_sql: tuple[dict[str, Any]] = response_sql
277
+
278
+ def loop_foo(self) -> dict[Type[Table], list[Table]]:
279
+ # We must ensure to get the valid attributes for each instance
280
+ table_initialize = defaultdict(list)
281
+
282
+ unic_table: dict[Table, list[TableColumn]] = defaultdict(list)
283
+ for table_col in self._select.select_list:
284
+ unic_table[table_col._table].append(table_col)
285
+
286
+ for table_, table_col in unic_table.items():
287
+ for dicc_cols in self._response_sql:
288
+ valid_attr: dict[str, Any] = {}
289
+ for col in table_col:
290
+ valid_attr[col.real_column] = dicc_cols[col.alias]
291
+ # COMMENT: At this point we are going to instantiate Table class with specific attributes getting directly from database
292
+ table_initialize[table_].append(table_(**valid_attr))
293
+ return table_initialize
294
+
295
+ def clean_response(self) -> tuple[dict[Type[Table], tuple[Table]]]:
296
+ tbl_dicc: dict[Type[Table], list[Table]] = self.loop_foo()
297
+
298
+ # it not depend of flavour attr
299
+ for key, val in tbl_dicc.items():
300
+ tbl_dicc[key] = tuple(val)
301
+
302
+ return tuple(tbl_dicc.values())
@@ -0,0 +1,33 @@
1
+ from abc import abstractmethod
2
+ from typing import Any, Optional, override
3
+
4
+ from ..interfaces.INonQueryCommand import INonQueryCommand
5
+
6
+ from ..interfaces import IRepositoryBase
7
+ from ...utils import Table
8
+
9
+
10
+ class NonQueryBase[T: Table, TRepo: IRepositoryBase](INonQueryCommand):
11
+ __slots__: tuple[str, ...] = ("_model", "_repository", "_values", "_query")
12
+
13
+ def __init__(self, model: T, repository: TRepo) -> None:
14
+ self._model: T = model
15
+ self._repository: TRepo = repository
16
+ self._values: list[tuple[Any]] = []
17
+ self._query: Optional[str] = None
18
+
19
+ @property
20
+ @abstractmethod
21
+ def CLAUSE(self) -> str: ...
22
+
23
+ @abstractmethod
24
+ def execute(self) -> None: ...
25
+
26
+ @property
27
+ @override
28
+ def query(self) -> str:
29
+ return self._query
30
+
31
+ @property
32
+ def values(self) -> list[tuple[Any, ...]]:
33
+ return self._values
@@ -0,0 +1,10 @@
1
+ from abc import abstractmethod
2
+
3
+ from ...utils import Table
4
+ from ..interfaces import IQuery
5
+
6
+
7
+ class QueryBase[T: Table](IQuery):
8
+ @property
9
+ @abstractmethod
10
+ def query(self) -> str: ...
@@ -0,0 +1,2 @@
1
+ from .join_type import JoinType # noqa: F401
2
+ from .condition_types import ConditionType # noqa: F401
@@ -0,0 +1,16 @@
1
+ from enum import Enum
2
+
3
+
4
+ class ConditionType(Enum):
5
+ EQUAL = "=="
6
+ LESS_THAN = "<"
7
+ GREATER_THAN = ">"
8
+ LESS_THAN_OR_EQUAL = "<="
9
+ GREATER_THAN_OR_EQUAL = ">="
10
+ NOT_EQUAL = "!="
11
+ REGEXP = "REGEXP"
12
+ BETWEEN = "BETWEEN"
13
+ LIKE = "LIKE"
14
+ IN = "IN"
15
+ IS = "IS"
16
+ IS_NOT = "IS NOT"
@@ -0,0 +1,10 @@
1
+ from enum import Enum
2
+
3
+ class JoinType(Enum):
4
+ RIGHT_INCLUSIVE = "RIGHT JOIN"
5
+ LEFT_INCLUSIVE = "LEFT JOIN"
6
+ RIGHT_EXCLUSIVE = "RIGHT JOIN"
7
+ LEFT_EXCLUSIVE = "LEFT JOIN"
8
+ FULL_OUTER_INCLUSIVE = "RIGHT JOIN"
9
+ FULL_OUTER_EXCLUSIVE = "RIGHT JOIN"
10
+ INNER_JOIN = "INNER JOIN"
@@ -0,0 +1,9 @@
1
+ from abc import abstractmethod
2
+ from .IQueryCommand import IQuery
3
+
4
+
5
+ class INonQueryCommand(IQuery):
6
+ """Interface to queries that does not retrieve any element such as insert, update, delete, etc..."""
7
+
8
+ @abstractmethod
9
+ def execute(self) -> None: ...
@@ -0,0 +1,11 @@
1
+ from abc import abstractmethod, ABC
2
+
3
+
4
+ class IQuery(ABC):
5
+ """ Interface to queries that retrieve any element such as select, limit, offset, where, group by, etc..."""
6
+ @property
7
+ @abstractmethod
8
+ def query(self) -> str: ...
9
+
10
+ def __repr__(self) -> str:
11
+ return f"{IQuery.__name__}: {self.__class__.__name__}"
@@ -0,0 +1,67 @@
1
+ from abc import ABC, abstractmethod
2
+ import functools
3
+ from typing import Any, Callable, Literal, Optional, Type
4
+
5
+ TypeExists = Literal["fail", "replace", "append"]
6
+
7
+
8
+ 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
+ def __repr__(self) -> str:
22
+ return f"{IRepositoryBase.__name__}: {self.__class__.__name__}"
23
+
24
+ @abstractmethod
25
+ def is_connected(self) -> bool: ...
26
+
27
+ @abstractmethod
28
+ def connect(self, **kwargs: Any) -> "IRepositoryBase[T]": ...
29
+
30
+ @abstractmethod
31
+ def close_connection(self) -> None: ...
32
+
33
+ @abstractmethod
34
+ def read_sql[TFlavour](self, query: str, flavour: Optional[Type[TFlavour]], **kwargs) -> tuple[TFlavour]: ...
35
+
36
+ @abstractmethod
37
+ def executemany_with_values(self, query: str, values) -> None: ...
38
+
39
+ @abstractmethod
40
+ def execute_with_values(self, query: str, values) -> None: ...
41
+
42
+ @abstractmethod
43
+ def execute(self, query: str) -> None: ...
44
+
45
+ @abstractmethod
46
+ def drop_database(self, name: str) -> None: ...
47
+
48
+ @abstractmethod
49
+ def create_database(self, name: str, if_exists: TypeExists = "fail") -> None: ...
50
+
51
+ @abstractmethod
52
+ def drop_table(self, name: str) -> None: ...
53
+
54
+ @abstractmethod
55
+ def table_exists(self, name: str) -> bool: ...
56
+
57
+ @abstractmethod
58
+ def database_exists(self, name: str) -> bool: ...
59
+
60
+ @property
61
+ @abstractmethod
62
+ def connection(self) -> T: ...
63
+
64
+ @abstractmethod
65
+ def set_config(self, value: dict[str, Any]) -> dict[str, Any]:
66
+ """Method to update database config"""
67
+ ...