Skip to content

Commit 0b0a8d9

Browse files
author
oleksandr.volha
committed
aql, xql str value managers, func dataclasses
1 parent d970669 commit 0b0a8d9

File tree

45 files changed

+1062
-345
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+1062
-345
lines changed

uncoder-core/app/translator/core/custom_types/functions.py

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,29 @@ class FunctionType(CustomEnum):
55
avg = "avg"
66
count = "count"
77
distinct_count = "distinct_count"
8+
max = "max"
9+
min = "min"
10+
sum = "sum"
11+
12+
divide = "divide"
13+
814
earliest = "earliest"
15+
latest = "latest"
16+
17+
lower = "lower"
18+
upper = "upper"
19+
20+
compare_boolean = "compare_boolean"
21+
22+
ipv4_is_in_range = "ipv4_is_in_range"
23+
24+
bin = "bin"
925
eval = "eval"
1026
fields = "fields"
11-
latest = "latest"
12-
max = "max"
13-
min = "min"
1427
rename = "rename"
1528
search = "search"
16-
sort = "sort"
29+
sort_limit = "sort_limit"
1730
stats = "stats"
18-
sum = "sum"
1931
table = "table"
32+
timeframe = "timeframe"
2033
values = "values"

uncoder-core/app/translator/core/custom_types/tokens.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,12 @@ class GroupType(CustomEnum):
3333

3434

3535
STR_SEARCH_OPERATORS = (
36-
OperatorType.CONTAINS, OperatorType.NOT_CONTAINS, OperatorType.ENDSWITH, OperatorType.NOT_ENDSWITH,
37-
OperatorType.STARTSWITH, OperatorType.NOT_STARTSWITH, OperatorType.REGEX, OperatorType.NOT_REGEX
36+
OperatorType.CONTAINS,
37+
OperatorType.NOT_CONTAINS,
38+
OperatorType.ENDSWITH,
39+
OperatorType.NOT_ENDSWITH,
40+
OperatorType.STARTSWITH,
41+
OperatorType.NOT_STARTSWITH,
42+
OperatorType.REGEX,
43+
OperatorType.NOT_REGEX,
3844
)

uncoder-core/app/translator/core/functions.py

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,10 @@ class PlatformFunctionsManager:
100100
def __init__(self):
101101
self._parsers_map: dict[str, HigherOrderFunctionParser] = {}
102102
self._renders_map: dict[str, FunctionRender] = {}
103+
self._in_query_renders_map: dict[str, FunctionRender] = {}
103104
self._names_map: dict[str, str] = {}
105+
self._order_to_render: dict[str, int] = {}
106+
self._render_to_prefix_functions: list[str] = []
104107

105108
def post_init_configure(self, platform_render: PlatformQueryRender) -> None:
106109
raise NotImplementedError
@@ -121,6 +124,12 @@ def get_render(self, generic_func_name: str) -> FunctionRender:
121124

122125
raise NotSupportedFunctionException
123126

127+
def get_in_query_render(self, generic_func_name: str) -> FunctionRender:
128+
if INIT_FUNCTIONS and (render := self._in_query_renders_map.get(generic_func_name)):
129+
return render
130+
131+
raise NotSupportedFunctionException
132+
124133
def get_generic_func_name(self, platform_func_name: str) -> Optional[str]:
125134
if INIT_FUNCTIONS and (generic_func_name := self._names_map.get(platform_func_name)):
126135
return generic_func_name
@@ -131,6 +140,20 @@ def get_platform_func_name(self, generic_func_name: str) -> Optional[str]:
131140
if INIT_FUNCTIONS:
132141
return self._inverted_names_map.get(generic_func_name)
133142

143+
@property
144+
def order_to_render(self) -> dict[str, int]:
145+
if INIT_FUNCTIONS:
146+
return self._order_to_render
147+
148+
return {}
149+
150+
@property
151+
def render_to_prefix_functions(self) -> list[str]:
152+
if INIT_FUNCTIONS:
153+
return self._render_to_prefix_functions
154+
155+
return []
156+
134157

135158
class PlatformFunctions:
136159
manager: PlatformFunctionsManager = PlatformFunctionsManager()
@@ -158,18 +181,27 @@ def parse(self, query: str) -> ParsedFunctions:
158181
invalid=invalid,
159182
)
160183

