querymodelling 0.0.7__tar.gz → 0.0.9__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.
- {querymodelling-0.0.7/querymodelling.egg-info → querymodelling-0.0.9}/PKG-INFO +1 -1
- {querymodelling-0.0.7 → querymodelling-0.0.9}/pyproject.toml +1 -1
- {querymodelling-0.0.7 → querymodelling-0.0.9}/querymodelling/__version__.py +1 -1
- querymodelling-0.0.9/querymodelling/redis_om.py +154 -0
- {querymodelling-0.0.7 → querymodelling-0.0.9/querymodelling.egg-info}/PKG-INFO +1 -1
- {querymodelling-0.0.7 → querymodelling-0.0.9}/querymodelling.egg-info/SOURCES.txt +1 -0
- {querymodelling-0.0.7 → querymodelling-0.0.9}/AUTHORS.rst +0 -0
- {querymodelling-0.0.7 → querymodelling-0.0.9}/LICENSE +0 -0
- {querymodelling-0.0.7 → querymodelling-0.0.9}/README.md +0 -0
- {querymodelling-0.0.7 → querymodelling-0.0.9}/querymodelling/__helper__.py +0 -0
- {querymodelling-0.0.7 → querymodelling-0.0.9}/querymodelling/__init__.py +0 -0
- {querymodelling-0.0.7 → querymodelling-0.0.9}/querymodelling/base.py +0 -0
- {querymodelling-0.0.7 → querymodelling-0.0.9}/querymodelling/fields.py +0 -0
- {querymodelling-0.0.7 → querymodelling-0.0.9}/querymodelling/model.py +0 -0
- {querymodelling-0.0.7 → querymodelling-0.0.9}/querymodelling/pydantic.py +0 -0
- {querymodelling-0.0.7 → querymodelling-0.0.9}/querymodelling/sql.py +0 -0
- {querymodelling-0.0.7 → querymodelling-0.0.9}/querymodelling.egg-info/dependency_links.txt +0 -0
- {querymodelling-0.0.7 → querymodelling-0.0.9}/querymodelling.egg-info/requires.txt +0 -0
- {querymodelling-0.0.7 → querymodelling-0.0.9}/querymodelling.egg-info/top_level.txt +0 -0
- {querymodelling-0.0.7 → querymodelling-0.0.9}/setup.cfg +0 -0
- {querymodelling-0.0.7 → querymodelling-0.0.9}/setup.py +0 -0
- {querymodelling-0.0.7 → querymodelling-0.0.9}/tests/__init__.py +0 -0
- {querymodelling-0.0.7 → querymodelling-0.0.9}/tests/__main__.py +0 -0
- {querymodelling-0.0.7 → querymodelling-0.0.9}/tests/basic_test.py +0 -0
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
from datetime import datetime
|
|
2
|
+
from typing import TypeVar, Sequence, Type, Callable, ParamSpec
|
|
3
|
+
|
|
4
|
+
from .__helper__ import is_enum
|
|
5
|
+
from .base import get_functions, DefaultSort
|
|
6
|
+
from .fields import QueryField, SortField
|
|
7
|
+
from .model import PageQuery
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
T = TypeVar("T")
|
|
11
|
+
PK = ParamSpec("PK")
|
|
12
|
+
Q = TypeVar("Q", bound=PageQuery)
|
|
13
|
+
|
|
14
|
+
def sortable_by(field, field_name):
|
|
15
|
+
def wrapper(order: DefaultSort):
|
|
16
|
+
if order == "desc":
|
|
17
|
+
return f"-{field_name}"
|
|
18
|
+
if order == "asc":
|
|
19
|
+
return field_name
|
|
20
|
+
return wrapper
|
|
21
|
+
|
|
22
|
+
def create_statement(
|
|
23
|
+
query: Q,
|
|
24
|
+
t: Type[T]
|
|
25
|
+
):
|
|
26
|
+
search_clause = get_functions(query, "query")
|
|
27
|
+
order_clause = get_functions(query, "sort")
|
|
28
|
+
statement = t.find(*search_clause)
|
|
29
|
+
if order_clause:
|
|
30
|
+
for order_clause in order_clause:
|
|
31
|
+
statement = statement.sort_by(order_clause)
|
|
32
|
+
return statement
|
|
33
|
+
|
|
34
|
+
def retrieve_paged_entries(
|
|
35
|
+
query: Q,
|
|
36
|
+
t: Type[T],
|
|
37
|
+
) -> tuple[int, Sequence[T]]:
|
|
38
|
+
statement = create_statement(query, t)
|
|
39
|
+
|
|
40
|
+
statement = statement.copy(
|
|
41
|
+
offset=query.page * query.size, limit=query.size)
|
|
42
|
+
|
|
43
|
+
entries = statement.execute(exhaust_results=False)
|
|
44
|
+
total_elements = statement.count()
|
|
45
|
+
|
|
46
|
+
return total_elements, entries
|
|
47
|
+
|
|
48
|
+
def retrieve_entries(
|
|
49
|
+
query: Q,
|
|
50
|
+
t: Type[T]
|
|
51
|
+
) -> tuple[int, Sequence[T]]:
|
|
52
|
+
statement = create_statement(query, t)
|
|
53
|
+
return statement.all()
|
|
54
|
+
|
|
55
|
+
def create_query_fields(
|
|
56
|
+
base_field: any,
|
|
57
|
+
field_name: str,
|
|
58
|
+
annotation: any,
|
|
59
|
+
operator_mapping: dict[str, Callable],
|
|
60
|
+
json_schema_extra: dict
|
|
61
|
+
):
|
|
62
|
+
for operator, operator_function in operator_mapping.items():
|
|
63
|
+
if operator is None:
|
|
64
|
+
name = field_name
|
|
65
|
+
else:
|
|
66
|
+
name = f"{field_name}_{operator}"
|
|
67
|
+
yield (
|
|
68
|
+
name,
|
|
69
|
+
QueryField(base_field)(
|
|
70
|
+
operator_function,
|
|
71
|
+
default=None,
|
|
72
|
+
json_schema_extra=json_schema_extra | {
|
|
73
|
+
"query.operator": operator
|
|
74
|
+
}
|
|
75
|
+
),
|
|
76
|
+
annotation
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
def create_callback(
|
|
80
|
+
base_field,
|
|
81
|
+
copy_field_properties: list[str] = None,
|
|
82
|
+
schema_extra: dict = None
|
|
83
|
+
):
|
|
84
|
+
def auto_create_callback(
|
|
85
|
+
source_type: type,
|
|
86
|
+
field_name: str,
|
|
87
|
+
field,
|
|
88
|
+
field_info,
|
|
89
|
+
annotation
|
|
90
|
+
):
|
|
91
|
+
if copy_field_properties is None and schema_extra is None:
|
|
92
|
+
json_schema_extra = field_info.json_schema_extra
|
|
93
|
+
json_schema_extra = schema_extra or {}
|
|
94
|
+
if copy_field_properties is not None:
|
|
95
|
+
for property_name in copy_field_properties:
|
|
96
|
+
json_schema_extra[property_name] = field_info[
|
|
97
|
+
property_name]
|
|
98
|
+
|
|
99
|
+
json_schema_extra = json_schema_extra | {
|
|
100
|
+
"query.backend": "redis",
|
|
101
|
+
"query.field": field_name
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if annotation == str:
|
|
105
|
+
operator_mapping = {
|
|
106
|
+
None: lambda value: field == value,
|
|
107
|
+
"not": lambda value: field != value,
|
|
108
|
+
"startswith": lambda value: field.startswith(value),
|
|
109
|
+
"endswith": lambda value: field.endswith(value),
|
|
110
|
+
"contains": lambda value: field % value
|
|
111
|
+
}
|
|
112
|
+
yield from create_query_fields(
|
|
113
|
+
base_field,
|
|
114
|
+
field_name,
|
|
115
|
+
annotation,
|
|
116
|
+
operator_mapping,
|
|
117
|
+
json_schema_extra
|
|
118
|
+
)
|
|
119
|
+
elif annotation in (datetime, int):
|
|
120
|
+
operator_mapping = {
|
|
121
|
+
None: lambda value: field == value,
|
|
122
|
+
"from": lambda value: field >= value,
|
|
123
|
+
"to": lambda value: field <= value,
|
|
124
|
+
"not": lambda value: field != value
|
|
125
|
+
}
|
|
126
|
+
yield from create_query_fields(
|
|
127
|
+
base_field,
|
|
128
|
+
field_name,
|
|
129
|
+
annotation,
|
|
130
|
+
operator_mapping,
|
|
131
|
+
json_schema_extra
|
|
132
|
+
)
|
|
133
|
+
elif is_enum(annotation):
|
|
134
|
+
operator_mapping = {
|
|
135
|
+
None: lambda value: field == value,
|
|
136
|
+
"not": lambda value: field != value
|
|
137
|
+
}
|
|
138
|
+
yield from create_query_fields(
|
|
139
|
+
base_field,
|
|
140
|
+
field_name,
|
|
141
|
+
annotation,
|
|
142
|
+
operator_mapping,
|
|
143
|
+
json_schema_extra
|
|
144
|
+
)
|
|
145
|
+
yield (
|
|
146
|
+
f"sort_{field_name}",
|
|
147
|
+
SortField(base_field)(
|
|
148
|
+
sortable_by(source_type.__dict__[field_name], field_name),
|
|
149
|
+
default=None,
|
|
150
|
+
json_schema_extra=json_schema_extra
|
|
151
|
+
),
|
|
152
|
+
DefaultSort
|
|
153
|
+
)
|
|
154
|
+
return auto_create_callback
|
|
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
|