Path: blob/main/singlestoredb/utils/mogrify.py
801 views
#!/usr/bin/env python31from collections.abc import Sequence2from typing import Any3from typing import Dict4from typing import Optional5from typing import Union67from ..mysql import converters8from ..mysql.constants import SERVER_STATUS91011Encoders = converters.Encoders121314def escape(15obj: Any,16charset: str = 'utf8',17mapping: Optional[Encoders] = None,18server_status: int = 0,19binary_prefix: bool = False,20) -> str:21"""22Escape whatever value is passed.2324Non-standard, for internal use; do not use this in your applications.2526"""27dtype = type(obj)28if dtype is str or isinstance(obj, str):29return "'{}'".format(escape_string(obj, server_status=server_status))30if dtype is bytes or dtype is bytearray or isinstance(obj, (bytes, bytearray)):31return _quote_bytes(32obj,33server_status=server_status,34binary_prefix=binary_prefix,35)36if mapping is None:37mapping = converters.encoders38return converters.escape_item(obj, charset, mapping=mapping)394041def literal(42obj: Any,43charset: str = 'utf8',44encoders: Optional[Encoders] = None,45server_status: int = 0,46binary_prefix: bool = False,47) -> str:48"""49Alias for escape().5051Non-standard, for internal use; do not use this in your applications.5253"""54return escape(55obj, charset=charset, mapping=encoders,56server_status=server_status, binary_prefix=binary_prefix,57)585960def escape_string(61s: str,62server_status: int = 0,63) -> str:64"""Escape a string value."""65if server_status & SERVER_STATUS.SERVER_STATUS_NO_BACKSLASH_ESCAPES:66return s.replace("'", "''")67return converters.escape_string(s)686970def _quote_bytes(71s: bytes,72server_status: int = 0,73binary_prefix: bool = False,74) -> str:75if server_status & SERVER_STATUS.SERVER_STATUS_NO_BACKSLASH_ESCAPES:76if binary_prefix:77return "_binary X'{}'".format(s.hex())78return "X'{}'".format(s.hex())79return converters.escape_bytes(s)808182def _escape_args(83args: Union[Sequence[Any], Dict[str, Any], None],84charset: str = 'utf8',85encoders: Optional[Encoders] = None,86server_status: int = 0,87binary_prefix: bool = False,88) -> Any:89if encoders is None:90encoders = converters.encoders9192if isinstance(args, (tuple, list)):93return tuple(94literal(95arg, charset=charset, encoders=encoders,96server_status=server_status,97binary_prefix=binary_prefix,98) for arg in args99)100101elif isinstance(args, dict):102return {103key: literal(104val, charset=charset, encoders=encoders,105server_status=server_status,106binary_prefix=binary_prefix,107) for (key, val) in args.items()108}109110# If it's not a dictionary let's try escaping it anyways.111# Worst case it will throw a Value error112return escape(113args, charset=charset, mapping=encoders,114server_status=server_status, binary_prefix=binary_prefix,115)116117118def mogrify(119query: Union[str, bytes],120args: Union[Sequence[Any], Dict[str, Any], None] = None,121charset: str = 'utf8',122encoders: Optional[Encoders] = None,123server_status: int = 0,124binary_prefix: bool = False,125interpolate_query_with_empty_args: bool = False,126) -> Union[str, bytes]:127"""128Returns the exact string sent to the database by calling the execute() method.129130This method follows the extension to the DB API 2.0 followed by Psycopg.131132Parameters133----------134query : str135Query to mogrify.136args : Sequence[Any] or Dict[str, Any] or Any, optional137Parameters used with query. (optional)138interpolate_query_with_empty_args : bool, optional139If True, apply string interpolation even when args is an empty tuple/list.140If False, only apply when args is truthy. Defaults to False.141142Returns143-------144str : The query with argument binding applied.145146"""147if should_interpolate_query(interpolate_query_with_empty_args, args):148query = query % _escape_args(149args, charset=charset,150encoders=encoders,151server_status=server_status,152binary_prefix=binary_prefix,153)154return query155156157def should_interpolate_query(158interpolate_query_with_empty_args: bool,159args: Union[Sequence[Any], Dict[str, Any], None],160) -> bool:161if interpolate_query_with_empty_args:162return args is not None163return bool(args)164165166