singlestoredb 1.16.1__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.
- singlestoredb/__init__.py +75 -0
- singlestoredb/ai/__init__.py +2 -0
- singlestoredb/ai/chat.py +139 -0
- singlestoredb/ai/embeddings.py +128 -0
- singlestoredb/alchemy/__init__.py +90 -0
- singlestoredb/apps/__init__.py +3 -0
- singlestoredb/apps/_cloud_functions.py +90 -0
- singlestoredb/apps/_config.py +72 -0
- singlestoredb/apps/_connection_info.py +18 -0
- singlestoredb/apps/_dashboards.py +47 -0
- singlestoredb/apps/_process.py +32 -0
- singlestoredb/apps/_python_udfs.py +100 -0
- singlestoredb/apps/_stdout_supress.py +30 -0
- singlestoredb/apps/_uvicorn_util.py +36 -0
- singlestoredb/auth.py +245 -0
- singlestoredb/config.py +484 -0
- singlestoredb/connection.py +1487 -0
- singlestoredb/converters.py +950 -0
- singlestoredb/docstring/__init__.py +33 -0
- singlestoredb/docstring/attrdoc.py +126 -0
- singlestoredb/docstring/common.py +230 -0
- singlestoredb/docstring/epydoc.py +267 -0
- singlestoredb/docstring/google.py +412 -0
- singlestoredb/docstring/numpydoc.py +562 -0
- singlestoredb/docstring/parser.py +100 -0
- singlestoredb/docstring/py.typed +1 -0
- singlestoredb/docstring/rest.py +256 -0
- singlestoredb/docstring/tests/__init__.py +1 -0
- singlestoredb/docstring/tests/_pydoctor.py +21 -0
- singlestoredb/docstring/tests/test_epydoc.py +729 -0
- singlestoredb/docstring/tests/test_google.py +1007 -0
- singlestoredb/docstring/tests/test_numpydoc.py +1100 -0
- singlestoredb/docstring/tests/test_parse_from_object.py +109 -0
- singlestoredb/docstring/tests/test_parser.py +248 -0
- singlestoredb/docstring/tests/test_rest.py +547 -0
- singlestoredb/docstring/tests/test_util.py +70 -0
- singlestoredb/docstring/util.py +141 -0
- singlestoredb/exceptions.py +120 -0
- singlestoredb/functions/__init__.py +16 -0
- singlestoredb/functions/decorator.py +201 -0
- singlestoredb/functions/dtypes.py +1793 -0
- singlestoredb/functions/ext/__init__.py +1 -0
- singlestoredb/functions/ext/arrow.py +375 -0
- singlestoredb/functions/ext/asgi.py +2133 -0
- singlestoredb/functions/ext/json.py +420 -0
- singlestoredb/functions/ext/mmap.py +413 -0
- singlestoredb/functions/ext/rowdat_1.py +724 -0
- singlestoredb/functions/ext/timer.py +89 -0
- singlestoredb/functions/ext/utils.py +218 -0
- singlestoredb/functions/signature.py +1578 -0
- singlestoredb/functions/typing/__init__.py +41 -0
- singlestoredb/functions/typing/numpy.py +20 -0
- singlestoredb/functions/typing/pandas.py +2 -0
- singlestoredb/functions/typing/polars.py +2 -0
- singlestoredb/functions/typing/pyarrow.py +2 -0
- singlestoredb/functions/utils.py +421 -0
- singlestoredb/fusion/__init__.py +11 -0
- singlestoredb/fusion/graphql.py +213 -0
- singlestoredb/fusion/handler.py +916 -0
- singlestoredb/fusion/handlers/__init__.py +0 -0
- singlestoredb/fusion/handlers/export.py +525 -0
- singlestoredb/fusion/handlers/files.py +690 -0
- singlestoredb/fusion/handlers/job.py +660 -0
- singlestoredb/fusion/handlers/models.py +250 -0
- singlestoredb/fusion/handlers/stage.py +502 -0
- singlestoredb/fusion/handlers/utils.py +324 -0
- singlestoredb/fusion/handlers/workspace.py +956 -0
- singlestoredb/fusion/registry.py +249 -0
- singlestoredb/fusion/result.py +399 -0
- singlestoredb/http/__init__.py +27 -0
- singlestoredb/http/connection.py +1267 -0
- singlestoredb/magics/__init__.py +34 -0
- singlestoredb/magics/run_personal.py +137 -0
- singlestoredb/magics/run_shared.py +134 -0
- singlestoredb/management/__init__.py +9 -0
- singlestoredb/management/billing_usage.py +148 -0
- singlestoredb/management/cluster.py +462 -0
- singlestoredb/management/export.py +295 -0
- singlestoredb/management/files.py +1102 -0
- singlestoredb/management/inference_api.py +105 -0
- singlestoredb/management/job.py +887 -0
- singlestoredb/management/manager.py +373 -0
- singlestoredb/management/organization.py +226 -0
- singlestoredb/management/region.py +169 -0
- singlestoredb/management/utils.py +423 -0
- singlestoredb/management/workspace.py +1927 -0
- singlestoredb/mysql/__init__.py +177 -0
- singlestoredb/mysql/_auth.py +298 -0
- singlestoredb/mysql/charset.py +214 -0
- singlestoredb/mysql/connection.py +2032 -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/EXTENDED_TYPE.py +3 -0
- singlestoredb/mysql/constants/FIELD_TYPE.py +48 -0
- singlestoredb/mysql/constants/FLAG.py +15 -0
- singlestoredb/mysql/constants/SERVER_STATUS.py +10 -0
- singlestoredb/mysql/constants/VECTOR_TYPE.py +6 -0
- singlestoredb/mysql/constants/__init__.py +0 -0
- singlestoredb/mysql/converters.py +271 -0
- singlestoredb/mysql/cursors.py +896 -0
- singlestoredb/mysql/err.py +92 -0
- singlestoredb/mysql/optionfile.py +20 -0
- singlestoredb/mysql/protocol.py +450 -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/notebook/__init__.py +16 -0
- singlestoredb/notebook/_objects.py +213 -0
- singlestoredb/notebook/_portal.py +352 -0
- singlestoredb/py.typed +0 -0
- singlestoredb/pytest.py +352 -0
- singlestoredb/server/__init__.py +0 -0
- singlestoredb/server/docker.py +452 -0
- singlestoredb/server/free_tier.py +267 -0
- singlestoredb/tests/__init__.py +0 -0
- singlestoredb/tests/alltypes.sql +307 -0
- singlestoredb/tests/alltypes_no_nulls.sql +208 -0
- singlestoredb/tests/empty.sql +0 -0
- singlestoredb/tests/ext_funcs/__init__.py +702 -0
- singlestoredb/tests/local_infile.csv +3 -0
- singlestoredb/tests/test.ipynb +18 -0
- singlestoredb/tests/test.sql +680 -0
- singlestoredb/tests/test2.ipynb +18 -0
- singlestoredb/tests/test2.sql +1 -0
- singlestoredb/tests/test_basics.py +1332 -0
- singlestoredb/tests/test_config.py +318 -0
- singlestoredb/tests/test_connection.py +3103 -0
- singlestoredb/tests/test_dbapi.py +27 -0
- singlestoredb/tests/test_exceptions.py +45 -0
- singlestoredb/tests/test_ext_func.py +1472 -0
- singlestoredb/tests/test_ext_func_data.py +1101 -0
- singlestoredb/tests/test_fusion.py +1527 -0
- singlestoredb/tests/test_http.py +288 -0
- singlestoredb/tests/test_management.py +1599 -0
- singlestoredb/tests/test_plugin.py +33 -0
- singlestoredb/tests/test_results.py +171 -0
- singlestoredb/tests/test_types.py +132 -0
- singlestoredb/tests/test_udf.py +737 -0
- singlestoredb/tests/test_udf_returns.py +459 -0
- singlestoredb/tests/test_vectorstore.py +51 -0
- singlestoredb/tests/test_xdict.py +333 -0
- singlestoredb/tests/utils.py +141 -0
- singlestoredb/types.py +373 -0
- singlestoredb/utils/__init__.py +0 -0
- singlestoredb/utils/config.py +950 -0
- singlestoredb/utils/convert_rows.py +69 -0
- singlestoredb/utils/debug.py +13 -0
- singlestoredb/utils/dtypes.py +205 -0
- singlestoredb/utils/events.py +65 -0
- singlestoredb/utils/mogrify.py +151 -0
- singlestoredb/utils/results.py +585 -0
- singlestoredb/utils/xdict.py +425 -0
- singlestoredb/vectorstore.py +192 -0
- singlestoredb/warnings.py +5 -0
- singlestoredb-1.16.1.dist-info/METADATA +165 -0
- singlestoredb-1.16.1.dist-info/RECORD +183 -0
- singlestoredb-1.16.1.dist-info/WHEEL +5 -0
- singlestoredb-1.16.1.dist-info/entry_points.txt +2 -0
- singlestoredb-1.16.1.dist-info/licenses/LICENSE +201 -0
- singlestoredb-1.16.1.dist-info/top_level.txt +3 -0
- sqlx/__init__.py +4 -0
- sqlx/magic.py +113 -0
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
"""Data value conversion utilities."""
|
|
3
|
+
from typing import Any
|
|
4
|
+
from typing import List
|
|
5
|
+
from typing import Optional
|
|
6
|
+
from typing import Tuple
|
|
7
|
+
from typing import Union
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def convert_row(
|
|
11
|
+
values: Optional[Union[List[Any], Tuple[Any, ...]]],
|
|
12
|
+
converters: List[Any],
|
|
13
|
+
) -> Optional[Tuple[Any, ...]]:
|
|
14
|
+
"""
|
|
15
|
+
Convert a row of data values.
|
|
16
|
+
|
|
17
|
+
Parameters
|
|
18
|
+
----------
|
|
19
|
+
values : tuple or None
|
|
20
|
+
Tuple containing values in a row of data
|
|
21
|
+
converters : list[tuple]
|
|
22
|
+
List of two-element tuples containing a column index and a converter
|
|
23
|
+
function. The column index specifies which column to apply the function to.
|
|
24
|
+
|
|
25
|
+
Returns
|
|
26
|
+
-------
|
|
27
|
+
tuple or None
|
|
28
|
+
|
|
29
|
+
"""
|
|
30
|
+
if values is None:
|
|
31
|
+
return None
|
|
32
|
+
if not converters:
|
|
33
|
+
return tuple(values)
|
|
34
|
+
values = list(values)
|
|
35
|
+
for i, conv in enumerate(converters):
|
|
36
|
+
idx, encoding, func = conv
|
|
37
|
+
value = values[idx]
|
|
38
|
+
if encoding is not None and value is not None:
|
|
39
|
+
value = value.decode(encoding)
|
|
40
|
+
if func is not None:
|
|
41
|
+
values[idx] = func(value)
|
|
42
|
+
else:
|
|
43
|
+
values[idx] = value
|
|
44
|
+
return tuple(values)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def convert_rows(rows: List[Any], converters: List[Any]) -> List[Any]:
|
|
48
|
+
"""
|
|
49
|
+
Convert rows of data values.
|
|
50
|
+
|
|
51
|
+
Parameters
|
|
52
|
+
----------
|
|
53
|
+
rows : list of tuples or None
|
|
54
|
+
Rows of data from a query
|
|
55
|
+
converters : list[tuple]
|
|
56
|
+
List of two-element tuples containing a column index and a converter
|
|
57
|
+
function. The column index specifies which column to apply the function to.
|
|
58
|
+
|
|
59
|
+
Returns
|
|
60
|
+
-------
|
|
61
|
+
list of tuples
|
|
62
|
+
|
|
63
|
+
"""
|
|
64
|
+
if not rows or not converters:
|
|
65
|
+
return rows
|
|
66
|
+
rows = list(rows)
|
|
67
|
+
for i, row in enumerate(rows):
|
|
68
|
+
rows[i] = convert_row(row, converters=converters)
|
|
69
|
+
return rows
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
from typing import Any
|
|
3
|
+
|
|
4
|
+
from ..config import get_option
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def log_query(query: str, args: Any = None) -> None:
|
|
8
|
+
"""Log the query and parameters."""
|
|
9
|
+
if get_option('debug.queries'):
|
|
10
|
+
if args is None:
|
|
11
|
+
print('[QUERY]', query, file=sys.stderr)
|
|
12
|
+
else:
|
|
13
|
+
print('[QUERY]', query, args, file=sys.stderr)
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
|
|
3
|
+
try:
|
|
4
|
+
import numpy as np
|
|
5
|
+
has_numpy = True
|
|
6
|
+
except ImportError:
|
|
7
|
+
has_numpy = False
|
|
8
|
+
|
|
9
|
+
try:
|
|
10
|
+
import polars as pl
|
|
11
|
+
has_polars = True
|
|
12
|
+
except ImportError:
|
|
13
|
+
has_polars = False
|
|
14
|
+
|
|
15
|
+
try:
|
|
16
|
+
import pyarrow as pa
|
|
17
|
+
has_pyarrow = True
|
|
18
|
+
except ImportError:
|
|
19
|
+
has_pyarrow = False
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
DEFAULT_VALUES = {
|
|
23
|
+
0: 0, # Decimal
|
|
24
|
+
1: 0, # Tiny
|
|
25
|
+
-1: 0, # Unsigned Tiny
|
|
26
|
+
2: 0, # Short
|
|
27
|
+
-2: 0, # Unsigned Short
|
|
28
|
+
3: 0, # Long
|
|
29
|
+
-3: 0, # Unsigned Long
|
|
30
|
+
4: float('nan'), # Float
|
|
31
|
+
5: float('nan'), # Double,
|
|
32
|
+
6: None, # Null,
|
|
33
|
+
7: 0, # Timestamp
|
|
34
|
+
8: 0, # LongLong
|
|
35
|
+
-8: 0, # Unsigned Longlong
|
|
36
|
+
9: 0, # Int24
|
|
37
|
+
-9: 0, # Unsigned Int24
|
|
38
|
+
10: 0, # Date
|
|
39
|
+
-10: 0, # Date
|
|
40
|
+
11: 0, # Time
|
|
41
|
+
12: 0, # Datetime
|
|
42
|
+
13: 0, # Year
|
|
43
|
+
15: None, # Varchar
|
|
44
|
+
-15: None, # Varbinary
|
|
45
|
+
16: 0, # Bit
|
|
46
|
+
245: None, # JSON
|
|
47
|
+
246: 0, # NewDecimal
|
|
48
|
+
-246: 0, # NewDecimal
|
|
49
|
+
247: None, # Enum
|
|
50
|
+
248: None, # Set
|
|
51
|
+
249: None, # TinyText
|
|
52
|
+
-249: None, # TinyBlob
|
|
53
|
+
250: None, # MediumText
|
|
54
|
+
-250: None, # MediumBlob
|
|
55
|
+
251: None, # LongText
|
|
56
|
+
-251: None, # LongBlob
|
|
57
|
+
252: None, # Text
|
|
58
|
+
-252: None, # Blob
|
|
59
|
+
253: None, # VarString
|
|
60
|
+
-253: None, # VarBinary
|
|
61
|
+
254: None, # String
|
|
62
|
+
-254: None, # Binary
|
|
63
|
+
255: None, # Geometry
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
if has_numpy:
|
|
68
|
+
NUMPY_TYPE_MAP = {
|
|
69
|
+
0: object, # Decimal
|
|
70
|
+
1: np.int8, # Tiny
|
|
71
|
+
-1: np.uint8, # Unsigned Tiny
|
|
72
|
+
2: np.int16, # Short
|
|
73
|
+
-2: np.uint16, # Unsigned Short
|
|
74
|
+
3: np.int32, # Long
|
|
75
|
+
-3: np.uint32, # Unsigned Long
|
|
76
|
+
4: np.single, # Float
|
|
77
|
+
5: np.double, # Double,
|
|
78
|
+
6: object, # Null,
|
|
79
|
+
7: np.dtype('datetime64[us]'), # Timestamp
|
|
80
|
+
8: np.int64, # LongLong
|
|
81
|
+
-8: np.uint64, # Unsigned LongLong
|
|
82
|
+
9: np.int32, # Int24
|
|
83
|
+
-9: np.uint32, # Unsigned Int24
|
|
84
|
+
10: np.dtype('datetime64[D]'), # Date
|
|
85
|
+
11: np.dtype('timedelta64[us]'), # Time
|
|
86
|
+
12: np.dtype('datetime64[us]'), # Datetime
|
|
87
|
+
13: np.int16, # Year
|
|
88
|
+
15: object, # Varchar
|
|
89
|
+
-15: object, # Varbinary
|
|
90
|
+
16: object, # Bit
|
|
91
|
+
245: object, # JSON
|
|
92
|
+
246: object, # NewDecimal
|
|
93
|
+
-246: object, # NewDecimal
|
|
94
|
+
247: object, # Enum
|
|
95
|
+
248: object, # Set
|
|
96
|
+
249: object, # TinyText
|
|
97
|
+
-249: object, # TinyBlob
|
|
98
|
+
250: object, # MediumText
|
|
99
|
+
-250: object, # MediumBlob
|
|
100
|
+
251: object, # LongText
|
|
101
|
+
-251: object, # LongBlob
|
|
102
|
+
252: object, # Blob
|
|
103
|
+
-252: object, # Text
|
|
104
|
+
253: object, # VarString
|
|
105
|
+
-253: object, # VarBlob
|
|
106
|
+
254: object, # String
|
|
107
|
+
-254: object, # Binary
|
|
108
|
+
255: object, # Geometry
|
|
109
|
+
}
|
|
110
|
+
else:
|
|
111
|
+
NUMPY_TYPE_MAP = {}
|
|
112
|
+
|
|
113
|
+
PANDAS_TYPE_MAP = NUMPY_TYPE_MAP
|
|
114
|
+
|
|
115
|
+
if has_pyarrow:
|
|
116
|
+
PYARROW_TYPE_MAP = {
|
|
117
|
+
0: pa.decimal128(18, 6), # Decimal
|
|
118
|
+
1: pa.int8(), # Tiny
|
|
119
|
+
-1: pa.uint8(), # Unsigned Tiny
|
|
120
|
+
2: pa.int16(), # Short
|
|
121
|
+
-2: pa.uint16(), # Unsigned Short
|
|
122
|
+
3: pa.int32(), # Long
|
|
123
|
+
-3: pa.uint32(), # Unsigned Long
|
|
124
|
+
4: pa.float32(), # Float
|
|
125
|
+
5: pa.float64(), # Double,
|
|
126
|
+
6: pa.null(), # Null,
|
|
127
|
+
7: pa.timestamp('us'), # Timestamp
|
|
128
|
+
8: pa.int64(), # LongLong
|
|
129
|
+
-8: pa.uint64(), # Unsigned LongLong
|
|
130
|
+
9: pa.int32(), # Int24
|
|
131
|
+
-9: pa.uint32(), # Unsigned Int24
|
|
132
|
+
10: pa.date64(), # Date
|
|
133
|
+
11: pa.duration('us'), # Time
|
|
134
|
+
12: pa.timestamp('us'), # Datetime
|
|
135
|
+
13: pa.int16(), # Year
|
|
136
|
+
15: pa.string(), # Varchar
|
|
137
|
+
-15: pa.binary(), # Varbinary
|
|
138
|
+
16: pa.binary(), # Bit
|
|
139
|
+
245: pa.string(), # JSON
|
|
140
|
+
246: pa.decimal128(18, 6), # NewDecimal
|
|
141
|
+
-246: pa.decimal128(18, 6), # NewDecimal
|
|
142
|
+
247: pa.string(), # Enum
|
|
143
|
+
248: pa.string(), # Set
|
|
144
|
+
249: pa.string(), # TinyText
|
|
145
|
+
-249: pa.binary(), # TinyBlob
|
|
146
|
+
250: pa.string(), # MediumText
|
|
147
|
+
-250: pa.binary(), # MediumBlob
|
|
148
|
+
251: pa.string(), # LongText
|
|
149
|
+
-251: pa.binary(), # LongBlob
|
|
150
|
+
252: pa.string(), # Text
|
|
151
|
+
-252: pa.binary(), # Blob
|
|
152
|
+
253: pa.string(), # VarString
|
|
153
|
+
-253: pa.binary(), # VarBinary
|
|
154
|
+
254: pa.string(), # String
|
|
155
|
+
-254: pa.binary(), # Binary
|
|
156
|
+
255: pa.string(), # Geometry
|
|
157
|
+
}
|
|
158
|
+
else:
|
|
159
|
+
PYARROW_TYPE_MAP = {}
|
|
160
|
+
|
|
161
|
+
if has_polars:
|
|
162
|
+
POLARS_TYPE_MAP = {
|
|
163
|
+
0: pl.Decimal(10, 6), # Decimal
|
|
164
|
+
1: pl.Int8, # Tiny
|
|
165
|
+
-1: pl.UInt8, # Unsigned Tiny
|
|
166
|
+
2: pl.Int16, # Short
|
|
167
|
+
-2: pl.UInt16, # Unsigned Short
|
|
168
|
+
3: pl.Int32, # Long
|
|
169
|
+
-3: pl.UInt32, # Unsigned Long
|
|
170
|
+
4: pl.Float32, # Float
|
|
171
|
+
5: pl.Float64, # Double,
|
|
172
|
+
6: pl.Null, # Null,
|
|
173
|
+
7: pl.Datetime, # Timestamp
|
|
174
|
+
8: pl.Int64, # LongLong
|
|
175
|
+
-8: pl.UInt64, # Unsigned LongLong
|
|
176
|
+
9: pl.Int32, # Int24
|
|
177
|
+
-9: pl.UInt32, # Unsigned Int24
|
|
178
|
+
10: pl.Date, # Date
|
|
179
|
+
11: pl.Duration, # Time
|
|
180
|
+
12: pl.Datetime, # Datetime
|
|
181
|
+
13: pl.Int16, # Year
|
|
182
|
+
15: pl.Utf8, # Varchar
|
|
183
|
+
-15: pl.Utf8, # Varbinary
|
|
184
|
+
16: pl.Binary, # Bit
|
|
185
|
+
245: pl.Object, # JSON
|
|
186
|
+
246: pl.Decimal(10, 6), # NewDecimal
|
|
187
|
+
-246: pl.Decimal(10, 6), # NewDecimal
|
|
188
|
+
247: pl.Utf8, # Enum
|
|
189
|
+
248: pl.Utf8, # Set
|
|
190
|
+
249: pl.Utf8, # TinyText
|
|
191
|
+
-249: pl.Binary, # TinyBlob
|
|
192
|
+
250: pl.Utf8, # MediumBlob
|
|
193
|
+
-250: pl.Binary, # MediumText
|
|
194
|
+
251: pl.Utf8, # LongBlob
|
|
195
|
+
-251: pl.Binary, # LongText
|
|
196
|
+
252: pl.Utf8, # Blob
|
|
197
|
+
-252: pl.Binary, # Text
|
|
198
|
+
253: pl.Utf8, # VarString
|
|
199
|
+
-253: pl.Binary, # VarBinary
|
|
200
|
+
254: pl.Utf8, # String
|
|
201
|
+
-254: pl.Binary, # Binary
|
|
202
|
+
255: pl.Utf8, # Geometry
|
|
203
|
+
}
|
|
204
|
+
else:
|
|
205
|
+
POLARS_TYPE_MAP = {}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
from typing import Any
|
|
3
|
+
from typing import Callable
|
|
4
|
+
from typing import Dict
|
|
5
|
+
from typing import Set
|
|
6
|
+
|
|
7
|
+
try:
|
|
8
|
+
from IPython import get_ipython
|
|
9
|
+
has_ipython = True
|
|
10
|
+
except ImportError:
|
|
11
|
+
has_ipython = False
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
_subscribers: Set[Callable[[Dict[str, Any]], None]] = set()
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def subscribe(func: Callable[[Dict[str, Any]], None]) -> None:
|
|
18
|
+
"""
|
|
19
|
+
Subscribe to SingleStore portal events.
|
|
20
|
+
|
|
21
|
+
Parameters
|
|
22
|
+
----------
|
|
23
|
+
func : Callable
|
|
24
|
+
The function to call when an event is received
|
|
25
|
+
|
|
26
|
+
"""
|
|
27
|
+
_subscribers.add(func)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def unsubscribe(func: Callable[[Dict[str, Any]], None]) -> None:
|
|
31
|
+
"""
|
|
32
|
+
Unsubscribe from SingleStore portal events.
|
|
33
|
+
|
|
34
|
+
Parameters
|
|
35
|
+
----------
|
|
36
|
+
func : Callable
|
|
37
|
+
The function to call when an event is received
|
|
38
|
+
|
|
39
|
+
"""
|
|
40
|
+
try:
|
|
41
|
+
_subscribers.remove(func)
|
|
42
|
+
except KeyError:
|
|
43
|
+
pass
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def _event_handler(stream: Any, ident: Any, msg: Dict[str, Any]) -> None:
|
|
47
|
+
"""Handle request on the control stream."""
|
|
48
|
+
if not _subscribers or not isinstance(msg, dict):
|
|
49
|
+
return
|
|
50
|
+
|
|
51
|
+
content = msg.get('content', {})
|
|
52
|
+
if content.get('type', '') != 'event':
|
|
53
|
+
return
|
|
54
|
+
|
|
55
|
+
for func in _subscribers:
|
|
56
|
+
func(content)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
# Inject a control handler to receive SingleStore events
|
|
60
|
+
if has_ipython:
|
|
61
|
+
try:
|
|
62
|
+
_handlers = get_ipython().kernel.control_handlers
|
|
63
|
+
_handlers['singlestore_portal_request'] = _event_handler
|
|
64
|
+
except AttributeError:
|
|
65
|
+
pass
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
from collections.abc import Sequence
|
|
3
|
+
from typing import Any
|
|
4
|
+
from typing import Dict
|
|
5
|
+
from typing import Optional
|
|
6
|
+
from typing import Union
|
|
7
|
+
|
|
8
|
+
from ..mysql import converters
|
|
9
|
+
from ..mysql.constants import SERVER_STATUS
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
Encoders = converters.Encoders
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def escape(
|
|
16
|
+
obj: Any,
|
|
17
|
+
charset: str = 'utf8',
|
|
18
|
+
mapping: Optional[Encoders] = None,
|
|
19
|
+
server_status: int = 0,
|
|
20
|
+
binary_prefix: bool = False,
|
|
21
|
+
) -> str:
|
|
22
|
+
"""
|
|
23
|
+
Escape whatever value is passed.
|
|
24
|
+
|
|
25
|
+
Non-standard, for internal use; do not use this in your applications.
|
|
26
|
+
|
|
27
|
+
"""
|
|
28
|
+
dtype = type(obj)
|
|
29
|
+
if dtype is str or isinstance(obj, str):
|
|
30
|
+
return "'{}'".format(escape_string(obj, server_status=server_status))
|
|
31
|
+
if dtype is bytes or dtype is bytearray or isinstance(obj, (bytes, bytearray)):
|
|
32
|
+
return _quote_bytes(
|
|
33
|
+
obj,
|
|
34
|
+
server_status=server_status,
|
|
35
|
+
binary_prefix=binary_prefix,
|
|
36
|
+
)
|
|
37
|
+
if mapping is None:
|
|
38
|
+
mapping = converters.encoders
|
|
39
|
+
return converters.escape_item(obj, charset, mapping=mapping)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def literal(
|
|
43
|
+
obj: Any,
|
|
44
|
+
charset: str = 'utf8',
|
|
45
|
+
encoders: Optional[Encoders] = None,
|
|
46
|
+
server_status: int = 0,
|
|
47
|
+
binary_prefix: bool = False,
|
|
48
|
+
) -> str:
|
|
49
|
+
"""
|
|
50
|
+
Alias for escape().
|
|
51
|
+
|
|
52
|
+
Non-standard, for internal use; do not use this in your applications.
|
|
53
|
+
|
|
54
|
+
"""
|
|
55
|
+
return escape(
|
|
56
|
+
obj, charset=charset, mapping=encoders,
|
|
57
|
+
server_status=server_status, binary_prefix=binary_prefix,
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def escape_string(
|
|
62
|
+
s: str,
|
|
63
|
+
server_status: int = 0,
|
|
64
|
+
) -> str:
|
|
65
|
+
"""Escape a string value."""
|
|
66
|
+
if server_status & SERVER_STATUS.SERVER_STATUS_NO_BACKSLASH_ESCAPES:
|
|
67
|
+
return s.replace("'", "''")
|
|
68
|
+
return converters.escape_string(s)
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def _quote_bytes(
|
|
72
|
+
s: bytes,
|
|
73
|
+
server_status: int = 0,
|
|
74
|
+
binary_prefix: bool = False,
|
|
75
|
+
) -> str:
|
|
76
|
+
if server_status & SERVER_STATUS.SERVER_STATUS_NO_BACKSLASH_ESCAPES:
|
|
77
|
+
if binary_prefix:
|
|
78
|
+
return "_binary X'{}'".format(s.hex())
|
|
79
|
+
return "X'{}'".format(s.hex())
|
|
80
|
+
return converters.escape_bytes(s)
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def _escape_args(
|
|
84
|
+
args: Union[Sequence[Any], Dict[str, Any], None],
|
|
85
|
+
charset: str = 'utf8',
|
|
86
|
+
encoders: Optional[Encoders] = None,
|
|
87
|
+
server_status: int = 0,
|
|
88
|
+
binary_prefix: bool = False,
|
|
89
|
+
) -> Any:
|
|
90
|
+
if encoders is None:
|
|
91
|
+
encoders = converters.encoders
|
|
92
|
+
|
|
93
|
+
if isinstance(args, (tuple, list)):
|
|
94
|
+
return tuple(
|
|
95
|
+
literal(
|
|
96
|
+
arg, charset=charset, encoders=encoders,
|
|
97
|
+
server_status=server_status,
|
|
98
|
+
binary_prefix=binary_prefix,
|
|
99
|
+
) for arg in args
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
elif isinstance(args, dict):
|
|
103
|
+
return {
|
|
104
|
+
key: literal(
|
|
105
|
+
val, charset=charset, encoders=encoders,
|
|
106
|
+
server_status=server_status,
|
|
107
|
+
binary_prefix=binary_prefix,
|
|
108
|
+
) for (key, val) in args.items()
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
# If it's not a dictionary let's try escaping it anyways.
|
|
112
|
+
# Worst case it will throw a Value error
|
|
113
|
+
return escape(
|
|
114
|
+
args, charset=charset, mapping=encoders,
|
|
115
|
+
server_status=server_status, binary_prefix=binary_prefix,
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
def mogrify(
|
|
120
|
+
query: Union[str, bytes],
|
|
121
|
+
args: Union[Sequence[Any], Dict[str, Any], None] = None,
|
|
122
|
+
charset: str = 'utf8',
|
|
123
|
+
encoders: Optional[Encoders] = None,
|
|
124
|
+
server_status: int = 0,
|
|
125
|
+
binary_prefix: bool = False,
|
|
126
|
+
) -> Union[str, bytes]:
|
|
127
|
+
"""
|
|
128
|
+
Returns the exact string sent to the database by calling the execute() method.
|
|
129
|
+
|
|
130
|
+
This method follows the extension to the DB API 2.0 followed by Psycopg.
|
|
131
|
+
|
|
132
|
+
Parameters
|
|
133
|
+
----------
|
|
134
|
+
query : str
|
|
135
|
+
Query to mogrify.
|
|
136
|
+
args : Sequence[Any] or Dict[str, Any] or Any, optional
|
|
137
|
+
Parameters used with query. (optional)
|
|
138
|
+
|
|
139
|
+
Returns
|
|
140
|
+
-------
|
|
141
|
+
str : The query with argument binding applied.
|
|
142
|
+
|
|
143
|
+
"""
|
|
144
|
+
if args:
|
|
145
|
+
query = query % _escape_args(
|
|
146
|
+
args, charset=charset,
|
|
147
|
+
encoders=encoders,
|
|
148
|
+
server_status=server_status,
|
|
149
|
+
binary_prefix=binary_prefix,
|
|
150
|
+
)
|
|
151
|
+
return query
|