gbase8sdb 0.2.1__cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.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.
- gbase8sdb/__init__.py +121 -0
- gbase8sdb/column_metadata.py +121 -0
- gbase8sdb/connection.py +152 -0
- gbase8sdb/constructors.py +34 -0
- gbase8sdb/cursor.py +407 -0
- gbase8sdb/defaults.py +46 -0
- gbase8sdb/driver.cpython-312-aarch64-linux-gnu.so +0 -0
- gbase8sdb/dsn.py +39 -0
- gbase8sdb/errors.py +303 -0
- gbase8sdb/exceptions.py +41 -0
- gbase8sdb/lob.py +90 -0
- gbase8sdb/var.py +79 -0
- gbase8sdb/version.py +7 -0
- gbase8sdb-0.2.1.dist-info/METADATA +95 -0
- gbase8sdb-0.2.1.dist-info/RECORD +19 -0
- gbase8sdb-0.2.1.dist-info/WHEEL +6 -0
- gbase8sdb-0.2.1.dist-info/licenses/LICENSE.txt +21 -0
- gbase8sdb-0.2.1.dist-info/licenses/THIRD_PARTY_LICENSES.txt +455 -0
- gbase8sdb-0.2.1.dist-info/top_level.txt +1 -0
gbase8sdb/cursor.py
ADDED
@@ -0,0 +1,407 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
from typing import Any, Union, Callable
|
4
|
+
|
5
|
+
from . import __name__ as MODULE_NAME
|
6
|
+
from . import connection as connection_module
|
7
|
+
from . import errors
|
8
|
+
from .column_metadata import ColumnMetaData
|
9
|
+
from .var import Var
|
10
|
+
from .driver import DbType
|
11
|
+
|
12
|
+
|
13
|
+
class Cursor:
|
14
|
+
__module__ = MODULE_NAME
|
15
|
+
_cyobj = None
|
16
|
+
|
17
|
+
def __init__(
|
18
|
+
self,
|
19
|
+
connection: "connection_module.Connection",
|
20
|
+
) -> None:
|
21
|
+
self.connection = connection
|
22
|
+
self._cyobj = connection._cyobj.create_cursor_impl(False)
|
23
|
+
|
24
|
+
def __del__(self):
|
25
|
+
if self._cyobj is not None:
|
26
|
+
self._cyobj.close(in_del=True)
|
27
|
+
|
28
|
+
def __enter__(self):
|
29
|
+
self._verify_open()
|
30
|
+
return self
|
31
|
+
|
32
|
+
def __exit__(self, exc_type, exc_value, exc_tb):
|
33
|
+
self._verify_open()
|
34
|
+
self._cyobj.close(in_del=True)
|
35
|
+
self._cyobj = None
|
36
|
+
|
37
|
+
def __repr__(self):
|
38
|
+
cls_name = f"{self.__class__.__module__}.{self.__class__.__qualname__}"
|
39
|
+
return f"<{cls_name} on {self.connection!r}>"
|
40
|
+
|
41
|
+
def __iter__(self):
|
42
|
+
return self
|
43
|
+
|
44
|
+
def __next__(self):
|
45
|
+
self._verify_fetch()
|
46
|
+
row = self._cyobj.fetch_next_row(self)
|
47
|
+
if row is not None:
|
48
|
+
return row
|
49
|
+
raise StopIteration
|
50
|
+
|
51
|
+
def _get_gci_attr(self, attr_num: int, attr_type: int) -> Any:
|
52
|
+
self._verify_open()
|
53
|
+
return self._cyobj._get_gci_attr(attr_num, attr_type)
|
54
|
+
|
55
|
+
def _set_gci_attr(self, attr_num: int, attr_type: int, value: Any) -> None:
|
56
|
+
self._verify_open()
|
57
|
+
self._cyobj._set_gci_attr(attr_num, attr_type, value)
|
58
|
+
|
59
|
+
|
60
|
+
@staticmethod
|
61
|
+
def _check_proc_args(parameters: Union[list, tuple], keyword_parameters: dict):
|
62
|
+
if parameters is not None and not isinstance(parameters, (list, tuple)):
|
63
|
+
errors.raise_error(errors.ERR_ARGS_MUST_BE_LIST_OR_TUPLE)
|
64
|
+
if keyword_parameters is not None and not isinstance(
|
65
|
+
keyword_parameters, dict
|
66
|
+
):
|
67
|
+
errors.raise_error(errors.ERR_KEYWORD_ARGS_MUST_BE_DICT)
|
68
|
+
|
69
|
+
def _call(
|
70
|
+
self,
|
71
|
+
name: str,
|
72
|
+
parameters: Union[list, tuple],
|
73
|
+
keyword_parameters: dict,
|
74
|
+
return_value: Any = None,
|
75
|
+
) -> None:
|
76
|
+
self._check_proc_args(parameters, keyword_parameters)
|
77
|
+
self._verify_open()
|
78
|
+
statement, bind_values = self._call_get_execute_args(
|
79
|
+
name, parameters, keyword_parameters, return_value
|
80
|
+
)
|
81
|
+
return self.execute(statement, bind_values)
|
82
|
+
|
83
|
+
def _call_get_execute_args(
|
84
|
+
self,
|
85
|
+
name: str,
|
86
|
+
parameters: Union[list, tuple],
|
87
|
+
keyword_parameters: dict,
|
88
|
+
return_value: str = None,
|
89
|
+
) -> None:
|
90
|
+
bind_names = []
|
91
|
+
bind_values = []
|
92
|
+
statement_parts = ["begin "]
|
93
|
+
if return_value is not None:
|
94
|
+
statement_parts.append(":retval := ")
|
95
|
+
bind_values.append(return_value)
|
96
|
+
statement_parts.append(name + "(")
|
97
|
+
if parameters:
|
98
|
+
bind_values.extend(parameters)
|
99
|
+
bind_names = [":%d" % (i + 1) for i in range(len(parameters))]
|
100
|
+
if keyword_parameters:
|
101
|
+
for arg_name, arg_value in keyword_parameters.items():
|
102
|
+
bind_values.append(arg_value)
|
103
|
+
bind_names.append(f"{arg_name} => :{len(bind_names) + 1}")
|
104
|
+
statement_parts.append(",".join(bind_names))
|
105
|
+
statement_parts.append("); end;")
|
106
|
+
statement = "".join(statement_parts)
|
107
|
+
return (statement, bind_values)
|
108
|
+
|
109
|
+
def _prepare(
|
110
|
+
self, statement: str, tag: str = None, cache_statement: bool = True
|
111
|
+
) -> None:
|
112
|
+
self._cyobj.prepare(statement, tag, cache_statement)
|
113
|
+
|
114
|
+
def _prepare_for_execute(
|
115
|
+
self, statement, parameters, keyword_parameters=None
|
116
|
+
):
|
117
|
+
self._verify_open()
|
118
|
+
self._cyobj._prepare_for_execute(
|
119
|
+
self, statement, parameters, keyword_parameters
|
120
|
+
)
|
121
|
+
|
122
|
+
def _verify_fetch(self) -> None:
|
123
|
+
self._verify_open()
|
124
|
+
if not self._cyobj.is_query(self):
|
125
|
+
errors.raise_error(errors.ERR_NOT_A_QUERY)
|
126
|
+
|
127
|
+
def _verify_open(self) -> None:
|
128
|
+
if self._cyobj is None:
|
129
|
+
errors.raise_error(errors.ERR_CURSOR_NOT_OPEN)
|
130
|
+
self.connection._verify_connected()
|
131
|
+
|
132
|
+
|
133
|
+
def callproc(
|
134
|
+
self,
|
135
|
+
name: str,
|
136
|
+
parameters: Union[list, tuple] = None,
|
137
|
+
keyword_parameters: dict = None,
|
138
|
+
*,
|
139
|
+
keywordParameters: dict = None,
|
140
|
+
) -> list:
|
141
|
+
if keywordParameters is not None:
|
142
|
+
if keyword_parameters is not None:
|
143
|
+
errors.raise_error(
|
144
|
+
errors.ERR_DUPLICATED_PARAMETER,
|
145
|
+
deprecated_name="keywordParameters",
|
146
|
+
new_name="keyword_parameters",
|
147
|
+
)
|
148
|
+
keyword_parameters = keywordParameters
|
149
|
+
self._call(name, parameters, keyword_parameters)
|
150
|
+
if parameters is None:
|
151
|
+
return []
|
152
|
+
return [
|
153
|
+
v.get_value(0) for v in self._cyobj.bind_vars[: len(parameters)]
|
154
|
+
]
|
155
|
+
|
156
|
+
def execute(
|
157
|
+
self,
|
158
|
+
statement: Union[str, None],
|
159
|
+
parameters: Union[list, tuple, dict] = None,
|
160
|
+
**keyword_parameters: Any,
|
161
|
+
) -> Any:
|
162
|
+
self._prepare_for_execute(statement, parameters, keyword_parameters)
|
163
|
+
impl = self._cyobj
|
164
|
+
impl.execute(self)
|
165
|
+
if impl.fetch_vars is not None:
|
166
|
+
return self
|
167
|
+
|
168
|
+
def executemany(
|
169
|
+
self,
|
170
|
+
statement: Union[str, None],
|
171
|
+
parameters: Union[list, int],
|
172
|
+
batcherrors: bool = False,
|
173
|
+
arraydmlrowcounts: bool = False,
|
174
|
+
) -> None:
|
175
|
+
self._verify_open()
|
176
|
+
num_execs = self._cyobj._prepare_for_executemany(
|
177
|
+
self, statement, parameters
|
178
|
+
)
|
179
|
+
self._cyobj.executemany(
|
180
|
+
self, num_execs, bool(batcherrors), bool(arraydmlrowcounts)
|
181
|
+
)
|
182
|
+
|
183
|
+
def fetchall(self) -> list:
|
184
|
+
self._verify_fetch()
|
185
|
+
result = []
|
186
|
+
fetch_next_row = self._cyobj.fetch_next_row
|
187
|
+
while True:
|
188
|
+
row = fetch_next_row(self)
|
189
|
+
if row is None:
|
190
|
+
break
|
191
|
+
result.append(row)
|
192
|
+
return result
|
193
|
+
|
194
|
+
def fetchmany(self, size: int = None, numRows: int = None) -> list:
|
195
|
+
self._verify_fetch()
|
196
|
+
if size is None:
|
197
|
+
if numRows is not None:
|
198
|
+
size = numRows
|
199
|
+
else:
|
200
|
+
size = self._cyobj.arraysize
|
201
|
+
elif numRows is not None:
|
202
|
+
errors.raise_error(
|
203
|
+
errors.ERR_DUPLICATED_PARAMETER,
|
204
|
+
deprecated_name="numRows",
|
205
|
+
new_name="size",
|
206
|
+
)
|
207
|
+
result = []
|
208
|
+
fetch_next_row = self._cyobj.fetch_next_row
|
209
|
+
while len(result) < size:
|
210
|
+
row = fetch_next_row(self)
|
211
|
+
if row is None:
|
212
|
+
break
|
213
|
+
result.append(row)
|
214
|
+
return result
|
215
|
+
|
216
|
+
def fetchone(self) -> Any:
|
217
|
+
self._verify_fetch()
|
218
|
+
return self._cyobj.fetch_next_row(self)
|
219
|
+
|
220
|
+
def parse(self, statement: str) -> None:
|
221
|
+
self._verify_open()
|
222
|
+
self._prepare(statement)
|
223
|
+
self._cyobj.parse(self)
|
224
|
+
|
225
|
+
def bindnames(self) -> list:
|
226
|
+
self._verify_open()
|
227
|
+
if self._cyobj.statement is None:
|
228
|
+
errors.raise_error(errors.ERR_NO_STATEMENT_PREPARED)
|
229
|
+
return self._cyobj.get_bind_names()
|
230
|
+
|
231
|
+
def close(self) -> None:
|
232
|
+
self._verify_open()
|
233
|
+
self._cyobj.close()
|
234
|
+
self._cyobj = None
|
235
|
+
|
236
|
+
def setinputsizes(self, *args: Any, **kwargs: Any) -> Union[list, dict]:
|
237
|
+
if args and kwargs:
|
238
|
+
errors.raise_error(errors.ERR_ARGS_AND_KEYWORD_ARGS)
|
239
|
+
elif args or kwargs:
|
240
|
+
self._verify_open()
|
241
|
+
return self._cyobj.setinputsizes(self.connection, args, kwargs)
|
242
|
+
return []
|
243
|
+
|
244
|
+
def setoutputsize(self, size: int, column: int = 0) -> None:
|
245
|
+
pass
|
246
|
+
|
247
|
+
def prepare(
|
248
|
+
self, statement: str, tag: str = None, cache_statement: bool = True
|
249
|
+
) -> None:
|
250
|
+
self._verify_open()
|
251
|
+
self._prepare(statement, tag, cache_statement)
|
252
|
+
|
253
|
+
def var(
|
254
|
+
self,
|
255
|
+
typ: Union[DbType, type],
|
256
|
+
size: int = 0,
|
257
|
+
arraysize: int = 1,
|
258
|
+
inconverter: Callable = None,
|
259
|
+
outconverter: Callable = None,
|
260
|
+
encoding_errors: str = None,
|
261
|
+
bypass_decode: bool = False,
|
262
|
+
convert_nulls: bool = False,
|
263
|
+
*,
|
264
|
+
encodingErrors: str = None,
|
265
|
+
) -> "Var":
|
266
|
+
self._verify_open()
|
267
|
+
if encodingErrors is not None:
|
268
|
+
if encoding_errors is not None:
|
269
|
+
errors.raise_error(
|
270
|
+
errors.ERR_DUPLICATED_PARAMETER,
|
271
|
+
deprecated_name="encodingErrors",
|
272
|
+
new_name="encoding_errors",
|
273
|
+
)
|
274
|
+
encoding_errors = encodingErrors
|
275
|
+
return self._cyobj.create_var(
|
276
|
+
self.connection,
|
277
|
+
typ,
|
278
|
+
size,
|
279
|
+
arraysize,
|
280
|
+
inconverter,
|
281
|
+
outconverter,
|
282
|
+
encoding_errors,
|
283
|
+
bypass_decode,
|
284
|
+
convert_nulls=convert_nulls,
|
285
|
+
)
|
286
|
+
|
287
|
+
def arrayvar(
|
288
|
+
self,
|
289
|
+
typ: Union[DbType, type],
|
290
|
+
value: Union[list, int],
|
291
|
+
size: int = 0,
|
292
|
+
) -> Var:
|
293
|
+
self._verify_open()
|
294
|
+
if isinstance(value, list):
|
295
|
+
num_elements = len(value)
|
296
|
+
elif isinstance(value, int):
|
297
|
+
num_elements = value
|
298
|
+
else:
|
299
|
+
raise TypeError("expecting integer or list of values")
|
300
|
+
var = self._cyobj.create_var(
|
301
|
+
self.connection,
|
302
|
+
typ,
|
303
|
+
size=size,
|
304
|
+
num_elements=num_elements,
|
305
|
+
is_array=True,
|
306
|
+
)
|
307
|
+
if isinstance(value, list):
|
308
|
+
var.setvalue(0, value)
|
309
|
+
return var
|
310
|
+
|
311
|
+
@property
|
312
|
+
def arraysize(self) -> int:
|
313
|
+
self._verify_open()
|
314
|
+
return self._cyobj.arraysize
|
315
|
+
|
316
|
+
@arraysize.setter
|
317
|
+
def arraysize(self, value: int) -> None:
|
318
|
+
self._verify_open()
|
319
|
+
if not isinstance(value, int) or value <= 0:
|
320
|
+
errors.raise_error(errors.ERR_INVALID_ARRAYSIZE)
|
321
|
+
self._cyobj.arraysize = value
|
322
|
+
|
323
|
+
@property
|
324
|
+
def bindvars(self) -> list:
|
325
|
+
self._verify_open()
|
326
|
+
return self._cyobj.get_bind_vars()
|
327
|
+
|
328
|
+
@property
|
329
|
+
def description(self) -> tuple:
|
330
|
+
self._verify_open()
|
331
|
+
if self._cyobj.is_query(self):
|
332
|
+
return [
|
333
|
+
ColumnMetaData._create_with_cyobj(i) for i in self._cyobj.column_metadata_impls
|
334
|
+
]
|
335
|
+
|
336
|
+
@property
|
337
|
+
def fetchvars(self) -> list:
|
338
|
+
self._verify_open()
|
339
|
+
return self._cyobj.get_fetch_vars()
|
340
|
+
|
341
|
+
@property
|
342
|
+
def inputtypehandler(self) -> Callable:
|
343
|
+
self._verify_open()
|
344
|
+
return self._cyobj.inputtypehandler
|
345
|
+
|
346
|
+
@inputtypehandler.setter
|
347
|
+
def inputtypehandler(self, value: Callable) -> None:
|
348
|
+
self._verify_open()
|
349
|
+
self._cyobj.inputtypehandler = value
|
350
|
+
|
351
|
+
@property
|
352
|
+
def lastrowid(self) -> str:
|
353
|
+
self._verify_open()
|
354
|
+
lastrowid = self._cyobj.get_lastrowid()
|
355
|
+
return int(lastrowid) if lastrowid else None
|
356
|
+
|
357
|
+
@property
|
358
|
+
def outputtypehandler(self) -> Callable:
|
359
|
+
self._verify_open()
|
360
|
+
return self._cyobj.outputtypehandler
|
361
|
+
|
362
|
+
@outputtypehandler.setter
|
363
|
+
def outputtypehandler(self, value: Callable) -> None:
|
364
|
+
self._verify_open()
|
365
|
+
self._cyobj.outputtypehandler = value
|
366
|
+
|
367
|
+
@property
|
368
|
+
def prefetchrows(self) -> int:
|
369
|
+
self._verify_open()
|
370
|
+
return self._cyobj.prefetchrows
|
371
|
+
|
372
|
+
@prefetchrows.setter
|
373
|
+
def prefetchrows(self, value: int) -> None:
|
374
|
+
self._verify_open()
|
375
|
+
self._cyobj.prefetchrows = value
|
376
|
+
|
377
|
+
|
378
|
+
@property
|
379
|
+
def rowcount(self) -> int:
|
380
|
+
if self._cyobj is not None and self.connection._cyobj is not None:
|
381
|
+
return self._cyobj.rowcount
|
382
|
+
return -1
|
383
|
+
|
384
|
+
@property
|
385
|
+
def rowfactory(self) -> Callable:
|
386
|
+
self._verify_open()
|
387
|
+
return self._cyobj.rowfactory
|
388
|
+
|
389
|
+
@rowfactory.setter
|
390
|
+
def rowfactory(self, value: Callable) -> None:
|
391
|
+
self._verify_open()
|
392
|
+
self._cyobj.rowfactory = value
|
393
|
+
|
394
|
+
@property
|
395
|
+
def scrollable(self) -> bool:
|
396
|
+
self._verify_open()
|
397
|
+
return False
|
398
|
+
|
399
|
+
@property
|
400
|
+
def statement(self) -> Union[str, None]:
|
401
|
+
if self._cyobj is not None:
|
402
|
+
return self._cyobj.statement
|
403
|
+
|
404
|
+
@property
|
405
|
+
def warning(self) -> Union[errors.ErrorWrapper, None]:
|
406
|
+
self._verify_open()
|
407
|
+
return self._cyobj.warning
|
gbase8sdb/defaults.py
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
from . import driver
|
4
|
+
from . import __name__ as MODULE_NAME
|
5
|
+
|
6
|
+
|
7
|
+
class Defaults:
|
8
|
+
__module__ = MODULE_NAME
|
9
|
+
|
10
|
+
def __init__(self) -> None:
|
11
|
+
self._cyobj = driver.DEFAULTS
|
12
|
+
|
13
|
+
@property
|
14
|
+
def arraysize(self) -> int:
|
15
|
+
return self._cyobj.arraysize
|
16
|
+
|
17
|
+
@arraysize.setter
|
18
|
+
def arraysize(self, value: int):
|
19
|
+
self._cyobj.arraysize = value
|
20
|
+
|
21
|
+
@property
|
22
|
+
def fetch_lobs(self) -> bool:
|
23
|
+
return self._cyobj.fetch_lobs
|
24
|
+
|
25
|
+
@fetch_lobs.setter
|
26
|
+
def fetch_lobs(self, value: str):
|
27
|
+
self._cyobj.fetch_lobs = value
|
28
|
+
|
29
|
+
@property
|
30
|
+
def fetch_decimals(self) -> bool:
|
31
|
+
return self._cyobj.fetch_decimals
|
32
|
+
|
33
|
+
@fetch_decimals.setter
|
34
|
+
def fetch_decimals(self, value: str):
|
35
|
+
self._cyobj.fetch_decimals = value
|
36
|
+
|
37
|
+
@property
|
38
|
+
def prefetchrows(self) -> int:
|
39
|
+
return self._cyobj.prefetchrows
|
40
|
+
|
41
|
+
@prefetchrows.setter
|
42
|
+
def prefetchrows(self, value: int):
|
43
|
+
self._cyobj.prefetchrows = value
|
44
|
+
|
45
|
+
|
46
|
+
defaults = Defaults()
|
Binary file
|
gbase8sdb/dsn.py
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
from . import errors
|
3
|
+
|
4
|
+
def makedsn(
|
5
|
+
server_name: str,
|
6
|
+
db_name: str,
|
7
|
+
host: str = None,
|
8
|
+
port: int = None,
|
9
|
+
protocol: str = 'onsoctcp',
|
10
|
+
db_locale: str = 'zh_CN.57372',
|
11
|
+
**params
|
12
|
+
) -> str:
|
13
|
+
"""
|
14
|
+
Return a string for use as the dsn parameter for connect().
|
15
|
+
"""
|
16
|
+
dsn = f"gbase8s:GBASEDBTSERVER={server_name};DATABASE={db_name};"
|
17
|
+
if 'sqlh_file' in params and params['sqlh_file'] is not None:
|
18
|
+
dsn += f"SQLH_FILE={params.pop('sqlh_file')};"
|
19
|
+
elif all((host, port, protocol)):
|
20
|
+
dsn += f"HOST={host};SERVICE={port};PROTOCOL={protocol};"
|
21
|
+
else:
|
22
|
+
errors.raise_error(errors.ERR_INVALID_MAKEDSN_ARG,
|
23
|
+
context_error_message="The arguments for host, port, and protocol are mandatory if you do not use the argument sqlh_file.",
|
24
|
+
name="host|port|protocol")
|
25
|
+
if db_locale:
|
26
|
+
dsn += f"DB_LOCALE={db_locale};"
|
27
|
+
for k, v in params.items():
|
28
|
+
k_u = k.upper()
|
29
|
+
if k_u not in ('GBASEDBTSERVER', 'DATABASE', 'HOST',
|
30
|
+
'PORT', 'PROTOCOL', 'DB_LOCALE', 'CLIENT_LOCALE', 'SQLMODE',
|
31
|
+
'GCI_FACTORY', 'DELIMIDENT'):
|
32
|
+
if v is not None:
|
33
|
+
dsn += f"{k_u}={v};"
|
34
|
+
else:
|
35
|
+
errors.raise_error(errors.ERR_INVALID_MAKEDSN_ARG,
|
36
|
+
context_error_message=f"not supported parameter {k}",
|
37
|
+
name="params")
|
38
|
+
dsn += "CLIENT_LOCALE=zh_CN.57372;SQLMODE=oracle;GCI_FACTORY=4;DELIMIDENT=1;"
|
39
|
+
return dsn
|