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,690 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
from typing import Any
|
|
3
|
+
from typing import Dict
|
|
4
|
+
from typing import Optional
|
|
5
|
+
|
|
6
|
+
from .. import result
|
|
7
|
+
from ..handler import SQLHandler
|
|
8
|
+
from ..result import FusionSQLResult
|
|
9
|
+
from .utils import dt_isoformat
|
|
10
|
+
from .utils import get_file_space
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class ShowFilesHandler(SQLHandler):
|
|
14
|
+
"""
|
|
15
|
+
Generic handler for listing files in a personal/shared space.
|
|
16
|
+
""" # noqa: E501
|
|
17
|
+
|
|
18
|
+
def run(self, params: Dict[str, Any]) -> Optional[FusionSQLResult]:
|
|
19
|
+
file_space = get_file_space(params)
|
|
20
|
+
|
|
21
|
+
res = FusionSQLResult()
|
|
22
|
+
res.add_field('Name', result.STRING)
|
|
23
|
+
|
|
24
|
+
if params['extended']:
|
|
25
|
+
res.add_field('Type', result.STRING)
|
|
26
|
+
res.add_field('Size', result.INTEGER)
|
|
27
|
+
res.add_field('Writable', result.STRING)
|
|
28
|
+
res.add_field('CreatedAt', result.DATETIME)
|
|
29
|
+
res.add_field('LastModifiedAt', result.DATETIME)
|
|
30
|
+
|
|
31
|
+
files = []
|
|
32
|
+
for x in file_space.listdir(
|
|
33
|
+
params['at_path'] or '/',
|
|
34
|
+
recursive=params['recursive'],
|
|
35
|
+
):
|
|
36
|
+
info = file_space.info(x)
|
|
37
|
+
files.append(
|
|
38
|
+
tuple([
|
|
39
|
+
x, info.type, info.size or 0, info.writable,
|
|
40
|
+
dt_isoformat(info.created_at),
|
|
41
|
+
dt_isoformat(info.last_modified_at),
|
|
42
|
+
]),
|
|
43
|
+
)
|
|
44
|
+
res.set_rows(files)
|
|
45
|
+
|
|
46
|
+
else:
|
|
47
|
+
res.set_rows([(x,) for x in file_space.listdir(
|
|
48
|
+
params['at_path'] or '/',
|
|
49
|
+
recursive=params['recursive'],
|
|
50
|
+
)])
|
|
51
|
+
|
|
52
|
+
if params['like']:
|
|
53
|
+
res = res.like(Name=params['like'])
|
|
54
|
+
|
|
55
|
+
return res.order_by(**params['order_by']).limit(params['limit'])
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
class ShowPersonalFilesHandler(ShowFilesHandler):
|
|
59
|
+
"""
|
|
60
|
+
SHOW PERSONAL FILES
|
|
61
|
+
[ at_path ] [ <like> ]
|
|
62
|
+
[ <order-by> ]
|
|
63
|
+
[ <limit> ] [ recursive ] [ extended ];
|
|
64
|
+
|
|
65
|
+
# File path to list
|
|
66
|
+
at_path = AT '<path>'
|
|
67
|
+
|
|
68
|
+
# Should the listing be recursive?
|
|
69
|
+
recursive = RECURSIVE
|
|
70
|
+
|
|
71
|
+
# Should extended attributes be shown?
|
|
72
|
+
extended = EXTENDED
|
|
73
|
+
|
|
74
|
+
Description
|
|
75
|
+
-----------
|
|
76
|
+
Displays a list of files in a personal/shared space.
|
|
77
|
+
|
|
78
|
+
Arguments
|
|
79
|
+
---------
|
|
80
|
+
* ``<path>``: A path in the personal/shared space.
|
|
81
|
+
* ``<pattern>``: A pattern similar to SQL LIKE clause.
|
|
82
|
+
Uses ``%`` as the wildcard character.
|
|
83
|
+
|
|
84
|
+
Remarks
|
|
85
|
+
-------
|
|
86
|
+
* Use the ``LIKE`` clause to specify a pattern and return only the
|
|
87
|
+
files that match the specified pattern.
|
|
88
|
+
* The ``LIMIT`` clause limits the number of results to the
|
|
89
|
+
specified number.
|
|
90
|
+
* Use the ``ORDER BY`` clause to sort the results by the specified
|
|
91
|
+
key. By default, the results are sorted in the ascending order.
|
|
92
|
+
* The ``AT`` clause specifies the path in the personal/shared
|
|
93
|
+
space to list the files from.
|
|
94
|
+
* Use the ``RECURSIVE`` clause to list the files recursively.
|
|
95
|
+
* To return more information about the files, use the ``EXTENDED``
|
|
96
|
+
clause.
|
|
97
|
+
|
|
98
|
+
Examples
|
|
99
|
+
--------
|
|
100
|
+
The following command lists the files at a specific path::
|
|
101
|
+
|
|
102
|
+
SHOW PERSONAL FILES AT "/data/";
|
|
103
|
+
|
|
104
|
+
The following command lists the files recursively with
|
|
105
|
+
additional information::
|
|
106
|
+
|
|
107
|
+
SHOW PERSONAL FILES RECURSIVE EXTENDED;
|
|
108
|
+
|
|
109
|
+
See Also
|
|
110
|
+
--------
|
|
111
|
+
* ``SHOW SHARED FILES``
|
|
112
|
+
* ``UPLOAD PERSONAL FILE``
|
|
113
|
+
* ``UPLOAD SHARED FILE``
|
|
114
|
+
* ``DOWNLOAD PERSONAL FILE``
|
|
115
|
+
* ``DOWNLOAD SHARED FILE``
|
|
116
|
+
|
|
117
|
+
""" # noqa: E501
|
|
118
|
+
def run(self, params: Dict[str, Any]) -> Optional[FusionSQLResult]:
|
|
119
|
+
params['file_location'] = 'PERSONAL'
|
|
120
|
+
return super().run(params)
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
class ShowSharedFilesHandler(ShowFilesHandler):
|
|
124
|
+
"""
|
|
125
|
+
SHOW SHARED FILES
|
|
126
|
+
[ at_path ] [ <like> ]
|
|
127
|
+
[ <order-by> ]
|
|
128
|
+
[ <limit> ] [ recursive ] [ extended ];
|
|
129
|
+
|
|
130
|
+
# File path to list
|
|
131
|
+
at_path = AT '<path>'
|
|
132
|
+
|
|
133
|
+
# Should the listing be recursive?
|
|
134
|
+
recursive = RECURSIVE
|
|
135
|
+
|
|
136
|
+
# Should extended attributes be shown?
|
|
137
|
+
extended = EXTENDED
|
|
138
|
+
|
|
139
|
+
Description
|
|
140
|
+
-----------
|
|
141
|
+
Displays a list of files in a personal/shared space.
|
|
142
|
+
|
|
143
|
+
Arguments
|
|
144
|
+
---------
|
|
145
|
+
* ``<path>``: A path in the personal/shared space.
|
|
146
|
+
* ``<pattern>``: A pattern similar to SQL LIKE clause.
|
|
147
|
+
Uses ``%`` as the wildcard character.
|
|
148
|
+
|
|
149
|
+
Remarks
|
|
150
|
+
-------
|
|
151
|
+
* Use the ``LIKE`` clause to specify a pattern and return only the
|
|
152
|
+
files that match the specified pattern.
|
|
153
|
+
* The ``LIMIT`` clause limits the number of results to the
|
|
154
|
+
specified number.
|
|
155
|
+
* Use the ``ORDER BY`` clause to sort the results by the specified
|
|
156
|
+
key. By default, the results are sorted in the ascending order.
|
|
157
|
+
* The ``AT`` clause specifies the path in the personal/shared
|
|
158
|
+
space to list the files from.
|
|
159
|
+
* Use the ``RECURSIVE`` clause to list the files recursively.
|
|
160
|
+
* To return more information about the files, use the ``EXTENDED``
|
|
161
|
+
clause.
|
|
162
|
+
|
|
163
|
+
Examples
|
|
164
|
+
--------
|
|
165
|
+
The following command lists the files at a specific path::
|
|
166
|
+
|
|
167
|
+
SHOW SHARED FILES AT "/data/";
|
|
168
|
+
|
|
169
|
+
The following command lists the files recursively with
|
|
170
|
+
additional information::
|
|
171
|
+
|
|
172
|
+
SHOW SHARED FILES RECURSIVE EXTENDED;
|
|
173
|
+
|
|
174
|
+
See Also
|
|
175
|
+
--------
|
|
176
|
+
* ``SHOW PERSONAL FILES``
|
|
177
|
+
* ``UPLOAD PERSONAL FILE``
|
|
178
|
+
* ``UPLOAD SHARED FILE``
|
|
179
|
+
* ``DOWNLOAD PERSONAL FILE``
|
|
180
|
+
* ``DOWNLOAD SHARED FILE``
|
|
181
|
+
|
|
182
|
+
""" # noqa: E501
|
|
183
|
+
def run(self, params: Dict[str, Any]) -> Optional[FusionSQLResult]:
|
|
184
|
+
params['file_location'] = 'SHARED'
|
|
185
|
+
return super().run(params)
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
ShowPersonalFilesHandler.register(overwrite=True)
|
|
189
|
+
ShowSharedFilesHandler.register(overwrite=True)
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
class UploadFileHandler(SQLHandler):
|
|
193
|
+
"""
|
|
194
|
+
Generic handler for uploading files to a personal/shared space.
|
|
195
|
+
""" # noqa: E501
|
|
196
|
+
|
|
197
|
+
def run(self, params: Dict[str, Any]) -> Optional[FusionSQLResult]:
|
|
198
|
+
file_space = get_file_space(params)
|
|
199
|
+
file_space.upload_file(
|
|
200
|
+
params['local_path'], params['path'],
|
|
201
|
+
overwrite=params['overwrite'],
|
|
202
|
+
)
|
|
203
|
+
return None
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
class UploadPersonalFileHandler(UploadFileHandler):
|
|
207
|
+
"""
|
|
208
|
+
UPLOAD PERSONAL FILE TO path
|
|
209
|
+
FROM local_path [ overwrite ];
|
|
210
|
+
|
|
211
|
+
# Path to file
|
|
212
|
+
path = '<filename>'
|
|
213
|
+
|
|
214
|
+
# Path to local file
|
|
215
|
+
local_path = '<local-path>'
|
|
216
|
+
|
|
217
|
+
# Should an existing file be overwritten?
|
|
218
|
+
overwrite = OVERWRITE
|
|
219
|
+
|
|
220
|
+
Description
|
|
221
|
+
-----------
|
|
222
|
+
Uploads a file to a personal/shared space.
|
|
223
|
+
|
|
224
|
+
Arguments
|
|
225
|
+
---------
|
|
226
|
+
* ``<filename>``: The filename in the personal/shared space where the file is uploaded.
|
|
227
|
+
* ``<local-path>``: The path to the file to upload in the local
|
|
228
|
+
directory.
|
|
229
|
+
|
|
230
|
+
Remarks
|
|
231
|
+
-------
|
|
232
|
+
* If the ``OVERWRITE`` clause is specified, any existing file at the
|
|
233
|
+
specified path in the personal/shared space is overwritten.
|
|
234
|
+
|
|
235
|
+
Examples
|
|
236
|
+
--------
|
|
237
|
+
The following command uploads a file to a personal/shared space and overwrite any
|
|
238
|
+
existing files at the specified path::
|
|
239
|
+
|
|
240
|
+
UPLOAD PERSONAL FILE TO 'stats.csv'
|
|
241
|
+
FROM '/tmp/user/stats.csv' OVERWRITE;
|
|
242
|
+
|
|
243
|
+
See Also
|
|
244
|
+
--------
|
|
245
|
+
* ``UPLOAD SHARED FILE``
|
|
246
|
+
* ``DOWNLOAD PERSONAL FILE``
|
|
247
|
+
* ``DOWNLOAD SHARED FILE``
|
|
248
|
+
|
|
249
|
+
""" # noqa: E501
|
|
250
|
+
|
|
251
|
+
def run(self, params: Dict[str, Any]) -> Optional[FusionSQLResult]:
|
|
252
|
+
params['file_location'] = 'PERSONAL'
|
|
253
|
+
return super().run(params)
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
class UploadSharedFileHandler(UploadFileHandler):
|
|
257
|
+
"""
|
|
258
|
+
UPLOAD SHARED FILE TO path
|
|
259
|
+
FROM local_path [ overwrite ];
|
|
260
|
+
|
|
261
|
+
# Path to file
|
|
262
|
+
path = '<filename>'
|
|
263
|
+
|
|
264
|
+
# Path to local file
|
|
265
|
+
local_path = '<local-path>'
|
|
266
|
+
|
|
267
|
+
# Should an existing file be overwritten?
|
|
268
|
+
overwrite = OVERWRITE
|
|
269
|
+
|
|
270
|
+
Description
|
|
271
|
+
-----------
|
|
272
|
+
Uploads a file to a personal/shared space.
|
|
273
|
+
|
|
274
|
+
Arguments
|
|
275
|
+
---------
|
|
276
|
+
* ``<filename>``: The filename in the personal/shared space where the file is uploaded.
|
|
277
|
+
* ``<local-path>``: The path to the file to upload in the local
|
|
278
|
+
directory.
|
|
279
|
+
|
|
280
|
+
Remarks
|
|
281
|
+
-------
|
|
282
|
+
* If the ``OVERWRITE`` clause is specified, any existing file at the
|
|
283
|
+
specified path in the personal/shared space is overwritten.
|
|
284
|
+
|
|
285
|
+
Examples
|
|
286
|
+
--------
|
|
287
|
+
The following command uploads a file to a personal/shared space and overwrite any
|
|
288
|
+
existing files at the specified path::
|
|
289
|
+
|
|
290
|
+
UPLOAD SHARED FILE TO 'stats.csv'
|
|
291
|
+
FROM '/tmp/user/stats.csv' OVERWRITE;
|
|
292
|
+
|
|
293
|
+
See Also
|
|
294
|
+
--------
|
|
295
|
+
* ``UPLOAD PERSONAL FILE``
|
|
296
|
+
* ``DOWNLOAD PERSONAL FILE``
|
|
297
|
+
* ``DOWNLOAD SHARED FILE``
|
|
298
|
+
|
|
299
|
+
""" # noqa: E501
|
|
300
|
+
|
|
301
|
+
def run(self, params: Dict[str, Any]) -> Optional[FusionSQLResult]:
|
|
302
|
+
params['file_location'] = 'SHARED'
|
|
303
|
+
return super().run(params)
|
|
304
|
+
|
|
305
|
+
|
|
306
|
+
UploadPersonalFileHandler.register(overwrite=True)
|
|
307
|
+
UploadSharedFileHandler.register(overwrite=True)
|
|
308
|
+
|
|
309
|
+
|
|
310
|
+
class DownloadFileHandler(SQLHandler):
|
|
311
|
+
"""
|
|
312
|
+
Generic handler for downloading files from a personal/shared space.
|
|
313
|
+
""" # noqa: E501
|
|
314
|
+
|
|
315
|
+
def run(self, params: Dict[str, Any]) -> Optional[FusionSQLResult]:
|
|
316
|
+
file_space = get_file_space(params)
|
|
317
|
+
|
|
318
|
+
out = file_space.download_file(
|
|
319
|
+
params['path'],
|
|
320
|
+
local_path=params['local_path'] or None,
|
|
321
|
+
overwrite=params['overwrite'],
|
|
322
|
+
encoding=params['encoding'] or None,
|
|
323
|
+
)
|
|
324
|
+
|
|
325
|
+
if not params['local_path']:
|
|
326
|
+
res = FusionSQLResult()
|
|
327
|
+
if params['encoding']:
|
|
328
|
+
res.add_field('Data', result.STRING)
|
|
329
|
+
else:
|
|
330
|
+
res.add_field('Data', result.BLOB)
|
|
331
|
+
res.set_rows([(out,)])
|
|
332
|
+
return res
|
|
333
|
+
|
|
334
|
+
return None
|
|
335
|
+
|
|
336
|
+
|
|
337
|
+
class DownloadPersonalFileHandler(DownloadFileHandler):
|
|
338
|
+
"""
|
|
339
|
+
DOWNLOAD PERSONAL FILE path
|
|
340
|
+
[ local_path ]
|
|
341
|
+
[ overwrite ]
|
|
342
|
+
[ encoding ];
|
|
343
|
+
|
|
344
|
+
# Path to file
|
|
345
|
+
path = '<path>'
|
|
346
|
+
|
|
347
|
+
# Path to local file
|
|
348
|
+
local_path = TO '<local-path>'
|
|
349
|
+
|
|
350
|
+
# Should an existing file be overwritten?
|
|
351
|
+
overwrite = OVERWRITE
|
|
352
|
+
|
|
353
|
+
# File encoding
|
|
354
|
+
encoding = ENCODING '<encoding>'
|
|
355
|
+
|
|
356
|
+
Description
|
|
357
|
+
-----------
|
|
358
|
+
Download a file from a personal/shared space.
|
|
359
|
+
|
|
360
|
+
Arguments
|
|
361
|
+
---------
|
|
362
|
+
* ``<path>``: The path to the file to download in a personal/shared space.
|
|
363
|
+
* ``<encoding>``: The encoding to apply to the downloaded file.
|
|
364
|
+
* ``<local-path>``: Specifies the path in the local directory
|
|
365
|
+
where the file is downloaded.
|
|
366
|
+
|
|
367
|
+
Remarks
|
|
368
|
+
-------
|
|
369
|
+
* If the ``OVERWRITE`` clause is specified, any existing file at
|
|
370
|
+
the download location is overwritten.
|
|
371
|
+
* By default, files are downloaded in binary encoding. To view
|
|
372
|
+
the contents of the file on the standard output, use the
|
|
373
|
+
``ENCODING`` clause and specify an encoding.
|
|
374
|
+
* If ``<local-path>`` is not specified, the file is displayed
|
|
375
|
+
on the standard output.
|
|
376
|
+
|
|
377
|
+
Examples
|
|
378
|
+
--------
|
|
379
|
+
The following command displays the contents of the file on the
|
|
380
|
+
standard output::
|
|
381
|
+
|
|
382
|
+
DOWNLOAD PERSONAL FILE '/data/stats.csv' ENCODING 'utf8';
|
|
383
|
+
|
|
384
|
+
The following command downloads a file to a specific location and
|
|
385
|
+
overwrites any existing file with the name ``stats.csv`` on the local storage::
|
|
386
|
+
|
|
387
|
+
DOWNLOAD PERSONAL FILE '/data/stats.csv'
|
|
388
|
+
TO '/tmp/data.csv' OVERWRITE;
|
|
389
|
+
|
|
390
|
+
See Also
|
|
391
|
+
--------
|
|
392
|
+
* ``DOWNLOAD SHARED FILE``
|
|
393
|
+
* ``UPLOAD PERSONAL FILE``
|
|
394
|
+
* ``UPLOAD SHARED FILE``
|
|
395
|
+
|
|
396
|
+
""" # noqa: E501
|
|
397
|
+
|
|
398
|
+
def run(self, params: Dict[str, Any]) -> Optional[FusionSQLResult]:
|
|
399
|
+
params['file_location'] = 'PERSONAL'
|
|
400
|
+
return super().run(params)
|
|
401
|
+
|
|
402
|
+
|
|
403
|
+
class DownloadSharedFileHandler(DownloadFileHandler):
|
|
404
|
+
"""
|
|
405
|
+
DOWNLOAD SHARED FILE path
|
|
406
|
+
[ local_path ]
|
|
407
|
+
[ overwrite ]
|
|
408
|
+
[ encoding ];
|
|
409
|
+
|
|
410
|
+
# Path to file
|
|
411
|
+
path = '<path>'
|
|
412
|
+
|
|
413
|
+
# Path to local file
|
|
414
|
+
local_path = TO '<local-path>'
|
|
415
|
+
|
|
416
|
+
# Should an existing file be overwritten?
|
|
417
|
+
overwrite = OVERWRITE
|
|
418
|
+
|
|
419
|
+
# File encoding
|
|
420
|
+
encoding = ENCODING '<encoding>'
|
|
421
|
+
|
|
422
|
+
Description
|
|
423
|
+
-----------
|
|
424
|
+
Download a file from a personal/shared space.
|
|
425
|
+
|
|
426
|
+
Arguments
|
|
427
|
+
---------
|
|
428
|
+
* ``<path>``: The path to the file to download in a personal/shared space.
|
|
429
|
+
* ``<encoding>``: The encoding to apply to the downloaded file.
|
|
430
|
+
* ``<local-path>``: Specifies the path in the local directory
|
|
431
|
+
where the file is downloaded.
|
|
432
|
+
|
|
433
|
+
Remarks
|
|
434
|
+
-------
|
|
435
|
+
* If the ``OVERWRITE`` clause is specified, any existing file at
|
|
436
|
+
the download location is overwritten.
|
|
437
|
+
* By default, files are downloaded in binary encoding. To view
|
|
438
|
+
the contents of the file on the standard output, use the
|
|
439
|
+
``ENCODING`` clause and specify an encoding.
|
|
440
|
+
* If ``<local-path>`` is not specified, the file is displayed
|
|
441
|
+
on the standard output.
|
|
442
|
+
|
|
443
|
+
Examples
|
|
444
|
+
--------
|
|
445
|
+
The following command displays the contents of the file on the
|
|
446
|
+
standard output::
|
|
447
|
+
|
|
448
|
+
DOWNLOAD SHARED FILE '/data/stats.csv' ENCODING 'utf8';
|
|
449
|
+
|
|
450
|
+
The following command downloads a file to a specific location and
|
|
451
|
+
overwrites any existing file with the name ``stats.csv`` on the local storage::
|
|
452
|
+
|
|
453
|
+
DOWNLOAD SHARED FILE '/data/stats.csv'
|
|
454
|
+
TO '/tmp/data.csv' OVERWRITE;
|
|
455
|
+
|
|
456
|
+
See Also
|
|
457
|
+
--------
|
|
458
|
+
* ``DOWNLOAD PERSONAL FILE``
|
|
459
|
+
* ``UPLOAD PERSONAL FILE``
|
|
460
|
+
* ``UPLOAD SHARED FILE``
|
|
461
|
+
|
|
462
|
+
""" # noqa: E501
|
|
463
|
+
|
|
464
|
+
def run(self, params: Dict[str, Any]) -> Optional[FusionSQLResult]:
|
|
465
|
+
params['file_location'] = 'SHARED'
|
|
466
|
+
return super().run(params)
|
|
467
|
+
|
|
468
|
+
|
|
469
|
+
DownloadPersonalFileHandler.register(overwrite=True)
|
|
470
|
+
DownloadSharedFileHandler.register(overwrite=True)
|
|
471
|
+
|
|
472
|
+
|
|
473
|
+
class DropHandler(SQLHandler):
|
|
474
|
+
"""
|
|
475
|
+
Generic handler for deleting files/folders from a personal/shared space.
|
|
476
|
+
""" # noqa: E501
|
|
477
|
+
|
|
478
|
+
def run(self, params: Dict[str, Any]) -> Optional[FusionSQLResult]:
|
|
479
|
+
file_space = get_file_space(params)
|
|
480
|
+
|
|
481
|
+
file_type = params['file_type']
|
|
482
|
+
if not file_type:
|
|
483
|
+
raise KeyError('file type was not specified')
|
|
484
|
+
|
|
485
|
+
file_type = file_type.lower()
|
|
486
|
+
if file_type not in ['file', 'folder']:
|
|
487
|
+
raise ValueError('file type must be either FILE or FOLDER')
|
|
488
|
+
|
|
489
|
+
if file_type == 'file':
|
|
490
|
+
file_space.remove(params['path'])
|
|
491
|
+
elif file_type == 'folder':
|
|
492
|
+
if params['recursive']:
|
|
493
|
+
file_space.removedirs(params['path'])
|
|
494
|
+
else:
|
|
495
|
+
file_space.rmdir(params['path'])
|
|
496
|
+
|
|
497
|
+
return None
|
|
498
|
+
|
|
499
|
+
|
|
500
|
+
class DropPersonalHandler(DropHandler):
|
|
501
|
+
"""
|
|
502
|
+
DROP PERSONAL <file-type> path
|
|
503
|
+
[ recursive ];
|
|
504
|
+
|
|
505
|
+
# Path to file
|
|
506
|
+
path = '<path>'
|
|
507
|
+
|
|
508
|
+
# Should folders be deleted recursively?
|
|
509
|
+
recursive = RECURSIVE
|
|
510
|
+
|
|
511
|
+
Description
|
|
512
|
+
-----------
|
|
513
|
+
Deletes a file/folder from a personal/shared space.
|
|
514
|
+
|
|
515
|
+
Arguments
|
|
516
|
+
---------
|
|
517
|
+
* ``<file-type>``: The type of the file, it can
|
|
518
|
+
be either 'FILE' or 'FOLDER'.
|
|
519
|
+
* ``<path>``: The path to the file to delete in a personal/shared space.
|
|
520
|
+
|
|
521
|
+
Remarks
|
|
522
|
+
-------
|
|
523
|
+
* The ``RECURSIVE`` clause indicates that the specified folder
|
|
524
|
+
is deleted recursively.
|
|
525
|
+
|
|
526
|
+
Example
|
|
527
|
+
--------
|
|
528
|
+
The following commands delete a file/folder from a personal/shared space::
|
|
529
|
+
|
|
530
|
+
DROP PERSONAL FILE '/data/stats.csv';
|
|
531
|
+
DROP PERSONAL FOLDER '/data/' RECURSIVE;
|
|
532
|
+
|
|
533
|
+
See Also
|
|
534
|
+
--------
|
|
535
|
+
* ``DROP SHARED FILE``
|
|
536
|
+
* ``DROP SHARED FOLDER``
|
|
537
|
+
|
|
538
|
+
""" # noqa: E501
|
|
539
|
+
|
|
540
|
+
def run(self, params: Dict[str, Any]) -> Optional[FusionSQLResult]:
|
|
541
|
+
params['file_location'] = 'PERSONAL'
|
|
542
|
+
return super().run(params)
|
|
543
|
+
|
|
544
|
+
|
|
545
|
+
class DropSharedHandler(DropHandler):
|
|
546
|
+
"""
|
|
547
|
+
DROP SHARED <file-type> path
|
|
548
|
+
[ recursive ];
|
|
549
|
+
|
|
550
|
+
# Path to file
|
|
551
|
+
path = '<path>'
|
|
552
|
+
|
|
553
|
+
# Should folders be deleted recursively?
|
|
554
|
+
recursive = RECURSIVE
|
|
555
|
+
|
|
556
|
+
Description
|
|
557
|
+
-----------
|
|
558
|
+
Deletes a file/folder from a personal/shared space.
|
|
559
|
+
|
|
560
|
+
Arguments
|
|
561
|
+
---------
|
|
562
|
+
* ``<file-type>``: The type of the file, it can
|
|
563
|
+
be either 'FILE' or 'FOLDER'.
|
|
564
|
+
* ``<path>``: The path to the file to delete in a personal/shared space.
|
|
565
|
+
|
|
566
|
+
Remarks
|
|
567
|
+
-------
|
|
568
|
+
* The ``RECURSIVE`` clause indicates that the specified folder
|
|
569
|
+
is deleted recursively.
|
|
570
|
+
|
|
571
|
+
Example
|
|
572
|
+
--------
|
|
573
|
+
The following commands delete a file/folder from a personal/shared space::
|
|
574
|
+
|
|
575
|
+
DROP SHARED FILE '/data/stats.csv';
|
|
576
|
+
DROP SHARED FOLDER '/data/' RECURSIVE;
|
|
577
|
+
|
|
578
|
+
See Also
|
|
579
|
+
--------
|
|
580
|
+
* ``DROP PERSONAL FILE``
|
|
581
|
+
* ``DROP PERSONAL FOLDER``
|
|
582
|
+
|
|
583
|
+
""" # noqa: E501
|
|
584
|
+
|
|
585
|
+
def run(self, params: Dict[str, Any]) -> Optional[FusionSQLResult]:
|
|
586
|
+
params['file_location'] = 'SHARED'
|
|
587
|
+
return super().run(params)
|
|
588
|
+
|
|
589
|
+
|
|
590
|
+
DropPersonalHandler.register(overwrite=True)
|
|
591
|
+
DropSharedHandler.register(overwrite=True)
|
|
592
|
+
|
|
593
|
+
|
|
594
|
+
class CreateFolderHandler(SQLHandler):
|
|
595
|
+
"""
|
|
596
|
+
Generic handler for creating folders in a personal/shared space.
|
|
597
|
+
"""
|
|
598
|
+
|
|
599
|
+
def run(self, params: Dict[str, Any]) -> Optional[FusionSQLResult]:
|
|
600
|
+
file_space = get_file_space(params)
|
|
601
|
+
file_space.mkdir(params['path'], overwrite=params['overwrite'])
|
|
602
|
+
return None
|
|
603
|
+
|
|
604
|
+
|
|
605
|
+
class CreatePersonalFolderHandler(CreateFolderHandler):
|
|
606
|
+
"""
|
|
607
|
+
CREATE PERSONAL FOLDER path
|
|
608
|
+
[ overwrite ];
|
|
609
|
+
|
|
610
|
+
# Path to folder
|
|
611
|
+
path = '<path>'
|
|
612
|
+
|
|
613
|
+
# Should an existing folder be overwritten?
|
|
614
|
+
overwrite = OVERWRITE
|
|
615
|
+
|
|
616
|
+
Description
|
|
617
|
+
-----------
|
|
618
|
+
Creates a new folder at the specified path in a personal/shared space.
|
|
619
|
+
|
|
620
|
+
Arguments
|
|
621
|
+
---------
|
|
622
|
+
* ``<path>``: The path in a personal/shared space where the folder
|
|
623
|
+
is created. The path must end with a trailing slash (/).
|
|
624
|
+
|
|
625
|
+
Remarks
|
|
626
|
+
-------
|
|
627
|
+
* If the ``OVERWRITE`` clause is specified, any existing
|
|
628
|
+
folder at the specified path is overwritten.
|
|
629
|
+
|
|
630
|
+
Example
|
|
631
|
+
-------
|
|
632
|
+
The following command creates a folder in a personal/shared space::
|
|
633
|
+
|
|
634
|
+
CREATE PERSONAL FOLDER `/data/csv/`;
|
|
635
|
+
|
|
636
|
+
See Also
|
|
637
|
+
--------
|
|
638
|
+
* ``CREATE SHARED FOLDER``
|
|
639
|
+
|
|
640
|
+
"""
|
|
641
|
+
|
|
642
|
+
def run(self, params: Dict[str, Any]) -> Optional[FusionSQLResult]:
|
|
643
|
+
params['file_location'] = 'PERSONAL'
|
|
644
|
+
return super().run(params)
|
|
645
|
+
|
|
646
|
+
|
|
647
|
+
class CreateSharedFolderHandler(CreateFolderHandler):
|
|
648
|
+
"""
|
|
649
|
+
CREATE SHARED FOLDER path
|
|
650
|
+
[ overwrite ];
|
|
651
|
+
|
|
652
|
+
# Path to folder
|
|
653
|
+
path = '<path>'
|
|
654
|
+
|
|
655
|
+
# Should an existing folder be overwritten?
|
|
656
|
+
overwrite = OVERWRITE
|
|
657
|
+
|
|
658
|
+
Description
|
|
659
|
+
-----------
|
|
660
|
+
Creates a new folder at the specified path in a personal/shared space.
|
|
661
|
+
|
|
662
|
+
Arguments
|
|
663
|
+
---------
|
|
664
|
+
* ``<path>``: The path in a personal/shared space where the folder
|
|
665
|
+
is created. The path must end with a trailing slash (/).
|
|
666
|
+
|
|
667
|
+
Remarks
|
|
668
|
+
-------
|
|
669
|
+
* If the ``OVERWRITE`` clause is specified, any existing
|
|
670
|
+
folder at the specified path is overwritten.
|
|
671
|
+
|
|
672
|
+
Example
|
|
673
|
+
-------
|
|
674
|
+
The following command creates a folder in a personal/shared space::
|
|
675
|
+
|
|
676
|
+
CREATE SHARED FOLDER `/data/csv/`;
|
|
677
|
+
|
|
678
|
+
See Also
|
|
679
|
+
--------
|
|
680
|
+
* ``CREATE PERSONAL FOLDER``
|
|
681
|
+
|
|
682
|
+
"""
|
|
683
|
+
|
|
684
|
+
def run(self, params: Dict[str, Any]) -> Optional[FusionSQLResult]:
|
|
685
|
+
params['file_location'] = 'SHARED'
|
|
686
|
+
return super().run(params)
|
|
687
|
+
|
|
688
|
+
|
|
689
|
+
CreatePersonalFolderHandler.register(overwrite=True)
|
|
690
|
+
CreateSharedFolderHandler.register(overwrite=True)
|