184+
def _sort_functions_to_render(self, functions: list[Function]) -> list[Function]:
185+
return sorted(functions, key=lambda func: self.manager.order_to_render.get(func.name, 0))
186+
161187
def render(self, functions: list[Function], source_mapping: SourceMapping) -> RenderedFunctions:
162188
rendered = ""
189+
rendered_prefix = ""
163190
not_supported = []
191+
functions = self._sort_functions_to_render(functions)
164192
for func in functions:
165193
try:
166194
func_render = self.manager.get_render(func.name)
167-
rendered += self.wrap_function_with_delimiter(func_render.render(func, source_mapping))
195+
_rendered = func_render.render(func, source_mapping)
196+
if func.name in self.manager.render_to_prefix_functions:
197+
rendered_prefix += _rendered
198+
else:
199+
rendered += self.wrap_function_with_delimiter(_rendered)
168200
except NotSupportedFunctionException:
169201
not_supported.append(func.raw)
170202

171203
not_supported = [self.wrap_function_with_delimiter(func.strip()) for func in not_supported]
172-
return RenderedFunctions(rendered=rendered, not_supported=not_supported)
204+
return RenderedFunctions(rendered_prefix=rendered_prefix, rendered=rendered, not_supported=not_supported)
173205

174206
def wrap_function_with_delimiter(self, func: str) -> str:
175207
return f" {self.function_delimiter} {func}"

