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
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
# type: ignore
|
|
2
2
|
import datetime
|
|
3
3
|
import ssl
|
|
4
|
-
import sys
|
|
5
4
|
import time
|
|
6
5
|
from unittest import mock
|
|
7
6
|
|
|
8
7
|
import pytest
|
|
9
8
|
|
|
10
|
-
import singlestoredb.
|
|
11
|
-
from singlestoredb.
|
|
12
|
-
from singlestoredb.
|
|
9
|
+
import singlestoredb.mysql as sv
|
|
10
|
+
from singlestoredb.mysql.constants import CLIENT
|
|
11
|
+
from singlestoredb.mysql.tests import base
|
|
13
12
|
|
|
14
13
|
|
|
15
14
|
class TempUser:
|
|
15
|
+
|
|
16
16
|
def __init__(self, c, user, db, auth=None, authdata=None, password=None):
|
|
17
17
|
self._c = c
|
|
18
18
|
self._user = user
|
|
@@ -61,49 +61,51 @@ class TestAuthentication(base.PyMySQLTestCase):
|
|
|
61
61
|
|
|
62
62
|
osuser = os.environ.get('USER')
|
|
63
63
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
64
|
+
# # socket auth requires the current user and for the connection to be a socket
|
|
65
|
+
# # rest do grants @localhost due to incomplete logic - TODO change to @% then
|
|
66
|
+
# db = base.PyMySQLTestCase.databases[0].copy()
|
|
67
|
+
|
|
68
|
+
# socket_auth = db.get('unix_socket') is not None and db.get('host') in (
|
|
69
|
+
# 'localhost',
|
|
70
|
+
# '127.0.0.1',
|
|
71
|
+
# )
|
|
72
|
+
|
|
73
|
+
# dbname = db['database']
|
|
74
|
+
|
|
75
|
+
# cur = sv.connect(**db).cursor()
|
|
76
|
+
# db.pop('user', None)
|
|
77
|
+
# cur.execute('SHOW PLUGINS')
|
|
78
|
+
# for r in cur:
|
|
79
|
+
# if (r[1], r[2]) != ('ACTIVE', 'AUTHENTICATION'):
|
|
80
|
+
# continue
|
|
81
|
+
# if r[3] == 'auth_socket.so' or r[0] == 'unix_socket':
|
|
82
|
+
# socket_plugin_name = r[0]
|
|
83
|
+
# socket_found = True
|
|
84
|
+
# elif r[3] == 'dialog_examples.so':
|
|
85
|
+
# if r[0] == 'two_questions':
|
|
86
|
+
# two_questions_found = True
|
|
87
|
+
# elif r[0] == 'three_attempts':
|
|
88
|
+
# three_attempts_found = True
|
|
89
|
+
# elif r[0] == 'pam':
|
|
90
|
+
# pam_found = True
|
|
91
|
+
# pam_plugin_name = r[3].split('.')[0]
|
|
92
|
+
# if pam_plugin_name == 'auth_pam':
|
|
93
|
+
# pam_plugin_name = 'pam'
|
|
94
|
+
# # MySQL: authentication_pam
|
|
95
|
+
# # https://dev.mysql.com/doc/refman/5.5/en/pam-authentication-plugin.html
|
|
96
|
+
|
|
97
|
+
# # MariaDB: pam
|
|
98
|
+
# # https://mariadb.com/kb/en/mariadb/pam-authentication-plugin/
|
|
99
|
+
|
|
100
|
+
# # Names differ but functionality is close
|
|
101
|
+
# elif r[0] == 'mysql_old_password':
|
|
102
|
+
# mysql_old_password_found = True
|
|
103
|
+
# elif r[0] == 'sha256_password':
|
|
104
|
+
# sha256_password_found = True
|
|
105
|
+
# elif r[0] == 'ed25519':
|
|
106
|
+
# ed25519_found = True
|
|
107
|
+
# # else:
|
|
108
|
+
# # print("plugin: %r" % r[0])
|
|
107
109
|
|
|
108
110
|
@pytest.mark.skip(reason='not currently supported in SingleStoreDB')
|
|
109
111
|
def test_plugin(self):
|
|
@@ -151,8 +153,8 @@ class TestAuthentication(base.PyMySQLTestCase):
|
|
|
151
153
|
TestAuthentication.osuser + '@localhost',
|
|
152
154
|
self.databases[0]['database'],
|
|
153
155
|
self.socket_plugin_name,
|
|
154
|
-
) as
|
|
155
|
-
|
|
156
|
+
) as _:
|
|
157
|
+
sv.connect(user=TestAuthentication.osuser, **self.db)
|
|
156
158
|
|
|
157
159
|
class Dialog:
|
|
158
160
|
fail = False
|
|
@@ -174,7 +176,7 @@ class TestAuthentication(base.PyMySQLTestCase):
|
|
|
174
176
|
def authenticate(self, pkt):
|
|
175
177
|
while True:
|
|
176
178
|
flag = pkt.read_uint8()
|
|
177
|
-
echo = (flag & 0x06) == 0x02
|
|
179
|
+
echo = (flag & 0x06) == 0x02 # noqa: F841
|
|
178
180
|
last = (flag & 0x01) == 0x01
|
|
179
181
|
prompt = pkt.read_all()
|
|
180
182
|
|
|
@@ -224,15 +226,15 @@ class TestAuthentication(base.PyMySQLTestCase):
|
|
|
224
226
|
}
|
|
225
227
|
with TempUser(
|
|
226
228
|
self.connect().cursor(),
|
|
227
|
-
'
|
|
229
|
+
'singlestoredb_2q@localhost',
|
|
228
230
|
self.databases[0]['database'],
|
|
229
231
|
'two_questions',
|
|
230
232
|
'notverysecret',
|
|
231
|
-
) as
|
|
233
|
+
) as _:
|
|
232
234
|
with self.assertRaises(sv.err.OperationalError):
|
|
233
|
-
sv.connect(user='
|
|
235
|
+
sv.connect(user='singlestoredb_2q', **self.db)
|
|
234
236
|
sv.connect(
|
|
235
|
-
user='
|
|
237
|
+
user='singlestoredb_2q',
|
|
236
238
|
auth_plugin_map={b'dialog': TestAuthentication.Dialog},
|
|
237
239
|
**self.db,
|
|
238
240
|
)
|
|
@@ -268,49 +270,51 @@ class TestAuthentication(base.PyMySQLTestCase):
|
|
|
268
270
|
)
|
|
269
271
|
with TempUser(
|
|
270
272
|
self.connect().cursor(),
|
|
271
|
-
'
|
|
273
|
+
'singlestoredb_3a@localhost',
|
|
272
274
|
self.databases[0]['database'],
|
|
273
275
|
'three_attempts',
|
|
274
276
|
'stillnotverysecret',
|
|
275
|
-
) as
|
|
277
|
+
) as _:
|
|
276
278
|
sv.connect(
|
|
277
|
-
user='
|
|
279
|
+
user='singlestoredb_3a',
|
|
278
280
|
auth_plugin_map={b'dialog': TestAuthentication.Dialog},
|
|
279
281
|
**self.db,
|
|
280
282
|
)
|
|
281
283
|
sv.connect(
|
|
282
|
-
user='
|
|
284
|
+
user='singlestoredb_3a',
|
|
283
285
|
auth_plugin_map={b'dialog': TestAuthentication.DialogHandler},
|
|
284
286
|
**self.db,
|
|
285
287
|
)
|
|
286
288
|
with self.assertRaises(sv.err.OperationalError):
|
|
287
289
|
sv.connect(
|
|
288
|
-
user='
|
|
290
|
+
user='singlestoredb_3a',
|
|
291
|
+
auth_plugin_map={b'dialog': object},
|
|
292
|
+
**self.db,
|
|
289
293
|
)
|
|
290
294
|
|
|
291
295
|
with self.assertRaises(sv.err.OperationalError):
|
|
292
296
|
sv.connect(
|
|
293
|
-
user='
|
|
297
|
+
user='singlestoredb_3a',
|
|
294
298
|
auth_plugin_map={b'dialog': TestAuthentication.DefectiveHandler},
|
|
295
299
|
**self.db,
|
|
296
300
|
)
|
|
297
301
|
with self.assertRaises(sv.err.OperationalError):
|
|
298
302
|
sv.connect(
|
|
299
|
-
user='
|
|
303
|
+
user='singlestoredb_3a',
|
|
300
304
|
auth_plugin_map={b'notdialogplugin': TestAuthentication.Dialog},
|
|
301
305
|
**self.db,
|
|
302
306
|
)
|
|
303
307
|
TestAuthentication.Dialog.m = {b'Password, please:': b'I do not know'}
|
|
304
308
|
with self.assertRaises(sv.err.OperationalError):
|
|
305
309
|
sv.connect(
|
|
306
|
-
user='
|
|
310
|
+
user='singlestoredb_3a',
|
|
307
311
|
auth_plugin_map={b'dialog': TestAuthentication.Dialog},
|
|
308
312
|
**self.db,
|
|
309
313
|
)
|
|
310
314
|
TestAuthentication.Dialog.m = {b'Password, please:': None}
|
|
311
315
|
with self.assertRaises(sv.err.OperationalError):
|
|
312
316
|
sv.connect(
|
|
313
|
-
user='
|
|
317
|
+
user='singlestoredb_3a',
|
|
314
318
|
auth_plugin_map={b'dialog': TestAuthentication.Dialog},
|
|
315
319
|
**self.db,
|
|
316
320
|
)
|
|
@@ -368,26 +372,29 @@ class TestAuthentication(base.PyMySQLTestCase):
|
|
|
368
372
|
self.databases[0]['database'],
|
|
369
373
|
'pam',
|
|
370
374
|
os.environ.get('PAMSERVICE'),
|
|
371
|
-
) as
|
|
375
|
+
) as _:
|
|
372
376
|
try:
|
|
373
|
-
c = sv.connect(user=TestAuthentication.osuser, **db)
|
|
377
|
+
c = sv.connect(user=TestAuthentication.osuser, **db) # noqa: F841
|
|
374
378
|
db['password'] = 'very bad guess at password'
|
|
375
379
|
with self.assertRaises(sv.err.OperationalError):
|
|
376
380
|
sv.connect(
|
|
377
381
|
user=TestAuthentication.osuser,
|
|
378
382
|
auth_plugin_map={
|
|
379
|
-
b'mysql_cleartext_password':
|
|
383
|
+
b'mysql_cleartext_password':
|
|
384
|
+
TestAuthentication.DefectiveHandler,
|
|
380
385
|
},
|
|
381
386
|
**self.db,
|
|
382
387
|
)
|
|
383
388
|
except sv.OperationalError as e:
|
|
384
389
|
self.assertEqual(1045, e.args[0])
|
|
385
|
-
# we had 'bad guess at password' work with pam. Well at least
|
|
390
|
+
# we had 'bad guess at password' work with pam. Well at least
|
|
391
|
+
# we get a permission denied here
|
|
386
392
|
with self.assertRaises(sv.err.OperationalError):
|
|
387
393
|
sv.connect(
|
|
388
394
|
user=TestAuthentication.osuser,
|
|
389
395
|
auth_plugin_map={
|
|
390
|
-
b'mysql_cleartext_password':
|
|
396
|
+
b'mysql_cleartext_password':
|
|
397
|
+
TestAuthentication.DefectiveHandler,
|
|
391
398
|
},
|
|
392
399
|
**self.db,
|
|
393
400
|
)
|
|
@@ -406,17 +413,18 @@ class TestAuthentication(base.PyMySQLTestCase):
|
|
|
406
413
|
c = conn.cursor()
|
|
407
414
|
with TempUser(
|
|
408
415
|
c,
|
|
409
|
-
'
|
|
416
|
+
'singlestoredb_sha256@localhost',
|
|
410
417
|
self.databases[0]['database'],
|
|
411
418
|
'sha256_password',
|
|
412
|
-
) as
|
|
413
|
-
c.execute("SET PASSWORD FOR '
|
|
419
|
+
) as _:
|
|
420
|
+
c.execute("SET PASSWORD FOR 'singlestoredb_sha256'@'localhost' ='Sh@256Pa33'")
|
|
414
421
|
c.execute('FLUSH PRIVILEGES')
|
|
415
422
|
db = self.db.copy()
|
|
416
423
|
db['password'] = 'Sh@256Pa33'
|
|
417
|
-
# Although SHA256 is supported, need the configuration of public
|
|
424
|
+
# Although SHA256 is supported, need the configuration of public
|
|
425
|
+
# key of the mysql server. Currently will get error by this test.
|
|
418
426
|
with self.assertRaises(sv.err.OperationalError):
|
|
419
|
-
sv.connect(user='
|
|
427
|
+
sv.connect(user='singlestoredb_sha256', **db)
|
|
420
428
|
|
|
421
429
|
@pytest.mark.skipif(not ed25519_found, reason='no ed25519 authention plugin')
|
|
422
430
|
def testAuthEd25519(self):
|
|
@@ -431,32 +439,33 @@ class TestAuthentication(base.PyMySQLTestCase):
|
|
|
431
439
|
|
|
432
440
|
with TempUser(
|
|
433
441
|
c,
|
|
434
|
-
'
|
|
442
|
+
'singlestoredb_ed25519',
|
|
435
443
|
self.databases[0]['database'],
|
|
436
444
|
'ed25519',
|
|
437
445
|
empty_pass,
|
|
438
|
-
) as
|
|
439
|
-
sv.connect(user='
|
|
446
|
+
) as _:
|
|
447
|
+
sv.connect(user='singlestoredb_ed25519', password='', **db)
|
|
440
448
|
|
|
441
449
|
with TempUser(
|
|
442
450
|
c,
|
|
443
|
-
'
|
|
451
|
+
'singlestoredb_ed25519',
|
|
444
452
|
self.databases[0]['database'],
|
|
445
453
|
'ed25519',
|
|
446
454
|
non_empty_pass,
|
|
447
|
-
) as
|
|
448
|
-
sv.connect(user='
|
|
455
|
+
) as _:
|
|
456
|
+
sv.connect(user='singlestoredb_ed25519', password='ed25519_password', **db)
|
|
449
457
|
|
|
450
458
|
|
|
451
459
|
class TestConnection(base.PyMySQLTestCase):
|
|
460
|
+
|
|
452
461
|
def test_utf8mb4(self):
|
|
453
|
-
"""This test requires MySQL >= 5.5"""
|
|
462
|
+
"""This test requires MySQL >= 5.5."""
|
|
454
463
|
arg = self.databases[0].copy()
|
|
455
464
|
arg['charset'] = 'utf8mb4'
|
|
456
|
-
conn = sv.connect(**arg)
|
|
465
|
+
conn = sv.connect(**arg) # noqa: F841
|
|
457
466
|
|
|
458
467
|
def test_largedata(self):
|
|
459
|
-
"""Large query and response (>=16MB)"""
|
|
468
|
+
"""Large query and response (>=16MB)."""
|
|
460
469
|
cur = self.connect().cursor()
|
|
461
470
|
cur.execute('SELECT @@max_allowed_packet')
|
|
462
471
|
if cur.fetchone()[0] < 16 * 1024 * 1024 + 10:
|
|
@@ -497,6 +506,7 @@ class TestConnection(base.PyMySQLTestCase):
|
|
|
497
506
|
"""
|
|
498
507
|
http://dev.mysql.com/doc/refman/5.0/en/gone-away.html
|
|
499
508
|
http://dev.mysql.com/doc/refman/5.0/en/error-messages-client.html#error_cr_server_gone_error
|
|
509
|
+
|
|
500
510
|
"""
|
|
501
511
|
con = self.connect()
|
|
502
512
|
cur = con.cursor()
|
|
@@ -559,9 +569,9 @@ class TestConnection(base.PyMySQLTestCase):
|
|
|
559
569
|
def test_ssl_connect(self):
|
|
560
570
|
dummy_ssl_context = mock.Mock(options=0)
|
|
561
571
|
with mock.patch(
|
|
562
|
-
'
|
|
563
|
-
) as
|
|
564
|
-
'
|
|
572
|
+
'singlestoredb.connections.Connection.connect',
|
|
573
|
+
) as _, mock.patch(
|
|
574
|
+
'singlestoredb.connections.ssl.create_default_context',
|
|
565
575
|
new=mock.Mock(return_value=dummy_ssl_context),
|
|
566
576
|
) as create_default_context:
|
|
567
577
|
sv.connect(
|
|
@@ -580,9 +590,9 @@ class TestConnection(base.PyMySQLTestCase):
|
|
|
580
590
|
|
|
581
591
|
dummy_ssl_context = mock.Mock(options=0)
|
|
582
592
|
with mock.patch(
|
|
583
|
-
'
|
|
584
|
-
) as
|
|
585
|
-
'
|
|
593
|
+
'singlestoredb.connections.Connection.connect',
|
|
594
|
+
) as _, mock.patch(
|
|
595
|
+
'singelstoredb.connections.ssl.create_default_context',
|
|
586
596
|
new=mock.Mock(return_value=dummy_ssl_context),
|
|
587
597
|
) as create_default_context:
|
|
588
598
|
sv.connect(
|
|
@@ -600,9 +610,9 @@ class TestConnection(base.PyMySQLTestCase):
|
|
|
600
610
|
|
|
601
611
|
dummy_ssl_context = mock.Mock(options=0)
|
|
602
612
|
with mock.patch(
|
|
603
|
-
'
|
|
604
|
-
) as
|
|
605
|
-
'
|
|
613
|
+
'singelstoredb.connections.Connection.connect',
|
|
614
|
+
) as _, mock.patch(
|
|
615
|
+
'singlestoredb.connections.ssl.create_default_context',
|
|
606
616
|
new=mock.Mock(return_value=dummy_ssl_context),
|
|
607
617
|
) as create_default_context:
|
|
608
618
|
sv.connect(
|
|
@@ -616,9 +626,9 @@ class TestConnection(base.PyMySQLTestCase):
|
|
|
616
626
|
|
|
617
627
|
dummy_ssl_context = mock.Mock(options=0)
|
|
618
628
|
with mock.patch(
|
|
619
|
-
'
|
|
620
|
-
) as
|
|
621
|
-
'
|
|
629
|
+
'singlestoredb.connections.Connection.connect',
|
|
630
|
+
) as _, mock.patch(
|
|
631
|
+
'singlestoredb.connections.ssl.create_default_context',
|
|
622
632
|
new=mock.Mock(return_value=dummy_ssl_context),
|
|
623
633
|
) as create_default_context:
|
|
624
634
|
sv.connect(
|
|
@@ -635,9 +645,9 @@ class TestConnection(base.PyMySQLTestCase):
|
|
|
635
645
|
for ssl_verify_cert in (True, '1', 'yes', 'true'):
|
|
636
646
|
dummy_ssl_context = mock.Mock(options=0)
|
|
637
647
|
with mock.patch(
|
|
638
|
-
'
|
|
639
|
-
) as
|
|
640
|
-
'
|
|
648
|
+
'singlestoredb.connections.Connection.connect',
|
|
649
|
+
) as _, mock.patch(
|
|
650
|
+
'singlestoredb.connections.ssl.create_default_context',
|
|
641
651
|
new=mock.Mock(return_value=dummy_ssl_context),
|
|
642
652
|
) as create_default_context:
|
|
643
653
|
sv.connect(
|
|
@@ -656,9 +666,9 @@ class TestConnection(base.PyMySQLTestCase):
|
|
|
656
666
|
for ssl_verify_cert in (None, False, '0', 'no', 'false'):
|
|
657
667
|
dummy_ssl_context = mock.Mock(options=0)
|
|
658
668
|
with mock.patch(
|
|
659
|
-
'
|
|
660
|
-
) as
|
|
661
|
-
'
|
|
669
|
+
'singlestoredb.connections.Connection.connect',
|
|
670
|
+
) as _, mock.patch(
|
|
671
|
+
'singlestoredb.connections.ssl.create_default_context',
|
|
662
672
|
new=mock.Mock(return_value=dummy_ssl_context),
|
|
663
673
|
) as create_default_context:
|
|
664
674
|
sv.connect(
|
|
@@ -678,9 +688,9 @@ class TestConnection(base.PyMySQLTestCase):
|
|
|
678
688
|
for ssl_verify_cert in ('foo', 'bar', ''):
|
|
679
689
|
dummy_ssl_context = mock.Mock(options=0)
|
|
680
690
|
with mock.patch(
|
|
681
|
-
'
|
|
682
|
-
) as
|
|
683
|
-
'
|
|
691
|
+
'singlestoredb.connections.Connection.connect',
|
|
692
|
+
) as _, mock.patch(
|
|
693
|
+
'singlestoredb.connections.ssl.create_default_context',
|
|
684
694
|
new=mock.Mock(return_value=dummy_ssl_context),
|
|
685
695
|
) as create_default_context:
|
|
686
696
|
sv.connect(
|
|
@@ -701,9 +711,9 @@ class TestConnection(base.PyMySQLTestCase):
|
|
|
701
711
|
|
|
702
712
|
dummy_ssl_context = mock.Mock(options=0)
|
|
703
713
|
with mock.patch(
|
|
704
|
-
'
|
|
705
|
-
) as
|
|
706
|
-
'
|
|
714
|
+
'singlestoredb.connections.Connection.connect',
|
|
715
|
+
) as _, mock.patch(
|
|
716
|
+
'singlestoredb.connections.ssl.create_default_context',
|
|
707
717
|
new=mock.Mock(return_value=dummy_ssl_context),
|
|
708
718
|
) as create_default_context:
|
|
709
719
|
sv.connect(
|
|
@@ -720,9 +730,9 @@ class TestConnection(base.PyMySQLTestCase):
|
|
|
720
730
|
|
|
721
731
|
dummy_ssl_context = mock.Mock(options=0)
|
|
722
732
|
with mock.patch(
|
|
723
|
-
'
|
|
724
|
-
) as
|
|
725
|
-
'
|
|
733
|
+
'singlestoredb.connections.Connection.connect',
|
|
734
|
+
) as _, mock.patch(
|
|
735
|
+
'singlestoredb.connections.ssl.create_default_context',
|
|
726
736
|
new=mock.Mock(return_value=dummy_ssl_context),
|
|
727
737
|
) as create_default_context:
|
|
728
738
|
sv.connect(
|
|
@@ -737,9 +747,9 @@ class TestConnection(base.PyMySQLTestCase):
|
|
|
737
747
|
|
|
738
748
|
dummy_ssl_context = mock.Mock(options=0)
|
|
739
749
|
with mock.patch(
|
|
740
|
-
'
|
|
741
|
-
) as
|
|
742
|
-
'
|
|
750
|
+
'singlestoredb.connections.Connection.connect',
|
|
751
|
+
) as _, mock.patch(
|
|
752
|
+
'singlestoredb.connections.ssl.create_default_context',
|
|
743
753
|
new=mock.Mock(return_value=dummy_ssl_context),
|
|
744
754
|
) as create_default_context:
|
|
745
755
|
sv.connect(
|
|
@@ -761,9 +771,10 @@ def escape_foo(x, d):
|
|
|
761
771
|
|
|
762
772
|
|
|
763
773
|
class TestEscape(base.PyMySQLTestCase):
|
|
774
|
+
|
|
764
775
|
def test_escape_string(self):
|
|
765
776
|
con = self.connect()
|
|
766
|
-
cur = con.cursor()
|
|
777
|
+
cur = con.cursor() # noqa: F841
|
|
767
778
|
|
|
768
779
|
self.assertEqual(con.escape("foo'bar"), "'foo\\'bar'")
|
|
769
780
|
# # added NO_AUTO_CREATE_USER as not including it in 5.7 generates warnings
|
|
@@ -776,21 +787,21 @@ class TestEscape(base.PyMySQLTestCase):
|
|
|
776
787
|
|
|
777
788
|
def test_escape_builtin_encoders(self):
|
|
778
789
|
con = self.connect()
|
|
779
|
-
cur = con.cursor()
|
|
790
|
+
cur = con.cursor() # noqa: F841
|
|
780
791
|
|
|
781
792
|
val = datetime.datetime(2012, 3, 4, 5, 6)
|
|
782
793
|
self.assertEqual(con.escape(val, con.encoders), "'2012-03-04 05:06:00'")
|
|
783
794
|
|
|
784
795
|
def test_escape_custom_object(self):
|
|
785
796
|
con = self.connect()
|
|
786
|
-
cur = con.cursor()
|
|
797
|
+
cur = con.cursor() # noqa: F841
|
|
787
798
|
|
|
788
799
|
mapping = {Foo: escape_foo}
|
|
789
800
|
self.assertEqual(con.escape(Foo(), mapping), 'bar')
|
|
790
801
|
|
|
791
802
|
def test_escape_fallback_encoder(self):
|
|
792
803
|
con = self.connect()
|
|
793
|
-
cur = con.cursor()
|
|
804
|
+
cur = con.cursor() # noqa: F841
|
|
794
805
|
|
|
795
806
|
class Custom(str):
|
|
796
807
|
pass
|
|
@@ -800,13 +811,13 @@ class TestEscape(base.PyMySQLTestCase):
|
|
|
800
811
|
|
|
801
812
|
def test_escape_no_default(self):
|
|
802
813
|
con = self.connect()
|
|
803
|
-
cur = con.cursor()
|
|
814
|
+
cur = con.cursor() # noqa: F841
|
|
804
815
|
|
|
805
816
|
self.assertRaises(TypeError, con.escape, 42, {})
|
|
806
817
|
|
|
807
818
|
def test_escape_dict_value(self):
|
|
808
819
|
con = self.connect()
|
|
809
|
-
cur = con.cursor()
|
|
820
|
+
cur = con.cursor() # noqa: F841
|
|
810
821
|
|
|
811
822
|
mapping = con.encoders.copy()
|
|
812
823
|
mapping[Foo] = escape_foo
|
|
@@ -814,7 +825,7 @@ class TestEscape(base.PyMySQLTestCase):
|
|
|
814
825
|
|
|
815
826
|
def test_escape_list_item(self):
|
|
816
827
|
con = self.connect()
|
|
817
|
-
cur = con.cursor()
|
|
828
|
+
cur = con.cursor() # noqa: F841
|
|
818
829
|
|
|
819
830
|
mapping = con.encoders.copy()
|
|
820
831
|
mapping[Foo] = escape_foo
|
|
@@ -2,24 +2,26 @@
|
|
|
2
2
|
import datetime
|
|
3
3
|
from unittest import TestCase
|
|
4
4
|
|
|
5
|
-
from singlestoredb
|
|
5
|
+
from singlestoredb import converters
|
|
6
|
+
from singlestoredb.mysql.converters import escape_string
|
|
6
7
|
|
|
7
8
|
|
|
8
9
|
__all__ = ['TestConverter']
|
|
9
10
|
|
|
10
11
|
|
|
11
12
|
class TestConverter(TestCase):
|
|
13
|
+
|
|
12
14
|
def test_escape_string(self):
|
|
13
|
-
self.assertEqual(
|
|
15
|
+
self.assertEqual(escape_string('foo\nbar'), 'foo\\nbar')
|
|
14
16
|
|
|
15
17
|
def test_convert_datetime(self):
|
|
16
18
|
expected = datetime.datetime(2007, 2, 24, 23, 6, 20)
|
|
17
|
-
dt = converters.
|
|
19
|
+
dt = converters.datetime_or_none('2007-02-24 23:06:20')
|
|
18
20
|
self.assertEqual(dt, expected)
|
|
19
21
|
|
|
20
22
|
def test_convert_datetime_with_fsp(self):
|
|
21
23
|
expected = datetime.datetime(2007, 2, 24, 23, 6, 20, 511581)
|
|
22
|
-
dt = converters.
|
|
24
|
+
dt = converters.datetime_or_none('2007-02-24 23:06:20.511581')
|
|
23
25
|
self.assertEqual(dt, expected)
|
|
24
26
|
|
|
25
27
|
def _test_convert_timedelta(self, with_negate=False, with_fsp=False):
|
|
@@ -34,7 +36,7 @@ class TestConverter(TestCase):
|
|
|
34
36
|
expected = -expected
|
|
35
37
|
s = '-' + s
|
|
36
38
|
|
|
37
|
-
tdelta = converters.
|
|
39
|
+
tdelta = converters.timedelta_or_none(s)
|
|
38
40
|
self.assertEqual(tdelta, expected)
|
|
39
41
|
|
|
40
42
|
def test_convert_timedelta(self):
|
|
@@ -47,10 +49,10 @@ class TestConverter(TestCase):
|
|
|
47
49
|
|
|
48
50
|
def test_convert_time(self):
|
|
49
51
|
expected = datetime.time(23, 6, 20)
|
|
50
|
-
time_obj = converters.
|
|
52
|
+
time_obj = converters.time_or_none('23:06:20')
|
|
51
53
|
self.assertEqual(time_obj, expected)
|
|
52
54
|
|
|
53
55
|
def test_convert_time_with_fsp(self):
|
|
54
56
|
expected = datetime.time(23, 6, 20, 511581)
|
|
55
|
-
time_obj = converters.
|
|
57
|
+
time_obj = converters.time_or_none('23:06:20.511581')
|
|
56
58
|
self.assertEqual(time_obj, expected)
|