sqlobject 3.13.1__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- sqlobject/__init__.py +15 -0
- sqlobject/__version__.py +8 -0
- sqlobject/boundattributes.py +124 -0
- sqlobject/cache.py +376 -0
- sqlobject/classregistry.py +138 -0
- sqlobject/col.py +2187 -0
- sqlobject/compat.py +59 -0
- sqlobject/conftest.py +64 -0
- sqlobject/constraints.py +77 -0
- sqlobject/converters.py +278 -0
- sqlobject/dbconnection.py +1137 -0
- sqlobject/dberrors.py +54 -0
- sqlobject/declarative.py +211 -0
- sqlobject/events.py +365 -0
- sqlobject/firebird/__init__.py +8 -0
- sqlobject/firebird/firebirdconnection.py +463 -0
- sqlobject/include/__init__.py +1 -0
- sqlobject/include/hashcol.py +109 -0
- sqlobject/include/tests/__init__.py +1 -0
- sqlobject/include/tests/test_hashcol.py +84 -0
- sqlobject/index.py +189 -0
- sqlobject/inheritance/__init__.py +551 -0
- sqlobject/inheritance/iteration.py +106 -0
- sqlobject/inheritance/tests/__init__.py +1 -0
- sqlobject/inheritance/tests/test_aggregates.py +23 -0
- sqlobject/inheritance/tests/test_asdict.py +48 -0
- sqlobject/inheritance/tests/test_deep_inheritance.py +114 -0
- sqlobject/inheritance/tests/test_destroy_cascade.py +23 -0
- sqlobject/inheritance/tests/test_foreignKey.py +94 -0
- sqlobject/inheritance/tests/test_indexes.py +42 -0
- sqlobject/inheritance/tests/test_inheritance.py +164 -0
- sqlobject/inheritance/tests/test_inheritance_tree.py +50 -0
- sqlobject/joins.py +656 -0
- sqlobject/main.py +1880 -0
- sqlobject/manager/__init__.py +1 -0
- sqlobject/manager/command.py +1309 -0
- sqlobject/maxdb/__init__.py +8 -0
- sqlobject/maxdb/maxdbconnection.py +320 -0
- sqlobject/maxdb/readme.txt +27 -0
- sqlobject/mssql/__init__.py +8 -0
- sqlobject/mssql/mssqlconnection.py +417 -0
- sqlobject/mysql/__init__.py +8 -0
- sqlobject/mysql/mysqlconnection.py +562 -0
- sqlobject/postgres/__init__.py +8 -0
- sqlobject/postgres/pgconnection.py +619 -0
- sqlobject/sqlbuilder.py +1655 -0
- sqlobject/sqlite/__init__.py +8 -0
- sqlobject/sqlite/sqliteconnection.py +418 -0
- sqlobject/sresults.py +377 -0
- sqlobject/styles.py +174 -0
- sqlobject/sybase/__init__.py +8 -0
- sqlobject/sybase/sybaseconnection.py +183 -0
- sqlobject/tests/__init__.py +1 -0
- sqlobject/tests/dbtest.py +363 -0
- sqlobject/tests/test_ForeignKey.py +133 -0
- sqlobject/tests/test_ForeignKey_cascade.py +150 -0
- sqlobject/tests/test_NoneValuedResultItem.py +33 -0
- sqlobject/tests/test_SQLMultipleJoin.py +65 -0
- sqlobject/tests/test_SQLRelatedJoin.py +114 -0
- sqlobject/tests/test_SingleJoin.py +30 -0
- sqlobject/tests/test_aggregates.py +75 -0
- sqlobject/tests/test_aliases.py +49 -0
- sqlobject/tests/test_asdict.py +18 -0
- sqlobject/tests/test_auto.py +218 -0
- sqlobject/tests/test_basic.py +359 -0
- sqlobject/tests/test_blob.py +34 -0
- sqlobject/tests/test_boundattributes.py +67 -0
- sqlobject/tests/test_cache.py +57 -0
- sqlobject/tests/test_class_hash.py +22 -0
- sqlobject/tests/test_columns_order.py +18 -0
- sqlobject/tests/test_combining_joins.py +47 -0
- sqlobject/tests/test_comparison.py +24 -0
- sqlobject/tests/test_compat.py +10 -0
- sqlobject/tests/test_complex_sorting.py +77 -0
- sqlobject/tests/test_constraints.py +43 -0
- sqlobject/tests/test_converters.py +276 -0
- sqlobject/tests/test_create_drop.py +29 -0
- sqlobject/tests/test_csvexport.py +101 -0
- sqlobject/tests/test_csvimport.py +21 -0
- sqlobject/tests/test_cyclic_reference.py +55 -0
- sqlobject/tests/test_datetime.py +171 -0
- sqlobject/tests/test_dbconnection.py +17 -0
- sqlobject/tests/test_decimal.py +63 -0
- sqlobject/tests/test_declarative.py +83 -0
- sqlobject/tests/test_default_style.py +65 -0
- sqlobject/tests/test_delete.py +74 -0
- sqlobject/tests/test_distinct.py +36 -0
- sqlobject/tests/test_empty.py +22 -0
- sqlobject/tests/test_enum.py +75 -0
- sqlobject/tests/test_events.py +142 -0
- sqlobject/tests/test_exceptions.py +40 -0
- sqlobject/tests/test_expire.py +29 -0
- sqlobject/tests/test_groupBy.py +45 -0
- sqlobject/tests/test_identity.py +29 -0
- sqlobject/tests/test_indexes.py +100 -0
- sqlobject/tests/test_inheritance.py +35 -0
- sqlobject/tests/test_joins.py +160 -0
- sqlobject/tests/test_joins_conditional.py +143 -0
- sqlobject/tests/test_jsonbcol.py +53 -0
- sqlobject/tests/test_jsoncol.py +56 -0
- sqlobject/tests/test_lazy.py +165 -0
- sqlobject/tests/test_md5.py +13 -0
- sqlobject/tests/test_mysql.py +50 -0
- sqlobject/tests/test_new_joins.py +165 -0
- sqlobject/tests/test_parse_uri.py +147 -0
- sqlobject/tests/test_paste.py +92 -0
- sqlobject/tests/test_perConnection.py +20 -0
- sqlobject/tests/test_pickle.py +42 -0
- sqlobject/tests/test_picklecol.py +44 -0
- sqlobject/tests/test_postgres.py +82 -0
- sqlobject/tests/test_reparent_sqlmeta.py +33 -0
- sqlobject/tests/test_schema.py +30 -0
- sqlobject/tests/test_select.py +218 -0
- sqlobject/tests/test_select_through.py +63 -0
- sqlobject/tests/test_setters.py +23 -0
- sqlobject/tests/test_slice.py +59 -0
- sqlobject/tests/test_sorting.py +80 -0
- sqlobject/tests/test_sqlbuilder.py +134 -0
- sqlobject/tests/test_sqlbuilder_dbspecific.py +66 -0
- sqlobject/tests/test_sqlbuilder_importproxy.py +55 -0
- sqlobject/tests/test_sqlbuilder_joins_instances.py +90 -0
- sqlobject/tests/test_sqlite.py +160 -0
- sqlobject/tests/test_sqlmeta_idName.py +52 -0
- sqlobject/tests/test_sqlobject_admin.py +38 -0
- sqlobject/tests/test_string_id.py +79 -0
- sqlobject/tests/test_style.py +36 -0
- sqlobject/tests/test_subqueries.py +142 -0
- sqlobject/tests/test_transactions.py +122 -0
- sqlobject/tests/test_unicode.py +84 -0
- sqlobject/tests/test_uuidcol.py +40 -0
- sqlobject/tests/test_validation.py +125 -0
- sqlobject/tests/test_views.py +159 -0
- sqlobject/util/__init__.py +1 -0
- sqlobject/util/csvexport.py +210 -0
- sqlobject/util/csvimport.py +366 -0
- sqlobject/util/moduleloader.py +35 -0
- sqlobject/util/threadinglocal.py +6 -0
- sqlobject/versioning/__init__.py +120 -0
- sqlobject/versioning/test/__init__.py +0 -0
- sqlobject/versioning/test/test_version.py +183 -0
- sqlobject/views.py +151 -0
- sqlobject/wsgi_middleware.py +109 -0
- sqlobject-3.13.1.data/scripts/sqlobject-admin +36 -0
- sqlobject-3.13.1.data/scripts/sqlobject-convertOldURI +19 -0
- sqlobject-3.13.1.dist-info/METADATA +177 -0
- sqlobject-3.13.1.dist-info/RECORD +149 -0
- sqlobject-3.13.1.dist-info/WHEEL +6 -0
- sqlobject-3.13.1.dist-info/entry_points.txt +4 -0
- sqlobject-3.13.1.dist-info/top_level.txt +1 -0
sqlobject/compat.py
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import sys
|
|
3
|
+
import types
|
|
4
|
+
|
|
5
|
+
# Credit to six authors: https://pypi.org/project/six/
|
|
6
|
+
# License: MIT
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def with_metaclass(meta, *bases):
|
|
10
|
+
"""Create a base class with a metaclass."""
|
|
11
|
+
# This requires a bit of explanation: the basic idea is to make a dummy
|
|
12
|
+
# metaclass for one level of class instantiation that replaces itself with
|
|
13
|
+
# the actual metaclass.
|
|
14
|
+
|
|
15
|
+
class metaclass(meta):
|
|
16
|
+
def __new__(cls, name, this_bases, d):
|
|
17
|
+
return meta(name, bases, d)
|
|
18
|
+
return type.__new__(metaclass, 'temporary_class', (), {})
|
|
19
|
+
|
|
20
|
+
# Compatability definitions (inspired by six)
|
|
21
|
+
PY2 = sys.version_info[0] < 3
|
|
22
|
+
if PY2:
|
|
23
|
+
# disable flake8 checks on python 3
|
|
24
|
+
string_type = basestring # noqa
|
|
25
|
+
unicode_type = unicode # noqa
|
|
26
|
+
class_types = (type, types.ClassType)
|
|
27
|
+
buffer_type = buffer # noqa
|
|
28
|
+
else:
|
|
29
|
+
string_type = str
|
|
30
|
+
unicode_type = str
|
|
31
|
+
class_types = (type,)
|
|
32
|
+
buffer_type = memoryview
|
|
33
|
+
|
|
34
|
+
if PY2:
|
|
35
|
+
import imp
|
|
36
|
+
|
|
37
|
+
def load_module_from_file(base_name, module_name, filename):
|
|
38
|
+
fp, pathname, description = imp.find_module(
|
|
39
|
+
base_name, [os.path.dirname(filename)])
|
|
40
|
+
try:
|
|
41
|
+
module = imp.load_module(module_name, fp, pathname, description)
|
|
42
|
+
finally:
|
|
43
|
+
fp.close()
|
|
44
|
+
return module
|
|
45
|
+
else:
|
|
46
|
+
import importlib.util
|
|
47
|
+
|
|
48
|
+
def load_module_from_file(base_name, module_name, filename):
|
|
49
|
+
specs = importlib.util.spec_from_file_location(module_name, filename)
|
|
50
|
+
loader = specs.loader
|
|
51
|
+
if hasattr(loader, 'create_module'):
|
|
52
|
+
module = loader.create_module(specs)
|
|
53
|
+
else:
|
|
54
|
+
module = None
|
|
55
|
+
if module is None:
|
|
56
|
+
return specs.loader.load_module()
|
|
57
|
+
else:
|
|
58
|
+
loader.exec_module(module)
|
|
59
|
+
return module
|
sqlobject/conftest.py
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"""This module is used by pytest to configure testing"""
|
|
2
|
+
|
|
3
|
+
try:
|
|
4
|
+
import pkg_resources
|
|
5
|
+
except ImportError:
|
|
6
|
+
pass
|
|
7
|
+
else:
|
|
8
|
+
pkg_resources.require('SQLObject')
|
|
9
|
+
|
|
10
|
+
# Override some options (doesn't override command line):
|
|
11
|
+
verbose = 0
|
|
12
|
+
exitfirst = True
|
|
13
|
+
|
|
14
|
+
connectionShortcuts = {
|
|
15
|
+
'mysql': 'mysql://test@localhost/test',
|
|
16
|
+
'dbm': 'dbm:///data',
|
|
17
|
+
'postgres': 'postgres:///test',
|
|
18
|
+
'postgresql': 'postgres:///test',
|
|
19
|
+
'pygresql': 'pygresql://localhost/test',
|
|
20
|
+
'sqlite': 'sqlite:/:memory:',
|
|
21
|
+
'sybase': 'sybase://test:test123@sybase/test?autoCommit=0',
|
|
22
|
+
'firebird':
|
|
23
|
+
'firebird://sysdba:masterkey@localhost/var/lib/firebird/data/test.gdb',
|
|
24
|
+
'mssql': 'mssql://sa:@127.0.0.1/test'
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def pytest_addoption(parser):
|
|
29
|
+
"""Add the SQLObject options"""
|
|
30
|
+
parser.addoption(
|
|
31
|
+
'-D', '--Database',
|
|
32
|
+
action="store", dest="Database", default='sqlite',
|
|
33
|
+
help="The database to run the tests under (default sqlite). "
|
|
34
|
+
"Can also use an alias from: %s"
|
|
35
|
+
% (', '.join(connectionShortcuts.keys())))
|
|
36
|
+
parser.addoption(
|
|
37
|
+
'-S', '--SQL',
|
|
38
|
+
action="store_true", dest="show_sql", default=False,
|
|
39
|
+
help="Show SQL from statements (when capturing stdout the "
|
|
40
|
+
"SQL is only displayed when a test fails)")
|
|
41
|
+
parser.addoption(
|
|
42
|
+
'-O', '--SQL-output',
|
|
43
|
+
action="store_true", dest="show_sql_output", default=False,
|
|
44
|
+
help="Show output from SQL statements (when capturing "
|
|
45
|
+
"stdout the output is only displayed when a test fails)")
|
|
46
|
+
parser.addoption(
|
|
47
|
+
'-E', '--events',
|
|
48
|
+
action="store_true", dest="debug_events", default=False,
|
|
49
|
+
help="Debug events (print information about events as they are "
|
|
50
|
+
"sent)")
|
|
51
|
+
|
|
52
|
+
option = None
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def pytest_configure(config):
|
|
56
|
+
"""Make cmdline arguments available to dbtest"""
|
|
57
|
+
global option
|
|
58
|
+
option = config.option
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def setup_tests():
|
|
62
|
+
if option.debug_events:
|
|
63
|
+
from sqlobject import events
|
|
64
|
+
events.debug_events()
|
sqlobject/constraints.py
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Constraints
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from sqlobject.compat import PY2
|
|
6
|
+
|
|
7
|
+
if not PY2:
|
|
8
|
+
# alias for python 3 compatability
|
|
9
|
+
long = int
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class BadValue(ValueError):
|
|
13
|
+
|
|
14
|
+
def __init__(self, desc, obj, col, value, *args):
|
|
15
|
+
self.desc = desc
|
|
16
|
+
self.col = col
|
|
17
|
+
|
|
18
|
+
# I want these objects to be garbage-collectable, so
|
|
19
|
+
# I just keep their repr:
|
|
20
|
+
self.obj = repr(obj)
|
|
21
|
+
self.value = repr(value)
|
|
22
|
+
fullDesc = "%s.%s %s (you gave: %s)" \
|
|
23
|
+
% (obj, col.name, desc, value)
|
|
24
|
+
ValueError.__init__(self, fullDesc, *args)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def isString(obj, col, value):
|
|
28
|
+
if not isinstance(value, str):
|
|
29
|
+
raise BadValue("only allows strings", obj, col, value)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def notNull(obj, col, value):
|
|
33
|
+
if value is None:
|
|
34
|
+
raise BadValue("is defined NOT NULL", obj, col, value)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def isInt(obj, col, value):
|
|
38
|
+
if not isinstance(value, (int, long)):
|
|
39
|
+
raise BadValue("only allows integers", obj, col, value)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def isFloat(obj, col, value):
|
|
43
|
+
if not isinstance(value, (int, long, float)):
|
|
44
|
+
raise BadValue("only allows floating point numbers", obj, col, value)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def isBool(obj, col, value):
|
|
48
|
+
if not isinstance(value, bool):
|
|
49
|
+
raise BadValue("only allows booleans", obj, col, value)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
class InList:
|
|
53
|
+
|
|
54
|
+
def __init__(self, _l):
|
|
55
|
+
self.list = _l
|
|
56
|
+
|
|
57
|
+
def __call__(self, obj, col, value):
|
|
58
|
+
if value not in self.list:
|
|
59
|
+
raise BadValue("accepts only values in %s" % repr(self.list),
|
|
60
|
+
obj, col, value)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class MaxLength:
|
|
64
|
+
|
|
65
|
+
def __init__(self, length):
|
|
66
|
+
self.length = length
|
|
67
|
+
|
|
68
|
+
def __call__(self, obj, col, value):
|
|
69
|
+
try:
|
|
70
|
+
length = len(value)
|
|
71
|
+
except TypeError:
|
|
72
|
+
raise BadValue("object does not have a length",
|
|
73
|
+
obj, col, value)
|
|
74
|
+
if length > self.length:
|
|
75
|
+
raise BadValue("must be shorter in length than %s"
|
|
76
|
+
% self.length,
|
|
77
|
+
obj, col, value)
|
sqlobject/converters.py
ADDED
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
from array import array
|
|
2
|
+
import datetime
|
|
3
|
+
from decimal import Decimal
|
|
4
|
+
import time
|
|
5
|
+
import sys
|
|
6
|
+
from .compat import PY2, buffer_type
|
|
7
|
+
|
|
8
|
+
if PY2:
|
|
9
|
+
from types import ClassType, InstanceType, NoneType
|
|
10
|
+
else:
|
|
11
|
+
# Use suitable aliases for now
|
|
12
|
+
ClassType = type
|
|
13
|
+
NoneType = type(None)
|
|
14
|
+
# This is may not be what we want in all cases, but will do for now
|
|
15
|
+
InstanceType = object
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
try:
|
|
19
|
+
from mx.DateTime import DateTimeType as mxDateTimeType, \
|
|
20
|
+
DateTimeDeltaType as mxDateTimeDeltaType
|
|
21
|
+
except ImportError:
|
|
22
|
+
mxDateTimeType = None
|
|
23
|
+
mxDateTimeDeltaType = None
|
|
24
|
+
|
|
25
|
+
try:
|
|
26
|
+
import pendulum
|
|
27
|
+
except ImportError:
|
|
28
|
+
pendulumDateTimeType = None
|
|
29
|
+
else:
|
|
30
|
+
pendulumDateTimeType = pendulum.DateTime
|
|
31
|
+
|
|
32
|
+
try:
|
|
33
|
+
from DateTime import DateTime as zopeDateTime
|
|
34
|
+
except ImportError:
|
|
35
|
+
zopeDateTimeType = None
|
|
36
|
+
else:
|
|
37
|
+
zopeDateTimeType = type(zopeDateTime())
|
|
38
|
+
|
|
39
|
+
try:
|
|
40
|
+
import Sybase
|
|
41
|
+
NumericType = Sybase.NumericType
|
|
42
|
+
except ImportError:
|
|
43
|
+
NumericType = None
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
########################################
|
|
47
|
+
# Quoting
|
|
48
|
+
########################################
|
|
49
|
+
|
|
50
|
+
sqlStringReplace = [
|
|
51
|
+
("'", "''"),
|
|
52
|
+
('\\', '\\\\'),
|
|
53
|
+
('\000', '\\0'),
|
|
54
|
+
('\b', '\\b'),
|
|
55
|
+
('\n', '\\n'),
|
|
56
|
+
('\r', '\\r'),
|
|
57
|
+
('\t', '\\t'),
|
|
58
|
+
]
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
class ConverterRegistry:
|
|
62
|
+
|
|
63
|
+
def __init__(self):
|
|
64
|
+
self.basic = {}
|
|
65
|
+
self.klass = {}
|
|
66
|
+
|
|
67
|
+
def registerConverter(self, typ, func):
|
|
68
|
+
if type(typ) is ClassType:
|
|
69
|
+
self.klass[typ] = func
|
|
70
|
+
else:
|
|
71
|
+
self.basic[typ] = func
|
|
72
|
+
|
|
73
|
+
if PY2:
|
|
74
|
+
def lookupConverter(self, value, default=None):
|
|
75
|
+
if type(value) is InstanceType:
|
|
76
|
+
# lookup on klasses dict
|
|
77
|
+
return self.klass.get(value.__class__, default)
|
|
78
|
+
return self.basic.get(type(value), default)
|
|
79
|
+
else:
|
|
80
|
+
def lookupConverter(self, value, default=None):
|
|
81
|
+
# python 3 doesn't have classic classes, so everything's
|
|
82
|
+
# in self.klass due to comparison order in registerConvertor
|
|
83
|
+
return self.klass.get(value.__class__, default)
|
|
84
|
+
|
|
85
|
+
converters = ConverterRegistry()
|
|
86
|
+
registerConverter = converters.registerConverter
|
|
87
|
+
lookupConverter = converters.lookupConverter
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def StringLikeConverter(value, db):
|
|
91
|
+
if isinstance(value, array):
|
|
92
|
+
try:
|
|
93
|
+
value = value.tounicode()
|
|
94
|
+
except ValueError:
|
|
95
|
+
value = value.tostring()
|
|
96
|
+
elif isinstance(value, buffer_type):
|
|
97
|
+
value = str(value)
|
|
98
|
+
|
|
99
|
+
if db in ('mysql', 'postgres'):
|
|
100
|
+
for orig, repl in sqlStringReplace:
|
|
101
|
+
value = value.replace(orig, repl)
|
|
102
|
+
elif db in ('sqlite', 'firebird', 'sybase', 'maxdb', 'mssql'):
|
|
103
|
+
value = value.replace("'", "''")
|
|
104
|
+
else:
|
|
105
|
+
assert 0, "Database %s unknown" % db
|
|
106
|
+
if (db == 'postgres') and ('\\' in value):
|
|
107
|
+
return "E'%s'" % value
|
|
108
|
+
return "'%s'" % value
|
|
109
|
+
|
|
110
|
+
registerConverter(str, StringLikeConverter)
|
|
111
|
+
if PY2:
|
|
112
|
+
# noqa for flake8 & python3
|
|
113
|
+
registerConverter(unicode, StringLikeConverter) # noqa
|
|
114
|
+
registerConverter(array, StringLikeConverter)
|
|
115
|
+
if PY2:
|
|
116
|
+
registerConverter(bytearray, StringLikeConverter)
|
|
117
|
+
registerConverter(buffer_type, StringLikeConverter)
|
|
118
|
+
else:
|
|
119
|
+
registerConverter(memoryview, StringLikeConverter)
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
def IntConverter(value, db):
|
|
123
|
+
return repr(int(value))
|
|
124
|
+
|
|
125
|
+
registerConverter(int, IntConverter)
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
def LongConverter(value, db):
|
|
129
|
+
return str(value)
|
|
130
|
+
|
|
131
|
+
if sys.version_info[0] < 3:
|
|
132
|
+
# noqa for flake8 & python3
|
|
133
|
+
registerConverter(long, LongConverter) # noqa
|
|
134
|
+
|
|
135
|
+
if NumericType:
|
|
136
|
+
registerConverter(NumericType, IntConverter)
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
def BoolConverter(value, db):
|
|
140
|
+
if db == 'postgres':
|
|
141
|
+
if value:
|
|
142
|
+
return "'t'"
|
|
143
|
+
else:
|
|
144
|
+
return "'f'"
|
|
145
|
+
else:
|
|
146
|
+
if value:
|
|
147
|
+
return '1'
|
|
148
|
+
else:
|
|
149
|
+
return '0'
|
|
150
|
+
|
|
151
|
+
registerConverter(bool, BoolConverter)
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
def FloatConverter(value, db):
|
|
155
|
+
return repr(value)
|
|
156
|
+
|
|
157
|
+
registerConverter(float, FloatConverter)
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
def NoneConverter(value, db):
|
|
161
|
+
return "NULL"
|
|
162
|
+
|
|
163
|
+
registerConverter(NoneType, NoneConverter)
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
def SequenceConverter(value, db):
|
|
167
|
+
return "(%s)" % ", ".join([sqlrepr(v, db) for v in value])
|
|
168
|
+
|
|
169
|
+
registerConverter(tuple, SequenceConverter)
|
|
170
|
+
registerConverter(list, SequenceConverter)
|
|
171
|
+
registerConverter(dict, SequenceConverter)
|
|
172
|
+
registerConverter(set, SequenceConverter)
|
|
173
|
+
registerConverter(frozenset, SequenceConverter)
|
|
174
|
+
|
|
175
|
+
if hasattr(time, 'struct_time'):
|
|
176
|
+
def StructTimeConverter(value, db):
|
|
177
|
+
return time.strftime("'%Y-%m-%d %H:%M:%S'", value)
|
|
178
|
+
|
|
179
|
+
registerConverter(time.struct_time, StructTimeConverter)
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
def DateTimeConverter(value, db):
|
|
183
|
+
return "'%04d-%02d-%02d %02d:%02d:%02d'" % (
|
|
184
|
+
value.year, value.month, value.day,
|
|
185
|
+
value.hour, value.minute, value.second)
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
def DateTimeConverterMS(value, db):
|
|
189
|
+
return "'%04d-%02d-%02d %02d:%02d:%02d.%06d'" % (
|
|
190
|
+
value.year, value.month, value.day,
|
|
191
|
+
value.hour, value.minute, value.second, value.microsecond)
|
|
192
|
+
|
|
193
|
+
registerConverter(datetime.datetime, DateTimeConverterMS)
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
def DateConverter(value, db):
|
|
197
|
+
return "'%04d-%02d-%02d'" % (value.year, value.month, value.day)
|
|
198
|
+
|
|
199
|
+
registerConverter(datetime.date, DateConverter)
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
def TimeConverter(value, db):
|
|
203
|
+
return "'%02d:%02d:%02d'" % (value.hour, value.minute, value.second)
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
def TimeConverterMS(value, db):
|
|
207
|
+
return "'%02d:%02d:%02d.%06d'" % (value.hour, value.minute,
|
|
208
|
+
value.second, value.microsecond)
|
|
209
|
+
|
|
210
|
+
registerConverter(datetime.time, TimeConverterMS)
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
if mxDateTimeType:
|
|
214
|
+
def mxDateTimeConverter(value, db):
|
|
215
|
+
return "'%s'" % value.strftime("%Y-%m-%d %H:%M:%S")
|
|
216
|
+
|
|
217
|
+
registerConverter(mxDateTimeType, mxDateTimeConverter)
|
|
218
|
+
|
|
219
|
+
def mxTimeConverter(value, db):
|
|
220
|
+
return "'%s'" % value.strftime("%H:%M:%S")
|
|
221
|
+
|
|
222
|
+
registerConverter(mxDateTimeDeltaType, mxTimeConverter)
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
if pendulumDateTimeType:
|
|
226
|
+
def pendulumConverter(value, db):
|
|
227
|
+
return "'%s'" % value.to_datetime_string()
|
|
228
|
+
|
|
229
|
+
registerConverter(pendulum.DateTime, pendulumConverter)
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
if zopeDateTimeType:
|
|
233
|
+
def zopeDateTimeConverter(value, db):
|
|
234
|
+
return "'%s'" % value.strftime("%Y-%m-%d %H:%M:%S")
|
|
235
|
+
|
|
236
|
+
registerConverter(zopeDateTimeType, zopeDateTimeConverter)
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
def DecimalConverter(value, db):
|
|
240
|
+
return value.to_eng_string()
|
|
241
|
+
|
|
242
|
+
registerConverter(Decimal, DecimalConverter)
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
def TimedeltaConverter(value, db):
|
|
246
|
+
|
|
247
|
+
return """INTERVAL '%d days %d seconds'""" % \
|
|
248
|
+
(value.days, value.seconds)
|
|
249
|
+
|
|
250
|
+
registerConverter(datetime.timedelta, TimedeltaConverter)
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
def sqlrepr(obj, db=None):
|
|
254
|
+
try:
|
|
255
|
+
reprFunc = obj.__sqlrepr__
|
|
256
|
+
except AttributeError:
|
|
257
|
+
converter = lookupConverter(obj)
|
|
258
|
+
if converter is None:
|
|
259
|
+
raise ValueError("Unknown SQL builtin type: %s for %s" %
|
|
260
|
+
(type(obj), repr(obj)))
|
|
261
|
+
return converter(obj, db)
|
|
262
|
+
else:
|
|
263
|
+
return reprFunc(db)
|
|
264
|
+
|
|
265
|
+
|
|
266
|
+
def quote_str(s, db):
|
|
267
|
+
if (db == 'postgres') and ('\\' in s):
|
|
268
|
+
return "E'%s'" % s
|
|
269
|
+
return "'%s'" % s
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
def unquote_str(s):
|
|
273
|
+
if s[:2].upper().startswith("E'") and s.endswith("'"):
|
|
274
|
+
return s[2:-1]
|
|
275
|
+
elif s.startswith("'") and s.endswith("'"):
|
|
276
|
+
return s[1:-1]
|
|
277
|
+
else:
|
|
278
|
+
return s
|