Skip to content

sql str value manager #206

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Oct 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion uncoder-core/app/translator/core/str_value_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,11 @@ class StrValueManager:
container_spec_symbols_map: ClassVar[dict[type[BaseSpecSymbol], str]] = CONTAINER_SPEC_SYMBOLS_MAP

@staticmethod
def from_str_to_container(value: str) -> StrValue:
def from_str_to_container(
value: str,
value_type: str = ValueType.value, # noqa: ARG004
escape_symbol: Optional[str] = None, # noqa: ARG004
) -> StrValue:
return StrValue(value=value, split_value=[value])

def from_re_str_to_container(self, value: str) -> StrValue:
Expand Down
3 changes: 1 addition & 2 deletions uncoder-core/app/translator/core/tokenizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,8 +162,7 @@ def search_multi_value(

def _get_field_value_match(self, query: str, operator: str, field_name: str, value_pattern: str) -> re.Match:
field_value_pattern = self.get_field_value_pattern(operator, field_name, value_pattern)
field_value_regex = re.compile(field_value_pattern, re.IGNORECASE)
field_value_match = re.match(field_value_regex, query)
field_value_match = re.match(field_value_pattern, query, re.IGNORECASE)
if field_value_match is None:
raise TokenizerGeneralException(error=f"Value couldn't be found in query part: {query}")

Expand Down
50 changes: 11 additions & 39 deletions uncoder-core/app/translator/platforms/anomali/renders/anomali.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,65 +17,37 @@
-----------------------------------------------------------------
"""
from app.translator.const import DEFAULT_VALUE_TYPE
from app.translator.core.custom_types.values import ValueType
from app.translator.core.models.platform_details import PlatformDetails
from app.translator.core.render import BaseFieldValueRender, PlatformQueryRender
from app.translator.core.render import PlatformQueryRender
from app.translator.managers import render_manager
from app.translator.platforms.anomali.const import anomali_query_details
from app.translator.platforms.anomali.mapping import AnomaliMappings, anomali_query_mappings
from app.translator.platforms.base.sql.str_value_manager import sql_str_value_manager
from app.translator.platforms.base.sql.renders.sql import SqlFieldValueRender


class AnomaliFieldValueRender(BaseFieldValueRender):
class AnomaliFieldValueRender(SqlFieldValueRender):
details: PlatformDetails = anomali_query_details
str_value_manager = sql_str_value_manager

@staticmethod
def _wrap_str_value(value: str) -> str:
return f"'{value}'"

def equal_modifier(self, field: str, value: DEFAULT_VALUE_TYPE) -> str:
if isinstance(value, list):
return f"({self.or_token.join([self.equal_modifier(field=field, value=v) for v in value])})"
return f"{field} = {self._pre_process_value(field, value, wrap_str=True)}"

def not_equal_modifier(self, field: str, value: DEFAULT_VALUE_TYPE) -> str:
if isinstance(value, list):
return f"({self.or_token.join([self.not_equal_modifier(field=field, value=v) for v in value])})"
return f"{field} != {self._pre_process_value(field, value, wrap_str=True)}"

def less_modifier(self, field: str, value: DEFAULT_VALUE_TYPE) -> str:
return f"{field} < {self._pre_process_value(field, value, wrap_str=True)}"

def less_or_equal_modifier(self, field: str, value: DEFAULT_VALUE_TYPE) -> str:
return f"{field} <= {self._pre_process_value(field, value, wrap_str=True)}"

def greater_modifier(self, field: str, value: DEFAULT_VALUE_TYPE) -> str:
return f"{field} > {self._pre_process_value(field, value, wrap_str=True)}"

def greater_or_equal_modifier(self, field: str, value: DEFAULT_VALUE_TYPE) -> str:
return f"{field} >= {self._pre_process_value(field, value, wrap_str=True)}"

def contains_modifier(self, field: str, value: DEFAULT_VALUE_TYPE) -> str:
if isinstance(value, list):
return f"({self.or_token.join(self.contains_modifier(field=field, value=v) for v in value)})"
return f"{field} like '%{self._pre_process_value(field, value)}%'"

value = f"'%{self._pre_process_value(field, value)}%'"
return f"{field} like {value}"

def endswith_modifier(self, field: str, value: DEFAULT_VALUE_TYPE) -> str:
if isinstance(value, list):
return f"({self.or_token.join(self.endswith_modifier(field=field, value=v) for v in value)})"
return f"{field} like '%{self._pre_process_value(field, value)}'"

value = f"'%{self._pre_process_value(field, value)}'"
return f"{field} like {value}"

def startswith_modifier(self, field: str, value: DEFAULT_VALUE_TYPE) -> str:
if isinstance(value, list):
return f"({self.or_token.join(self.startswith_modifier(field=field, value=v) for v in value)})"
return f"{field} like '{self._pre_process_value(field, value)}%'"

def regex_modifier(self, field: str, value: DEFAULT_VALUE_TYPE) -> str:
if isinstance(value, list):
return f"({self.or_token.join(self.regex_modifier(field=field, value=v) for v in value)})"
regex_str = self._pre_process_value(field, value, value_type=ValueType.regex_value, wrap_str=True)
return f"regexp_like({field}, {regex_str})"
value = f"'{self._pre_process_value(field, value)}%'"
return f"{field} like {value}"

def keywords(self, field: str, value: DEFAULT_VALUE_TYPE) -> str:
return f'message contains "{self._pre_process_value(field, value)}"'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"""

import copy
from typing import ClassVar
from typing import ClassVar, Optional

from app.translator.core.custom_types.values import ValueType
from app.translator.core.str_value_manager import (
Expand Down Expand Up @@ -55,7 +55,12 @@ class AQLStrValueManager(StrValueManager):
"%": UnboundLenWildCard,
}

def from_str_to_container(self, value: str) -> StrValue:
def from_str_to_container(
self,
value: str,
value_type: str = ValueType.value, # noqa: ARG002
escape_symbol: Optional[str] = None, # noqa: ARG002
) -> StrValue:
split = []
prev_char = None
for char in value:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@
-----------------------------------------------------------------
"""

from typing import ClassVar
from typing import ClassVar, Optional

from app.translator.core.custom_types.values import ValueType
from app.translator.core.str_value_manager import (
BaseSpecSymbol,
ReAnySymbol,
Expand Down Expand Up @@ -68,7 +69,12 @@ class LuceneStrValueManager(StrValueManager):
}
re_str_spec_symbols_map = RE_STR_SPEC_SYMBOLS_MAP

def from_str_to_container(self, value: str) -> StrValue:
def from_str_to_container(
self,
value: str,
value_type: str = ValueType.value, # noqa: ARG002
escape_symbol: Optional[str] = None, # noqa: ARG002
) -> StrValue:
split = []
prev_char = None
for char in value:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,12 @@ def _wrap_str_value(value: str) -> str:
return f'"{value}"'

def _pre_process_value(
self, field: str, value: Union[int, str, StrValue], value_type: str = ValueType.value, wrap_str: bool = False
self,
field: str,
value: Union[bool, int, str, StrValue],
value_type: str = ValueType.value,
wrap_str: bool = False,
wrap_int: bool = False, # noqa: ARG002
) -> Union[int, str]:
value = super()._pre_process_value(field, value, value_type=value_type, wrap_str=wrap_str)
return self._wrap_str_value(str(value)) if not isinstance(value, str) else value
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@
limitations under the License.
-----------------------------------------------------------------
"""
from typing import ClassVar
from typing import ClassVar, Optional

from app.translator.core.custom_types.values import ValueType
from app.translator.core.str_value_manager import BaseSpecSymbol, StrValue, StrValueManager, UnboundLenWildCard
from app.translator.platforms.base.spl.escape_manager import spl_escape_manager

Expand All @@ -26,7 +27,12 @@ class SplStrValueManager(StrValueManager):
escape_manager = spl_escape_manager
str_spec_symbols_map: ClassVar[dict[str, type[BaseSpecSymbol]]] = {"*": UnboundLenWildCard}

def from_str_to_container(self, value: str) -> StrValue:
def from_str_to_container(
self,
value: str,
value_type: str = ValueType.value, # noqa: ARG002
escape_symbol: Optional[str] = None, # noqa: ARG002
) -> StrValue:
split = []
prev_char = None
for char in value:
Expand Down
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from app.translator.core.custom_types.values import ValueType


class SQLValueType(ValueType):
like_value = "like_value"
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
from typing import ClassVar

from app.translator.core.custom_types.values import ValueType
from app.translator.core.escape_manager import EscapeManager
from app.translator.core.models.escape_details import EscapeDetails
from app.translator.platforms.base.sql.custom_types.values import SQLValueType


class SQLEscapeManager(EscapeManager):
escape_map: ClassVar[dict[str, list[EscapeDetails]]] = {
ValueType.value: [EscapeDetails(pattern=r"(')", escape_symbols=r"'\1")],
ValueType.regex_value: [
SQLValueType.value: [EscapeDetails(pattern=r"(')", escape_symbols=r"'\1")],
SQLValueType.like_value: [EscapeDetails(pattern=r"(['%_\\])", escape_symbols=r"\\\1")],
SQLValueType.regex_value: [
EscapeDetails(pattern=r"([$^*+()\[\]{}|.?\-\\])", escape_symbols=r"\\\1"),
EscapeDetails(pattern=r"(')", escape_symbols=r"'\1"),
],
Expand Down
52 changes: 33 additions & 19 deletions uncoder-core/app/translator/platforms/base/sql/renders/sql.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,55 +17,69 @@
-----------------------------------------------------------------
"""

from typing import Union

from app.translator.const import DEFAULT_VALUE_TYPE
from app.translator.core.custom_types.values import ValueType
from app.translator.core.mapping import LogSourceSignature
from app.translator.core.render import BaseFieldValueRender, PlatformQueryRender
from app.translator.platforms.base.sql.custom_types.values import SQLValueType
from app.translator.platforms.base.sql.str_value_manager import sql_str_value_manager


class SqlFieldValueRender(BaseFieldValueRender):
str_value_manager = sql_str_value_manager

@staticmethod
def _wrap_str_value(value: str) -> str:
return f"'{value}'"

def equal_modifier(self, field: str, value: DEFAULT_VALUE_TYPE) -> str:
if isinstance(value, list):
return f"({self.or_token.join([self.equal_modifier(field=field, value=v) for v in value])})"
return f"{field} = '{value}'"
return f"{field} = {self._pre_process_value(field, value, wrap_str=True)}"

def less_modifier(self, field: str, value: Union[int, str]) -> str:
return f"{field} < '{value}'"
def not_equal_modifier(self, field: str, value: DEFAULT_VALUE_TYPE) -> str:
if isinstance(value, list):
return f"({self.or_token.join([self.not_equal_modifier(field=field, value=v) for v in value])})"
return f"{field} != {self._pre_process_value(field, value, wrap_str=True)}"

def less_or_equal_modifier(self, field: str, value: Union[int, str]) -> str:
return f"{field} <= '{value}'"
def less_modifier(self, field: str, value: DEFAULT_VALUE_TYPE) -> str:
return f"{field} < {self._pre_process_value(field, value, wrap_str=True)}"

def greater_modifier(self, field: str, value: Union[int, str]) -> str:
return f"{field} > '{value}'"
def less_or_equal_modifier(self, field: str, value: DEFAULT_VALUE_TYPE) -> str:
return f"{field} <= {self._pre_process_value(field, value, wrap_str=True)}"

def greater_or_equal_modifier(self, field: str, value: Union[int, str]) -> str:
return f"{field} >= '{value}'"
def greater_modifier(self, field: str, value: DEFAULT_VALUE_TYPE) -> str:
return f"{field} > {self._pre_process_value(field, value, wrap_str=True)}"

def not_equal_modifier(self, field: str, value: DEFAULT_VALUE_TYPE) -> str:
if isinstance(value, list):
return f"({self.or_token.join([self.not_equal_modifier(field=field, value=v) for v in value])})"
return f"{field} != '{value}'"
def greater_or_equal_modifier(self, field: str, value: DEFAULT_VALUE_TYPE) -> str:
return f"{field} >= {self._pre_process_value(field, value, wrap_str=True)}"

def contains_modifier(self, field: str, value: DEFAULT_VALUE_TYPE) -> str:
if isinstance(value, list):
return f"({self.or_token.join(self.contains_modifier(field=field, value=v) for v in value)})"
return f"{field} ILIKE '%{value}%' ESCAPE '\\'"

value = f"'%{self._pre_process_value(field, value, value_type=SQLValueType.like_value)}%' escape '\\'"
return f"{field} like {value}"

def endswith_modifier(self, field: str, value: DEFAULT_VALUE_TYPE) -> str:
if isinstance(value, list):
return f"({self.or_token.join(self.endswith_modifier(field=field, value=v) for v in value)})"
return f"{field} ILIKE '%{value}' ESCAPE '\\'"

value = f"'%{self._pre_process_value(field, value, value_type=SQLValueType.like_value)}' escape '\\'"
return f"{field} like {value}"

def startswith_modifier(self, field: str, value: DEFAULT_VALUE_TYPE) -> str:
if isinstance(value, list):
return f"({self.or_token.join(self.startswith_modifier(field=field, value=v) for v in value)})"
return f"{field} ILIKE '{value}%' ESCAPE '\\'"

value = f"'{self._pre_process_value(field, value, value_type=SQLValueType.like_value)}%' escape '\\'"
return f"{field} like {value}"

def regex_modifier(self, field: str, value: DEFAULT_VALUE_TYPE) -> str:
if isinstance(value, list):
return f"({self.or_token.join(self.regex_modifier(field=field, value=v) for v in value)})"
return f"{field} ILIKE '{value}' ESCAPE '\\'"
regex_str = self._pre_process_value(field, value, value_type=ValueType.regex_value, wrap_str=True)
return f"regexp_like({field}, {regex_str})"


class SqlQueryRender(PlatformQueryRender):
Expand Down
36 changes: 24 additions & 12 deletions uncoder-core/app/translator/platforms/base/sql/str_value_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,8 @@
"""

import copy
from typing import ClassVar
from typing import ClassVar, Optional

from app.translator.core.custom_types.values import ValueType
from app.translator.core.str_value_manager import (
CONTAINER_SPEC_SYMBOLS_MAP,
RE_STR_SPEC_SYMBOLS_MAP,
Expand All @@ -34,6 +33,7 @@
StrValueManager,
UnboundLenWildCard,
)
from app.translator.platforms.base.sql.custom_types.values import SQLValueType
from app.translator.platforms.base.sql.escape_manager import sql_escape_manager

SQL_CONTAINER_SPEC_SYMBOLS_MAP = copy.copy(CONTAINER_SPEC_SYMBOLS_MAP)
Expand All @@ -55,18 +55,30 @@ class SQLStrValueManager(StrValueManager):
"%": UnboundLenWildCard,
}

def from_str_to_container(self, value: str) -> StrValue:
def from_str_to_container(
self, value: str, value_type: str = SQLValueType.value, escape_symbol: Optional[str] = None
) -> StrValue:
split = []
prev_char = None
for char in value:
if char in self.str_spec_symbols_map:
split.append(self.str_spec_symbols_map[char]())
else:
if char == "'":
if prev_char == "'":
split.append(char)
prev_char = char
if escape_symbol and char == escape_symbol:
if prev_char == escape_symbol:
split.append(char)
prev_char = None
continue
prev_char = char
continue
if not escape_symbol and char == "'":
if prev_char == "'":
split.append(char)
prev_char = None
continue
elif char in ("'", "_", "%") and value_type == SQLValueType.like_value:
if escape_symbol and prev_char == escape_symbol:
split.append(char)
elif char in self.str_spec_symbols_map:
split.append(self.str_spec_symbols_map[char]())
else:
split.append(char)

prev_char = char
Expand All @@ -77,13 +89,13 @@ def from_re_str_to_container(self, value: str) -> StrValue:
value = value.replace("''", "'")
return super().from_re_str_to_container(value)

def from_container_to_str(self, container: StrValue, value_type: str = ValueType.value) -> str:
def from_container_to_str(self, container: StrValue, value_type: str = SQLValueType.value) -> str:
result = ""
for el in container.split_value:
if isinstance(el, str):
result += self.escape_manager.escape(el, value_type)
elif isinstance(el, BaseSpecSymbol):
if value_type == ValueType.regex_value:
if value_type == SQLValueType.regex_value:
if isinstance(el, SingleSymbolWildCard):
result += "."
continue
Expand Down
Loading
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