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,45 +0,0 @@
|
|
|
1
|
-
import re
|
|
2
|
-
from typing import Any
|
|
3
|
-
from typing import Dict
|
|
4
|
-
|
|
5
|
-
from . import base
|
|
6
|
-
from .cymysql import CyMySQLDriver
|
|
7
|
-
from .http import HTTPDriver
|
|
8
|
-
from .http import HTTPSDriver
|
|
9
|
-
from .mariadb import MariaDBDriver
|
|
10
|
-
from .mysqlconnector import MySQLConnectorDriver
|
|
11
|
-
from .mysqldb import MySQLdbDriver
|
|
12
|
-
from .pymysql import PyMySQLDriver
|
|
13
|
-
from .pymysqlsv import PyMySQLsvDriver
|
|
14
|
-
from .pyodbc import PyODBCDriver
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
def get_driver(name: str, params: Dict[str, Any]) -> base.Driver:
|
|
18
|
-
"""
|
|
19
|
-
Return the driver with the given name.
|
|
20
|
-
|
|
21
|
-
Parameters
|
|
22
|
-
----------
|
|
23
|
-
name : str
|
|
24
|
-
Name of the driver. All non-letters/digits will be removed
|
|
25
|
-
from the name when matching. For example, 'mysqlconnector'
|
|
26
|
-
will match 'mysql.connector' or 'mysqlconnector'. Matches
|
|
27
|
-
are also case-insensitive.
|
|
28
|
-
params : dict
|
|
29
|
-
Dictionary of connection parameters
|
|
30
|
-
|
|
31
|
-
Returns
|
|
32
|
-
-------
|
|
33
|
-
Driver
|
|
34
|
-
|
|
35
|
-
"""
|
|
36
|
-
rm_symbols = re.compile(r'[^A-Z0-9]', flags=re.I)
|
|
37
|
-
new_name = rm_symbols.sub(r'', name).lower()
|
|
38
|
-
for item in globals().values():
|
|
39
|
-
if type(item) is not type:
|
|
40
|
-
continue
|
|
41
|
-
if not issubclass(item, base.Driver):
|
|
42
|
-
continue
|
|
43
|
-
if new_name == rm_symbols.sub(r'', item.name.lower()):
|
|
44
|
-
return item(**params)
|
|
45
|
-
raise RuntimeError("Could not locate driver with name '{}'".format(name))
|
singlestoredb/drivers/base.py
DELETED
|
@@ -1,198 +0,0 @@
|
|
|
1
|
-
import sys
|
|
2
|
-
from typing import Any
|
|
3
|
-
from typing import Callable
|
|
4
|
-
from typing import Dict
|
|
5
|
-
from typing import Optional
|
|
6
|
-
|
|
7
|
-
from .. import exceptions
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
def wrap_converter(
|
|
11
|
-
outer: Optional[Callable[[Any], Any]],
|
|
12
|
-
conv: Optional[Callable[[Any], Any]],
|
|
13
|
-
) -> Optional[Callable[[Any], Any]]:
|
|
14
|
-
"""Create a pipeline from two functions."""
|
|
15
|
-
if outer is None:
|
|
16
|
-
return conv
|
|
17
|
-
|
|
18
|
-
if conv is None:
|
|
19
|
-
return outer
|
|
20
|
-
|
|
21
|
-
def converter(value: Any) -> Any:
|
|
22
|
-
return outer(conv(value)) # type: ignore
|
|
23
|
-
|
|
24
|
-
return converter
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
class Driver(object):
|
|
28
|
-
"""Base driver class."""
|
|
29
|
-
|
|
30
|
-
# Name of driver used in connections
|
|
31
|
-
name: str = ''
|
|
32
|
-
|
|
33
|
-
# Name of package to import
|
|
34
|
-
pkg_name: str = ''
|
|
35
|
-
|
|
36
|
-
# Name of the package on PyPI.org
|
|
37
|
-
pypi: str = ''
|
|
38
|
-
|
|
39
|
-
# Name of the package on Anaconda.org
|
|
40
|
-
anaconda: str = ''
|
|
41
|
-
|
|
42
|
-
# Does the driver return bytes for all data values?
|
|
43
|
-
# If true and flags are available in the description to deterimine
|
|
44
|
-
# if a character field is text or binary, the text will be automatically
|
|
45
|
-
# decoded before conversion functions are run.
|
|
46
|
-
returns_bytes: bool = False
|
|
47
|
-
|
|
48
|
-
def __init__(self, **kwargs: Any):
|
|
49
|
-
self._params = kwargs
|
|
50
|
-
|
|
51
|
-
# These converters get applied after the driver does its own
|
|
52
|
-
# conversions. This allows each driver to decide which conversions
|
|
53
|
-
# get handled internally and which get applied by this framework.
|
|
54
|
-
self.converters: Dict[int, Callable[[Any], Any]] = {}
|
|
55
|
-
|
|
56
|
-
def connect(self) -> Any:
|
|
57
|
-
"""Create a new connection."""
|
|
58
|
-
params = {
|
|
59
|
-
k: v for k, v in self.remap_params(self._params).items() if v is not None
|
|
60
|
-
}
|
|
61
|
-
conn = self.dbapi.connect(**params)
|
|
62
|
-
self.after_connect(conn, self._params)
|
|
63
|
-
return conn
|
|
64
|
-
|
|
65
|
-
def merge_converters(
|
|
66
|
-
self,
|
|
67
|
-
user_converters: Dict[int, Callable[[Any], Any]],
|
|
68
|
-
driver_converters: Dict[int, Callable[[Any], Any]],
|
|
69
|
-
) -> Dict[int, Callable[[Any], Any]]:
|
|
70
|
-
"""Merge two sets of converters into pipelines as needed."""
|
|
71
|
-
out = dict(driver_converters)
|
|
72
|
-
for key, value in user_converters.items():
|
|
73
|
-
func = wrap_converter(value, out.get(key))
|
|
74
|
-
if func is not None:
|
|
75
|
-
out[key] = func
|
|
76
|
-
return out
|
|
77
|
-
|
|
78
|
-
def after_connect(self, conn: Any, params: Dict[str, Any]) -> None:
|
|
79
|
-
"""
|
|
80
|
-
Callback for immediately after making a connection.
|
|
81
|
-
|
|
82
|
-
Parameters
|
|
83
|
-
----------
|
|
84
|
-
conn : Connection
|
|
85
|
-
Connection object
|
|
86
|
-
params : dict
|
|
87
|
-
Original connection parameters
|
|
88
|
-
|
|
89
|
-
"""
|
|
90
|
-
return
|
|
91
|
-
|
|
92
|
-
def is_connected(self, conn: Any, reconnect: bool = False) -> bool:
|
|
93
|
-
"""
|
|
94
|
-
Determine if the server is still connected.
|
|
95
|
-
|
|
96
|
-
Parameters
|
|
97
|
-
----------
|
|
98
|
-
conn : Connection
|
|
99
|
-
Connection object to test
|
|
100
|
-
reconnect : bool, optional
|
|
101
|
-
If the server is not connected, should a reconnection be attempted?
|
|
102
|
-
|
|
103
|
-
Returns
|
|
104
|
-
-------
|
|
105
|
-
bool
|
|
106
|
-
|
|
107
|
-
"""
|
|
108
|
-
raise NotImplementedError
|
|
109
|
-
|
|
110
|
-
def remap_params(self, params: Dict[str, Any]) -> Dict[str, Any]:
|
|
111
|
-
"""
|
|
112
|
-
Map generalized parameters to package-specific parameters.
|
|
113
|
-
|
|
114
|
-
Parameters
|
|
115
|
-
----------
|
|
116
|
-
params : dict
|
|
117
|
-
Dictionary of connection parameters.
|
|
118
|
-
|
|
119
|
-
Returns
|
|
120
|
-
-------
|
|
121
|
-
dict
|
|
122
|
-
|
|
123
|
-
"""
|
|
124
|
-
return params
|
|
125
|
-
|
|
126
|
-
def convert_exception(self, exc: Exception) -> Exception:
|
|
127
|
-
"""Convert driver-specific exception to SingleStoreDB exception."""
|
|
128
|
-
dbapi = self.dbapi
|
|
129
|
-
if not isinstance(exc, (dbapi.Error, dbapi.Warning)):
|
|
130
|
-
return exc
|
|
131
|
-
new_exc: Optional[type] = None
|
|
132
|
-
if isinstance(exc, dbapi.NotSupportedError):
|
|
133
|
-
new_exc = exceptions.NotSupportedError
|
|
134
|
-
elif isinstance(exc, dbapi.ProgrammingError):
|
|
135
|
-
new_exc = exceptions.ProgrammingError
|
|
136
|
-
elif isinstance(exc, dbapi.InternalError):
|
|
137
|
-
new_exc = exceptions.InternalError
|
|
138
|
-
elif isinstance(exc, dbapi.IntegrityError):
|
|
139
|
-
new_exc = exceptions.IntegrityError
|
|
140
|
-
elif isinstance(exc, dbapi.OperationalError):
|
|
141
|
-
new_exc = exceptions.OperationalError
|
|
142
|
-
elif isinstance(exc, dbapi.DataError):
|
|
143
|
-
new_exc = exceptions.DataError
|
|
144
|
-
elif isinstance(exc, dbapi.DatabaseError):
|
|
145
|
-
new_exc = exceptions.DatabaseError
|
|
146
|
-
elif isinstance(exc, dbapi.InterfaceError):
|
|
147
|
-
new_exc = exceptions.InterfaceError
|
|
148
|
-
elif isinstance(exc, dbapi.Error):
|
|
149
|
-
new_exc = exceptions.Error
|
|
150
|
-
elif isinstance(exc, dbapi.Warning):
|
|
151
|
-
new_exc = exceptions.Warning
|
|
152
|
-
if new_exc is None:
|
|
153
|
-
return exc
|
|
154
|
-
|
|
155
|
-
# Check for exceptions with errno / msg first
|
|
156
|
-
errno = getattr(exc, 'errno', None)
|
|
157
|
-
msg = getattr(exc, 'msg', None)
|
|
158
|
-
if msg:
|
|
159
|
-
return new_exc(
|
|
160
|
-
errno=errno, msg=msg,
|
|
161
|
-
sqlstate=getattr(exc, 'sqlstate', None),
|
|
162
|
-
)
|
|
163
|
-
|
|
164
|
-
# Check for exceptions with just args
|
|
165
|
-
args = getattr(exc, 'args', [])
|
|
166
|
-
if len(args) > 1:
|
|
167
|
-
return new_exc(args[0], args[1])
|
|
168
|
-
if len(args):
|
|
169
|
-
return new_exc(args[0])
|
|
170
|
-
|
|
171
|
-
# Don't know what type it is
|
|
172
|
-
raise ValueError(f'Unrecognized exception format: {exc}')
|
|
173
|
-
|
|
174
|
-
@property
|
|
175
|
-
def dbapi(self) -> Any:
|
|
176
|
-
"""Return imported DB-API-compatible module."""
|
|
177
|
-
if not type(self).pkg_name:
|
|
178
|
-
raise ValueError('No package name defined in driver.')
|
|
179
|
-
try:
|
|
180
|
-
return __import__(type(self).pkg_name, {}, {}, ['connect'])
|
|
181
|
-
except ModuleNotFoundError:
|
|
182
|
-
msg = []
|
|
183
|
-
msg.append('{} is not available.'.format(type(self).pkg_name))
|
|
184
|
-
msg.append(" Use 'pip install {}'".format(type(self).pypi))
|
|
185
|
-
if type(self).anaconda:
|
|
186
|
-
if '::' in type(self).anaconda:
|
|
187
|
-
msg.append(
|
|
188
|
-
" or 'conda install -c {} {}' (for Anaconda)"
|
|
189
|
-
.format(*type(self).anaconda.split('::', 1)),
|
|
190
|
-
)
|
|
191
|
-
else:
|
|
192
|
-
msg.append(
|
|
193
|
-
" or 'conda install {}' (for Anaconda)"
|
|
194
|
-
.format(type(self).anaconda),
|
|
195
|
-
)
|
|
196
|
-
msg.append(' to install it.')
|
|
197
|
-
print(''.join(msg), file=sys.stderr)
|
|
198
|
-
raise
|
singlestoredb/drivers/cymysql.py
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
from typing import Any
|
|
2
|
-
from typing import Dict
|
|
3
|
-
|
|
4
|
-
try:
|
|
5
|
-
from cymysql.converters import encoders
|
|
6
|
-
except ImportError:
|
|
7
|
-
encoders = {}
|
|
8
|
-
|
|
9
|
-
from .base import Driver
|
|
10
|
-
from ..converters import converters
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
converters = dict(converters)
|
|
14
|
-
converters.update(encoders)
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
class CyMySQLDriver(Driver):
|
|
18
|
-
|
|
19
|
-
name = 'CyMySQL'
|
|
20
|
-
|
|
21
|
-
pkg_name = 'cymysql'
|
|
22
|
-
pypi = 'cymysql'
|
|
23
|
-
anaconda = 'cymysql'
|
|
24
|
-
|
|
25
|
-
def remap_params(self, params: Dict[str, Any]) -> Dict[str, Any]:
|
|
26
|
-
params.pop('driver', None)
|
|
27
|
-
params.pop('pure_python', None)
|
|
28
|
-
params.pop('odbc_driver', None)
|
|
29
|
-
params.pop('credential_type', None)
|
|
30
|
-
params['port'] = params['port'] or 3306
|
|
31
|
-
params['db'] = params.pop('database', None)
|
|
32
|
-
params['passwd'] = params.pop('password', None)
|
|
33
|
-
params['conv'] = self.merge_converters(params.pop('converters', {}), converters)
|
|
34
|
-
params['ssl'] = dict(cipher=params.pop('ssl_cipher'))
|
|
35
|
-
return params
|
|
36
|
-
|
|
37
|
-
def is_connected(self, conn: Any, reconnect: bool = False) -> bool:
|
|
38
|
-
return conn.ping(reconnect=reconnect)
|
singlestoredb/drivers/http.py
DELETED
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import warnings
|
|
2
|
-
from typing import Any
|
|
3
|
-
from typing import Dict
|
|
4
|
-
|
|
5
|
-
from .base import Driver
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
class HTTPDriver(Driver):
|
|
9
|
-
|
|
10
|
-
name = 'http'
|
|
11
|
-
|
|
12
|
-
pkg_name = 'singlestoredb.http'
|
|
13
|
-
pypi = 'singlestoredb'
|
|
14
|
-
anaconda = 'singlestore::singlestoredb'
|
|
15
|
-
|
|
16
|
-
def remap_params(self, params: Dict[str, Any]) -> Dict[str, Any]:
|
|
17
|
-
params.pop('pure_python', False)
|
|
18
|
-
params.pop('charset', None)
|
|
19
|
-
params.pop('odbc_driver', None)
|
|
20
|
-
params.pop('credential_type', None)
|
|
21
|
-
params.pop('autocommit', None)
|
|
22
|
-
params.pop('ssl_cipher', None)
|
|
23
|
-
|
|
24
|
-
params['protocol'] = params.pop('driver', '').replace(
|
|
25
|
-
'singlestoredb+', '',
|
|
26
|
-
) or None
|
|
27
|
-
|
|
28
|
-
if params.pop('local_infile', False):
|
|
29
|
-
warnings.warn('The HTTP driver does not support file uploads.')
|
|
30
|
-
|
|
31
|
-
if params['port'] is None:
|
|
32
|
-
if type(self).name == 'https':
|
|
33
|
-
params['port'] = 443
|
|
34
|
-
else:
|
|
35
|
-
params['port'] = 80
|
|
36
|
-
|
|
37
|
-
self.converters = params.pop('converters', {})
|
|
38
|
-
|
|
39
|
-
return params
|
|
40
|
-
|
|
41
|
-
def is_connected(self, conn: Any, reconnect: bool = False) -> bool:
|
|
42
|
-
return conn.is_connected()
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
class HTTPSDriver(HTTPDriver):
|
|
46
|
-
|
|
47
|
-
name = 'https'
|
singlestoredb/drivers/mariadb.py
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import json
|
|
2
|
-
from typing import Any
|
|
3
|
-
from typing import Dict
|
|
4
|
-
|
|
5
|
-
from .base import Driver
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
converters = {245: json.loads}
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
class MariaDBDriver(Driver):
|
|
12
|
-
|
|
13
|
-
name = 'mariadb'
|
|
14
|
-
|
|
15
|
-
pkg_name = 'mariadb'
|
|
16
|
-
pypi = 'mariadb-connector-python'
|
|
17
|
-
anaconda = 'mariadb-connector-python'
|
|
18
|
-
|
|
19
|
-
def remap_params(self, params: Dict[str, Any]) -> Dict[str, Any]:
|
|
20
|
-
params.pop('driver', None)
|
|
21
|
-
params.pop('charset', None)
|
|
22
|
-
params.pop('odbc_driver', None)
|
|
23
|
-
params.pop('pure_python', None)
|
|
24
|
-
params.pop('credential_type', None)
|
|
25
|
-
params['converter'] = self.merge_converters(
|
|
26
|
-
params.pop('converters', {}),
|
|
27
|
-
dict(converters),
|
|
28
|
-
)
|
|
29
|
-
if params.pop('ssl_disabled', False):
|
|
30
|
-
params['ssl'] = False
|
|
31
|
-
params['ssl_verify_cert'] = False
|
|
32
|
-
|
|
33
|
-
return params
|
|
34
|
-
|
|
35
|
-
def is_connected(self, conn: Any, reconnect: bool = False) -> bool:
|
|
36
|
-
try:
|
|
37
|
-
conn.ping()
|
|
38
|
-
return True
|
|
39
|
-
except conn.InterfaceError:
|
|
40
|
-
return False
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
from typing import Any
|
|
2
|
-
from typing import Dict
|
|
3
|
-
|
|
4
|
-
from .. import auth
|
|
5
|
-
from ..converters import converters
|
|
6
|
-
from .base import Driver
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
class MySQLConnectorDriver(Driver):
|
|
10
|
-
|
|
11
|
-
name = 'mysqlconnector'
|
|
12
|
-
|
|
13
|
-
pkg_name = 'mysql.connector'
|
|
14
|
-
pypi = 'mysql-connector-python'
|
|
15
|
-
anaconda = 'mysql-connector-python'
|
|
16
|
-
|
|
17
|
-
# This flag lets the connection do the decoding of text / binary accordingly
|
|
18
|
-
returns_bytes = True
|
|
19
|
-
|
|
20
|
-
def remap_params(self, params: Dict[str, Any]) -> Dict[str, Any]:
|
|
21
|
-
params.pop('driver', None)
|
|
22
|
-
params.pop('odbc_driver', None)
|
|
23
|
-
params.pop('ssl_cipher', None)
|
|
24
|
-
if params.pop('pure_python', False):
|
|
25
|
-
params['use_pure'] = True
|
|
26
|
-
params['port'] = params['port'] or 3306
|
|
27
|
-
params['allow_local_infile'] = params.pop('local_infile')
|
|
28
|
-
|
|
29
|
-
# Always use raw, we're doing the conversions ourselves
|
|
30
|
-
params['raw'] = True
|
|
31
|
-
|
|
32
|
-
convs = params.pop('converters', {})
|
|
33
|
-
self.converters = self.merge_converters(convs, converters)
|
|
34
|
-
|
|
35
|
-
# Check authentication method
|
|
36
|
-
cred = params.pop('credential_type', None)
|
|
37
|
-
if cred in [auth.BROWSER_SSO, auth.JWT] and not params.get('use_pure', False):
|
|
38
|
-
# params['auth_plugin'] = 'mysql_clear_password'
|
|
39
|
-
params['ssl_verify_identity'] = True
|
|
40
|
-
params['ssl_verify_cert'] = True
|
|
41
|
-
|
|
42
|
-
return params
|
|
43
|
-
|
|
44
|
-
def is_connected(self, conn: Any, reconnect: bool = False) -> bool:
|
|
45
|
-
try:
|
|
46
|
-
conn.ping(reconnect=reconnect)
|
|
47
|
-
return True
|
|
48
|
-
except conn.InterfaceError:
|
|
49
|
-
return False
|
singlestoredb/drivers/mysqldb.py
DELETED
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
from typing import Any
|
|
2
|
-
from typing import Dict
|
|
3
|
-
|
|
4
|
-
from ..converters import converters
|
|
5
|
-
from .base import Driver
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
class MySQLdbDriver(Driver):
|
|
9
|
-
|
|
10
|
-
name = 'MySQLdb'
|
|
11
|
-
|
|
12
|
-
pkg_name = 'MySQLdb'
|
|
13
|
-
pypi = 'mysqlclient'
|
|
14
|
-
anaconda = 'mysqlclient'
|
|
15
|
-
|
|
16
|
-
def remap_params(self, params: Dict[str, Any]) -> Dict[str, Any]:
|
|
17
|
-
params.pop('driver', None)
|
|
18
|
-
params.pop('pure_python', None)
|
|
19
|
-
params.pop('odbc_driver', None)
|
|
20
|
-
params.pop('credential_type', None)
|
|
21
|
-
|
|
22
|
-
params['conv'] = dict(converters)
|
|
23
|
-
|
|
24
|
-
ssl = dict()
|
|
25
|
-
|
|
26
|
-
if params.get('ssl_key', None):
|
|
27
|
-
ssl['key'] = params.get('ssl_key')
|
|
28
|
-
if params.get('ssl_cert', None):
|
|
29
|
-
ssl['cert'] = params.get('ssl_cert')
|
|
30
|
-
if params.get('ssl_ca', None):
|
|
31
|
-
ssl['ca'] = params.get('ssl_ca')
|
|
32
|
-
if params.get('ssl_cipher', None):
|
|
33
|
-
ssl['cipher'] = params.get('ssl_cipher')
|
|
34
|
-
|
|
35
|
-
params.pop('ssl_key', None)
|
|
36
|
-
params.pop('ssl_cert', None)
|
|
37
|
-
params.pop('ssl_ca', None)
|
|
38
|
-
params.pop('ssl_cipher', None)
|
|
39
|
-
|
|
40
|
-
if ssl:
|
|
41
|
-
params['ssl'] = dict(ssl=ssl)
|
|
42
|
-
|
|
43
|
-
if params.pop('ssl_disabled', False):
|
|
44
|
-
params['ssl_mode'] = 'DISABLED'
|
|
45
|
-
|
|
46
|
-
self.converters = params.pop('converters', {})
|
|
47
|
-
|
|
48
|
-
return params
|
|
49
|
-
|
|
50
|
-
def after_connect(self, conn: Any, params: Dict[str, Any]) -> None:
|
|
51
|
-
# This must be done afterward because use_unicode= whacks the
|
|
52
|
-
# json converter if you try to put it in earlier.
|
|
53
|
-
conn.converter[245] = converters[245]
|
|
54
|
-
|
|
55
|
-
def is_connected(self, conn: Any, reconnect: bool = False) -> bool:
|
|
56
|
-
try:
|
|
57
|
-
conn.ping(reconnect)
|
|
58
|
-
return True
|
|
59
|
-
except conn.InterfaceError:
|
|
60
|
-
return False
|
singlestoredb/drivers/pymysql.py
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
from typing import Any
|
|
2
|
-
from typing import Callable
|
|
3
|
-
from typing import Dict
|
|
4
|
-
|
|
5
|
-
try:
|
|
6
|
-
from pymysql.converters import encoders
|
|
7
|
-
except ImportError:
|
|
8
|
-
encoders = {}
|
|
9
|
-
|
|
10
|
-
from .base import Driver
|
|
11
|
-
from ..converters import converters as convs
|
|
12
|
-
|
|
13
|
-
converters: Dict[Any, Callable[..., Any]] = dict(convs)
|
|
14
|
-
converters.update(encoders)
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
class PyMySQLDriver(Driver):
|
|
18
|
-
|
|
19
|
-
name = 'PyMySQL'
|
|
20
|
-
|
|
21
|
-
pkg_name = 'pymysql'
|
|
22
|
-
pypi = 'pymysql'
|
|
23
|
-
anaconda = 'pymysql'
|
|
24
|
-
|
|
25
|
-
def remap_params(self, params: Dict[str, Any]) -> Dict[str, Any]:
|
|
26
|
-
params.pop('driver', None)
|
|
27
|
-
params.pop('odbc_driver', None)
|
|
28
|
-
params.pop('pure_python', None)
|
|
29
|
-
params.pop('credential_type', None)
|
|
30
|
-
# The cipher must be set to this level for SingleStoreDB Cloud.
|
|
31
|
-
params['ssl'] = dict(cipher=params.pop('ssl_cipher'))
|
|
32
|
-
params['port'] = params['port'] or 3306
|
|
33
|
-
params['conv'] = self.merge_converters(params.pop('converters', {}), converters)
|
|
34
|
-
return params
|
|
35
|
-
|
|
36
|
-
def is_connected(self, conn: Any, reconnect: bool = False) -> bool:
|
|
37
|
-
return conn.open
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
from typing import Any
|
|
2
|
-
from typing import Callable
|
|
3
|
-
from typing import Dict
|
|
4
|
-
|
|
5
|
-
try:
|
|
6
|
-
from ..clients.pymysqlsv.converters import encoders # type: ignore
|
|
7
|
-
except (ImportError, ModuleNotFoundError):
|
|
8
|
-
encoders = {}
|
|
9
|
-
|
|
10
|
-
from .base import Driver
|
|
11
|
-
from ..converters import converters as convs
|
|
12
|
-
|
|
13
|
-
converters: Dict[Any, Callable[..., Any]] = dict(convs)
|
|
14
|
-
converters.update(encoders)
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
class PyMySQLsvDriver(Driver):
|
|
18
|
-
|
|
19
|
-
name = 'PyMySQLsv'
|
|
20
|
-
|
|
21
|
-
pkg_name = 'singlestoredb.clients.pymysqlsv'
|
|
22
|
-
|
|
23
|
-
def remap_params(self, params: Dict[str, Any]) -> Dict[str, Any]:
|
|
24
|
-
params.pop('driver', None)
|
|
25
|
-
params.pop('odbc_driver', None)
|
|
26
|
-
params.pop('pure_python', None)
|
|
27
|
-
params.pop('credential_type', None)
|
|
28
|
-
# The cipher must be set to this level for SingleStoreDB Cloud.
|
|
29
|
-
params['ssl'] = dict(cipher=params.pop('ssl_cipher'))
|
|
30
|
-
params['port'] = params['port'] or 3306
|
|
31
|
-
params['conv'] = self.merge_converters(params.pop('converters', {}), converters)
|
|
32
|
-
return params
|
|
33
|
-
|
|
34
|
-
def is_connected(self, conn: Any, reconnect: bool = False) -> bool:
|
|
35
|
-
return conn.open
|
singlestoredb/drivers/pyodbc.py
DELETED
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
import datetime
|
|
2
|
-
import json
|
|
3
|
-
from typing import Any
|
|
4
|
-
from typing import Dict
|
|
5
|
-
from typing import Optional
|
|
6
|
-
|
|
7
|
-
from .base import Driver
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
datetime_min = datetime.datetime.min
|
|
11
|
-
date_min = datetime.date.min
|
|
12
|
-
datetime_combine = datetime.datetime.combine
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
def convert_time(value: Optional[datetime.time]) -> Optional[datetime.timedelta]:
|
|
16
|
-
"""Convert time to timedelta."""
|
|
17
|
-
if value is None:
|
|
18
|
-
return None
|
|
19
|
-
return datetime_combine(date_min, value) - datetime_min
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
def convert_json(value: Optional[str]) -> Optional[Dict[str, Any]]:
|
|
23
|
-
"""Convert JSON str to dict."""
|
|
24
|
-
if value is None:
|
|
25
|
-
return None
|
|
26
|
-
return json.loads(value)
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
class PyODBCDriver(Driver):
|
|
30
|
-
|
|
31
|
-
name = 'pyodbc'
|
|
32
|
-
|
|
33
|
-
pkg_name = 'pyodbc'
|
|
34
|
-
pypi = 'pyodbc'
|
|
35
|
-
anaconda = 'pyodbc'
|
|
36
|
-
|
|
37
|
-
def remap_params(self, params: Dict[str, Any]) -> Dict[str, Any]:
|
|
38
|
-
out = {
|
|
39
|
-
k: v for k, v in dict(
|
|
40
|
-
server=params.get('host', '127.0.0.1'),
|
|
41
|
-
port=params.get('port', 0) or 3306,
|
|
42
|
-
database=params.get('database'),
|
|
43
|
-
uid=params.get('user'),
|
|
44
|
-
pwd=params.get('password'),
|
|
45
|
-
charset=params.get('charset'),
|
|
46
|
-
driver=params.get('odbc_driver'),
|
|
47
|
-
).items() if v is not None
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
convs = params.pop('converters', {})
|
|
51
|
-
self.converters = self.merge_converters(
|
|
52
|
-
convs, {
|
|
53
|
-
11: convert_time,
|
|
54
|
-
245: convert_json,
|
|
55
|
-
},
|
|
56
|
-
)
|
|
57
|
-
|
|
58
|
-
return out
|
|
59
|
-
|
|
60
|
-
def after_connect(self, conn: Any, params: Dict[str, Any]) -> None:
|
|
61
|
-
if params.get('autocommit'):
|
|
62
|
-
conn.autocommit(True)
|
|
63
|
-
|
|
64
|
-
def is_connected(self, conn: Any, reconnect: bool = False) -> bool:
|
|
65
|
-
return not conn.closed
|