singlestoredb 0.3.3__py3-none-any.whl → 1.0.3__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 -2
- singlestoredb/alchemy/__init__.py +90 -0
- singlestoredb/auth.py +6 -4
- singlestoredb/config.py +116 -16
- singlestoredb/connection.py +489 -523
- singlestoredb/converters.py +275 -26
- singlestoredb/exceptions.py +30 -4
- 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/__init__.py +0 -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/connection.py +1192 -0
- singlestoredb/management/__init__.py +3 -2
- singlestoredb/management/billing_usage.py +148 -0
- singlestoredb/management/cluster.py +19 -14
- singlestoredb/management/manager.py +100 -40
- singlestoredb/management/organization.py +188 -0
- singlestoredb/management/region.py +6 -8
- singlestoredb/management/utils.py +253 -4
- singlestoredb/management/workspace.py +1153 -35
- singlestoredb/mysql/__init__.py +177 -0
- singlestoredb/mysql/_auth.py +298 -0
- singlestoredb/mysql/charset.py +214 -0
- singlestoredb/mysql/connection.py +1814 -0
- singlestoredb/mysql/constants/CLIENT.py +38 -0
- singlestoredb/mysql/constants/COMMAND.py +32 -0
- singlestoredb/mysql/constants/CR.py +78 -0
- singlestoredb/mysql/constants/ER.py +474 -0
- singlestoredb/mysql/constants/FIELD_TYPE.py +32 -0
- singlestoredb/mysql/constants/FLAG.py +15 -0
- singlestoredb/mysql/constants/SERVER_STATUS.py +10 -0
- singlestoredb/mysql/constants/__init__.py +0 -0
- singlestoredb/mysql/converters.py +271 -0
- singlestoredb/mysql/cursors.py +713 -0
- singlestoredb/mysql/err.py +92 -0
- singlestoredb/mysql/optionfile.py +20 -0
- singlestoredb/mysql/protocol.py +388 -0
- singlestoredb/mysql/tests/__init__.py +19 -0
- singlestoredb/mysql/tests/base.py +126 -0
- singlestoredb/mysql/tests/conftest.py +37 -0
- singlestoredb/mysql/tests/test_DictCursor.py +132 -0
- singlestoredb/mysql/tests/test_SSCursor.py +141 -0
- singlestoredb/mysql/tests/test_basic.py +452 -0
- singlestoredb/mysql/tests/test_connection.py +851 -0
- singlestoredb/mysql/tests/test_converters.py +58 -0
- singlestoredb/mysql/tests/test_cursor.py +141 -0
- singlestoredb/mysql/tests/test_err.py +16 -0
- singlestoredb/mysql/tests/test_issues.py +514 -0
- singlestoredb/mysql/tests/test_load_local.py +75 -0
- singlestoredb/mysql/tests/test_nextset.py +88 -0
- singlestoredb/mysql/tests/test_optionfile.py +27 -0
- singlestoredb/mysql/tests/thirdparty/__init__.py +6 -0
- singlestoredb/mysql/tests/thirdparty/test_MySQLdb/__init__.py +9 -0
- singlestoredb/mysql/tests/thirdparty/test_MySQLdb/capabilities.py +323 -0
- singlestoredb/mysql/tests/thirdparty/test_MySQLdb/dbapi20.py +865 -0
- singlestoredb/mysql/tests/thirdparty/test_MySQLdb/test_MySQLdb_capabilities.py +110 -0
- singlestoredb/mysql/tests/thirdparty/test_MySQLdb/test_MySQLdb_dbapi20.py +224 -0
- singlestoredb/mysql/tests/thirdparty/test_MySQLdb/test_MySQLdb_nonstandard.py +101 -0
- singlestoredb/mysql/times.py +23 -0
- 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 -117
- singlestoredb/tests/test_config.py +13 -15
- singlestoredb/tests/test_connection.py +241 -289
- singlestoredb/tests/test_dbapi.py +27 -0
- singlestoredb/tests/test_exceptions.py +0 -2
- 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 -28
- singlestoredb/tests/test_management.py +588 -10
- singlestoredb/tests/test_plugin.py +33 -0
- singlestoredb/tests/test_results.py +11 -14
- singlestoredb/tests/test_types.py +0 -2
- singlestoredb/tests/test_udf.py +687 -0
- singlestoredb/tests/test_xdict.py +0 -2
- singlestoredb/tests/utils.py +3 -4
- singlestoredb/types.py +4 -5
- singlestoredb/utils/config.py +71 -12
- singlestoredb/utils/convert_rows.py +0 -2
- singlestoredb/utils/debug.py +13 -0
- singlestoredb/utils/mogrify.py +151 -0
- singlestoredb/utils/results.py +4 -3
- singlestoredb/utils/xdict.py +12 -12
- singlestoredb-1.0.3.dist-info/METADATA +139 -0
- singlestoredb-1.0.3.dist-info/RECORD +112 -0
- {singlestoredb-0.3.3.dist-info → singlestoredb-1.0.3.dist-info}/WHEEL +1 -1
- singlestoredb-1.0.3.dist-info/entry_points.txt +2 -0
- singlestoredb/drivers/__init__.py +0 -46
- singlestoredb/drivers/base.py +0 -200
- singlestoredb/drivers/cymysql.py +0 -40
- singlestoredb/drivers/http.py +0 -49
- singlestoredb/drivers/mariadb.py +0 -42
- singlestoredb/drivers/mysqlconnector.py +0 -51
- singlestoredb/drivers/mysqldb.py +0 -62
- singlestoredb/drivers/pymysql.py +0 -39
- singlestoredb/drivers/pyodbc.py +0 -67
- singlestoredb/http.py +0 -794
- singlestoredb-0.3.3.dist-info/METADATA +0 -105
- singlestoredb-0.3.3.dist-info/RECORD +0 -46
- {singlestoredb-0.3.3.dist-info → singlestoredb-1.0.3.dist-info}/LICENSE +0 -0
- {singlestoredb-0.3.3.dist-info → singlestoredb-1.0.3.dist-info}/top_level.txt +0 -0
|
@@ -1,20 +1,16 @@
|
|
|
1
1
|
#!/usr/bin/env python
|
|
2
2
|
# type: ignore
|
|
3
3
|
"""Basic SingleStoreDB connection testing."""
|
|
4
|
-
from __future__ import annotations
|
|
5
|
-
|
|
6
4
|
import datetime
|
|
7
5
|
import decimal
|
|
8
6
|
import os
|
|
9
7
|
import unittest
|
|
10
8
|
import uuid
|
|
11
|
-
import warnings
|
|
12
|
-
|
|
13
|
-
import pandas as pd
|
|
14
9
|
|
|
15
10
|
import singlestoredb as s2
|
|
16
11
|
from singlestoredb import connection as sc
|
|
17
12
|
from singlestoredb.tests import utils
|
|
13
|
+
# import pandas as pd
|
|
18
14
|
# import traceback
|
|
19
15
|
|
|
20
16
|
|
|
@@ -36,9 +32,6 @@ class TestConnection(unittest.TestCase):
|
|
|
36
32
|
def setUp(self):
|
|
37
33
|
self.conn = s2.connect(database=type(self).dbname, local_infile=True)
|
|
38
34
|
self.cur = self.conn.cursor()
|
|
39
|
-
self.driver = self.conn._driver.dbapi.__name__.replace(
|
|
40
|
-
'singlestoredb.', '',
|
|
41
|
-
)
|
|
42
35
|
|
|
43
36
|
def tearDown(self):
|
|
44
37
|
try:
|
|
@@ -83,16 +76,16 @@ class TestConnection(unittest.TestCase):
|
|
|
83
76
|
assert cbp('enable') is True, cbp('enable')
|
|
84
77
|
assert cbp('enabled') is True, cbp('enabled')
|
|
85
78
|
|
|
86
|
-
assert cbp('false') is
|
|
87
|
-
assert cbp('f') is
|
|
88
|
-
assert cbp('False') is
|
|
89
|
-
assert cbp('F') is
|
|
90
|
-
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')
|
|
91
84
|
|
|
92
|
-
assert cbp('off') is
|
|
93
|
-
assert cbp('no') is
|
|
94
|
-
assert cbp('disable') is
|
|
95
|
-
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')
|
|
96
89
|
|
|
97
90
|
with self.assertRaises(ValueError):
|
|
98
91
|
cbp('nein')
|
|
@@ -121,7 +114,7 @@ class TestConnection(unittest.TestCase):
|
|
|
121
114
|
('e', 'elephants', 0),
|
|
122
115
|
]), out
|
|
123
116
|
|
|
124
|
-
assert rowcount
|
|
117
|
+
assert rowcount in (5, -1), rowcount
|
|
125
118
|
assert rownumber == 5, rownumber
|
|
126
119
|
assert lastrowid is None, lastrowid
|
|
127
120
|
assert len(desc) == 3, desc
|
|
@@ -156,7 +149,7 @@ class TestConnection(unittest.TestCase):
|
|
|
156
149
|
('e', 'elephants', 0),
|
|
157
150
|
]), out
|
|
158
151
|
|
|
159
|
-
assert rowcount
|
|
152
|
+
assert rowcount in (5, -1), rowcount
|
|
160
153
|
assert rownumber == 5, rownumber
|
|
161
154
|
assert lastrowid is None, lastrowid
|
|
162
155
|
assert len(desc) == 3, desc
|
|
@@ -192,7 +185,7 @@ class TestConnection(unittest.TestCase):
|
|
|
192
185
|
('e', 'elephants', 0),
|
|
193
186
|
]), out
|
|
194
187
|
|
|
195
|
-
assert rowcount
|
|
188
|
+
assert rowcount in (5, -1), rowcount
|
|
196
189
|
assert rownumber == 5, rownumber
|
|
197
190
|
assert lastrowid is None, lastrowid
|
|
198
191
|
assert len(desc) == 3, desc
|
|
@@ -229,7 +222,7 @@ class TestConnection(unittest.TestCase):
|
|
|
229
222
|
assert self.cur.rownumber == 5, self.cur.rownumber
|
|
230
223
|
|
|
231
224
|
def test_execute_with_dict_params(self):
|
|
232
|
-
self.cur.execute('select * from data where id <
|
|
225
|
+
self.cur.execute('select * from data where id < %(name)s', dict(name='d'))
|
|
233
226
|
out = self.cur.fetchall()
|
|
234
227
|
|
|
235
228
|
desc = self.cur.description
|
|
@@ -242,7 +235,7 @@ class TestConnection(unittest.TestCase):
|
|
|
242
235
|
('c', 'cats', 5),
|
|
243
236
|
]), out
|
|
244
237
|
|
|
245
|
-
assert rowcount
|
|
238
|
+
assert rowcount in (3, -1), rowcount
|
|
246
239
|
assert lastrowid is None, lastrowid
|
|
247
240
|
assert len(desc) == 3, desc
|
|
248
241
|
assert desc[0].name == 'id', desc[0].name
|
|
@@ -253,7 +246,7 @@ class TestConnection(unittest.TestCase):
|
|
|
253
246
|
assert desc[2].type_code == 8, desc[2].type_code
|
|
254
247
|
|
|
255
248
|
def test_execute_with_positional_params(self):
|
|
256
|
-
self.cur.execute('select * from data where id <
|
|
249
|
+
self.cur.execute('select * from data where id < %s', ['d'])
|
|
257
250
|
out = self.cur.fetchall()
|
|
258
251
|
|
|
259
252
|
desc = self.cur.description
|
|
@@ -266,7 +259,7 @@ class TestConnection(unittest.TestCase):
|
|
|
266
259
|
('c', 'cats', 5),
|
|
267
260
|
]), out
|
|
268
261
|
|
|
269
|
-
assert rowcount
|
|
262
|
+
assert rowcount in (3, -1), rowcount
|
|
270
263
|
assert lastrowid is None, lastrowid
|
|
271
264
|
assert len(desc) == 3, desc
|
|
272
265
|
assert desc[0].name == 'id', desc[0].name
|
|
@@ -278,7 +271,7 @@ class TestConnection(unittest.TestCase):
|
|
|
278
271
|
|
|
279
272
|
def test_execute_with_escaped_positional_substitutions(self):
|
|
280
273
|
self.cur.execute(
|
|
281
|
-
'select `id`, `time` from alltypes where `time` =
|
|
274
|
+
'select `id`, `time` from alltypes where `time` = %s', [
|
|
282
275
|
'00:07:00',
|
|
283
276
|
],
|
|
284
277
|
)
|
|
@@ -291,44 +284,44 @@ class TestConnection(unittest.TestCase):
|
|
|
291
284
|
out = self.cur.fetchall()
|
|
292
285
|
assert out[0] == (0, datetime.timedelta(seconds=420)), out[0]
|
|
293
286
|
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
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
|
+
# )
|
|
299
292
|
|
|
300
293
|
self.cur.execute(
|
|
301
|
-
'select `id`, `time` from alltypes where `id` =
|
|
302
|
-
'or `time` = "00
|
|
294
|
+
'select `id`, `time` from alltypes where `id` = %s '
|
|
295
|
+
'or `time` = "00:07:00"', [0],
|
|
303
296
|
)
|
|
304
297
|
out = self.cur.fetchall()
|
|
305
298
|
assert out[0] == (0, datetime.timedelta(seconds=420)), out[0]
|
|
306
299
|
|
|
307
300
|
def test_execute_with_escaped_substitutions(self):
|
|
308
301
|
self.cur.execute(
|
|
309
|
-
'select `id`, `time` from alltypes where `time` =
|
|
302
|
+
'select `id`, `time` from alltypes where `time` = %(time)s',
|
|
310
303
|
dict(time='00:07:00'),
|
|
311
304
|
)
|
|
312
305
|
out = self.cur.fetchall()
|
|
313
306
|
assert out[0] == (0, datetime.timedelta(seconds=420)), out[0]
|
|
314
307
|
|
|
315
308
|
self.cur.execute(
|
|
316
|
-
'select `id`, `time` from alltypes where `time` =
|
|
317
|
-
dict(time='00
|
|
309
|
+
'select `id`, `time` from alltypes where `time` = %(time)s',
|
|
310
|
+
dict(time='00:07:00'),
|
|
318
311
|
)
|
|
319
312
|
out = self.cur.fetchall()
|
|
320
|
-
assert len(out) ==
|
|
313
|
+
assert len(out) == 1, out
|
|
321
314
|
|
|
322
315
|
with self.assertRaises(KeyError):
|
|
323
316
|
self.cur.execute(
|
|
324
317
|
'select `id`, `time`, `char_100` from alltypes '
|
|
325
|
-
'where `time` =
|
|
326
|
-
dict(
|
|
318
|
+
'where `time` = %(time)s or `char_100` like "foo:bar"',
|
|
319
|
+
dict(x='00:07:00'),
|
|
327
320
|
)
|
|
328
321
|
|
|
329
322
|
self.cur.execute(
|
|
330
323
|
'select `id`, `time`, `char_100` from alltypes '
|
|
331
|
-
'where `time` =
|
|
324
|
+
'where `time` = %(time)s or `char_100` like "foo::bar"',
|
|
332
325
|
dict(time='00:07:00'),
|
|
333
326
|
)
|
|
334
327
|
out = self.cur.fetchall()
|
|
@@ -352,7 +345,7 @@ class TestConnection(unittest.TestCase):
|
|
|
352
345
|
def test_executemany(self):
|
|
353
346
|
# NOTE: Doesn't actually do anything since no rows match
|
|
354
347
|
self.cur.executemany(
|
|
355
|
-
'delete from data where id >
|
|
348
|
+
'delete from data where id > %(name)s',
|
|
356
349
|
[dict(name='z'), dict(name='y')],
|
|
357
350
|
)
|
|
358
351
|
|
|
@@ -541,8 +534,6 @@ class TestConnection(unittest.TestCase):
|
|
|
541
534
|
with self.assertRaises(s2.ProgrammingError) as cm:
|
|
542
535
|
self.cur.execute('garbage syntax')
|
|
543
536
|
exc = cm.exception
|
|
544
|
-
if self.driver != 'pyodbc':
|
|
545
|
-
assert exc.errno == 1064, exc.errno
|
|
546
537
|
assert 'You have an error in your SQL syntax' in exc.errmsg, exc.errmsg
|
|
547
538
|
|
|
548
539
|
def test_alltypes(self):
|
|
@@ -555,30 +546,8 @@ class TestConnection(unittest.TestCase):
|
|
|
555
546
|
|
|
556
547
|
bits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
|
|
557
548
|
|
|
558
|
-
if self.driver == 'pyodbc':
|
|
559
|
-
odbc_types = {
|
|
560
|
-
# int -> bigint
|
|
561
|
-
3: 8, 1: 8, 2: 8, 9: 8,
|
|
562
|
-
# float -> double
|
|
563
|
-
4: 5,
|
|
564
|
-
# timestamp -> datetime
|
|
565
|
-
7: 12,
|
|
566
|
-
# year -> bigint
|
|
567
|
-
13: 8,
|
|
568
|
-
# char/binary -> varchar/varbinary
|
|
569
|
-
249: 15, 250: 15, 251: 15, 252: 15, 253: 15, 254: 15, 255: 15,
|
|
570
|
-
# newdecimal -> decimal
|
|
571
|
-
246: 0,
|
|
572
|
-
# json -> varchar
|
|
573
|
-
245: 15,
|
|
574
|
-
# bit -> varchar
|
|
575
|
-
16: 15,
|
|
576
|
-
}
|
|
577
|
-
else:
|
|
578
|
-
odbc_types = {}
|
|
579
|
-
|
|
580
549
|
def otype(x):
|
|
581
|
-
return
|
|
550
|
+
return x
|
|
582
551
|
|
|
583
552
|
assert row['id'] == 0, row['id']
|
|
584
553
|
assert typ['id'] == otype(3), typ['id']
|
|
@@ -664,11 +633,6 @@ class TestConnection(unittest.TestCase):
|
|
|
664
633
|
assert row['time'] == datetime.timedelta(minutes=7), row['time']
|
|
665
634
|
assert typ['time'] == 11, typ['time']
|
|
666
635
|
|
|
667
|
-
# pyodbc doesn't support microseconds on times
|
|
668
|
-
if not self.driver == 'pyodbc':
|
|
669
|
-
assert row['time_6'] == datetime.timedelta(
|
|
670
|
-
hours=1, minutes=10, microseconds=2,
|
|
671
|
-
), row['time_6']
|
|
672
636
|
assert typ['time_6'] == 11, typ['time_6']
|
|
673
637
|
|
|
674
638
|
assert row['datetime'] == datetime.datetime(
|
|
@@ -742,14 +706,10 @@ class TestConnection(unittest.TestCase):
|
|
|
742
706
|
), row['tinyblob']
|
|
743
707
|
assert typ['tinyblob'] == otype(249), typ['tinyblob']
|
|
744
708
|
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
assert row['json'] == {
|
|
750
|
-
'a': 10, 'b': 2.75,
|
|
751
|
-
'c': 'hello world',
|
|
752
|
-
}, row['json']
|
|
709
|
+
assert row['json'] == {
|
|
710
|
+
'a': 10, 'b': 2.75,
|
|
711
|
+
'c': 'hello world',
|
|
712
|
+
}, row['json']
|
|
753
713
|
assert typ['json'] == otype(245), typ['json']
|
|
754
714
|
|
|
755
715
|
assert row['enum'] == 'one', row['enum']
|
|
@@ -758,10 +718,7 @@ class TestConnection(unittest.TestCase):
|
|
|
758
718
|
assert row['set'] == 'two', row['set']
|
|
759
719
|
assert typ['set'] == otype(253), typ['set'] # mysql code: 248
|
|
760
720
|
|
|
761
|
-
|
|
762
|
-
assert row['bit'] == b'\x80\x00\x00\x00\x00\x00\x00\x00', row['bit']
|
|
763
|
-
else:
|
|
764
|
-
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']
|
|
765
722
|
assert typ['bit'] == otype(16), typ['bit']
|
|
766
723
|
|
|
767
724
|
def test_alltypes_nulls(self):
|
|
@@ -772,30 +729,8 @@ class TestConnection(unittest.TestCase):
|
|
|
772
729
|
row = dict(zip(names, out))
|
|
773
730
|
typ = dict(zip(names, types))
|
|
774
731
|
|
|
775
|
-
if self.driver == 'pyodbc':
|
|
776
|
-
odbc_types = {
|
|
777
|
-
# int -> bigint
|
|
778
|
-
3: 8, 1: 8, 2: 8, 9: 8,
|
|
779
|
-
# float -> double
|
|
780
|
-
4: 5,
|
|
781
|
-
# timestamp -> datetime
|
|
782
|
-
7: 12,
|
|
783
|
-
# year -> bigint
|
|
784
|
-
13: 8,
|
|
785
|
-
# char/binary -> varchar/varbinary
|
|
786
|
-
249: 15, 250: 15, 251: 15, 252: 15, 253: 15, 254: 15, 255: 15,
|
|
787
|
-
# newdecimal -> decimal
|
|
788
|
-
246: 0,
|
|
789
|
-
# json -> varchar
|
|
790
|
-
245: 15,
|
|
791
|
-
# bit -> varchar
|
|
792
|
-
16: 15,
|
|
793
|
-
}
|
|
794
|
-
else:
|
|
795
|
-
odbc_types = {}
|
|
796
|
-
|
|
797
732
|
def otype(x):
|
|
798
|
-
return
|
|
733
|
+
return x
|
|
799
734
|
|
|
800
735
|
assert row['id'] == 1, row['id']
|
|
801
736
|
assert typ['id'] == otype(3), typ['id']
|
|
@@ -924,78 +859,6 @@ class TestConnection(unittest.TestCase):
|
|
|
924
859
|
assert row['bit'] is None, row['bit']
|
|
925
860
|
assert typ['bit'] == otype(16), typ['bit']
|
|
926
861
|
|
|
927
|
-
def test_convert_exception(self):
|
|
928
|
-
driver = self.conn._driver
|
|
929
|
-
dbapi = driver.dbapi
|
|
930
|
-
|
|
931
|
-
if self.driver in ['mysql.connector', 'http', 'https']:
|
|
932
|
-
exc_args = tuple()
|
|
933
|
-
exc_kwargs = dict(errno=-1, msg='hi there')
|
|
934
|
-
else:
|
|
935
|
-
exc_args = (-1, 'hi there')
|
|
936
|
-
exc_kwargs = {}
|
|
937
|
-
|
|
938
|
-
exc = driver.convert_exception(
|
|
939
|
-
dbapi.NotSupportedError(*exc_args, **exc_kwargs),
|
|
940
|
-
)
|
|
941
|
-
assert exc.args[0] == -1
|
|
942
|
-
assert exc.args[1] == 'hi there'
|
|
943
|
-
assert exc.errno == -1
|
|
944
|
-
assert exc.errmsg == 'hi there'
|
|
945
|
-
assert exc.msg == 'hi there'
|
|
946
|
-
|
|
947
|
-
with self.assertRaises(s2.NotSupportedError):
|
|
948
|
-
raise driver.convert_exception(
|
|
949
|
-
dbapi.NotSupportedError(*exc_args, **exc_kwargs),
|
|
950
|
-
)
|
|
951
|
-
|
|
952
|
-
with self.assertRaises(s2.ProgrammingError):
|
|
953
|
-
raise driver.convert_exception(
|
|
954
|
-
dbapi.ProgrammingError(*exc_args, **exc_kwargs),
|
|
955
|
-
)
|
|
956
|
-
|
|
957
|
-
with self.assertRaises(s2.InternalError):
|
|
958
|
-
raise driver.convert_exception(
|
|
959
|
-
dbapi.InternalError(*exc_args, **exc_kwargs),
|
|
960
|
-
)
|
|
961
|
-
|
|
962
|
-
with self.assertRaises(s2.IntegrityError):
|
|
963
|
-
raise driver.convert_exception(
|
|
964
|
-
dbapi.IntegrityError(*exc_args, **exc_kwargs),
|
|
965
|
-
)
|
|
966
|
-
|
|
967
|
-
with self.assertRaises(s2.OperationalError):
|
|
968
|
-
raise driver.convert_exception(
|
|
969
|
-
dbapi.OperationalError(*exc_args, **exc_kwargs),
|
|
970
|
-
)
|
|
971
|
-
|
|
972
|
-
with self.assertRaises(s2.DataError):
|
|
973
|
-
raise driver.convert_exception(
|
|
974
|
-
dbapi.DataError(*exc_args, **exc_kwargs),
|
|
975
|
-
)
|
|
976
|
-
|
|
977
|
-
with self.assertRaises(s2.DatabaseError):
|
|
978
|
-
raise driver.convert_exception(
|
|
979
|
-
dbapi.DatabaseError(*exc_args, **exc_kwargs),
|
|
980
|
-
)
|
|
981
|
-
|
|
982
|
-
with self.assertRaises(s2.InterfaceError):
|
|
983
|
-
raise driver.convert_exception(
|
|
984
|
-
dbapi.InterfaceError(*exc_args, **exc_kwargs),
|
|
985
|
-
)
|
|
986
|
-
|
|
987
|
-
with self.assertRaises(s2.Error):
|
|
988
|
-
raise driver.convert_exception(
|
|
989
|
-
dbapi.Error(*exc_args, **exc_kwargs),
|
|
990
|
-
)
|
|
991
|
-
|
|
992
|
-
if self.driver == 'mariadb':
|
|
993
|
-
with self.assertRaises(s2.Error):
|
|
994
|
-
raise driver.convert_exception(dbapi.Warning('hi there'))
|
|
995
|
-
else:
|
|
996
|
-
with self.assertRaises(s2.Warning):
|
|
997
|
-
raise driver.convert_exception(dbapi.Warning('hi there'))
|
|
998
|
-
|
|
999
862
|
def test_name_check(self):
|
|
1000
863
|
nc = sc._name_check
|
|
1001
864
|
assert nc('foo') == 'foo'
|
|
@@ -1016,46 +879,31 @@ class TestConnection(unittest.TestCase):
|
|
|
1016
879
|
self.cur.execute('echo return_int()')
|
|
1017
880
|
|
|
1018
881
|
out = self.cur.fetchall()
|
|
1019
|
-
assert out == [(1234567890,)], out
|
|
1020
|
-
|
|
1021
|
-
# These take an extra `nextset` for some reason
|
|
1022
|
-
if self.driver in ['pymysql', 'MySQLdb', 'cymysql', 'pyodbc']:
|
|
1023
|
-
self.cur.nextset()
|
|
882
|
+
assert list(out) == [(1234567890,)], out
|
|
1024
883
|
|
|
1025
884
|
out = self.cur.nextset()
|
|
1026
|
-
assert out is
|
|
885
|
+
assert out is None, out
|
|
1027
886
|
|
|
1028
887
|
def test_echo_with_result_set(self):
|
|
1029
888
|
self.cur.execute('echo result_set_and_return_int()')
|
|
1030
889
|
|
|
1031
890
|
out = self.cur.fetchall()
|
|
1032
|
-
assert out == [(5,)], out
|
|
1033
|
-
|
|
1034
|
-
if self.driver == 'mysql.connector' and s2.get_option('pure_python'):
|
|
1035
|
-
warnings.warn(
|
|
1036
|
-
'The mysql.connector in pure python mode does not '
|
|
1037
|
-
'support multiple result sets.',
|
|
1038
|
-
)
|
|
1039
|
-
return
|
|
891
|
+
assert list(out) == [(5,)], out
|
|
1040
892
|
|
|
1041
893
|
out = self.cur.nextset()
|
|
1042
894
|
assert out is True, out
|
|
1043
895
|
|
|
1044
896
|
out = self.cur.fetchall()
|
|
1045
|
-
assert out == [(1, 2, 3)], out
|
|
897
|
+
assert list(out) == [(1, 2, 3)], out
|
|
1046
898
|
|
|
1047
899
|
out = self.cur.nextset()
|
|
1048
900
|
assert out is True, out
|
|
1049
901
|
|
|
1050
902
|
out = self.cur.fetchall()
|
|
1051
|
-
assert out == [(1234567890,)], out
|
|
1052
|
-
|
|
1053
|
-
# These take an extra `nextset` for some reason
|
|
1054
|
-
if self.driver in ['pymysql', 'MySQLdb', 'cymysql', 'pyodbc']:
|
|
1055
|
-
self.cur.nextset()
|
|
903
|
+
assert list(out) == [(1234567890,)], out
|
|
1056
904
|
|
|
1057
905
|
out = self.cur.nextset()
|
|
1058
|
-
assert out is
|
|
906
|
+
assert out is None, out
|
|
1059
907
|
|
|
1060
908
|
def test_callproc(self):
|
|
1061
909
|
self.cur.callproc('get_animal', ['cats'])
|
|
@@ -1063,25 +911,21 @@ class TestConnection(unittest.TestCase):
|
|
|
1063
911
|
out = self.cur.fetchall()
|
|
1064
912
|
assert list(out) == [(5,)], out
|
|
1065
913
|
|
|
1066
|
-
if self.driver == 'mysql.connector' and s2.get_option('pure_python'):
|
|
1067
|
-
warnings.warn(
|
|
1068
|
-
'The mysql.connector in pure python mode does not '
|
|
1069
|
-
'support multiple result sets.',
|
|
1070
|
-
)
|
|
1071
|
-
return
|
|
1072
|
-
|
|
1073
914
|
out = self.cur.nextset()
|
|
1074
915
|
assert out is True, out
|
|
1075
916
|
|
|
1076
917
|
out = self.cur.fetchall()
|
|
1077
918
|
assert list(out) == [(1, 2, 3)], out
|
|
1078
919
|
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
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
|
|
1082
926
|
|
|
1083
927
|
out = self.cur.nextset()
|
|
1084
|
-
assert out is
|
|
928
|
+
assert out is None, out
|
|
1085
929
|
|
|
1086
930
|
def test_callproc_no_args(self):
|
|
1087
931
|
self.cur.callproc('no_args')
|
|
@@ -1089,38 +933,37 @@ class TestConnection(unittest.TestCase):
|
|
|
1089
933
|
out = self.cur.fetchall()
|
|
1090
934
|
assert list(out) == [(4, 5, 6)], out
|
|
1091
935
|
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
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
|
|
1095
942
|
|
|
1096
943
|
out = self.cur.nextset()
|
|
1097
|
-
assert out is
|
|
944
|
+
assert out is None, out
|
|
1098
945
|
|
|
1099
946
|
def test_callproc_return_int(self):
|
|
1100
947
|
self.cur.callproc('result_set_and_return_int')
|
|
1101
948
|
|
|
1102
949
|
out = self.cur.fetchall()
|
|
1103
|
-
assert out == [(5,)], out
|
|
1104
|
-
|
|
1105
|
-
if self.driver == 'mysql.connector' and s2.get_option('pure_python'):
|
|
1106
|
-
warnings.warn(
|
|
1107
|
-
'The mysql.connector in pure python mode does not '
|
|
1108
|
-
'support multiple result sets.',
|
|
1109
|
-
)
|
|
1110
|
-
return
|
|
950
|
+
assert list(out) == [(5,)], out
|
|
1111
951
|
|
|
1112
952
|
out = self.cur.nextset()
|
|
1113
953
|
assert out is True, out
|
|
1114
954
|
|
|
1115
955
|
out = self.cur.fetchall()
|
|
1116
|
-
assert out == [(1, 2, 3)], out
|
|
956
|
+
assert list(out) == [(1, 2, 3)], out
|
|
1117
957
|
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
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
|
|
1121
964
|
|
|
1122
965
|
out = self.cur.nextset()
|
|
1123
|
-
assert out is
|
|
966
|
+
assert out is None, out
|
|
1124
967
|
|
|
1125
968
|
def test_callproc_bad_args(self):
|
|
1126
969
|
self.cur.callproc('get_animal', [10])
|
|
@@ -1128,31 +971,28 @@ class TestConnection(unittest.TestCase):
|
|
|
1128
971
|
out = self.cur.fetchall()
|
|
1129
972
|
assert list(out) == [], out
|
|
1130
973
|
|
|
1131
|
-
if self.driver == 'mysql.connector' and s2.get_option('pure_python'):
|
|
1132
|
-
warnings.warn(
|
|
1133
|
-
'The mysql.connector in pure python mode does not '
|
|
1134
|
-
'support multiple result sets.',
|
|
1135
|
-
)
|
|
1136
|
-
return
|
|
1137
|
-
|
|
1138
974
|
out = self.cur.nextset()
|
|
1139
975
|
assert out is True, out
|
|
1140
976
|
|
|
1141
977
|
out = self.cur.fetchall()
|
|
1142
978
|
assert list(out) == [(1, 2, 3)], out
|
|
1143
979
|
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
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
|
|
1147
986
|
|
|
1148
987
|
out = self.cur.nextset()
|
|
1149
|
-
assert out is
|
|
988
|
+
assert out is None, out
|
|
1150
989
|
|
|
1151
990
|
def test_callproc_too_many_args(self):
|
|
1152
991
|
with self.assertRaises((
|
|
1153
992
|
s2.ProgrammingError,
|
|
1154
993
|
s2.OperationalError,
|
|
1155
994
|
s2.InternalError,
|
|
995
|
+
TypeError,
|
|
1156
996
|
)):
|
|
1157
997
|
self.cur.callproc('get_animal', ['cats', 'dogs'])
|
|
1158
998
|
|
|
@@ -1160,6 +1000,7 @@ class TestConnection(unittest.TestCase):
|
|
|
1160
1000
|
s2.ProgrammingError,
|
|
1161
1001
|
s2.OperationalError,
|
|
1162
1002
|
s2.InternalError,
|
|
1003
|
+
TypeError,
|
|
1163
1004
|
)):
|
|
1164
1005
|
self.cur.callproc('get_animal', [])
|
|
1165
1006
|
|
|
@@ -1167,43 +1008,43 @@ class TestConnection(unittest.TestCase):
|
|
|
1167
1008
|
s2.ProgrammingError,
|
|
1168
1009
|
s2.OperationalError,
|
|
1169
1010
|
s2.InternalError,
|
|
1011
|
+
TypeError,
|
|
1170
1012
|
)):
|
|
1171
1013
|
self.cur.callproc('get_animal')
|
|
1172
1014
|
|
|
1173
1015
|
def test_cursor_close(self):
|
|
1174
1016
|
self.cur.close()
|
|
1175
1017
|
|
|
1176
|
-
|
|
1177
|
-
self.cur.close()
|
|
1018
|
+
self.cur.close()
|
|
1178
1019
|
|
|
1179
|
-
with self.assertRaises(s2.
|
|
1020
|
+
with self.assertRaises(s2.ProgrammingError):
|
|
1180
1021
|
self.cur.callproc('foo')
|
|
1181
1022
|
|
|
1182
|
-
with self.assertRaises(s2.
|
|
1023
|
+
with self.assertRaises(s2.ProgrammingError):
|
|
1183
1024
|
self.cur.execute('select 1')
|
|
1184
1025
|
|
|
1185
|
-
|
|
1186
|
-
|
|
1026
|
+
# with self.assertRaises(s2.ProgrammingError):
|
|
1027
|
+
# self.cur.executemany('select 1')
|
|
1187
1028
|
|
|
1188
|
-
with self.assertRaises(s2.
|
|
1029
|
+
with self.assertRaises(s2.ProgrammingError):
|
|
1189
1030
|
self.cur.fetchone()
|
|
1190
1031
|
|
|
1191
|
-
with self.assertRaises(s2.
|
|
1032
|
+
with self.assertRaises(s2.ProgrammingError):
|
|
1192
1033
|
self.cur.fetchall()
|
|
1193
1034
|
|
|
1194
|
-
with self.assertRaises(s2.
|
|
1035
|
+
with self.assertRaises(s2.ProgrammingError):
|
|
1195
1036
|
self.cur.fetchmany()
|
|
1196
1037
|
|
|
1197
|
-
with self.assertRaises(s2.
|
|
1038
|
+
with self.assertRaises(s2.ProgrammingError):
|
|
1198
1039
|
self.cur.nextset()
|
|
1199
1040
|
|
|
1200
|
-
|
|
1201
|
-
|
|
1041
|
+
# with self.assertRaises(s2.ProgrammingError):
|
|
1042
|
+
# self.cur.setinputsizes([])
|
|
1202
1043
|
|
|
1203
|
-
|
|
1204
|
-
|
|
1044
|
+
# with self.assertRaises(s2.ProgrammingError):
|
|
1045
|
+
# self.cur.setoutputsize(10)
|
|
1205
1046
|
|
|
1206
|
-
with self.assertRaises(s2.
|
|
1047
|
+
with self.assertRaises(s2.ProgrammingError):
|
|
1207
1048
|
self.cur.scroll(2)
|
|
1208
1049
|
|
|
1209
1050
|
with self.assertRaises(s2.InterfaceError):
|
|
@@ -1221,15 +1062,9 @@ class TestConnection(unittest.TestCase):
|
|
|
1221
1062
|
self.cur.setinputsizes([10, 20, 30])
|
|
1222
1063
|
|
|
1223
1064
|
def test_setoutputsize(self):
|
|
1224
|
-
if self.driver in ['MySQLdb', 'pymysql', 'cymysql']:
|
|
1225
|
-
self.skipTest('outputsize is not supported')
|
|
1226
|
-
|
|
1227
1065
|
self.cur.setoutputsize(100)
|
|
1228
1066
|
|
|
1229
1067
|
def test_scroll(self):
|
|
1230
|
-
if self.driver in ['mysql.connector', 'pyodbc', 'mariadb', 'cymysql']:
|
|
1231
|
-
self.skipTest('scroll is not supported')
|
|
1232
|
-
|
|
1233
1068
|
self.cur.execute('select * from data order by name')
|
|
1234
1069
|
|
|
1235
1070
|
out = self.cur.fetchone()
|
|
@@ -1242,19 +1077,21 @@ class TestConnection(unittest.TestCase):
|
|
|
1242
1077
|
assert out[1] == 'elephants', out[1]
|
|
1243
1078
|
assert self.cur.rownumber == 5, self.cur.rownumber
|
|
1244
1079
|
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1080
|
+
try:
|
|
1081
|
+
self.cur.scroll(0, mode='absolute')
|
|
1082
|
+
assert self.cur.rownumber == 0, self.cur.rownumber
|
|
1248
1083
|
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
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
|
|
1252
1089
|
|
|
1253
1090
|
with self.assertRaises((ValueError, s2.ProgrammingError)):
|
|
1254
1091
|
self.cur.scroll(0, mode='badmode')
|
|
1255
1092
|
|
|
1256
1093
|
def test_autocommit(self):
|
|
1257
|
-
if self.driver in ['http', 'https']:
|
|
1094
|
+
if self.conn.driver in ['http', 'https']:
|
|
1258
1095
|
self.skipTest('Can not set autocommit in HTTP')
|
|
1259
1096
|
|
|
1260
1097
|
orig = self.conn.locals.autocommit
|
|
@@ -1272,10 +1109,11 @@ class TestConnection(unittest.TestCase):
|
|
|
1272
1109
|
def test_conn_close(self):
|
|
1273
1110
|
self.conn.close()
|
|
1274
1111
|
|
|
1275
|
-
self.
|
|
1112
|
+
with self.assertRaises(s2.Error):
|
|
1113
|
+
self.conn.close()
|
|
1276
1114
|
|
|
1277
1115
|
with self.assertRaises(s2.InterfaceError):
|
|
1278
|
-
self.conn.autocommit()
|
|
1116
|
+
self.conn.autocommit(False)
|
|
1279
1117
|
|
|
1280
1118
|
with self.assertRaises(s2.InterfaceError):
|
|
1281
1119
|
self.conn.commit()
|
|
@@ -1283,11 +1121,11 @@ class TestConnection(unittest.TestCase):
|
|
|
1283
1121
|
with self.assertRaises(s2.InterfaceError):
|
|
1284
1122
|
self.conn.rollback()
|
|
1285
1123
|
|
|
1286
|
-
|
|
1287
|
-
|
|
1124
|
+
# with self.assertRaises(s2.InterfaceError):
|
|
1125
|
+
# self.conn.cursor()
|
|
1288
1126
|
|
|
1289
|
-
|
|
1290
|
-
|
|
1127
|
+
# with self.assertRaises(s2.InterfaceError):
|
|
1128
|
+
# self.conn.messages
|
|
1291
1129
|
|
|
1292
1130
|
with self.assertRaises(s2.InterfaceError):
|
|
1293
1131
|
self.conn.globals.autocommit = True
|
|
@@ -1308,7 +1146,7 @@ class TestConnection(unittest.TestCase):
|
|
|
1308
1146
|
self.conn.disable_data_api()
|
|
1309
1147
|
|
|
1310
1148
|
def test_rollback(self):
|
|
1311
|
-
if self.driver in ['http', 'https']:
|
|
1149
|
+
if self.conn.driver in ['http', 'https']:
|
|
1312
1150
|
self.skipTest('Can not set autocommit in HTTP')
|
|
1313
1151
|
|
|
1314
1152
|
self.conn.autocommit(False)
|
|
@@ -1330,7 +1168,7 @@ class TestConnection(unittest.TestCase):
|
|
|
1330
1168
|
assert len(out) == 5, len(out)
|
|
1331
1169
|
|
|
1332
1170
|
def test_commit(self):
|
|
1333
|
-
if self.driver in ['http', 'https']:
|
|
1171
|
+
if self.conn.driver in ['http', 'https']:
|
|
1334
1172
|
self.skipTest('Can not set autocommit in HTTP')
|
|
1335
1173
|
|
|
1336
1174
|
self.conn.autocommit(False)
|
|
@@ -1379,7 +1217,7 @@ class TestConnection(unittest.TestCase):
|
|
|
1379
1217
|
assert val == orig, val
|
|
1380
1218
|
|
|
1381
1219
|
def test_session_var(self):
|
|
1382
|
-
if self.driver in ['http', 'https']:
|
|
1220
|
+
if self.conn.driver in ['http', 'https']:
|
|
1383
1221
|
self.skipTest('Can not change session variable in HTTP')
|
|
1384
1222
|
|
|
1385
1223
|
orig = self.conn.locals.enable_multipartition_queries
|
|
@@ -1397,7 +1235,7 @@ class TestConnection(unittest.TestCase):
|
|
|
1397
1235
|
assert val == orig, val
|
|
1398
1236
|
|
|
1399
1237
|
def test_local_infile(self):
|
|
1400
|
-
if self.driver in ['http', 'https']:
|
|
1238
|
+
if self.conn.driver in ['http', 'https']:
|
|
1401
1239
|
self.skipTest('Can not load local files in HTTP')
|
|
1402
1240
|
|
|
1403
1241
|
path = os.path.join(os.path.dirname(__file__), 'local_infile.csv')
|
|
@@ -1413,16 +1251,16 @@ class TestConnection(unittest.TestCase):
|
|
|
1413
1251
|
|
|
1414
1252
|
try:
|
|
1415
1253
|
self.cur.execute(
|
|
1416
|
-
f'load data local infile
|
|
1254
|
+
f'load data local infile %s into table {tblname} '
|
|
1417
1255
|
'fields terminated by "," lines terminated by "\n";', [path],
|
|
1418
1256
|
)
|
|
1419
1257
|
|
|
1420
|
-
self.cur.execute(f'select * from {tblname}
|
|
1258
|
+
self.cur.execute(f'select * from {tblname} order by first_name')
|
|
1421
1259
|
out = list(self.cur)
|
|
1422
1260
|
assert out == [
|
|
1423
1261
|
('John', 'Doe', 34),
|
|
1424
|
-
('Sandy', 'Smith', 24),
|
|
1425
1262
|
('Patty', 'Jones', 57),
|
|
1263
|
+
('Sandy', 'Smith', 24),
|
|
1426
1264
|
], out
|
|
1427
1265
|
|
|
1428
1266
|
finally:
|
|
@@ -1444,7 +1282,7 @@ class TestConnection(unittest.TestCase):
|
|
|
1444
1282
|
254: upper,
|
|
1445
1283
|
}
|
|
1446
1284
|
|
|
1447
|
-
with s2.connect(database=type(self).dbname,
|
|
1285
|
+
with s2.connect(database=type(self).dbname, conv=convs) as conn:
|
|
1448
1286
|
with conn.cursor() as cur:
|
|
1449
1287
|
cur.execute('select * from alltypes where id = 0')
|
|
1450
1288
|
names = [x[0] for x in cur.description]
|
|
@@ -1474,7 +1312,7 @@ class TestConnection(unittest.TestCase):
|
|
|
1474
1312
|
assert row['tinytext'] == 'This is a tinytext column.', \
|
|
1475
1313
|
row['tinytext']
|
|
1476
1314
|
|
|
1477
|
-
def
|
|
1315
|
+
def test_results_type(self):
|
|
1478
1316
|
columns = [
|
|
1479
1317
|
'id', 'tinyint', 'unsigned_tinyint', 'bool', 'boolean',
|
|
1480
1318
|
'smallint', 'unsigned_smallint', 'mediumint', 'unsigned_mediumint',
|
|
@@ -1488,33 +1326,147 @@ class TestConnection(unittest.TestCase):
|
|
|
1488
1326
|
'set', 'bit',
|
|
1489
1327
|
]
|
|
1490
1328
|
|
|
1491
|
-
with s2.connect(database=type(self).dbname,
|
|
1329
|
+
with s2.connect(database=type(self).dbname, results_type='tuples') as conn:
|
|
1492
1330
|
with conn.cursor() as cur:
|
|
1493
1331
|
cur.execute('select * from alltypes')
|
|
1494
1332
|
out = cur.fetchall()
|
|
1495
1333
|
assert type(out[0]) is tuple, type(out[0])
|
|
1496
1334
|
assert len(out[0]) == len(columns), len(out[0])
|
|
1497
1335
|
|
|
1498
|
-
with s2.connect(database=type(self).dbname,
|
|
1336
|
+
with s2.connect(database=type(self).dbname, results_type='namedtuples') as conn:
|
|
1499
1337
|
with conn.cursor() as cur:
|
|
1500
1338
|
cur.execute('select * from alltypes')
|
|
1501
1339
|
out = cur.fetchall()
|
|
1502
1340
|
assert type(out[0]).__name__ == 'Row', type(out)
|
|
1503
|
-
|
|
1341
|
+
for i, name in enumerate(columns):
|
|
1342
|
+
assert hasattr(out[0], name)
|
|
1343
|
+
assert out[0][i] == getattr(out[0], name)
|
|
1504
1344
|
|
|
1505
|
-
with s2.connect(database=type(self).dbname,
|
|
1345
|
+
with s2.connect(database=type(self).dbname, results_type='dicts') as conn:
|
|
1506
1346
|
with conn.cursor() as cur:
|
|
1507
1347
|
cur.execute('select * from alltypes')
|
|
1508
1348
|
out = cur.fetchall()
|
|
1509
1349
|
assert type(out[0]) is dict, type(out)
|
|
1510
1350
|
assert list(out[0].keys()) == columns, out[0].keys()
|
|
1511
1351
|
|
|
1512
|
-
|
|
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:
|
|
1513
1375
|
with conn.cursor() as cur:
|
|
1514
|
-
cur.execute('
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
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')
|
|
1518
1470
|
|
|
1519
1471
|
|
|
1520
1472
|
if __name__ == '__main__':
|