Loglan-Core 0.4.3__tar.gz → 0.4.5__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.
- {loglan_core-0.4.3 → loglan_core-0.4.5/Loglan_Core.egg-info}/PKG-INFO +2 -2
- {loglan_core-0.4.3/Loglan_Core.egg-info → loglan_core-0.4.5}/PKG-INFO +2 -2
- {loglan_core-0.4.3 → loglan_core-0.4.5}/loglan_core/addons/base_selector.py +73 -30
- {loglan_core-0.4.3 → loglan_core-0.4.5}/loglan_core/addons/word_selector.py +1 -1
- {loglan_core-0.4.3 → loglan_core-0.4.5}/setup.py +1 -1
- {loglan_core-0.4.3 → loglan_core-0.4.5}/LICENSE +0 -0
- {loglan_core-0.4.3 → loglan_core-0.4.5}/Loglan_Core.egg-info/SOURCES.txt +0 -0
- {loglan_core-0.4.3 → loglan_core-0.4.5}/Loglan_Core.egg-info/dependency_links.txt +0 -0
- {loglan_core-0.4.3 → loglan_core-0.4.5}/Loglan_Core.egg-info/requires.txt +0 -0
- {loglan_core-0.4.3 → loglan_core-0.4.5}/Loglan_Core.egg-info/top_level.txt +0 -0
- {loglan_core-0.4.3 → loglan_core-0.4.5}/README.md +0 -0
- {loglan_core-0.4.3 → loglan_core-0.4.5}/loglan_core/__init__.py +0 -0
- {loglan_core-0.4.3 → loglan_core-0.4.5}/loglan_core/addons/__init__.py +0 -0
- {loglan_core-0.4.3 → loglan_core-0.4.5}/loglan_core/addons/definition_selector.py +0 -0
- {loglan_core-0.4.3 → loglan_core-0.4.5}/loglan_core/addons/export_word_converter.py +0 -0
- {loglan_core-0.4.3 → loglan_core-0.4.5}/loglan_core/addons/exporter.py +0 -0
- {loglan_core-0.4.3 → loglan_core-0.4.5}/loglan_core/addons/key_selector.py +0 -0
- {loglan_core-0.4.3 → loglan_core-0.4.5}/loglan_core/addons/utils.py +0 -0
- {loglan_core-0.4.3 → loglan_core-0.4.5}/loglan_core/addons/word_linker.py +0 -0
- {loglan_core-0.4.3 → loglan_core-0.4.5}/loglan_core/addons/word_sourcer.py +0 -0
- {loglan_core-0.4.3 → loglan_core-0.4.5}/loglan_core/author.py +0 -0
- {loglan_core-0.4.3 → loglan_core-0.4.5}/loglan_core/base.py +0 -0
- {loglan_core-0.4.3 → loglan_core-0.4.5}/loglan_core/connect_tables.py +0 -0
- {loglan_core-0.4.3 → loglan_core-0.4.5}/loglan_core/definition.py +0 -0
- {loglan_core-0.4.3 → loglan_core-0.4.5}/loglan_core/event.py +0 -0
- {loglan_core-0.4.3 → loglan_core-0.4.5}/loglan_core/key.py +0 -0
- {loglan_core-0.4.3 → loglan_core-0.4.5}/loglan_core/setting.py +0 -0
- {loglan_core-0.4.3 → loglan_core-0.4.5}/loglan_core/syllable.py +0 -0
- {loglan_core-0.4.3 → loglan_core-0.4.5}/loglan_core/table_names.py +0 -0
- {loglan_core-0.4.3 → loglan_core-0.4.5}/loglan_core/type.py +0 -0
- {loglan_core-0.4.3 → loglan_core-0.4.5}/loglan_core/word.py +0 -0
- {loglan_core-0.4.3 → loglan_core-0.4.5}/loglan_core/word_spell.py +0 -0
- {loglan_core-0.4.3 → loglan_core-0.4.5}/pyproject.toml +0 -0
- {loglan_core-0.4.3 → loglan_core-0.4.5}/setup.cfg +0 -0
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: Loglan-Core
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.5
|
|
4
4
|
Summary: Loglan Dictionary Database Model for SQLAlchemy
|
|
5
5
|
Home-page: https://github.com/torrua/loglan_core
|
|
6
|
-
Download-URL: https://github.com/torrua/loglan_core/archive/0.4.
|
|
6
|
+
Download-URL: https://github.com/torrua/loglan_core/archive/0.4.5.tar.gz
|
|
7
7
|
Author: torrua
|
|
8
8
|
Author-email: torrua@gmail.com
|
|
9
9
|
License: MIT
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: Loglan-Core
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.5
|
|
4
4
|
Summary: Loglan Dictionary Database Model for SQLAlchemy
|
|
5
5
|
Home-page: https://github.com/torrua/loglan_core
|
|
6
|
-
Download-URL: https://github.com/torrua/loglan_core/archive/0.4.
|
|
6
|
+
Download-URL: https://github.com/torrua/loglan_core/archive/0.4.5.tar.gz
|
|
7
7
|
Author: torrua
|
|
8
8
|
Author-email: torrua@gmail.com
|
|
9
9
|
License: MIT
|
|
@@ -8,6 +8,7 @@ from typing import Type, Iterable, Any
|
|
|
8
8
|
|
|
9
9
|
from sqlalchemy import select, Select
|
|
10
10
|
from sqlalchemy.orm import Session, InstrumentedAttribute, joinedload
|
|
11
|
+
from sqlalchemy.types import String
|
|
11
12
|
from typing_extensions import Self
|
|
12
13
|
|
|
13
14
|
from loglan_core.base import BaseModel
|
|
@@ -62,8 +63,7 @@ class BaseSelector: # pylint: disable=too-many-ancestors
|
|
|
62
63
|
self.case_sensitive = case_sensitive
|
|
63
64
|
|
|
64
65
|
def execute(self, session: Session):
|
|
65
|
-
"""
|
|
66
|
-
Executes the given session and returns the result.
|
|
66
|
+
"""Executes the given session and returns the result.
|
|
67
67
|
|
|
68
68
|
Args:
|
|
69
69
|
session (Session): SQLAlchemy Session object.
|
|
@@ -74,8 +74,7 @@ class BaseSelector: # pylint: disable=too-many-ancestors
|
|
|
74
74
|
return session.execute(self._statement)
|
|
75
75
|
|
|
76
76
|
def all(self, session: Session):
|
|
77
|
-
"""
|
|
78
|
-
Executes the given session and returns all the results as a list.
|
|
77
|
+
"""Executes the given session and returns all the results as a list.
|
|
79
78
|
|
|
80
79
|
Args:
|
|
81
80
|
session (Session): SQLAlchemy Session object.
|
|
@@ -86,8 +85,7 @@ class BaseSelector: # pylint: disable=too-many-ancestors
|
|
|
86
85
|
return session.execute(self._statement).scalars().all()
|
|
87
86
|
|
|
88
87
|
def scalar(self, session: Session):
|
|
89
|
-
"""
|
|
90
|
-
Executes the given session and returns a scalar result.
|
|
88
|
+
"""Executes the given session and returns a scalar result.
|
|
91
89
|
|
|
92
90
|
Args:
|
|
93
91
|
session (Session): SQLAlchemy Session object.
|
|
@@ -98,8 +96,7 @@ class BaseSelector: # pylint: disable=too-many-ancestors
|
|
|
98
96
|
return session.execute(self._statement).scalar()
|
|
99
97
|
|
|
100
98
|
def fetchmany(self, session: Session, size: int | None = None):
|
|
101
|
-
"""
|
|
102
|
-
Executes the given session and fetches a specified number of results.
|
|
99
|
+
"""Executes the given session and fetches a specified number of results.
|
|
103
100
|
|
|
104
101
|
Args:
|
|
105
102
|
session (Session): SQLAlchemy Session object.
|
|
@@ -204,15 +201,47 @@ class BaseSelector: # pylint: disable=too-many-ancestors
|
|
|
204
201
|
self._statement = self._statement.where(*args)
|
|
205
202
|
return self
|
|
206
203
|
|
|
207
|
-
def
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
204
|
+
def where_like(self, **kwargs) -> Self:
|
|
205
|
+
"""Filter results based on arbitrary keyword arguments.
|
|
206
|
+
Use internal method `_generate_column_condition` to generate
|
|
207
|
+
the condition based on settings provided by Selector instance
|
|
208
|
+
like (is_sqlite, case_sensitive).
|
|
209
|
+
|
|
210
|
+
Args:
|
|
211
|
+
**kwargs: Column-value pairs to filter by.
|
|
211
212
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
213
|
+
Returns:
|
|
214
|
+
Self: The current instance for method chaining.
|
|
215
|
+
"""
|
|
216
|
+
for key, value in kwargs.items():
|
|
217
|
+
self._statement = self._statement.where(self.get_like_condition(key, value))
|
|
218
|
+
return self
|
|
219
|
+
|
|
220
|
+
def get_like_condition(self, key: str | InstrumentedAttribute, value: Any):
|
|
221
|
+
"""Generate the condition based on settings provided by Selector instance
|
|
222
|
+
like (is_sqlite, case_sensitive).
|
|
223
|
+
|
|
224
|
+
Args:
|
|
225
|
+
key (str | InstrumentedAttribute): The key of the column to filter by.
|
|
226
|
+
value (Any): The value to filter by.
|
|
227
|
+
|
|
228
|
+
Returns:
|
|
229
|
+
Condition: The SQLAlchemy condition to filter by.
|
|
230
|
+
"""
|
|
231
|
+
column = self._get_column(key)
|
|
232
|
+
|
|
233
|
+
if not isinstance(column.type, String):
|
|
234
|
+
return column == value
|
|
235
|
+
|
|
236
|
+
value = value.replace("*", "%")
|
|
237
|
+
|
|
238
|
+
if not self.case_sensitive:
|
|
239
|
+
return column.ilike(value)
|
|
240
|
+
|
|
241
|
+
if self.is_sqlite:
|
|
242
|
+
return column.op("GLOB")(value)
|
|
243
|
+
|
|
244
|
+
return column.like(value)
|
|
216
245
|
|
|
217
246
|
def get_statement(self) -> Select:
|
|
218
247
|
"""Get the current SQLAlchemy _statement.
|
|
@@ -233,21 +262,8 @@ class BaseSelector: # pylint: disable=too-many-ancestors
|
|
|
233
262
|
"""
|
|
234
263
|
return self.all(session)
|
|
235
264
|
|
|
236
|
-
@staticmethod
|
|
237
|
-
def _is_model_accepted(model, parent: type[BaseModel] = BaseModel):
|
|
238
|
-
"""
|
|
239
|
-
Checks if the model is an instance of BaseModel or its child.
|
|
240
|
-
Raises:
|
|
241
|
-
ValueError: If the model is not an instance of BaseModel or its child.
|
|
242
|
-
"""
|
|
243
|
-
if not issubclass(model, parent):
|
|
244
|
-
raise ValueError(
|
|
245
|
-
f"Provided class_={model} is not a inherited from {parent}"
|
|
246
|
-
)
|
|
247
|
-
|
|
248
265
|
def with_relationships(self, selected: Iterable[str] | None = None) -> Self:
|
|
249
|
-
"""
|
|
250
|
-
Adds relationships to the query.
|
|
266
|
+
"""Adds relationships to the query.
|
|
251
267
|
|
|
252
268
|
Args:
|
|
253
269
|
selected (set[str]): A set of relationship names to include.
|
|
@@ -266,3 +282,30 @@ class BaseSelector: # pylint: disable=too-many-ancestors
|
|
|
266
282
|
}
|
|
267
283
|
self._statement = self._statement.options(*relationships)
|
|
268
284
|
return self
|
|
285
|
+
|
|
286
|
+
@staticmethod
|
|
287
|
+
def _is_model_accepted(model, parent: type[BaseModel] = BaseModel):
|
|
288
|
+
"""Checks if the model is an instance of BaseModel or its child.
|
|
289
|
+
|
|
290
|
+
Raises:
|
|
291
|
+
ValueError: If the model is not an instance of BaseModel or its child.
|
|
292
|
+
"""
|
|
293
|
+
if not issubclass(model, parent):
|
|
294
|
+
raise ValueError(f"Provided model={model} is not a inherited from {parent}")
|
|
295
|
+
|
|
296
|
+
def _get_column(self, key: str | InstrumentedAttribute) -> InstrumentedAttribute:
|
|
297
|
+
"""Get the column from the model.
|
|
298
|
+
|
|
299
|
+
Args:
|
|
300
|
+
key (str | InstrumentedAttribute): The key of the column to filter by.
|
|
301
|
+
|
|
302
|
+
Raises:
|
|
303
|
+
AttributeError: If the model has no attribute with the given key.
|
|
304
|
+
|
|
305
|
+
Returns:
|
|
306
|
+
InstrumentedAttribute: The SQLAlchemy column to filter by.
|
|
307
|
+
"""
|
|
308
|
+
column = getattr(self.model, key, None) if isinstance(key, str) else key
|
|
309
|
+
if column is None:
|
|
310
|
+
raise AttributeError(f"Model {self.model} has no attribute {key}")
|
|
311
|
+
return column
|
|
@@ -87,7 +87,7 @@ class WordSelector(BaseSelector): # pylint: disable=too-many-ancestors
|
|
|
87
87
|
Self: A query with the filter applied.
|
|
88
88
|
"""
|
|
89
89
|
if hasattr(self.model, "name"):
|
|
90
|
-
condition = self.
|
|
90
|
+
condition = self.get_like_condition(self.model.name, name)
|
|
91
91
|
else:
|
|
92
92
|
raise AttributeError(
|
|
93
93
|
f"{self.model.__name__} does not have a 'name' attribute"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|