uncoder-core/app/translator/core/mapping.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ def __init__(
8282

8383
class BasePlatformMappings:
8484
skip_load_default_mappings: bool = True
85+
extend_default_mapping_with_all_fields: bool = False
8586

8687
def __init__(self, platform_dir: str):
8788
self._loader = LoaderFileMappings()
@@ -116,6 +117,9 @@ def prepare_mapping(self) -> dict[str, SourceMapping]:
116117
if self.skip_load_default_mappings:
117118
source_mappings[DEFAULT_MAPPING_NAME] = default_mapping
118119

120+
if self.extend_default_mapping_with_all_fields:
121+
source_mappings[DEFAULT_MAPPING_NAME].fields_mapping.update(default_mapping.fields_mapping)
122+
119123
return source_mappings
120124

121125
@staticmethod

uncoder-core/app/translator/core/models/field.py

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
from typing import Optional, Union
22

3-
from app.translator.core.custom_types.tokens import OperatorType, STR_SEARCH_OPERATORS
3+
from app.translator.core.custom_types.tokens import STR_SEARCH_OPERATORS, OperatorType
44
from app.translator.core.mapping import DEFAULT_MAPPING_NAME, SourceMapping
55
from app.translator.core.models.identifier import Identifier
66
from app.translator.core.str_value_manager import StrValue
77

88

9+
class Alias:
10+
def __init__(self, name: str):
11+
self.name = name
12+
13+
914
class Field:
1015
def __init__(self, source_name: str):
1116
self.source_name = source_name
@@ -33,8 +38,18 @@ def set_generic_names_map(self, source_mappings: list[SourceMapping], default_ma
3338

3439

3540
class FieldValue:
36-
def __init__(self, source_name: str, operator: Identifier, value: Union[int, str, StrValue, list, tuple]):
41+
def __init__(
42+
self,
43+
source_name: str,
44+
operator: Identifier,
45+
value: Union[int, str, StrValue, list, tuple],
46+
is_alias: bool = False,
47+
):
3748
self.field = Field(source_name=source_name)
49+
self.alias = None
50+
if is_alias:
51+
self.alias = Alias(name=source_name)
52+
3853
self.operator = operator
3954
self.values = []
4055
self.__add_value(value)
@@ -49,13 +64,21 @@ def __add_value(self, value: Optional[Union[int, str, StrValue, list, tuple]]) -
4964
if value and isinstance(value, (list, tuple)):
5065
for v in value:
5166
self.__add_value(v)
52-
elif value and isinstance(value, str) and value.isnumeric() and self.operator.token_type not in STR_SEARCH_OPERATORS:
67+
elif (
68+
value
69+
and isinstance(value, str)
70+
and value.isnumeric()
71+
and self.operator.token_type not in STR_SEARCH_OPERATORS
72+
):
5373
self.values.append(int(value))
5474
elif value is not None and isinstance(value, (int, str)):
5575
self.values.append(value)
5676

5777
def __repr__(self):
58-
return f"{self.field.source_name} {self.operator.token_type} {self.values}"
78+
if self.field:
79+
return f"{self.field.source_name} {self.operator.token_type} {self.values}"
80+
81+
return f"{self.alias.name} {self.operator.token_type} {self.values}"
5982

6083

6184
class Keyword:
Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
11
from __future__ import annotations
22

33
from dataclasses import dataclass, field
4-
from typing import Union
4+
from typing import Optional, Union
55

6-
from app.translator.core.models.field import Field, FieldValue, Keyword
6+
from app.translator.core.models.field import Alias, Field, FieldValue, Keyword
77
from app.translator.core.models.identifier import Identifier
88

99

1010
@dataclass
1111
class Function:
1212
name: str = None
13-
args: list[Union[Field, FieldValue, Keyword, Function, Identifier]] = field(default_factory=list)
14-
as_clause: str = None
15-
by_clauses: list[Field] = field(default_factory=list)
13+
args: list[Union[Alias, Field, FieldValue, Keyword, Function, Identifier, str, bool]] = field(default_factory=list)
14+
alias: Optional[Alias] = None
1615
raw: str = ""
1716

1817

@@ -21,9 +20,11 @@ class ParsedFunctions:
2120
functions: list[Function] = field(default_factory=list)
2221
not_supported: list[str] = field(default_factory=list)
2322
invalid: list[str] = field(default_factory=list)
23+
aliases: dict[str, Function] = field(default_factory=dict)
2424

2525

2626
@dataclass
2727
class RenderedFunctions:
28+
rendered_prefix: str = ""
2829
rendered: str = ""
2930
not_supported: list[str] = field(default_factory=list)
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
from dataclasses import dataclass
2+
from typing import Optional
3+
4+
from app.translator.core.custom_types.functions import FunctionType
5+
from app.translator.core.models.field import Field
6+
from app.translator.core.models.functions.base import Function
7+
from app.translator.tools.custom_enum import CustomEnum
8+
9+
10+
class SpanType(CustomEnum):
11+
days = "days"
12+
hours = "hours"
13+
minutes = "minutes"
14+
15+
16+
@dataclass
17+
class Span:
18+
value: str = "1"
19+
type_: str = SpanType.days
20+
21+
22+
@dataclass
23+
class BinFunction(Function):
24+
name: str = FunctionType.bin
25+
span: Optional[Span] = None
26+
field: Optional[Field] = None
27+
bins: Optional[int] = None

uncoder-core/app/translator/core/models/functions/eval.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@
22
from typing import Union
33

44
from app.translator.core.custom_types.functions import FunctionType
5-
from app.translator.core.models.field import Field
5+
from app.translator.core.models.field import Alias, Field
66
from app.translator.core.models.functions.base import Function
77
from app.translator.core.models.identifier import Identifier
88

99

1010
@dataclass
1111
class EvalArg:
12-
field_: Field = None
12+
field_: Union[Alias, Field] = None
1313
expression: list[Union[Field, Function, Identifier, int, float, str]] = field(default_factory=list)
1414

1515

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
from dataclasses import Field, dataclass, field
2+
from typing import Union
3+
4+
from app.translator.core.custom_types.functions import FunctionType
5+
from app.translator.core.models.field import Alias
6+
from app.translator.core.models.functions.base import Function
7+
8+
9+
@dataclass
10+
class GroupByFunction(Function):
11+
name: str = FunctionType.stats
12+
args: list[Function] = field(default_factory=list)
13+
by_clauses: list[Union[Alias, Field]] = field(default_factory=list)
14+
filter_: Function = None

uncoder-core/app/translator/core/models/functions/rename.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
from dataclasses import dataclass
22

33
from app.translator.core.custom_types.functions import FunctionType
4-
from app.translator.core.models.field import Field
4+
from app.translator.core.models.field import Alias, Field
55
from app.translator.core.models.functions.base import Function
66

77

88
@dataclass
99
class RenameArg:
1010
field_: Field = None
11-
alias: str = None
11+
alias: Alias = None
1212

1313

1414
@dataclass

0 commit comments

Comments
 (0)