Skip to content

Commit abfc3d6

Browse files
authored
Merge pull request #130 from UncoderIO/aql-xql-str-value-managers
aql, xql str value managers, func data classes
2 parents d970669 + 723b70c commit abfc3d6

Some content is hidden

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

43 files changed

+973
-259
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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy