jararaca 0.2.30__py3-none-any.whl → 0.2.32__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.
Potentially problematic release.
This version of jararaca might be problematic. Click here for more details.
- jararaca/persistence/sort_filter.py +66 -11
- jararaca/persistence/utilities.py +20 -1
- {jararaca-0.2.30.dist-info → jararaca-0.2.32.dist-info}/METADATA +1 -1
- {jararaca-0.2.30.dist-info → jararaca-0.2.32.dist-info}/RECORD +8 -8
- pyproject.toml +1 -1
- {jararaca-0.2.30.dist-info → jararaca-0.2.32.dist-info}/LICENSE +0 -0
- {jararaca-0.2.30.dist-info → jararaca-0.2.32.dist-info}/WHEEL +0 -0
- {jararaca-0.2.30.dist-info → jararaca-0.2.32.dist-info}/entry_points.txt +0 -0
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import re
|
|
1
2
|
from datetime import date, datetime
|
|
2
3
|
from functools import reduce
|
|
3
4
|
from typing import Literal, Tuple, TypeVar
|
|
@@ -10,7 +11,7 @@ from sqlalchemy.orm.attributes import InstrumentedAttribute
|
|
|
10
11
|
from jararaca import BaseEntity
|
|
11
12
|
|
|
12
13
|
FILTER_SORT_ENTITY_ATTR_MAP = dict[
|
|
13
|
-
str, InstrumentedAttribute[str | int | datetime | date | UUID]
|
|
14
|
+
str, InstrumentedAttribute[str | int | datetime | date | UUID | None]
|
|
14
15
|
]
|
|
15
16
|
|
|
16
17
|
|
|
@@ -54,14 +55,12 @@ class FilterModel(BaseModel):
|
|
|
54
55
|
INHERITS_BASE_ENTITY = TypeVar("INHERITS_BASE_ENTITY", bound=BaseEntity)
|
|
55
56
|
|
|
56
57
|
|
|
57
|
-
class
|
|
58
|
+
class FilterRuleApplier:
|
|
58
59
|
def __init__(
|
|
59
60
|
self,
|
|
60
61
|
allowed_filters: FILTER_SORT_ENTITY_ATTR_MAP,
|
|
61
|
-
allowed_sorts: FILTER_SORT_ENTITY_ATTR_MAP,
|
|
62
62
|
):
|
|
63
63
|
self.allowed_filters = allowed_filters
|
|
64
|
-
self.allowed_sorts = allowed_sorts
|
|
65
64
|
|
|
66
65
|
def create_query_for_filter(
|
|
67
66
|
self, query: Select[Tuple[INHERITS_BASE_ENTITY]], filter: FilterModel
|
|
@@ -139,25 +138,41 @@ class SortFilterRunner:
|
|
|
139
138
|
case _:
|
|
140
139
|
raise ValueError(f"Unsupported bool operator: {filter.operator}")
|
|
141
140
|
elif field_type is int:
|
|
141
|
+
__value = (
|
|
142
|
+
filter.value[0] if isinstance(filter.value, list) else filter.value
|
|
143
|
+
)
|
|
144
|
+
if not re.match(r"^-?\d+$", __value):
|
|
145
|
+
raise ValueError(
|
|
146
|
+
f"Unsupported value type for int field: {type(__value)}"
|
|
147
|
+
)
|
|
148
|
+
number_value = int(__value)
|
|
142
149
|
match filter.operator:
|
|
143
150
|
case "=":
|
|
144
|
-
return query.filter(field ==
|
|
151
|
+
return query.filter(field == number_value)
|
|
145
152
|
case "!=":
|
|
146
|
-
return query.filter(field !=
|
|
153
|
+
return query.filter(field != number_value)
|
|
147
154
|
case ">":
|
|
148
|
-
return query.filter(field >
|
|
155
|
+
return query.filter(field > number_value)
|
|
149
156
|
case "<":
|
|
150
|
-
return query.filter(field <
|
|
157
|
+
return query.filter(field < number_value)
|
|
151
158
|
case ">=":
|
|
152
|
-
return query.filter(field >=
|
|
159
|
+
return query.filter(field >= number_value)
|
|
153
160
|
case "<=":
|
|
154
|
-
return query.filter(field <=
|
|
161
|
+
return query.filter(field <= number_value)
|
|
155
162
|
case "isEmpty":
|
|
156
163
|
return query.filter(field == None) # noqa
|
|
157
164
|
case "isNotEmpty":
|
|
158
165
|
return query.filter(field != None) # noqa
|
|
159
166
|
case "isAnyOf":
|
|
160
|
-
|
|
167
|
+
if not isinstance(filter.value, list):
|
|
168
|
+
raise ValueError(
|
|
169
|
+
f"Unsupported value type for isAnyOf operator: {type(filter.value)}"
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
number_values = [
|
|
173
|
+
int(v) for v in filter.value if re.match(r"^-?\d+$", v)
|
|
174
|
+
]
|
|
175
|
+
return query.filter(field.in_(number_values))
|
|
161
176
|
case _:
|
|
162
177
|
raise ValueError(f"Unsupported int operator: {filter.operator}")
|
|
163
178
|
|
|
@@ -168,6 +183,14 @@ class SortFilterRunner:
|
|
|
168
183
|
) -> Select[Tuple[INHERITS_BASE_ENTITY]]:
|
|
169
184
|
return reduce(lambda q, f: self.create_query_for_filter(q, f), filters, query)
|
|
170
185
|
|
|
186
|
+
|
|
187
|
+
class SortRuleApplier:
|
|
188
|
+
def __init__(
|
|
189
|
+
self,
|
|
190
|
+
allowed_sorts: FILTER_SORT_ENTITY_ATTR_MAP,
|
|
191
|
+
):
|
|
192
|
+
self.allowed_sorts = allowed_sorts
|
|
193
|
+
|
|
171
194
|
def create_query_for_sorting(
|
|
172
195
|
self, query: Select[Tuple[INHERITS_BASE_ENTITY]], sort: SortModel
|
|
173
196
|
) -> Select[Tuple[INHERITS_BASE_ENTITY]]:
|
|
@@ -182,6 +205,38 @@ class SortFilterRunner:
|
|
|
182
205
|
return reduce(lambda q, s: self.create_query_for_sorting(q, s), sorts, query)
|
|
183
206
|
|
|
184
207
|
|
|
208
|
+
class SortFilterRunner:
|
|
209
|
+
def __init__(
|
|
210
|
+
self,
|
|
211
|
+
allowed_filters: FILTER_SORT_ENTITY_ATTR_MAP,
|
|
212
|
+
allowed_sorts: FILTER_SORT_ENTITY_ATTR_MAP,
|
|
213
|
+
):
|
|
214
|
+
self.allowed_filters = allowed_filters
|
|
215
|
+
self.allowed_sorts = allowed_sorts
|
|
216
|
+
self.filter_rule_applier = FilterRuleApplier(allowed_filters)
|
|
217
|
+
self.sort_rule_applier = SortRuleApplier(allowed_sorts)
|
|
218
|
+
|
|
219
|
+
def create_query_for_filter(
|
|
220
|
+
self, query: Select[Tuple[INHERITS_BASE_ENTITY]], filter: FilterModel
|
|
221
|
+
) -> Select[Tuple[INHERITS_BASE_ENTITY]]:
|
|
222
|
+
return self.filter_rule_applier.create_query_for_filter(query, filter)
|
|
223
|
+
|
|
224
|
+
def create_query_for_filter_list(
|
|
225
|
+
self, query: Select[Tuple[INHERITS_BASE_ENTITY]], filters: list[FilterModel]
|
|
226
|
+
) -> Select[Tuple[INHERITS_BASE_ENTITY]]:
|
|
227
|
+
return self.filter_rule_applier.create_query_for_filter_list(query, filters)
|
|
228
|
+
|
|
229
|
+
def create_query_for_sorting(
|
|
230
|
+
self, query: Select[Tuple[INHERITS_BASE_ENTITY]], sort: SortModel
|
|
231
|
+
) -> Select[Tuple[INHERITS_BASE_ENTITY]]:
|
|
232
|
+
return self.sort_rule_applier.create_query_for_sorting(query, sort)
|
|
233
|
+
|
|
234
|
+
def create_query_for_sorting_list(
|
|
235
|
+
self, query: Select[Tuple[INHERITS_BASE_ENTITY]], sorts: list[SortModel]
|
|
236
|
+
) -> Select[Tuple[INHERITS_BASE_ENTITY]]:
|
|
237
|
+
return self.sort_rule_applier.create_query_for_sorting_list(query, sorts)
|
|
238
|
+
|
|
239
|
+
|
|
185
240
|
__all__ = [
|
|
186
241
|
"SortFilterRunner",
|
|
187
242
|
"FilterModel",
|
|
@@ -29,7 +29,12 @@ from jararaca.persistence.base import (
|
|
|
29
29
|
BaseEntity,
|
|
30
30
|
recursive_get_dict,
|
|
31
31
|
)
|
|
32
|
-
from jararaca.persistence.sort_filter import
|
|
32
|
+
from jararaca.persistence.sort_filter import (
|
|
33
|
+
FilterModel,
|
|
34
|
+
FilterRuleApplier,
|
|
35
|
+
SortModel,
|
|
36
|
+
SortRuleApplier,
|
|
37
|
+
)
|
|
33
38
|
|
|
34
39
|
logger = logging.getLogger(__name__)
|
|
35
40
|
|
|
@@ -257,11 +262,15 @@ class QueryOperations(Generic[QUERY_FILTER_T, QUERY_ENTITY_T]):
|
|
|
257
262
|
session_provider: Callable[[], AsyncSession],
|
|
258
263
|
filters_functions: list[QueryInjector],
|
|
259
264
|
unique: bool = False,
|
|
265
|
+
sort_rule_applier: SortRuleApplier | None = None,
|
|
266
|
+
filter_rule_applier: FilterRuleApplier | None = None,
|
|
260
267
|
) -> None:
|
|
261
268
|
self.entity_type: type[QUERY_ENTITY_T] = entity_type
|
|
262
269
|
self.session_provider = session_provider
|
|
263
270
|
self.filters_functions = filters_functions
|
|
264
271
|
self.unique = unique
|
|
272
|
+
self.sort_rule_applier = sort_rule_applier
|
|
273
|
+
self.filter_rule_applier = filter_rule_applier
|
|
265
274
|
|
|
266
275
|
@property
|
|
267
276
|
def session(self) -> AsyncSession:
|
|
@@ -281,6 +290,16 @@ class QueryOperations(Generic[QUERY_FILTER_T, QUERY_ENTITY_T]):
|
|
|
281
290
|
select(self.entity_type),
|
|
282
291
|
)
|
|
283
292
|
|
|
293
|
+
if self.sort_rule_applier:
|
|
294
|
+
query = self.sort_rule_applier.create_query_for_sorting_list(
|
|
295
|
+
query, filter.sort_models
|
|
296
|
+
)
|
|
297
|
+
|
|
298
|
+
if self.filter_rule_applier:
|
|
299
|
+
query = self.filter_rule_applier.create_query_for_filter_list(
|
|
300
|
+
query, filter.filter_models
|
|
301
|
+
)
|
|
302
|
+
|
|
284
303
|
unpaginated_total = (
|
|
285
304
|
await self.session.execute(
|
|
286
305
|
select(func.count()).select_from(query.subquery())
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
2
2
|
README.md,sha256=mte30I-ZEJJp-Oax-OganNgl6G9GaCZPL6JVFAvZGz4,7034
|
|
3
|
-
pyproject.toml,sha256=
|
|
3
|
+
pyproject.toml,sha256=nco-vWu7KyNTRSj1yP_qjFqw3B-lzHJ8aCecPhkhN2o,1837
|
|
4
4
|
jararaca/__init__.py,sha256=h1lYQMmB8TATPG0GXjIzLZWHbWFhvkAFu-yBjm2W18g,13875
|
|
5
5
|
jararaca/__main__.py,sha256=-O3vsB5lHdqNFjUtoELDF81IYFtR-DSiiFMzRaiSsv4,67
|
|
6
6
|
jararaca/cli.py,sha256=fh7lp7rf5xbV5VaoSYWWehktel6BPcOXMjW7cw4wKms,5693
|
|
@@ -28,8 +28,8 @@ jararaca/persistence/exports.py,sha256=Ghx4yoFaB4QVTb9WxrFYgmcSATXMNvrOvT8ybPNKX
|
|
|
28
28
|
jararaca/persistence/interceptors/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
29
29
|
jararaca/persistence/interceptors/aiosqa_interceptor.py,sha256=H6ZjOdosYGCZUzKjugiXQwJkAbnsL4HnkZLOEQhULEc,1986
|
|
30
30
|
jararaca/persistence/session.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
31
|
-
jararaca/persistence/sort_filter.py,sha256=
|
|
32
|
-
jararaca/persistence/utilities.py,sha256=
|
|
31
|
+
jararaca/persistence/sort_filter.py,sha256=A5UsXUuo-vBasZZN0M4C_vGfUVgmhgoGoJzcFc6JkBw,9029
|
|
32
|
+
jararaca/persistence/utilities.py,sha256=v9ckhzti3GKWQrng2I03EO-dxGRGp-sLoVnVNf_UFU4,12478
|
|
33
33
|
jararaca/presentation/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
34
34
|
jararaca/presentation/decorators.py,sha256=eL2YCgMSr19m4YCri5PQU46NRxf0QxsqDnz6MqKu0YQ,8389
|
|
35
35
|
jararaca/presentation/hooks.py,sha256=WBbU5DG3-MAm2Ro2YraQyYG_HENfizYfyShL2ktHi6k,1980
|
|
@@ -58,8 +58,8 @@ jararaca/tools/app_config/decorators.py,sha256=-ckkMZ1dswOmECdo1rFrZ15UAku--txaN
|
|
|
58
58
|
jararaca/tools/app_config/interceptor.py,sha256=nfFZiS80hrbnL7-XEYrwmp2rwaVYBqxvqu3Y-6o_ov4,2575
|
|
59
59
|
jararaca/tools/metadata.py,sha256=7nlCDYgItNybentPSSCc2MLqN7IpBd0VyQzfjfQycVI,1402
|
|
60
60
|
jararaca/tools/typescript/interface_parser.py,sha256=_dPBRKs_67eiQ8cPWp8q1uGbIPxZ30dypfoqhbBAL_Y,28790
|
|
61
|
-
jararaca-0.2.
|
|
62
|
-
jararaca-0.2.
|
|
63
|
-
jararaca-0.2.
|
|
64
|
-
jararaca-0.2.
|
|
65
|
-
jararaca-0.2.
|
|
61
|
+
jararaca-0.2.32.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
62
|
+
jararaca-0.2.32.dist-info/METADATA,sha256=X27cj2J9B40gzbZEZaWq0Sktjo_z1Dtx-cwG2350Bp4,8552
|
|
63
|
+
jararaca-0.2.32.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
|
|
64
|
+
jararaca-0.2.32.dist-info/entry_points.txt,sha256=WIh3aIvz8LwUJZIDfs4EeH3VoFyCGEk7cWJurW38q0I,45
|
|
65
|
+
jararaca-0.2.32.dist-info/RECORD,,
|
pyproject.toml
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|