8000 refactor: update parse functions, add unit tests (#533) · FirePing32/python-spanner-django@bbd7c2c · GitHub
[go: up one dir, main page]

Skip to content

Commit bbd7c2c

Browse files
author
Ilya Gurov
authored
refactor: update parse functions, add unit tests (googleapis#533)
1 parent 392a4aa commit bbd7c2c

File tree

2 files changed

+183
-235
lines changed

2 files changed

+183
-235
lines changed

google/cloud/spanner_dbapi/parse_utils.py

Lines changed: 145 additions & 125 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,117 @@
1919
from .types import DateStr, TimestampStr
2020
from .utils import sanitize_literals_for_upload
2121

22+
TYPES_MAP = {
23+
bool: spanner.param_types.BOOL,
24+
bytes: spanner.param_types.BYTES,
25+
str: spanner.param_types.STRING,
26+
int: spanner.param_types.INT64,
27+
float: spanner.param_types.FLOAT64,
28+
datetime.datetime: spanner.param_types.TIMESTAMP,
29+
datetime.date: spanner.param_types.DATE,
30+
DateStr: spanner.param_types.DATE,
31+
TimestampStr: spanner.param_types.TIMESTAMP,
32+
}
33+
34+
SPANNER_RESERVED_KEYWORDS = {
35+
"ALL",
36+
"AND",
37+
"ANY",
38+
"ARRAY",
39+
"AS",
40+
"ASC",
41+
"ASSERT_ROWS_MODIFIED",
42+
"AT",
43+
"BETWEEN",
44+
"BY",
45+
"CASE",
46+
"CAST",
47+
"COLLATE",
48+
"CONTAINS",
49+
"CREATE",
50+
"CROSS",
51+
"CUBE",
52+
"CURRENT",
53+
"DEFAULT",
54+
"DEFINE",
55+
"DESC",
56+
"DISTINCT",
57+
"DROP",
58+
"ELSE",
59+
"END",
60+
"ENUM",
61+
"ESCAPE",
62+
"EXCEPT",
63+
"EXCLUDE",
64+
"EXISTS",
65+
"EXTRACT",
66+
"FALSE",
67+
"FETCH",
68+
"FOLLOWING",
69+
"FOR",
70+
"FROM",
71+
"FULL",
72+
"GROUP",
73+
"GROUPING",
74+
"GROUPS",
75+
"HASH",
76+
"HAVING",
77+
"IF",
78+
"IGNORE",
79+
"IN",
80+
"INNER",
81+
"INTERSECT",
82+
"INTERVAL",
83+
"INTO",
84+
"IS",
85+
"JOIN",
86+
"LATERAL",
87+
"LEFT",
88+
"LIKE",
89+
"LIMIT",
90+
"LOOKUP",
91+
"MERGE",
92+
"NATURAL",
93+
"NEW",
94+
"NO",
95+
"NOT",
96+
"NULL",
97+
"NULLS",
98+
"OF",
99+
"ON",
100+
"OR",
101+
"ORDER",
102+
"OUTER",
103+
"OVER",
104+
"PARTITION",
105+
"PRECEDING",
106+
"PROTO",
107+
"RANGE",
108+
"RECURSIVE",
109+
"RESPECT",
110+
"RIGHT",
111+
"ROLLUP",
112+
"ROWS",
113+
"SELECT",
114+
"SET",
115+
"SOME",
116+
"STRUCT",
117+
"TABLESAMPLE",
118+
"THEN",
119+
"TO",
120+
"TREAT",
121+
"TRUE",
122+
"UNBOUNDED",
123+
"UNION",
124+
"UNNEST",
125+
"USING",
126+
"WHEN",
127+
"WHERE",
128+
"WINDOW",
129+
"WITH",
130+
"WITHIN",
131+
}
132+
22133
STMT_DDL = "DDL"
23134
STMT_NON_UPDATING = "NON_UPDATING"
24135
STMT_UPDATING = "UPDATING"
@@ -359,36 +470,39 @@ def sql_pyformat_args_to_spanner(sql, params):
359470
return sanitize_literals_for_upload(sql), named_args
360471

361472

362-
def cast_for_spanner(param):
363-
"""Convert param to its Cloud Spanner equivalent type."""
364-
if isinstance(param, decimal.Decimal):
365-
return float(param)
366-
else:
367-
return param
473+
def cast_for_spanner(value):
474+
"""Convert the param to its Cloud Spanner equivalent type.
368475
476+
:type value: Any
477+
:param value: Value to convert to a Cloud Spanner type.
369478
370-
def get_param_types(params):
479+
:rtype: Any
480+
:returns: Value converted to a Cloud Spanner type.
371481
"""
372-
Return a dictionary of spanner.param_types for a dictionary of parameters.
482+
if isinstance(value, decimal.Decimal):
483+
return float(value)
484+
return value
485+
486+
487+
def get_param_types(params):
488+
"""Determine Cloud Spanner types for the given parameters.
489+
490+
:type params: :class:`dict`
491+
:param params: Parameters requiring to find Cloud Spanner types.
492+
493+
:rtype: :class:`dict`
494+
:returns: The types index for the given parameters.
373495
"""
374496
if params is None:
375-
return None
497+
return
498+
376499
param_types = {}
500+
377501
for key, value in params.items():
378-
if isinstance(value, bool):
379-
param_types[key] = spanner.param_types.BOOL
380-
elif isinstance(value, float):
381-
param_types[key] = spanner.param_types.FLOAT64
382-
elif isinstance(value, int):
383-
param_types[key] = spanner.param_types.INT64
384-
elif isinstance(value, (TimestampStr, datetime.datetime)):
385-
param_types[key] = spanner.param_types.TIMESTAMP
386-
elif isinstance(value, (DateStr, datetime.date)):
387-
param_types[key] = spanner.param_types.DATE
388-
elif isinstance(value, str):
389-
param_types[key] = spanner.param_types.STRING
390-
elif isinstance(value, bytes):
391-
param_types[key] = spanner.param_types.BYTES
502+
type_ = type(value)
503+
if type_ in TYPES_MAP:
504+
param_types[key] = TYPES_MAP[type_]
505+
392506
return param_types
393507

394508

@@ -405,110 +519,16 @@ def ensure_where_clause(sql):
405519
return sql + " WHERE 1=1"
406520

407521

408-
SPANNER_RESERVED_KEYWORDS = {
409-
"ALL",
410-
"AND",
411-
"ANY",
412-
"ARRAY",
413-
"AS",
414-
"ASC",
415-
"ASSERT_ROWS_MODIFIED",
416-
"AT",
417-
"BETWEEN",
418-
"BY",
419-
"CASE",
420-
"CAST",
421-
"COLLATE",
422-
"CONTAINS",
423-
"CREATE",
424-
"CROSS",
425-
"CUBE",
426-
"CURRENT",
427-
"DEFAULT",
428-
"DEFINE",
429-
"DESC",
430-
"DISTINCT",
431-
"DROP",
432-
"ELSE",
433-
"END",
434-
"ENUM",
435-
"ESCAPE",
436-
"EXCEPT",
437-
"EXCLUDE",
438-
"EXISTS",
439-
"EXTRACT",
440-
"FALSE",
441-
"FETCH",
442-
"FOLLOWING",
443-
"FOR",
444-
"FROM",
445-
"FULL",
446-
"GROUP",
447-
"GROUPING",
448-
"GROUPS",
449-
"HASH",
450-
"HAVING",
451-
"IF",
452-
"IGNORE",
453-
"IN",
454-
"INNER",
455-
"INTERSECT",
456-
"INTERVAL",
457-
"INTO",
458-
"IS",
459-
"JOIN",
460-
"LATERAL",
461-
"LEFT",
462-
"LIKE",
463-
"LIMIT",
464-
"LOOKUP",
465-
"MERGE",
466-
"NATURAL",
467-
"NEW",
468-
"NO",
469-
"NOT",
470-
"NULL",
471-
"NULLS",
472-
"OF",
473-
"ON",
474-
"OR",
475-
"ORDER",
476-
"OUTER",
477-
"OVER",
478-
"PARTITION",
479-
"PRECEDING",
480-
"PROTO",
481-
"RANGE",
482-
"RECURSIVE",
483-
"RESPECT",
484-
"RIGHT",
485-
"ROLLUP",
486-
"ROWS",
487-
"SELECT",
488-
"SET",
489-
"SOME",
490-
"STRUCT",
491-
"TABLESAMPLE",
492-
"THEN",
493-
"TO",
494-
"TREAT",
495-
"TRUE",
496-
"UNBOUNDED",
497-
"UNION",
498-
"UNNEST",
499-
"USING",
500-
"WHEN",
501-
"WHERE",
502-
"WINDOW",
503-
"WITH",
504-
"WITHIN",
505-
}
506-
507-
508522
def escape_name(name):
509523
"""
510-
Escape name by applying backticks to value that either
511-
contain '-' or are any of Cloud Spanner's reserved keywords.
524+
Apply backticks to the name that either contain '-' or
525+
' ', or is a Cloud Spanner' 682D s reserved keyword.
526+
527+
:type name: :class:`str`
528+
:param name: Name to escape.
529+
530+
:rtype: :class:`str`
531+
:returns: Name escaped if it has to be escaped.
512532
"""
513533
if "-" in name or " " in name or name.upper() in SPANNER_RESERVED_KEYWORDS:
514534
return "`" + name + "`"

0 commit comments

Comments
 (0)
0