95 lines
2.2 KiB
Python
95 lines
2.2 KiB
Python
from datetime import date, datetime, time
|
|
from enum import Enum
|
|
from functools import wraps
|
|
from uuid import UUID
|
|
|
|
from pytz import timezone
|
|
|
|
|
|
escape_chars_map = {
|
|
"\b": "\\b",
|
|
"\f": "\\f",
|
|
"\r": "\\r",
|
|
"\n": "\\n",
|
|
"\t": "\\t",
|
|
"\0": "\\0",
|
|
"\a": "\\a",
|
|
"\v": "\\v",
|
|
"\\": "\\\\",
|
|
"'": "\\'"
|
|
}
|
|
|
|
|
|
def escape_datetime(item, context):
|
|
server_tz = timezone(context.server_info.get_timezone())
|
|
|
|
if item.tzinfo is not None:
|
|
item = item.astimezone(server_tz)
|
|
|
|
return "'%s'" % item.strftime('%Y-%m-%d %H:%M:%S')
|
|
|
|
|
|
def maybe_enquote_for_server(f):
|
|
@wraps(f)
|
|
def wrapper(*args, **kwargs):
|
|
rv = f(*args, **kwargs)
|
|
|
|
if kwargs.get('for_server'):
|
|
is_str = isinstance(rv, str)
|
|
|
|
if not is_str or (is_str and not rv.startswith("'")):
|
|
rv = "'%s'" % rv
|
|
|
|
return rv
|
|
|
|
return wrapper
|
|
|
|
|
|
@maybe_enquote_for_server
|
|
def escape_param(item, context, for_server=False):
|
|
if item is None:
|
|
return 'NULL'
|
|
|
|
elif isinstance(item, datetime):
|
|
return escape_datetime(item, context)
|
|
|
|
elif isinstance(item, date):
|
|
return "'%s'" % item.strftime('%Y-%m-%d')
|
|
|
|
elif isinstance(item, time):
|
|
return "'%s'" % item.strftime('%H:%M:%S')
|
|
|
|
elif isinstance(item, str):
|
|
# We need double escaping for server-side parameters.
|
|
if for_server:
|
|
item = ''.join(escape_chars_map.get(c, c) for c in item)
|
|
return "'%s'" % ''.join(escape_chars_map.get(c, c) for c in item)
|
|
|
|
elif isinstance(item, list):
|
|
return "[%s]" % ', '.join(
|
|
str(escape_param(x, context, for_server=for_server)) for x in item
|
|
)
|
|
|
|
elif isinstance(item, tuple):
|
|
return "(%s)" % ', '.join(
|
|
str(escape_param(x, context, for_server=for_server)) for x in item
|
|
)
|
|
|
|
elif isinstance(item, Enum):
|
|
return escape_param(item.value, context, for_server=for_server)
|
|
|
|
elif isinstance(item, UUID):
|
|
return "'%s'" % str(item)
|
|
|
|
else:
|
|
return item
|
|
|
|
|
|
def escape_params(params, context, for_server=False):
|
|
escaped = {}
|
|
|
|
for key, value in params.items():
|
|
escaped[key] = escape_param(value, context, for_server=for_server)
|
|
|
|
return escaped
|