singlestoredb 0.4.0__py3-none-any.whl → 1.0.4__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.
Potentially problematic release.
This version of singlestoredb might be problematic. Click here for more details.
- singlestoredb/__init__.py +33 -1
- singlestoredb/alchemy/__init__.py +90 -0
- singlestoredb/auth.py +5 -1
- singlestoredb/config.py +116 -14
- singlestoredb/connection.py +483 -516
- singlestoredb/converters.py +238 -135
- singlestoredb/exceptions.py +30 -2
- singlestoredb/functions/__init__.py +1 -0
- singlestoredb/functions/decorator.py +142 -0
- singlestoredb/functions/dtypes.py +1639 -0
- singlestoredb/functions/ext/__init__.py +2 -0
- singlestoredb/functions/ext/arrow.py +375 -0
- singlestoredb/functions/ext/asgi.py +661 -0
- singlestoredb/functions/ext/json.py +427 -0
- singlestoredb/functions/ext/mmap.py +306 -0
- singlestoredb/functions/ext/rowdat_1.py +744 -0
- singlestoredb/functions/signature.py +673 -0
- singlestoredb/fusion/__init__.py +11 -0
- singlestoredb/fusion/graphql.py +213 -0
- singlestoredb/fusion/handler.py +621 -0
- singlestoredb/fusion/handlers/stage.py +257 -0
- singlestoredb/fusion/handlers/utils.py +162 -0
- singlestoredb/fusion/handlers/workspace.py +412 -0
- singlestoredb/fusion/registry.py +164 -0
- singlestoredb/fusion/result.py +399 -0
- singlestoredb/http/__init__.py +27 -0
- singlestoredb/{http.py → http/connection.py} +555 -154
- singlestoredb/management/__init__.py +3 -0
- singlestoredb/management/billing_usage.py +148 -0
- singlestoredb/management/cluster.py +14 -6
- singlestoredb/management/manager.py +100 -38
- singlestoredb/management/organization.py +188 -0
- singlestoredb/management/region.py +5 -5
- singlestoredb/management/utils.py +281 -2
- singlestoredb/management/workspace.py +1344 -49
- singlestoredb/{clients/pymysqlsv → mysql}/__init__.py +16 -21
- singlestoredb/{clients/pymysqlsv → mysql}/_auth.py +39 -8
- singlestoredb/{clients/pymysqlsv → mysql}/charset.py +26 -23
- singlestoredb/{clients/pymysqlsv/connections.py → mysql/connection.py} +532 -165
- singlestoredb/{clients/pymysqlsv → mysql}/constants/CLIENT.py +0 -1
- singlestoredb/{clients/pymysqlsv → mysql}/constants/COMMAND.py +0 -1
- singlestoredb/{clients/pymysqlsv → mysql}/constants/CR.py +0 -2
- singlestoredb/{clients/pymysqlsv → mysql}/constants/ER.py +0 -1
- singlestoredb/{clients/pymysqlsv → mysql}/constants/FIELD_TYPE.py +1 -1
- singlestoredb/{clients/pymysqlsv → mysql}/constants/FLAG.py +0 -1
- singlestoredb/{clients/pymysqlsv → mysql}/constants/SERVER_STATUS.py +0 -1
- singlestoredb/mysql/converters.py +271 -0
- singlestoredb/{clients/pymysqlsv → mysql}/cursors.py +228 -112
- singlestoredb/mysql/err.py +92 -0
- singlestoredb/{clients/pymysqlsv → mysql}/optionfile.py +5 -4
- singlestoredb/{clients/pymysqlsv → mysql}/protocol.py +49 -20
- singlestoredb/mysql/tests/__init__.py +19 -0
- singlestoredb/{clients/pymysqlsv → mysql}/tests/base.py +32 -12
- singlestoredb/mysql/tests/conftest.py +37 -0
- singlestoredb/{clients/pymysqlsv → mysql}/tests/test_DictCursor.py +11 -7
- singlestoredb/{clients/pymysqlsv → mysql}/tests/test_SSCursor.py +17 -12
- singlestoredb/{clients/pymysqlsv → mysql}/tests/test_basic.py +32 -24
- singlestoredb/{clients/pymysqlsv → mysql}/tests/test_connection.py +130 -119
- singlestoredb/{clients/pymysqlsv → mysql}/tests/test_converters.py +9 -7
- singlestoredb/mysql/tests/test_cursor.py +141 -0
- singlestoredb/{clients/pymysqlsv → mysql}/tests/test_err.py +3 -2
- singlestoredb/{clients/pymysqlsv → mysql}/tests/test_issues.py +35 -27
- singlestoredb/{clients/pymysqlsv → mysql}/tests/test_load_local.py +13 -11
- singlestoredb/{clients/pymysqlsv → mysql}/tests/test_nextset.py +7 -3
- singlestoredb/{clients/pymysqlsv → mysql}/tests/test_optionfile.py +2 -1
- singlestoredb/{clients/pymysqlsv → mysql}/tests/thirdparty/__init__.py +1 -1
- singlestoredb/mysql/tests/thirdparty/test_MySQLdb/__init__.py +9 -0
- singlestoredb/{clients/pymysqlsv → mysql}/tests/thirdparty/test_MySQLdb/capabilities.py +19 -17
- singlestoredb/{clients/pymysqlsv → mysql}/tests/thirdparty/test_MySQLdb/dbapi20.py +31 -22
- singlestoredb/{clients/pymysqlsv → mysql}/tests/thirdparty/test_MySQLdb/test_MySQLdb_capabilities.py +3 -4
- singlestoredb/{clients/pymysqlsv → mysql}/tests/thirdparty/test_MySQLdb/test_MySQLdb_dbapi20.py +24 -20
- singlestoredb/{clients/pymysqlsv → mysql}/tests/thirdparty/test_MySQLdb/test_MySQLdb_nonstandard.py +4 -4
- singlestoredb/{clients/pymysqlsv → mysql}/times.py +3 -4
- singlestoredb/pytest.py +283 -0
- singlestoredb/tests/empty.sql +0 -0
- singlestoredb/tests/ext_funcs/__init__.py +385 -0
- singlestoredb/tests/test.sql +210 -0
- singlestoredb/tests/test2.sql +1 -0
- singlestoredb/tests/test_basics.py +482 -115
- singlestoredb/tests/test_config.py +13 -13
- singlestoredb/tests/test_connection.py +241 -305
- singlestoredb/tests/test_dbapi.py +27 -0
- singlestoredb/tests/test_ext_func.py +1193 -0
- singlestoredb/tests/test_ext_func_data.py +1101 -0
- singlestoredb/tests/test_fusion.py +465 -0
- singlestoredb/tests/test_http.py +32 -26
- singlestoredb/tests/test_management.py +588 -8
- singlestoredb/tests/test_plugin.py +33 -0
- singlestoredb/tests/test_results.py +11 -12
- singlestoredb/tests/test_udf.py +687 -0
- singlestoredb/tests/utils.py +3 -2
- singlestoredb/utils/config.py +58 -0
- singlestoredb/utils/debug.py +13 -0
- singlestoredb/utils/mogrify.py +151 -0
- singlestoredb/utils/results.py +4 -1
- singlestoredb-1.0.4.dist-info/METADATA +139 -0
- singlestoredb-1.0.4.dist-info/RECORD +112 -0
- {singlestoredb-0.4.0.dist-info → singlestoredb-1.0.4.dist-info}/WHEEL +1 -1
- singlestoredb-1.0.4.dist-info/entry_points.txt +2 -0
- singlestoredb/clients/pymysqlsv/converters.py +0 -365
- singlestoredb/clients/pymysqlsv/err.py +0 -144
- singlestoredb/clients/pymysqlsv/tests/__init__.py +0 -19
- singlestoredb/clients/pymysqlsv/tests/test_cursor.py +0 -133
- singlestoredb/clients/pymysqlsv/tests/thirdparty/test_MySQLdb/__init__.py +0 -9
- singlestoredb/drivers/__init__.py +0 -45
- singlestoredb/drivers/base.py +0 -198
- singlestoredb/drivers/cymysql.py +0 -38
- singlestoredb/drivers/http.py +0 -47
- singlestoredb/drivers/mariadb.py +0 -40
- singlestoredb/drivers/mysqlconnector.py +0 -49
- singlestoredb/drivers/mysqldb.py +0 -60
- singlestoredb/drivers/pymysql.py +0 -37
- singlestoredb/drivers/pymysqlsv.py +0 -35
- singlestoredb/drivers/pyodbc.py +0 -65
- singlestoredb-0.4.0.dist-info/METADATA +0 -111
- singlestoredb-0.4.0.dist-info/RECORD +0 -86
- /singlestoredb/{clients → fusion/handlers}/__init__.py +0 -0
- /singlestoredb/{clients/pymysqlsv → mysql}/constants/__init__.py +0 -0
- {singlestoredb-0.4.0.dist-info → singlestoredb-1.0.4.dist-info}/LICENSE +0 -0
- {singlestoredb-0.4.0.dist-info → singlestoredb-1.0.4.dist-info}/top_level.txt +0 -0
|
@@ -6,13 +6,11 @@ import decimal
|
|
|
6
6
|
import os
|
|
7
7
|
import unittest
|
|
8
8
|
import uuid
|
|
9
|
-
import warnings
|
|
10
|
-
|
|
11
|
-
import pandas as pd
|
|
12
9
|
|
|
13
10
|
import singlestoredb as s2
|
|
14
11
|
from singlestoredb import connection as sc
|
|
15
12
|
from singlestoredb.tests import utils
|
|
13
|
+
# import pandas as pd
|
|
16
14
|
# import traceback
|
|
17
15
|
|
|
18
16
|
|
|
@@ -34,9 +32,6 @@ class TestConnection(unittest.TestCase):
|
|
|
34
32
|
def setUp(self):
|
|
35
33
|
self.conn = s2.connect(database=type(self).dbname, local_infile=True)
|
|
36
34
|
self.cur = self.conn.cursor()
|
|
37
|
-
self.driver = self.conn._driver.dbapi.__name__.replace(
|
|
38
|
-
'singlestoredb.', '',
|
|
39
|
-
)
|
|
40
35
|
|
|
41
36
|
def tearDown(self):
|
|
42
37
|
try:
|
|
@@ -81,16 +76,16 @@ class TestConnection(unittest.TestCase):
|
|
|
81
76
|
assert cbp('enable') is True, cbp('enable')
|
|
82
77
|
assert cbp('enabled') is True, cbp('enabled')
|
|
83
78
|
|
|
84
|
-
assert cbp('false') is
|
|
85
|
-
assert cbp('f') is
|
|
86
|
-
assert cbp('False') is
|
|
87
|
-
assert cbp('F') is
|
|
88
|
-
assert cbp('FALSE') is
|
|
79
|
+
assert cbp('false') is False, cbp('false')
|
|
80
|
+
assert cbp('f') is False, cbp('f')
|
|
81
|
+
assert cbp('False') is False, cbp('False')
|
|
82
|
+
assert cbp('F') is False, cbp('F')
|
|
83
|
+
assert cbp('FALSE') is False, cbp('FALSE')
|
|
89
84
|
|
|
90
|
-
assert cbp('off') is
|
|
91
|
-
assert cbp('no') is
|
|
92
|
-
assert cbp('disable') is
|
|
93
|
-
assert cbp('disabled') is
|
|
85
|
+
assert cbp('off') is False, cbp('off')
|
|
86
|
+
assert cbp('no') is False, cbp('no')
|
|
87
|
+
assert cbp('disable') is False, cbp('disable')
|
|
88
|
+
assert cbp('disabled') is False, cbp('disabled')
|
|
94
89
|
|
|
95
90
|
with self.assertRaises(ValueError):
|
|
96
91
|
cbp('nein')
|
|
@@ -119,7 +114,7 @@ class TestConnection(unittest.TestCase):
|
|
|
119
114
|
('e', 'elephants', 0),
|
|
120
115
|
]), out
|
|
121
116
|
|
|
122
|
-
assert rowcount
|
|
117
|
+
assert rowcount in (5, -1), rowcount
|
|
123
118
|
assert rownumber == 5, rownumber
|
|
124
119
|
assert lastrowid is None, lastrowid
|
|
125
120
|
assert len(desc) == 3, desc
|
|
@@ -154,7 +149,7 @@ class TestConnection(unittest.TestCase):
|
|
|
154
149
|
('e', 'elephants', 0),
|
|
155
150
|
]), out
|
|
156
151
|
|
|
157
|
-
assert rowcount
|
|
152
|
+
assert rowcount in (5, -1), rowcount
|
|
158
153
|
assert rownumber == 5, rownumber
|
|
159
154
|
assert lastrowid is None, lastrowid
|
|
160
155
|
assert len(desc) == 3, desc
|
|
@@ -190,7 +185,7 @@ class TestConnection(unittest.TestCase):
|
|
|
190
185
|
('e', 'elephants', 0),
|
|
191
186
|
]), out
|
|
192
187
|
|
|
193
|
-
assert rowcount
|
|
188
|
+
assert rowcount in (5, -1), rowcount
|
|
194
189
|
assert rownumber == 5, rownumber
|
|
195
190
|
assert lastrowid is None, lastrowid
|
|
196
191
|
assert len(desc) == 3, desc
|
|
@@ -227,7 +222,7 @@ class TestConnection(unittest.TestCase):
|
|
|
227
222
|
assert self.cur.rownumber == 5, self.cur.rownumber
|
|
228
223
|
|
|
229
224
|
def test_execute_with_dict_params(self):
|
|
230
|
-
self.cur.execute('select * from data where id <
|
|
225
|
+
self.cur.execute('select * from data where id < %(name)s', dict(name='d'))
|
|
231
226
|
out = self.cur.fetchall()
|
|
232
227
|
|
|
233
228
|
desc = self.cur.description
|
|
@@ -240,7 +235,7 @@ class TestConnection(unittest.TestCase):
|
|
|
240
235
|
('c', 'cats', 5),
|
|
241
236
|
]), out
|
|
242
237
|
|
|
243
|
-
assert rowcount
|
|
238
|
+
assert rowcount in (3, -1), rowcount
|
|
244
239
|
assert lastrowid is None, lastrowid
|
|
245
240
|
assert len(desc) == 3, desc
|
|
246
241
|
assert desc[0].name == 'id', desc[0].name
|
|
@@ -251,7 +246,7 @@ class TestConnection(unittest.TestCase):
|
|
|
251
246
|
assert desc[2].type_code == 8, desc[2].type_code
|
|
252
247
|
|
|
253
248
|
def test_execute_with_positional_params(self):
|
|
254
|
-
self.cur.execute('select * from data where id <
|
|
249
|
+
self.cur.execute('select * from data where id < %s', ['d'])
|
|
255
250
|
out = self.cur.fetchall()
|
|
256
251
|
|
|
257
252
|
desc = self.cur.description
|
|
@@ -264,7 +259,7 @@ class TestConnection(unittest.TestCase):
|
|
|
264
259
|
('c', 'cats', 5),
|
|
265
260
|
]), out
|
|
266
261
|
|
|
267
|
-
assert rowcount
|
|
262
|
+
assert rowcount in (3, -1), rowcount
|
|
268
263
|
assert lastrowid is None, lastrowid
|
|
269
264
|
assert len(desc) == 3, desc
|
|
270
265
|
assert desc[0].name == 'id', desc[0].name
|
|
@@ -276,7 +271,7 @@ class TestConnection(unittest.TestCase):
|
|
|
276
271
|
|
|
277
272
|
def test_execute_with_escaped_positional_substitutions(self):
|
|
278
273
|
self.cur.execute(
|
|
279
|
-
'select `id`, `time` from alltypes where `time` =
|
|
274
|
+
'select `id`, `time` from alltypes where `time` = %s', [
|
|
280
275
|
'00:07:00',
|
|
281
276
|
],
|
|
282
277
|
)
|
|
@@ -289,44 +284,44 @@ class TestConnection(unittest.TestCase):
|
|
|
289
284
|
out = self.cur.fetchall()
|
|
290
285
|
assert out[0] == (0, datetime.timedelta(seconds=420)), out[0]
|
|
291
286
|
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
287
|
+
# with self.assertRaises(IndexError):
|
|
288
|
+
# self.cur.execute(
|
|
289
|
+
# 'select `id`, `time` from alltypes where `id` = %1s '
|
|
290
|
+
# 'or `time` = "00:07:00"', [0],
|
|
291
|
+
# )
|
|
297
292
|
|
|
298
293
|
self.cur.execute(
|
|
299
|
-
'select `id`, `time` from alltypes where `id` =
|
|
300
|
-
'or `time` = "00
|
|
294
|
+
'select `id`, `time` from alltypes where `id` = %s '
|
|
295
|
+
'or `time` = "00:07:00"', [0],
|
|
301
296
|
)
|
|
302
297
|
out = self.cur.fetchall()
|
|
303
298
|
assert out[0] == (0, datetime.timedelta(seconds=420)), out[0]
|
|
304
299
|
|
|
305
300
|
def test_execute_with_escaped_substitutions(self):
|
|
306
301
|
self.cur.execute(
|
|
307
|
-
'select `id`, `time` from alltypes where `time` =
|
|
302
|
+
'select `id`, `time` from alltypes where `time` = %(time)s',
|
|
308
303
|
dict(time='00:07:00'),
|
|
309
304
|
)
|
|
310
305
|
out = self.cur.fetchall()
|
|
311
306
|
assert out[0] == (0, datetime.timedelta(seconds=420)), out[0]
|
|
312
307
|
|
|
313
308
|
self.cur.execute(
|
|
314
|
-
'select `id`, `time` from alltypes where `time` =
|
|
315
|
-
dict(time='00
|
|
309
|
+
'select `id`, `time` from alltypes where `time` = %(time)s',
|
|
310
|
+
dict(time='00:07:00'),
|
|
316
311
|
)
|
|
317
312
|
out = self.cur.fetchall()
|
|
318
|
-
assert len(out) ==
|
|
313
|
+
assert len(out) == 1, out
|
|
319
314
|
|
|
320
315
|
with self.assertRaises(KeyError):
|
|
321
316
|
self.cur.execute(
|
|
322
317
|
'select `id`, `time`, `char_100` from alltypes '
|
|
323
|
-
'where `time` =
|
|
324
|
-
dict(
|
|
318
|
+
'where `time` = %(time)s or `char_100` like "foo:bar"',
|
|
319
|
+
dict(x='00:07:00'),
|
|
325
320
|
)
|
|
326
321
|
|
|
327
322
|
self.cur.execute(
|
|
328
323
|
'select `id`, `time`, `char_100` from alltypes '
|
|
329
|
-
'where `time` =
|
|
324
|
+
'where `time` = %(time)s or `char_100` like "foo::bar"',
|
|
330
325
|
dict(time='00:07:00'),
|
|
331
326
|
)
|
|
332
327
|
out = self.cur.fetchall()
|
|
@@ -350,7 +345,7 @@ class TestConnection(unittest.TestCase):
|
|
|
350
345
|
def test_executemany(self):
|
|
351
346
|
# NOTE: Doesn't actually do anything since no rows match
|
|
352
347
|
self.cur.executemany(
|
|
353
|
-
'delete from data where id >
|
|
348
|
+
'delete from data where id > %(name)s',
|
|
354
349
|
[dict(name='z'), dict(name='y')],
|
|
355
350
|
)
|
|
356
351
|
|
|
@@ -539,8 +534,6 @@ class TestConnection(unittest.TestCase):
|
|
|
539
534
|
with self.assertRaises(s2.ProgrammingError) as cm:
|
|
540
535
|
self.cur.execute('garbage syntax')
|
|
541
536
|
exc = cm.exception
|
|
542
|
-
if self.driver != 'pyodbc':
|
|
543
|
-
assert exc.errno == 1064, exc.errno
|
|
544
537
|
assert 'You have an error in your SQL syntax' in exc.errmsg, exc.errmsg
|
|
545
538
|
|
|
546
539
|
def test_alltypes(self):
|
|
@@ -553,30 +546,8 @@ class TestConnection(unittest.TestCase):
|
|
|
553
546
|
|
|
554
547
|
bits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
|
|
555
548
|
|
|
556
|
-
if self.driver == 'pyodbc':
|
|
557
|
-
odbc_types = {
|
|
558
|
-
# int -> bigint
|
|
559
|
-
3: 8, 1: 8, 2: 8, 9: 8,
|
|
560
|
-
# float -> double
|
|
561
|
-
4: 5,
|
|
562
|
-
# timestamp -> datetime
|
|
563
|
-
7: 12,
|
|
564
|
-
# year -> bigint
|
|
565
|
-
13: 8,
|
|
566
|
-
# char/binary -> varchar/varbinary
|
|
567
|
-
249: 15, 250: 15, 251: 15, 252: 15, 253: 15, 254: 15, 255: 15,
|
|
568
|
-
# newdecimal -> decimal
|
|
569
|
-
246: 0,
|
|
570
|
-
# json -> varchar
|
|
571
|
-
245: 15,
|
|
572
|
-
# bit -> varchar
|
|
573
|
-
16: 15,
|
|
574
|
-
}
|
|
575
|
-
else:
|
|
576
|
-
odbc_types = {}
|
|
577
|
-
|
|
578
549
|
def otype(x):
|
|
579
|
-
return
|
|
550
|
+
return x
|
|
580
551
|
|
|
581
552
|
assert row['id'] == 0, row['id']
|
|
582
553
|
assert typ['id'] == otype(3), typ['id']
|
|
@@ -662,11 +633,6 @@ class TestConnection(unittest.TestCase):
|
|
|
662
633
|
assert row['time'] == datetime.timedelta(minutes=7), row['time']
|
|
663
634
|
assert typ['time'] == 11, typ['time']
|
|
664
635
|
|
|
665
|
-
# pyodbc doesn't support microseconds on times
|
|
666
|
-
if not self.driver == 'pyodbc':
|
|
667
|
-
assert row['time_6'] == datetime.timedelta(
|
|
668
|
-
hours=1, minutes=10, microseconds=2,
|
|
669
|
-
), row['time_6']
|
|
670
636
|
assert typ['time_6'] == 11, typ['time_6']
|
|
671
637
|
|
|
672
638
|
assert row['datetime'] == datetime.datetime(
|
|
@@ -740,14 +706,10 @@ class TestConnection(unittest.TestCase):
|
|
|
740
706
|
), row['tinyblob']
|
|
741
707
|
assert typ['tinyblob'] == otype(249), typ['tinyblob']
|
|
742
708
|
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
assert row['json'] == {
|
|
748
|
-
'a': 10, 'b': 2.75,
|
|
749
|
-
'c': 'hello world',
|
|
750
|
-
}, row['json']
|
|
709
|
+
assert row['json'] == {
|
|
710
|
+
'a': 10, 'b': 2.75,
|
|
711
|
+
'c': 'hello world',
|
|
712
|
+
}, row['json']
|
|
751
713
|
assert typ['json'] == otype(245), typ['json']
|
|
752
714
|
|
|
753
715
|
assert row['enum'] == 'one', row['enum']
|
|
@@ -756,10 +718,7 @@ class TestConnection(unittest.TestCase):
|
|
|
756
718
|
assert row['set'] == 'two', row['set']
|
|
757
719
|
assert typ['set'] == otype(253), typ['set'] # mysql code: 248
|
|
758
720
|
|
|
759
|
-
|
|
760
|
-
assert row['bit'] == b'\x80\x00\x00\x00\x00\x00\x00\x00', row['bit']
|
|
761
|
-
else:
|
|
762
|
-
assert row['bit'] == b'\x00\x00\x00\x00\x00\x00\x00\x80', row['bit']
|
|
721
|
+
assert row['bit'] == b'\x00\x00\x00\x00\x00\x00\x00\x80', row['bit']
|
|
763
722
|
assert typ['bit'] == otype(16), typ['bit']
|
|
764
723
|
|
|
765
724
|
def test_alltypes_nulls(self):
|
|
@@ -770,30 +729,8 @@ class TestConnection(unittest.TestCase):
|
|
|
770
729
|
row = dict(zip(names, out))
|
|
771
730
|
typ = dict(zip(names, types))
|
|
772
731
|
|
|
773
|
-
if self.driver == 'pyodbc':
|
|
774
|
-
odbc_types = {
|
|
775
|
-
# int -> bigint
|
|
776
|
-
3: 8, 1: 8, 2: 8, 9: 8,
|
|
777
|
-
# float -> double
|
|
778
|
-
4: 5,
|
|
779
|
-
# timestamp -> datetime
|
|
780
|
-
7: 12,
|
|
781
|
-
# year -> bigint
|
|
782
|
-
13: 8,
|
|
783
|
-
# char/binary -> varchar/varbinary
|
|
784
|
-
249: 15, 250: 15, 251: 15, 252: 15, 253: 15, 254: 15, 255: 15,
|
|
785
|
-
# newdecimal -> decimal
|
|
786
|
-
246: 0,
|
|
787
|
-
# json -> varchar
|
|
788
|
-
245: 15,
|
|
789
|
-
# bit -> varchar
|
|
790
|
-
16: 15,
|
|
791
|
-
}
|
|
792
|
-
else:
|
|
793
|
-
odbc_types = {}
|
|
794
|
-
|
|
795
732
|
def otype(x):
|
|
796
|
-
return
|
|
733
|
+
return x
|
|
797
734
|
|
|
798
735
|
assert row['id'] == 1, row['id']
|
|
799
736
|
assert typ['id'] == otype(3), typ['id']
|
|
@@ -922,78 +859,6 @@ class TestConnection(unittest.TestCase):
|
|
|
922
859
|
assert row['bit'] is None, row['bit']
|
|
923
860
|
assert typ['bit'] == otype(16), typ['bit']
|
|
924
861
|
|
|
925
|
-
def test_convert_exception(self):
|
|
926
|
-
driver = self.conn._driver
|
|
927
|
-
dbapi = driver.dbapi
|
|
928
|
-
|
|
929
|
-
if self.driver in ['mysql.connector', 'http', 'https']:
|
|
930
|
-
exc_args = tuple()
|
|
931
|
-
exc_kwargs = dict(errno=-1, msg='hi there')
|
|
932
|
-
else:
|
|
933
|
-
exc_args = (-1, 'hi there')
|
|
934
|
-
exc_kwargs = {}
|
|
935
|
-
|
|
936
|
-
exc = driver.convert_exception(
|
|
937
|
-
dbapi.NotSupportedError(*exc_args, **exc_kwargs),
|
|
938
|
-
)
|
|
939
|
-
assert exc.args[0] == -1
|
|
940
|
-
assert exc.args[1] == 'hi there'
|
|
941
|
-
assert exc.errno == -1
|
|
942
|
-
assert exc.errmsg == 'hi there'
|
|
943
|
-
assert exc.msg == 'hi there'
|
|
944
|
-
|
|
945
|
-
with self.assertRaises(s2.NotSupportedError):
|
|
946
|
-
raise driver.convert_exception(
|
|
947
|
-
dbapi.NotSupportedError(*exc_args, **exc_kwargs),
|
|
948
|
-
)
|
|
949
|
-
|
|
950
|
-
with self.assertRaises(s2.ProgrammingError):
|
|
951
|
-
raise driver.convert_exception(
|
|
952
|
-
dbapi.ProgrammingError(*exc_args, **exc_kwargs),
|
|
953
|
-
)
|
|
954
|
-
|
|
955
|
-
with self.assertRaises(s2.InternalError):
|
|
956
|
-
raise driver.convert_exception(
|
|
957
|
-
dbapi.InternalError(*exc_args, **exc_kwargs),
|
|
958
|
-
)
|
|
959
|
-
|
|
960
|
-
with self.assertRaises(s2.IntegrityError):
|
|
961
|
-
raise driver.convert_exception(
|
|
962
|
-
dbapi.IntegrityError(*exc_args, **exc_kwargs),
|
|
963
|
-
)
|
|
964
|
-
|
|
965
|
-
with self.assertRaises(s2.OperationalError):
|
|
966
|
-
raise driver.convert_exception(
|
|
967
|
-
dbapi.OperationalError(*exc_args, **exc_kwargs),
|
|
968
|
-
)
|
|
969
|
-
|
|
970
|
-
with self.assertRaises(s2.DataError):
|
|
971
|
-
raise driver.convert_exception(
|
|
972
|
-
dbapi.DataError(*exc_args, **exc_kwargs),
|
|
973
|
-
)
|
|
974
|
-
|
|
975
|
-
with self.assertRaises(s2.DatabaseError):
|
|
976
|
-
raise driver.convert_exception(
|
|
977
|
-
dbapi.DatabaseError(*exc_args, **exc_kwargs),
|
|
978
|
-
)
|
|
979
|
-
|
|
980
|
-
with self.assertRaises(s2.InterfaceError):
|
|
981
|
-
raise driver.convert_exception(
|
|
982
|
-
dbapi.InterfaceError(*exc_args, **exc_kwargs),
|
|
983
|
-
)
|
|
984
|
-
|
|
985
|
-
with self.assertRaises(s2.Error):
|
|
986
|
-
raise driver.convert_exception(
|
|
987
|
-
dbapi.Error(*exc_args, **exc_kwargs),
|
|
988
|
-
)
|
|
989
|
-
|
|
990
|
-
if self.driver == 'mariadb':
|
|
991
|
-
with self.assertRaises(s2.Error):
|
|
992
|
-
raise driver.convert_exception(dbapi.Warning('hi there'))
|
|
993
|
-
else:
|
|
994
|
-
with self.assertRaises(s2.Warning):
|
|
995
|
-
raise driver.convert_exception(dbapi.Warning('hi there'))
|
|
996
|
-
|
|
997
862
|
def test_name_check(self):
|
|
998
863
|
nc = sc._name_check
|
|
999
864
|
assert nc('foo') == 'foo'
|
|
@@ -1014,52 +879,31 @@ class TestConnection(unittest.TestCase):
|
|
|
1014
879
|
self.cur.execute('echo return_int()')
|
|
1015
880
|
|
|
1016
881
|
out = self.cur.fetchall()
|
|
1017
|
-
assert out == [(1234567890,)], out
|
|
1018
|
-
|
|
1019
|
-
# These take an extra `nextset` for some reason
|
|
1020
|
-
if self.driver in [
|
|
1021
|
-
'pymysql', 'clients.pymysqlsv',
|
|
1022
|
-
'MySQLdb', 'cymysql', 'pyodbc',
|
|
1023
|
-
]:
|
|
1024
|
-
self.cur.nextset()
|
|
882
|
+
assert list(out) == [(1234567890,)], out
|
|
1025
883
|
|
|
1026
884
|
out = self.cur.nextset()
|
|
1027
|
-
assert out is
|
|
885
|
+
assert out is None, out
|
|
1028
886
|
|
|
1029
887
|
def test_echo_with_result_set(self):
|
|
1030
888
|
self.cur.execute('echo result_set_and_return_int()')
|
|
1031
889
|
|
|
1032
890
|
out = self.cur.fetchall()
|
|
1033
|
-
assert out == [(5,)], out
|
|
1034
|
-
|
|
1035
|
-
if self.driver == 'mysql.connector' and s2.get_option('pure_python'):
|
|
1036
|
-
warnings.warn(
|
|
1037
|
-
'The mysql.connector in pure python mode does not '
|
|
1038
|
-
'support multiple result sets.',
|
|
1039
|
-
)
|
|
1040
|
-
return
|
|
891
|
+
assert list(out) == [(5,)], out
|
|
1041
892
|
|
|
1042
893
|
out = self.cur.nextset()
|
|
1043
894
|
assert out is True, out
|
|
1044
895
|
|
|
1045
896
|
out = self.cur.fetchall()
|
|
1046
|
-
assert out == [(1, 2, 3)], out
|
|
897
|
+
assert list(out) == [(1, 2, 3)], out
|
|
1047
898
|
|
|
1048
899
|
out = self.cur.nextset()
|
|
1049
900
|
assert out is True, out
|
|
1050
901
|
|
|
1051
902
|
out = self.cur.fetchall()
|
|
1052
|
-
assert out == [(1234567890,)], out
|
|
1053
|
-
|
|
1054
|
-
# These take an extra `nextset` for some reason
|
|
1055
|
-
if self.driver in [
|
|
1056
|
-
'pymysql', 'clients.pymysqlsv',
|
|
1057
|
-
'MySQLdb', 'cymysql', 'pyodbc',
|
|
1058
|
-
]:
|
|
1059
|
-
self.cur.nextset()
|
|
903
|
+
assert list(out) == [(1234567890,)], out
|
|
1060
904
|
|
|
1061
905
|
out = self.cur.nextset()
|
|
1062
|
-
assert out is
|
|
906
|
+
assert out is None, out
|
|
1063
907
|
|
|
1064
908
|
def test_callproc(self):
|
|
1065
909
|
self.cur.callproc('get_animal', ['cats'])
|
|
@@ -1067,28 +911,21 @@ class TestConnection(unittest.TestCase):
|
|
|
1067
911
|
out = self.cur.fetchall()
|
|
1068
912
|
assert list(out) == [(5,)], out
|
|
1069
913
|
|
|
1070
|
-
if self.driver == 'mysql.connector' and s2.get_option('pure_python'):
|
|
1071
|
-
warnings.warn(
|
|
1072
|
-
'The mysql.connector in pure python mode does not '
|
|
1073
|
-
'support multiple result sets.',
|
|
1074
|
-
)
|
|
1075
|
-
return
|
|
1076
|
-
|
|
1077
914
|
out = self.cur.nextset()
|
|
1078
915
|
assert out is True, out
|
|
1079
916
|
|
|
1080
917
|
out = self.cur.fetchall()
|
|
1081
918
|
assert list(out) == [(1, 2, 3)], out
|
|
1082
919
|
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
920
|
+
out = self.cur.nextset()
|
|
921
|
+
assert out is True, out
|
|
922
|
+
|
|
923
|
+
# Always get an empty set at the end
|
|
924
|
+
out = self.cur.fetchall()
|
|
925
|
+
assert list(out) == [], out
|
|
1089
926
|
|
|
1090
927
|
out = self.cur.nextset()
|
|
1091
|
-
assert out is
|
|
928
|
+
assert out is None, out
|
|
1092
929
|
|
|
1093
930
|
def test_callproc_no_args(self):
|
|
1094
931
|
self.cur.callproc('no_args')
|
|
@@ -1096,44 +933,37 @@ class TestConnection(unittest.TestCase):
|
|
|
1096
933
|
out = self.cur.fetchall()
|
|
1097
934
|
assert list(out) == [(4, 5, 6)], out
|
|
1098
935
|
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
936
|
+
out = self.cur.nextset()
|
|
937
|
+
assert out is True, out
|
|
938
|
+
|
|
939
|
+
# Always get an empty set at the end
|
|
940
|
+
out = self.cur.fetchall()
|
|
941
|
+
assert list(out) == [], out
|
|
1105
942
|
|
|
1106
943
|
out = self.cur.nextset()
|
|
1107
|
-
assert out is
|
|
944
|
+
assert out is None, out
|
|
1108
945
|
|
|
1109
946
|
def test_callproc_return_int(self):
|
|
1110
947
|
self.cur.callproc('result_set_and_return_int')
|
|
1111
948
|
|
|
1112
949
|
out = self.cur.fetchall()
|
|
1113
|
-
assert out == [(5,)], out
|
|
1114
|
-
|
|
1115
|
-
if self.driver == 'mysql.connector' and s2.get_option('pure_python'):
|
|
1116
|
-
warnings.warn(
|
|
1117
|
-
'The mysql.connector in pure python mode does not '
|
|
1118
|
-
'support multiple result sets.',
|
|
1119
|
-
)
|
|
1120
|
-
return
|
|
950
|
+
assert list(out) == [(5,)], out
|
|
1121
951
|
|
|
1122
952
|
out = self.cur.nextset()
|
|
1123
953
|
assert out is True, out
|
|
1124
954
|
|
|
1125
955
|
out = self.cur.fetchall()
|
|
1126
|
-
assert out == [(1, 2, 3)], out
|
|
956
|
+
assert list(out) == [(1, 2, 3)], out
|
|
1127
957
|
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
958
|
+
out = self.cur.nextset()
|
|
959
|
+
assert out is True, out
|
|
960
|
+
|
|
961
|
+
# Always get an empty set at the end
|
|
962
|
+
out = self.cur.fetchall()
|
|
963
|
+
assert list(out) == [], out
|
|
1134
964
|
|
|
1135
965
|
out = self.cur.nextset()
|
|
1136
|
-
assert out is
|
|
966
|
+
assert out is None, out
|
|
1137
967
|
|
|
1138
968
|
def test_callproc_bad_args(self):
|
|
1139
969
|
self.cur.callproc('get_animal', [10])
|
|
@@ -1141,34 +971,28 @@ class TestConnection(unittest.TestCase):
|
|
|
1141
971
|
out = self.cur.fetchall()
|
|
1142
972
|
assert list(out) == [], out
|
|
1143
973
|
|
|
1144
|
-
if self.driver == 'mysql.connector' and s2.get_option('pure_python'):
|
|
1145
|
-
warnings.warn(
|
|
1146
|
-
'The mysql.connector in pure python mode does not '
|
|
1147
|
-
'support multiple result sets.',
|
|
1148
|
-
)
|
|
1149
|
-
return
|
|
1150
|
-
|
|
1151
974
|
out = self.cur.nextset()
|
|
1152
975
|
assert out is True, out
|
|
1153
976
|
|
|
1154
977
|
out = self.cur.fetchall()
|
|
1155
978
|
assert list(out) == [(1, 2, 3)], out
|
|
1156
979
|
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
980
|
+
out = self.cur.nextset()
|
|
981
|
+
assert out is True, out
|
|
982
|
+
|
|
983
|
+
# Always get an empty set at the end
|
|
984
|
+
out = self.cur.fetchall()
|
|
985
|
+
assert list(out) == [], out
|
|
1163
986
|
|
|
1164
987
|
out = self.cur.nextset()
|
|
1165
|
-
assert out is
|
|
988
|
+
assert out is None, out
|
|
1166
989
|
|
|
1167
990
|
def test_callproc_too_many_args(self):
|
|
1168
991
|
with self.assertRaises((
|
|
1169
992
|
s2.ProgrammingError,
|
|
1170
993
|
s2.OperationalError,
|
|
1171
994
|
s2.InternalError,
|
|
995
|
+
TypeError,
|
|
1172
996
|
)):
|
|
1173
997
|
self.cur.callproc('get_animal', ['cats', 'dogs'])
|
|
1174
998
|
|
|
@@ -1176,6 +1000,7 @@ class TestConnection(unittest.TestCase):
|
|
|
1176
1000
|
s2.ProgrammingError,
|
|
1177
1001
|
s2.OperationalError,
|
|
1178
1002
|
s2.InternalError,
|
|
1003
|
+
TypeError,
|
|
1179
1004
|
)):
|
|
1180
1005
|
self.cur.callproc('get_animal', [])
|
|
1181
1006
|
|
|
@@ -1183,43 +1008,43 @@ class TestConnection(unittest.TestCase):
|
|
|
1183
1008
|
s2.ProgrammingError,
|
|
1184
1009
|
s2.OperationalError,
|
|
1185
1010
|
s2.InternalError,
|
|
1011
|
+
TypeError,
|
|
1186
1012
|
)):
|
|
1187
1013
|
self.cur.callproc('get_animal')
|
|
1188
1014
|
|
|
1189
1015
|
def test_cursor_close(self):
|
|
1190
1016
|
self.cur.close()
|
|
1191
1017
|
|
|
1192
|
-
|
|
1193
|
-
self.cur.close()
|
|
1018
|
+
self.cur.close()
|
|
1194
1019
|
|
|
1195
|
-
with self.assertRaises(s2.
|
|
1020
|
+
with self.assertRaises(s2.ProgrammingError):
|
|
1196
1021
|
self.cur.callproc('foo')
|
|
1197
1022
|
|
|
1198
|
-
with self.assertRaises(s2.
|
|
1023
|
+
with self.assertRaises(s2.ProgrammingError):
|
|
1199
1024
|
self.cur.execute('select 1')
|
|
1200
1025
|
|
|
1201
|
-
|
|
1202
|
-
|
|
1026
|
+
# with self.assertRaises(s2.ProgrammingError):
|
|
1027
|
+
# self.cur.executemany('select 1')
|
|
1203
1028
|
|
|
1204
|
-
with self.assertRaises(s2.
|
|
1029
|
+
with self.assertRaises(s2.ProgrammingError):
|
|
1205
1030
|
self.cur.fetchone()
|
|
1206
1031
|
|
|
1207
|
-
with self.assertRaises(s2.
|
|
1032
|
+
with self.assertRaises(s2.ProgrammingError):
|
|
1208
1033
|
self.cur.fetchall()
|
|
1209
1034
|
|
|
1210
|
-
with self.assertRaises(s2.
|
|
1035
|
+
with self.assertRaises(s2.ProgrammingError):
|
|
1211
1036
|
self.cur.fetchmany()
|
|
1212
1037
|
|
|
1213
|
-
with self.assertRaises(s2.
|
|
1038
|
+
with self.assertRaises(s2.ProgrammingError):
|
|
1214
1039
|
self.cur.nextset()
|
|
1215
1040
|
|
|
1216
|
-
|
|
1217
|
-
|
|
1041
|
+
# with self.assertRaises(s2.ProgrammingError):
|
|
1042
|
+
# self.cur.setinputsizes([])
|
|
1218
1043
|
|
|
1219
|
-
|
|
1220
|
-
|
|
1044
|
+
# with self.assertRaises(s2.ProgrammingError):
|
|
1045
|
+
# self.cur.setoutputsize(10)
|
|
1221
1046
|
|
|
1222
|
-
with self.assertRaises(s2.
|
|
1047
|
+
with self.assertRaises(s2.ProgrammingError):
|
|
1223
1048
|
self.cur.scroll(2)
|
|
1224
1049
|
|
|
1225
1050
|
with self.assertRaises(s2.InterfaceError):
|
|
@@ -1237,15 +1062,9 @@ class TestConnection(unittest.TestCase):
|
|
|
1237
1062
|
self.cur.setinputsizes([10, 20, 30])
|
|
1238
1063
|
|
|
1239
1064
|
def test_setoutputsize(self):
|
|
1240
|
-
if self.driver in ['MySQLdb', 'pymysql', 'clients.pymysqlsv', 'cymysql']:
|
|
1241
|
-
self.skipTest('outputsize is not supported')
|
|
1242
|
-
|
|
1243
1065
|
self.cur.setoutputsize(100)
|
|
1244
1066
|
|
|
1245
1067
|
def test_scroll(self):
|
|
1246
|
-
if self.driver in ['mysql.connector', 'pyodbc', 'mariadb', 'cymysql']:
|
|
1247
|
-
self.skipTest('scroll is not supported')
|
|
1248
|
-
|
|
1249
1068
|
self.cur.execute('select * from data order by name')
|
|
1250
1069
|
|
|
1251
1070
|
out = self.cur.fetchone()
|
|
@@ -1258,19 +1077,21 @@ class TestConnection(unittest.TestCase):
|
|
|
1258
1077
|
assert out[1] == 'elephants', out[1]
|
|
1259
1078
|
assert self.cur.rownumber == 5, self.cur.rownumber
|
|
1260
1079
|
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1080
|
+
try:
|
|
1081
|
+
self.cur.scroll(0, mode='absolute')
|
|
1082
|
+
assert self.cur.rownumber == 0, self.cur.rownumber
|
|
1264
1083
|
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1084
|
+
out = self.cur.fetchone()
|
|
1085
|
+
assert out[1] == 'antelopes', out[1]
|
|
1086
|
+
assert self.cur.rownumber == 1, self.cur.rownumber
|
|
1087
|
+
except s2.NotSupportedError:
|
|
1088
|
+
pass
|
|
1268
1089
|
|
|
1269
1090
|
with self.assertRaises((ValueError, s2.ProgrammingError)):
|
|
1270
1091
|
self.cur.scroll(0, mode='badmode')
|
|
1271
1092
|
|
|
1272
1093
|
def test_autocommit(self):
|
|
1273
|
-
if self.driver in ['http', 'https']:
|
|
1094
|
+
if self.conn.driver in ['http', 'https']:
|
|
1274
1095
|
self.skipTest('Can not set autocommit in HTTP')
|
|
1275
1096
|
|
|
1276
1097
|
orig = self.conn.locals.autocommit
|
|
@@ -1288,10 +1109,11 @@ class TestConnection(unittest.TestCase):
|
|
|
1288
1109
|
def test_conn_close(self):
|
|
1289
1110
|
self.conn.close()
|
|
1290
1111
|
|
|
1291
|
-
self.
|
|
1112
|
+
with self.assertRaises(s2.Error):
|
|
1113
|
+
self.conn.close()
|
|
1292
1114
|
|
|
1293
1115
|
with self.assertRaises(s2.InterfaceError):
|
|
1294
|
-
self.conn.autocommit()
|
|
1116
|
+
self.conn.autocommit(False)
|
|
1295
1117
|
|
|
1296
1118
|
with self.assertRaises(s2.InterfaceError):
|
|
1297
1119
|
self.conn.commit()
|
|
@@ -1299,11 +1121,11 @@ class TestConnection(unittest.TestCase):
|
|
|
1299
1121
|
with self.assertRaises(s2.InterfaceError):
|
|
1300
1122
|
self.conn.rollback()
|
|
1301
1123
|
|
|
1302
|
-
|
|
1303
|
-
|
|
1124
|
+
# with self.assertRaises(s2.InterfaceError):
|
|
1125
|
+
# self.conn.cursor()
|
|
1304
1126
|
|
|
1305
|
-
|
|
1306
|
-
|
|
1127
|
+
# with self.assertRaises(s2.InterfaceError):
|
|
1128
|
+
# self.conn.messages
|
|
1307
1129
|
|
|
1308
1130
|
with self.assertRaises(s2.InterfaceError):
|
|
1309
1131
|
self.conn.globals.autocommit = True
|
|
@@ -1324,7 +1146,7 @@ class TestConnection(unittest.TestCase):
|
|
|
1324
1146
|
self.conn.disable_data_api()
|
|
1325
1147
|
|
|
1326
1148
|
def test_rollback(self):
|
|
1327
|
-
if self.driver in ['http', 'https']:
|
|
1149
|
+
if self.conn.driver in ['http', 'https']:
|
|
1328
1150
|
self.skipTest('Can not set autocommit in HTTP')
|
|
1329
1151
|
|
|
1330
1152
|
self.conn.autocommit(False)
|
|
@@ -1346,7 +1168,7 @@ class TestConnection(unittest.TestCase):
|
|
|
1346
1168
|
assert len(out) == 5, len(out)
|
|
1347
1169
|
|
|
1348
1170
|
def test_commit(self):
|
|
1349
|
-
if self.driver in ['http', 'https']:
|
|
1171
|
+
if self.conn.driver in ['http', 'https']:
|
|
1350
1172
|
self.skipTest('Can not set autocommit in HTTP')
|
|
1351
1173
|
|
|
1352
1174
|
self.conn.autocommit(False)
|
|
@@ -1395,7 +1217,7 @@ class TestConnection(unittest.TestCase):
|
|
|
1395
1217
|
assert val == orig, val
|
|
1396
1218
|
|
|
1397
1219
|
def test_session_var(self):
|
|
1398
|
-
if self.driver in ['http', 'https']:
|
|
1220
|
+
if self.conn.driver in ['http', 'https']:
|
|
1399
1221
|
self.skipTest('Can not change session variable in HTTP')
|
|
1400
1222
|
|
|
1401
1223
|
orig = self.conn.locals.enable_multipartition_queries
|
|
@@ -1413,7 +1235,7 @@ class TestConnection(unittest.TestCase):
|
|
|
1413
1235
|
assert val == orig, val
|
|
1414
1236
|
|
|
1415
1237
|
def test_local_infile(self):
|
|
1416
|
-
if self.driver in ['http', 'https']:
|
|
1238
|
+
if self.conn.driver in ['http', 'https']:
|
|
1417
1239
|
self.skipTest('Can not load local files in HTTP')
|
|
1418
1240
|
|
|
1419
1241
|
path = os.path.join(os.path.dirname(__file__), 'local_infile.csv')
|
|
@@ -1429,16 +1251,16 @@ class TestConnection(unittest.TestCase):
|
|
|
1429
1251
|
|
|
1430
1252
|
try:
|
|
1431
1253
|
self.cur.execute(
|
|
1432
|
-
f'load data local infile
|
|
1254
|
+
f'load data local infile %s into table {tblname} '
|
|
1433
1255
|
'fields terminated by "," lines terminated by "\n";', [path],
|
|
1434
1256
|
)
|
|
1435
1257
|
|
|
1436
|
-
self.cur.execute(f'select * from {tblname}
|
|
1258
|
+
self.cur.execute(f'select * from {tblname} order by first_name')
|
|
1437
1259
|
out = list(self.cur)
|
|
1438
1260
|
assert out == [
|
|
1439
1261
|
('John', 'Doe', 34),
|
|
1440
|
-
('Sandy', 'Smith', 24),
|
|
1441
1262
|
('Patty', 'Jones', 57),
|
|
1263
|
+
('Sandy', 'Smith', 24),
|
|
1442
1264
|
], out
|
|
1443
1265
|
|
|
1444
1266
|
finally:
|
|
@@ -1460,7 +1282,7 @@ class TestConnection(unittest.TestCase):
|
|
|
1460
1282
|
254: upper,
|
|
1461
1283
|
}
|
|
1462
1284
|
|
|
1463
|
-
with s2.connect(database=type(self).dbname,
|
|
1285
|
+
with s2.connect(database=type(self).dbname, conv=convs) as conn:
|
|
1464
1286
|
with conn.cursor() as cur:
|
|
1465
1287
|
cur.execute('select * from alltypes where id = 0')
|
|
1466
1288
|
names = [x[0] for x in cur.description]
|
|
@@ -1490,7 +1312,7 @@ class TestConnection(unittest.TestCase):
|
|
|
1490
1312
|
assert row['tinytext'] == 'This is a tinytext column.', \
|
|
1491
1313
|
row['tinytext']
|
|
1492
1314
|
|
|
1493
|
-
def
|
|
1315
|
+
def test_results_type(self):
|
|
1494
1316
|
columns = [
|
|
1495
1317
|
'id', 'tinyint', 'unsigned_tinyint', 'bool', 'boolean',
|
|
1496
1318
|
'smallint', 'unsigned_smallint', 'mediumint', 'unsigned_mediumint',
|
|
@@ -1504,33 +1326,147 @@ class TestConnection(unittest.TestCase):
|
|
|
1504
1326
|
'set', 'bit',
|
|
1505
1327
|
]
|
|
1506
1328
|
|
|
1507
|
-
with s2.connect(database=type(self).dbname,
|
|
1329
|
+
with s2.connect(database=type(self).dbname, results_type='tuples') as conn:
|
|
1508
1330
|
with conn.cursor() as cur:
|
|
1509
1331
|
cur.execute('select * from alltypes')
|
|
1510
1332
|
out = cur.fetchall()
|
|
1511
1333
|
assert type(out[0]) is tuple, type(out[0])
|
|
1512
1334
|
assert len(out[0]) == len(columns), len(out[0])
|
|
1513
1335
|
|
|
1514
|
-
with s2.connect(database=type(self).dbname,
|
|
1336
|
+
with s2.connect(database=type(self).dbname, results_type='namedtuples') as conn:
|
|
1515
1337
|
with conn.cursor() as cur:
|
|
1516
1338
|
cur.execute('select * from alltypes')
|
|
1517
1339
|
out = cur.fetchall()
|
|
1518
1340
|
assert type(out[0]).__name__ == 'Row', type(out)
|
|
1519
|
-
|
|
1341
|
+
for i, name in enumerate(columns):
|
|
1342
|
+
assert hasattr(out[0], name)
|
|
1343
|
+
assert out[0][i] == getattr(out[0], name)
|
|
1520
1344
|
|
|
1521
|
-
with s2.connect(database=type(self).dbname,
|
|
1345
|
+
with s2.connect(database=type(self).dbname, results_type='dicts') as conn:
|
|
1522
1346
|
with conn.cursor() as cur:
|
|
1523
1347
|
cur.execute('select * from alltypes')
|
|
1524
1348
|
out = cur.fetchall()
|
|
1525
1349
|
assert type(out[0]) is dict, type(out)
|
|
1526
1350
|
assert list(out[0].keys()) == columns, out[0].keys()
|
|
1527
1351
|
|
|
1528
|
-
|
|
1352
|
+
def test_results_format(self):
|
|
1353
|
+
with self.assertWarns(DeprecationWarning):
|
|
1354
|
+
with s2.connect(database=type(self).dbname, results_format='dicts') as conn:
|
|
1355
|
+
with conn.cursor() as cur:
|
|
1356
|
+
cur.execute('select * from alltypes')
|
|
1357
|
+
out = cur.fetchall()
|
|
1358
|
+
assert type(out[0]) is dict, type(out)
|
|
1359
|
+
|
|
1360
|
+
def test_multi_statements(self):
|
|
1361
|
+
if self.conn.driver not in ['http', 'https']:
|
|
1362
|
+
with s2.connect(database=type(self).dbname, multi_statements=True) as conn:
|
|
1363
|
+
with conn.cursor() as cur:
|
|
1364
|
+
cur.execute('SELECT 1; SELECT 2;')
|
|
1365
|
+
self.assertEqual([(1,)], list(cur))
|
|
1366
|
+
|
|
1367
|
+
r = cur.nextset()
|
|
1368
|
+
self.assertTrue(r)
|
|
1369
|
+
|
|
1370
|
+
self.assertEqual([(2,)], list(cur))
|
|
1371
|
+
self.assertIsNone(cur.nextset())
|
|
1372
|
+
|
|
1373
|
+
def test_connect_timeout(self):
|
|
1374
|
+
with s2.connect(database=type(self).dbname, connect_timeout=8) as conn:
|
|
1529
1375
|
with conn.cursor() as cur:
|
|
1530
|
-
cur.execute('
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1376
|
+
cur.execute('SELECT 1')
|
|
1377
|
+
self.assertEqual([(1,)], list(cur))
|
|
1378
|
+
|
|
1379
|
+
def test_show_accessors(self):
|
|
1380
|
+
out = self.conn.show.columns('data')
|
|
1381
|
+
assert out.columns == [
|
|
1382
|
+
'Name', 'Type', 'Null',
|
|
1383
|
+
'Key', 'Default', 'Extra',
|
|
1384
|
+
], out.columns
|
|
1385
|
+
assert out.Name == ['id', 'name', 'value'], out.Name
|
|
1386
|
+
assert out.Type == ['varchar(255)', 'varchar(255)', 'bigint(20)'], out.Type
|
|
1387
|
+
assert str(out).count('varchar(255)') == 2, out
|
|
1388
|
+
|
|
1389
|
+
html = out._repr_html_()
|
|
1390
|
+
assert html.count('varchar(255)') == 2
|
|
1391
|
+
assert html.count('bigint(20)') == 1
|
|
1392
|
+
assert '<table' in html
|
|
1393
|
+
|
|
1394
|
+
out = self.conn.show.tables()
|
|
1395
|
+
assert out.columns == ['Name'], out.columns
|
|
1396
|
+
assert 'data' in out.Name, out.Name
|
|
1397
|
+
assert 'alltypes' in out.Name, out.Name
|
|
1398
|
+
|
|
1399
|
+
out = self.conn.show.warnings()
|
|
1400
|
+
|
|
1401
|
+
out = self.conn.show.errors()
|
|
1402
|
+
|
|
1403
|
+
out = self.conn.show.databases()
|
|
1404
|
+
assert out.columns == ['Name'], out.columns
|
|
1405
|
+
assert 'information_schema' in out.Name
|
|
1406
|
+
|
|
1407
|
+
out = self.conn.show.database_status()
|
|
1408
|
+
assert out.columns == ['Name', 'Value'], out.columns
|
|
1409
|
+
assert 'database' in out.Name
|
|
1410
|
+
|
|
1411
|
+
out = self.conn.show.global_status()
|
|
1412
|
+
assert out.columns == ['Name', 'Value'], out.columns
|
|
1413
|
+
|
|
1414
|
+
out = self.conn.show.indexes('data')
|
|
1415
|
+
assert 'Name' in out.columns, out.columns
|
|
1416
|
+
assert 'KeyName' in out.columns, out.columns
|
|
1417
|
+
assert out.Name == ['data'], out.Name
|
|
1418
|
+
|
|
1419
|
+
out = self.conn.show.functions()
|
|
1420
|
+
|
|
1421
|
+
out = self.conn.show.partitions()
|
|
1422
|
+
assert 'Name' in out.columns, out.columns
|
|
1423
|
+
assert 'Role' in out.columns, out.columns
|
|
1424
|
+
|
|
1425
|
+
out = self.conn.show.pipelines()
|
|
1426
|
+
|
|
1427
|
+
# out = self.conn.show.plan(1)
|
|
1428
|
+
|
|
1429
|
+
# out = self.conn.show.plancache()
|
|
1430
|
+
|
|
1431
|
+
out = self.conn.show.processlist()
|
|
1432
|
+
assert 'Name' in out.columns, out.columns
|
|
1433
|
+
assert 'Command' in out.columns, out.columns
|
|
1434
|
+
|
|
1435
|
+
# out = self.conn.show.reproduction()
|
|
1436
|
+
|
|
1437
|
+
out = self.conn.show.schemas()
|
|
1438
|
+
assert out.columns == ['Name'], out.columns
|
|
1439
|
+
assert 'information_schema' in out.Name
|
|
1440
|
+
|
|
1441
|
+
out = self.conn.show.session_status()
|
|
1442
|
+
assert out.columns == ['Name', 'Value']
|
|
1443
|
+
|
|
1444
|
+
out = self.conn.show.status()
|
|
1445
|
+
assert out.columns == ['Name', 'Value']
|
|
1446
|
+
|
|
1447
|
+
out = self.conn.show.table_status()
|
|
1448
|
+
assert 'Name' in out.columns, out.columns
|
|
1449
|
+
assert 'alltypes' in out.Name, out.Name
|
|
1450
|
+
assert 'data' in out.Name, out.Name
|
|
1451
|
+
|
|
1452
|
+
out = self.conn.show.procedures()
|
|
1453
|
+
|
|
1454
|
+
out = self.conn.show.aggregates()
|
|
1455
|
+
|
|
1456
|
+
# out = self.conn.show.create_aggregate('aname')
|
|
1457
|
+
|
|
1458
|
+
# out = self.conn.show.create_function('fname')
|
|
1459
|
+
|
|
1460
|
+
# out = self.conn.show.create_pipeline('pname')
|
|
1461
|
+
|
|
1462
|
+
out = self.conn.show.create_table('data')
|
|
1463
|
+
assert 'Name' in out.columns, out.columns
|
|
1464
|
+
assert 'CreateTable' in out.columns, out.columns
|
|
1465
|
+
assert '`id` varchar(255)' in out.CreateTable[0], out.CreateTable[0]
|
|
1466
|
+
assert '`name` varchar(255)' in out.CreateTable[0], out.CreateTable[0]
|
|
1467
|
+
assert '`value` bigint(20)' in out.CreateTable[0], out.CreateTable[0]
|
|
1468
|
+
|
|
1469
|
+
# out = self.conn.show.create_view('vname')
|
|
1534
1470
|
|
|
1535
1471
|
|
|
1536
1472
|
if __name__ == '__main__':
|