sqlalchemy-iris 0.10.0b2__py3-none-any.whl → 0.10.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.
- intersystems_iris/dbapi/_DBAPI.py +403 -222
- intersystems_iris/dbapi/_Parameter.py +8 -2
- intersystems_iris/dbapi/_ResultSetRow.py +3 -1
- sqlalchemy_iris/alembic.py +83 -18
- sqlalchemy_iris/base.py +25 -10
- {sqlalchemy_iris-0.10.0b2.dist-info → sqlalchemy_iris-0.10.1.dist-info}/METADATA +1 -1
- {sqlalchemy_iris-0.10.0b2.dist-info → sqlalchemy_iris-0.10.1.dist-info}/RECORD +11 -11
- {sqlalchemy_iris-0.10.0b2.dist-info → sqlalchemy_iris-0.10.1.dist-info}/LICENSE +0 -0
- {sqlalchemy_iris-0.10.0b2.dist-info → sqlalchemy_iris-0.10.1.dist-info}/WHEEL +0 -0
- {sqlalchemy_iris-0.10.0b2.dist-info → sqlalchemy_iris-0.10.1.dist-info}/entry_points.txt +0 -0
- {sqlalchemy_iris-0.10.0b2.dist-info → sqlalchemy_iris-0.10.1.dist-info}/top_level.txt +0 -0
@@ -13,32 +13,44 @@ from intersystems_iris.dbapi._Parameter import ParameterMode
|
|
13
13
|
from intersystems_iris.dbapi.preparser._PreParser import StatementType, MultiValuesInsert
|
14
14
|
from intersystems_iris._IRISConnection import Feature
|
15
15
|
from intersystems_iris._InStream import _InStream
|
16
|
-
from intersystems_iris.dbapi._IRISStream import (
|
16
|
+
from intersystems_iris.dbapi._IRISStream import (
|
17
|
+
IRISStream,
|
18
|
+
IRISBinaryStream,
|
19
|
+
)
|
17
20
|
from ._SQLType import SQLType
|
18
21
|
|
19
22
|
from .._IRISNative import connect as native_connect
|
20
23
|
from .._IRISEmbedded import _IRISEmbedded
|
21
24
|
|
25
|
+
|
22
26
|
def NotImplementedErrorDBAPI(msg=None):
|
23
27
|
import traceback
|
28
|
+
|
24
29
|
if msg is None:
|
25
30
|
traceback.print_stack()
|
26
31
|
msg = "Coming soon to an IRIS DB API near you!"
|
27
32
|
return NotImplementedError(msg)
|
28
33
|
|
29
|
-
|
34
|
+
|
35
|
+
def embedded_connect(*args, hostname=None, port=None, namespace=None, username=None, password=None, **kw):
|
30
36
|
connection = _IRISEmbedded()
|
31
|
-
connection.connect(hostname, port,
|
37
|
+
connection.connect(hostname, port, namespace, username, password, **kw)
|
32
38
|
return connection
|
33
39
|
|
34
|
-
|
40
|
+
|
41
|
+
def connect(*args, embedded=False, hostname=None, port=None, namespace=None, username=None, password=None, **kw):
|
35
42
|
try:
|
36
43
|
if not embedded:
|
37
|
-
return native_connect(
|
44
|
+
return native_connect(
|
45
|
+
*args, hostname=hostname, port=port, namespace=namespace, username=username, password=password, **kw
|
46
|
+
)
|
38
47
|
else:
|
39
|
-
return embedded_connect(
|
48
|
+
return embedded_connect(
|
49
|
+
*args, hostname=hostname, port=port, namespace=namespace, username=username, password=password, **kw
|
50
|
+
)
|
40
51
|
except Exception as e:
|
41
|
-
raise
|
52
|
+
raise OperationalError(e)
|
53
|
+
|
42
54
|
|
43
55
|
class ServerReturnType(enum.IntEnum):
|
44
56
|
NO_RETURN_VALUE = 0
|
@@ -46,25 +58,29 @@ class ServerReturnType(enum.IntEnum):
|
|
46
58
|
HAS_RETURN_VALUE = 2
|
47
59
|
NULL_RETURN_VALUE = 3
|
48
60
|
|
61
|
+
|
49
62
|
class CursorType(enum.IntEnum):
|
50
63
|
DEFAULT = 0
|
51
64
|
PREPARED = 1
|
52
65
|
CALLABLE = 2
|
53
66
|
|
67
|
+
|
54
68
|
# api globals, methods, classes, etc.
|
55
69
|
# globals
|
56
70
|
apilevel = "2.0"
|
57
71
|
threadsafety = 0
|
58
72
|
paramstyle = "qmark"
|
59
73
|
|
74
|
+
|
60
75
|
class _BaseCursor:
|
61
76
|
embedded = False
|
77
|
+
|
62
78
|
def __init__(self, connection):
|
63
79
|
self._connection = connection
|
64
|
-
|
80
|
+
|
65
81
|
self.statement = None
|
66
82
|
self._parsed_statement = None
|
67
|
-
|
83
|
+
|
68
84
|
self._columns = None
|
69
85
|
self._rowcount = -1
|
70
86
|
self.arraysize = 1
|
@@ -104,7 +120,9 @@ class _BaseCursor:
|
|
104
120
|
|
105
121
|
def __iter__(self):
|
106
122
|
if self._result_set == None:
|
107
|
-
raise InterfaceError(
|
123
|
+
raise InterfaceError(
|
124
|
+
"Either execute has not yet been called, or the previous call of execute did not return a result set"
|
125
|
+
)
|
108
126
|
return self
|
109
127
|
|
110
128
|
def __next__(self):
|
@@ -112,17 +130,17 @@ class _BaseCursor:
|
|
112
130
|
if row:
|
113
131
|
return row
|
114
132
|
raise StopIteration
|
115
|
-
|
133
|
+
|
116
134
|
# non-api methods and classes
|
117
135
|
def isClosed(self):
|
118
|
-
return self._closed
|
136
|
+
return self._closed
|
119
137
|
|
120
138
|
def setinputsizes(self, sizes):
|
121
139
|
raise NotImplementedErrorDBAPI()
|
122
140
|
|
123
|
-
def setoutputsize(size, column
|
141
|
+
def setoutputsize(size, column=None):
|
124
142
|
raise NotImplementedErrorDBAPI()
|
125
|
-
|
143
|
+
|
126
144
|
@property
|
127
145
|
def sqlcode(self):
|
128
146
|
if self._closed:
|
@@ -154,7 +172,7 @@ class _BaseCursor:
|
|
154
172
|
self._params = None
|
155
173
|
self._parsed_statement = None
|
156
174
|
self._cursor_type = CursorType.DEFAULT
|
157
|
-
self._statementType = StatementType.UPDATE
|
175
|
+
self._statementType = StatementType.UPDATE # default
|
158
176
|
self._paramInfo = None
|
159
177
|
self.statement = None
|
160
178
|
self.statementFeatureOption = Feature.optionNone
|
@@ -221,7 +239,7 @@ class _BaseCursor:
|
|
221
239
|
|
222
240
|
self.statement = operation
|
223
241
|
if params and not isinstance(params, list) and not isinstance(params, tuple):
|
224
|
-
params = (params,
|
242
|
+
params = (params,)
|
225
243
|
self.params = params if params is not None else ()
|
226
244
|
self._params.set_input_params(self.params)
|
227
245
|
|
@@ -232,7 +250,7 @@ class _BaseCursor:
|
|
232
250
|
# convert to executemany
|
233
251
|
params = params or ex.params
|
234
252
|
params_count = int(len(params) / ex.rows)
|
235
|
-
new_params = [params[i:i + params_count] for i in range(0, len(params), params_count)]
|
253
|
+
new_params = [params[i : i + params_count] for i in range(0, len(params), params_count)]
|
236
254
|
return self.executemany(ex.query, new_params)
|
237
255
|
except Exception:
|
238
256
|
raise
|
@@ -248,7 +266,7 @@ class _BaseCursor:
|
|
248
266
|
|
249
267
|
def add_batch(self):
|
250
268
|
self._is_alive()
|
251
|
-
|
269
|
+
|
252
270
|
if self._params._array_bound:
|
253
271
|
if len(self._params._params_list) > 0:
|
254
272
|
cnt = 0
|
@@ -261,8 +279,15 @@ class _BaseCursor:
|
|
261
279
|
self._parameter_sets = cnt
|
262
280
|
first = False
|
263
281
|
elif self._parameter_sets != cnt:
|
264
|
-
raise Exception(
|
265
|
-
|
282
|
+
raise Exception(
|
283
|
+
"Unmatched columnwise parameter values: "
|
284
|
+
+ str(self._parameter_sets)
|
285
|
+
+ " rows expected, but found only "
|
286
|
+
+ str(cnt)
|
287
|
+
+ " in "
|
288
|
+
+ str(i)
|
289
|
+
+ " parameter!"
|
290
|
+
)
|
266
291
|
if self._parameter_sets > 1:
|
267
292
|
return
|
268
293
|
self._parameter_sets = self._parameter_sets + 1
|
@@ -295,12 +320,12 @@ class _BaseCursor:
|
|
295
320
|
|
296
321
|
for row_num, param_row in enumerate(seq_of_params):
|
297
322
|
self.add_batch()
|
298
|
-
|
323
|
+
|
299
324
|
if self._parameter_sets == 0:
|
300
325
|
for param in self._params._params_list:
|
301
|
-
if param.value ==
|
326
|
+
if param.value == "?":
|
302
327
|
raise ValueError("Missing value")
|
303
|
-
self._prepared_update_execute()
|
328
|
+
self._prepared_update_execute() # similar to executing a statement w/ literals
|
304
329
|
return
|
305
330
|
|
306
331
|
for param in self._params._params_list:
|
@@ -318,11 +343,13 @@ class _BaseCursor:
|
|
318
343
|
return
|
319
344
|
if abs(sqlcode) in [108, 119, 121, 122]:
|
320
345
|
raise IntegrityError(message)
|
346
|
+
if abs(sqlcode) in [1, 12]:
|
347
|
+
raise OperationalError(message)
|
321
348
|
raise DatabaseError(message)
|
322
349
|
|
323
350
|
def _preparse(self):
|
324
351
|
csql = self._connection._pre_preparse_cache.get(self.statement)
|
325
|
-
if csql
|
352
|
+
if csql is not None:
|
326
353
|
self._has_return_value = csql._has_return_value
|
327
354
|
self._params = copy.deepcopy(csql._params)
|
328
355
|
self._params.set_input_params(self.params)
|
@@ -337,7 +364,8 @@ class _BaseCursor:
|
|
337
364
|
if not self._is_batch_update:
|
338
365
|
raise TypeError("Unsupported argument type: " + str(type(item)))
|
339
366
|
for ele in item:
|
340
|
-
if intersystems_iris._DBList._DBList._set_switcher.get(type(ele), None)
|
367
|
+
if (not intersystems_iris._DBList._DBList._set_switcher.get(type(ele), None) and not issubclass(
|
368
|
+
type(ele), enum.Enum)):
|
341
369
|
raise TypeError("Unsupported argument type: " + str(type(ele)))
|
342
370
|
elif intersystems_iris._DBList._DBList._set_switcher.get(type(item), None) is None:
|
343
371
|
item = str(item)
|
@@ -349,7 +377,9 @@ class _BaseCursor:
|
|
349
377
|
if count != curr_count:
|
350
378
|
raise Exception("Parameter count does not match")
|
351
379
|
|
352
|
-
parser = intersystems_iris.dbapi.preparser._PreParser._PreParser(
|
380
|
+
parser = intersystems_iris.dbapi.preparser._PreParser._PreParser(
|
381
|
+
self._connection._connection_info._delimited_ids, embedded=self.embedded
|
382
|
+
)
|
353
383
|
try:
|
354
384
|
pOut = parser.PreParse(self.statement, self._params)
|
355
385
|
except MultiValuesInsert:
|
@@ -361,22 +391,23 @@ class _BaseCursor:
|
|
361
391
|
item = self.params[0]
|
362
392
|
if (isinstance(item, list) or isinstance(item, tuple)) and not self._is_batch_update:
|
363
393
|
raise TypeError("Unsupported argument type: " + str(type(item)))
|
364
|
-
|
394
|
+
|
365
395
|
self._parsed_statement = pOut.sResult
|
366
396
|
self._statementType = pOut.p_eStmtType
|
367
397
|
self._paramInfo = parser.m_ParamInfo
|
368
398
|
|
369
|
-
if self._statementType == StatementType.CALL:
|
399
|
+
if self._statementType == StatementType.CALL:
|
370
400
|
self._has_return_value = ServerReturnType.NO_RETURN_VALUE
|
371
|
-
elif self._statementType == StatementType.CALLWITHRESULT:
|
401
|
+
elif self._statementType == StatementType.CALLWITHRESULT:
|
372
402
|
self._has_return_value = ServerReturnType.HAS_RETURN_VALUE
|
373
403
|
|
374
404
|
self._update_parameters()
|
375
405
|
self._connection._add_pre_preparse_cache(self.statement, self)
|
376
406
|
|
377
407
|
def _prepare(self):
|
378
|
-
notDDL = bool(
|
379
|
-
|
408
|
+
notDDL = bool(
|
409
|
+
self._statementType != StatementType.DDL_ALTER_DROP and self._statementType != StatementType.DDL_OTHER
|
410
|
+
)
|
380
411
|
|
381
412
|
if notDDL and self._get_cached_info():
|
382
413
|
return
|
@@ -384,18 +415,18 @@ class _BaseCursor:
|
|
384
415
|
self._prepare_new()
|
385
416
|
|
386
417
|
def _update_parameters(self):
|
387
|
-
count = self._paramInfo._list_data[0]
|
418
|
+
count = self._paramInfo._list_data[0] # self._paramInfo.count()
|
388
419
|
if count == 0:
|
389
420
|
return
|
390
|
-
|
421
|
+
|
391
422
|
temp_list_data = self._paramInfo._list_data[1:]
|
392
|
-
param_info_count = int(len(temp_list_data)/2)
|
423
|
+
param_info_count = int(len(temp_list_data) / 2)
|
393
424
|
if self._is_batch_update:
|
394
425
|
unknown_count = replaced_count = 0
|
395
426
|
for item in temp_list_data:
|
396
|
-
if item ==
|
427
|
+
if item == "c":
|
397
428
|
replaced_count = replaced_count + 1
|
398
|
-
elif item ==
|
429
|
+
elif item == "?":
|
399
430
|
unknown_count = unknown_count + 1
|
400
431
|
|
401
432
|
if len(self.params) > 0:
|
@@ -420,24 +451,30 @@ class _BaseCursor:
|
|
420
451
|
param.mode = ParameterMode.OUTPUT
|
421
452
|
i += 1
|
422
453
|
return
|
423
|
-
|
454
|
+
|
424
455
|
if len(temp_list_data) > 0:
|
425
456
|
if count != param_info_count:
|
426
457
|
raise Exception("Parameter mismatch")
|
427
458
|
|
428
459
|
unknown_count = replaced_count = 0
|
429
460
|
for item in temp_list_data:
|
430
|
-
if item ==
|
461
|
+
if item == "c":
|
431
462
|
replaced_count = replaced_count + 1
|
432
|
-
elif item ==
|
463
|
+
elif item == "?":
|
433
464
|
unknown_count = unknown_count + 1
|
434
465
|
|
435
466
|
if unknown_count != len(self.params):
|
436
|
-
raise Exception(
|
467
|
+
raise Exception(
|
468
|
+
f"Incorrect number of parameters: {unknown_count}/{replaced_count}/{len(self.params)}"
|
469
|
+
)
|
437
470
|
|
438
471
|
def _is_not_default_or_replaced(self, param):
|
439
472
|
mode = param.mode
|
440
|
-
if
|
473
|
+
if (
|
474
|
+
mode != ParameterMode.REPLACED_LITERAL
|
475
|
+
and mode != ParameterMode.DEFAULT_PARAMETER
|
476
|
+
and mode != ParameterMode.INPUT
|
477
|
+
):
|
441
478
|
raise Exception("Parameters not allowed in Cursor class")
|
442
479
|
|
443
480
|
def _validate_parameters(self):
|
@@ -450,7 +487,10 @@ class _BaseCursor:
|
|
450
487
|
if self._parameter_list_mismatch_exception and not self._params._has_bound_by_param_name:
|
451
488
|
raise Exception("Parameter list mismatch")
|
452
489
|
i = 0
|
453
|
-
if
|
490
|
+
if (
|
491
|
+
self._has_return_value == ServerReturnType.IGNORE_RETURN_VALUE
|
492
|
+
or self._has_return_value == ServerReturnType.NULL_RETURN_VALUE
|
493
|
+
):
|
454
494
|
i = 1
|
455
495
|
for param in self._params._params_list:
|
456
496
|
if i == 1:
|
@@ -474,14 +514,14 @@ class _BaseCursor:
|
|
474
514
|
StatementType.STMT_USE: self._execute_update,
|
475
515
|
StatementType.UPDATE: self._execute_update,
|
476
516
|
StatementType.DDL_OTHER: self._execute_update,
|
477
|
-
StatementType.DDL_ALTER_DROP: self._execute_update
|
517
|
+
StatementType.DDL_ALTER_DROP: self._execute_update,
|
478
518
|
}
|
479
519
|
exec_func = exec_switcher.get(self._statementType, None)
|
480
520
|
if exec_func is None:
|
481
|
-
raise NotImplementedErrorDBAPI(f
|
521
|
+
raise NotImplementedErrorDBAPI(f"StatementType {self._statementType.name} not implemented")
|
482
522
|
else:
|
483
523
|
return exec_func()
|
484
|
-
|
524
|
+
|
485
525
|
def _prepare_stored_procedure(self):
|
486
526
|
if self._get_cached_info():
|
487
527
|
self._prepared_stored_procedure_execute()
|
@@ -528,20 +568,22 @@ class _BaseCursor:
|
|
528
568
|
# not found in client side cache - send DQ message
|
529
569
|
self._send_direct_query_request()
|
530
570
|
else:
|
531
|
-
if (
|
532
|
-
self._statementType != StatementType.
|
533
|
-
self._statementType != StatementType.
|
571
|
+
if (
|
572
|
+
self._statementType != StatementType.QUERY
|
573
|
+
and self._statementType != StatementType.PREPARED_CALL_QUERY
|
574
|
+
and self._statementType != StatementType.DIRECT_CALL_QUERY
|
575
|
+
):
|
534
576
|
raise Exception("Not a query")
|
535
|
-
|
577
|
+
|
536
578
|
if self._exec_params != None:
|
537
579
|
self._bind_exec_params()
|
538
580
|
self._validate_prepared_parameters()
|
539
|
-
|
581
|
+
|
540
582
|
if self.statementFeatureOption & Feature.optionFastSelect == Feature.optionFastSelect:
|
541
583
|
self._rsrow = _ResultSetRow(self._connection, self._columns, self.maxRowItemCount)
|
542
584
|
else:
|
543
585
|
self._rsrow = _ResultSetRow(self._connection, self._columns, 0)
|
544
|
-
|
586
|
+
|
545
587
|
if self._cursor_type == CursorType.CALLABLE or self._statementType == StatementType.PREPARED_CALL_QUERY:
|
546
588
|
self._stored_procedure_query()
|
547
589
|
return
|
@@ -569,8 +611,9 @@ class _BaseCursor:
|
|
569
611
|
raise Exception("Not an update")
|
570
612
|
return
|
571
613
|
|
572
|
-
notDDL = bool(
|
573
|
-
|
614
|
+
notDDL = bool(
|
615
|
+
self._statementType != StatementType.DDL_ALTER_DROP and self._statementType != StatementType.DDL_OTHER
|
616
|
+
)
|
574
617
|
|
575
618
|
if notDDL and self._get_cached_info():
|
576
619
|
# found in client side cache - send PU message
|
@@ -581,19 +624,21 @@ class _BaseCursor:
|
|
581
624
|
else:
|
582
625
|
if self._statementType == StatementType.QUERY or self._statementType == StatementType.PREPARED_CALL_QUERY:
|
583
626
|
raise Exception("Not an update")
|
584
|
-
|
627
|
+
|
585
628
|
if self._exec_params != None:
|
586
629
|
self._bind_exec_params()
|
587
630
|
self._validate_prepared_parameters()
|
588
|
-
|
589
|
-
if (
|
590
|
-
self.
|
591
|
-
self._statementType == StatementType.
|
631
|
+
|
632
|
+
if (
|
633
|
+
self._cursor_type == CursorType.CALLABLE
|
634
|
+
or self._statementType == StatementType.PREPARED_CALL_UPDATE
|
635
|
+
or self._statementType == StatementType.DIRECT_CALL_UPDATE
|
636
|
+
):
|
592
637
|
self._stored_procedure_update()
|
593
638
|
return
|
594
639
|
|
595
640
|
self._prepared_update_execute()
|
596
|
-
|
641
|
+
|
597
642
|
def _query404(self):
|
598
643
|
with self._connection._lock:
|
599
644
|
self._validate_parameters()
|
@@ -610,33 +655,40 @@ class _BaseCursor:
|
|
610
655
|
if self._columns == None:
|
611
656
|
return None
|
612
657
|
|
613
|
-
Column = namedtuple(
|
614
|
-
|
615
|
-
|
616
|
-
|
617
|
-
|
618
|
-
|
619
|
-
|
620
|
-
|
621
|
-
|
658
|
+
Column = namedtuple(
|
659
|
+
"Column",
|
660
|
+
[
|
661
|
+
"name",
|
662
|
+
"type_code",
|
663
|
+
"display_size",
|
664
|
+
"internal_size",
|
665
|
+
"precision",
|
666
|
+
"scale",
|
667
|
+
"null_ok",
|
668
|
+
],
|
669
|
+
)
|
622
670
|
|
623
671
|
sequence = []
|
624
|
-
for column in self._columns:
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
|
629
|
-
|
630
|
-
|
631
|
-
|
632
|
-
|
672
|
+
for column in self._columns:
|
673
|
+
sequence.append(
|
674
|
+
Column(
|
675
|
+
column.name,
|
676
|
+
column.type,
|
677
|
+
None,
|
678
|
+
None,
|
679
|
+
column.precision,
|
680
|
+
column.scale,
|
681
|
+
column.nullable,
|
682
|
+
)
|
683
|
+
)
|
633
684
|
return tuple(sequence)
|
634
|
-
|
685
|
+
|
635
686
|
# currently doesn't work for queries
|
636
687
|
@property
|
637
688
|
def rowcount(self):
|
638
689
|
return self._rowcount
|
639
690
|
|
691
|
+
|
640
692
|
# Cursor class
|
641
693
|
class Cursor(_BaseCursor):
|
642
694
|
def __init__(self, connection):
|
@@ -657,7 +709,7 @@ class Cursor(_BaseCursor):
|
|
657
709
|
self._cursor_ptr = 0
|
658
710
|
self._scroll_flag = False
|
659
711
|
self._warehouse = list()
|
660
|
-
|
712
|
+
|
661
713
|
self._warehouse_dict = dict()
|
662
714
|
self._last_row_in_warehouse_dict = -1
|
663
715
|
self._warehouse_dict_keys = list()
|
@@ -688,7 +740,7 @@ class Cursor(_BaseCursor):
|
|
688
740
|
super()._process_sqlcode(sqlcode, self._get_error_info(sqlcode))
|
689
741
|
|
690
742
|
def _get_cached_info(self):
|
691
|
-
if not self._connection._preparedCache or not hasattr(self._connection._preparedCache,
|
743
|
+
if not self._connection._preparedCache or not hasattr(self._connection._preparedCache, "__iter__"):
|
692
744
|
return False
|
693
745
|
if self._parsed_statement in self._connection._preparedCache:
|
694
746
|
self._prepare_cached(self._connection._preparedCache[self._parsed_statement])
|
@@ -701,17 +753,21 @@ class Cursor(_BaseCursor):
|
|
701
753
|
|
702
754
|
if self._statementType == StatementType.CALL or self._statementType == StatementType.CALLWITHRESULT:
|
703
755
|
if len(self._params._params_list) != len(cached_statement._params._params_list):
|
704
|
-
if (
|
705
|
-
self.
|
706
|
-
|
707
|
-
|
708
|
-
self._params._params_list
|
756
|
+
if (
|
757
|
+
self._statementType == StatementType.CALL
|
758
|
+
and self._has_return_value == 0
|
759
|
+
and cached_statement._has_return_value == 1
|
760
|
+
and len(self._params._params_list) + 1 == len(cached_statement._params._params_list)
|
761
|
+
):
|
762
|
+
self._params._params_list.insert(
|
763
|
+
0, intersystems_iris.dbapi._Parameter._Parameter(None, ParameterMode.OUTPUT, "c")
|
764
|
+
)
|
709
765
|
else:
|
710
766
|
if len(self._params._params_list) == 0 or len(self._params._params_list) == 1:
|
711
767
|
self._params._clear()
|
712
768
|
else:
|
713
769
|
return False
|
714
|
-
|
770
|
+
|
715
771
|
if cached_statement._statementType == StatementType.QUERY:
|
716
772
|
self._statementType = StatementType.PREPARED_CALL_QUERY
|
717
773
|
else:
|
@@ -724,8 +780,10 @@ class Cursor(_BaseCursor):
|
|
724
780
|
self._multiple_result_sets = cached_statement.multiple_result_sets
|
725
781
|
self._mrs_done = False
|
726
782
|
|
727
|
-
if
|
728
|
-
|
783
|
+
if not self._multiple_result_sets and (
|
784
|
+
self._statementType
|
785
|
+
in [StatementType.QUERY, StatementType.PREPARED_CALL_QUERY, StatementType.DIRECT_CALL_QUERY]
|
786
|
+
):
|
729
787
|
self._columns = []
|
730
788
|
for column in cached_statement.columns:
|
731
789
|
self._columns.append(column.Clone())
|
@@ -752,19 +810,21 @@ class Cursor(_BaseCursor):
|
|
752
810
|
self.maxRowItemCount = cached_statement.maxRowItemCount
|
753
811
|
if hasattr(cached_statement, "_params"):
|
754
812
|
self._params._update_param_info(cached_statement._params)
|
755
|
-
|
813
|
+
|
756
814
|
def _prepare_new(self):
|
757
815
|
# send PP message
|
758
816
|
with self._connection._lock:
|
759
817
|
# message header
|
760
818
|
self._statement_id = self._connection._get_new_statement_id()
|
761
819
|
self._out_message.wire._write_header(_Message.PREPARE)
|
762
|
-
intersystems_iris._MessageHeader._MessageHeader._set_statement_id(
|
820
|
+
intersystems_iris._MessageHeader._MessageHeader._set_statement_id(
|
821
|
+
self._out_message.wire.buffer, self._statement_id
|
822
|
+
)
|
763
823
|
|
764
824
|
# message body
|
765
|
-
self._out_message.wire._set(1)
|
766
|
-
self._out_message.wire._set(self._parsed_statement)
|
767
|
-
self._out_message.wire._set_raw_bytes(self._paramInfo.getBuffer())
|
825
|
+
self._out_message.wire._set(1) # number of statement chunks
|
826
|
+
self._out_message.wire._set(self._parsed_statement) # statement itself
|
827
|
+
self._out_message.wire._set_raw_bytes(self._paramInfo.getBuffer()) # paramInfo (from _PreParser)
|
768
828
|
|
769
829
|
# send message
|
770
830
|
sequence_number = self._connection._get_new_sequence_number()
|
@@ -800,7 +860,7 @@ class Cursor(_BaseCursor):
|
|
800
860
|
with self._connection._lock:
|
801
861
|
self._out_message.wire._write_header(_Message.GET_SERVER_ERROR)
|
802
862
|
self._out_message.wire._set(sqlcode)
|
803
|
-
|
863
|
+
|
804
864
|
sequence_number = self._connection._get_new_sequence_number()
|
805
865
|
self._out_message._send(sequence_number)
|
806
866
|
|
@@ -809,7 +869,10 @@ class Cursor(_BaseCursor):
|
|
809
869
|
|
810
870
|
def _check_statement_feature(self, wire):
|
811
871
|
self.statementFeatureOption = wire._get()
|
812
|
-
if
|
872
|
+
if (
|
873
|
+
self.statementFeatureOption == Feature.optionFastSelect
|
874
|
+
or self.statementFeatureOption == Feature.optionFastInsert
|
875
|
+
):
|
813
876
|
self.maxRowItemCount = wire._get()
|
814
877
|
else:
|
815
878
|
self.maxRowItemCount = 0
|
@@ -830,15 +893,33 @@ class Cursor(_BaseCursor):
|
|
830
893
|
if catalog == 0:
|
831
894
|
catalog = None
|
832
895
|
additionalData = wire._get().encode()
|
833
|
-
slotPosition =
|
834
|
-
|
896
|
+
slotPosition = (
|
897
|
+
wire._get()
|
898
|
+
if self.statementFeatureOption & Feature.optionFastSelect == Feature.optionFastSelect
|
899
|
+
else i + 1
|
900
|
+
)
|
901
|
+
self._columns.append(
|
902
|
+
intersystems_iris.dbapi._Column._Column(
|
903
|
+
name,
|
904
|
+
type,
|
905
|
+
precision,
|
906
|
+
scale,
|
907
|
+
nullable,
|
908
|
+
label,
|
909
|
+
tableName,
|
910
|
+
schema,
|
911
|
+
catalog,
|
912
|
+
additionalData,
|
913
|
+
slotPosition,
|
914
|
+
)
|
915
|
+
)
|
835
916
|
|
836
917
|
def _get_parameter_info(self, wire):
|
837
918
|
count = wire._get()
|
838
919
|
if count != len(self._params._params_list):
|
839
920
|
raise Exception("Invalid number of parameters")
|
840
921
|
self._read_parameter_data(wire, count, False)
|
841
|
-
|
922
|
+
|
842
923
|
addToCache = bool(wire._get())
|
843
924
|
return addToCache
|
844
925
|
|
@@ -862,7 +943,7 @@ class Cursor(_BaseCursor):
|
|
862
943
|
|
863
944
|
if self.statementFeatureOption & Feature.optionFastInsert == Feature.optionFastInsert:
|
864
945
|
param.slotPosition = wire._get()
|
865
|
-
self.rowOfDefaultValues = wire._get()
|
946
|
+
self.rowOfDefaultValues = wire._get() # needs to be processed
|
866
947
|
else:
|
867
948
|
param.slotPosition = i + r
|
868
949
|
|
@@ -879,7 +960,6 @@ class Cursor(_BaseCursor):
|
|
879
960
|
if self._parameter_sets == 0 and not self._multiple_result_sets:
|
880
961
|
self._rowcount = self._in_message.wire._get()
|
881
962
|
|
882
|
-
|
883
963
|
class prepared_statement(intersystems_iris._IRISConnection.CachedSQL):
|
884
964
|
def __init__(self, cursor):
|
885
965
|
if not isinstance(cursor, Cursor):
|
@@ -907,8 +987,8 @@ class Cursor(_BaseCursor):
|
|
907
987
|
def _write_parameters(self):
|
908
988
|
sets = self._parameter_sets or 1
|
909
989
|
|
910
|
-
self._out_message.wire._set(sets)
|
911
|
-
self._out_message.wire._set(len(self._params._params_list))
|
990
|
+
self._out_message.wire._set(sets) # nParamSets
|
991
|
+
self._out_message.wire._set(len(self._params._params_list)) # nParams
|
912
992
|
for i in range(sets):
|
913
993
|
param_index = 0
|
914
994
|
param_counter = i
|
@@ -937,12 +1017,14 @@ class Cursor(_BaseCursor):
|
|
937
1017
|
with self._connection._lock:
|
938
1018
|
# message header
|
939
1019
|
self._out_message.wire._write_header(_Message.PREPARED_QUERY_EXECUTE)
|
940
|
-
intersystems_iris._MessageHeader._MessageHeader._set_statement_id(
|
1020
|
+
intersystems_iris._MessageHeader._MessageHeader._set_statement_id(
|
1021
|
+
self._out_message.wire.buffer, self._statement_id
|
1022
|
+
)
|
941
1023
|
|
942
1024
|
# message body
|
943
1025
|
self._write_parameters()
|
944
|
-
self._out_message.wire._set(0)
|
945
|
-
self._out_message.wire._set(0)
|
1026
|
+
self._out_message.wire._set(0) # query timeout
|
1027
|
+
self._out_message.wire._set(0) # maxRows (0 = all rows)
|
946
1028
|
|
947
1029
|
# send
|
948
1030
|
sequence_number = self._connection._get_new_sequence_number()
|
@@ -959,7 +1041,7 @@ class Cursor(_BaseCursor):
|
|
959
1041
|
self._current_wire = self._in_message.wire
|
960
1042
|
self._result_set = [self._current_wire]
|
961
1043
|
self._rs_index = 0
|
962
|
-
|
1044
|
+
|
963
1045
|
self._rowcount = -1
|
964
1046
|
|
965
1047
|
def _send_direct_stored_procedure_request(self):
|
@@ -969,13 +1051,15 @@ class Cursor(_BaseCursor):
|
|
969
1051
|
# message header
|
970
1052
|
self._statement_id = self._connection._get_new_statement_id()
|
971
1053
|
self._out_message.wire._write_header(_Message.DIRECT_STORED_PROCEDURE)
|
972
|
-
intersystems_iris._MessageHeader._MessageHeader._set_statement_id(
|
1054
|
+
intersystems_iris._MessageHeader._MessageHeader._set_statement_id(
|
1055
|
+
self._out_message.wire.buffer, self._statement_id
|
1056
|
+
)
|
973
1057
|
|
974
1058
|
# message body
|
975
|
-
self._out_message.wire._set(self._parsed_statement)
|
976
|
-
self._out_message.wire._set(0)
|
977
|
-
self._out_message.wire._set(0)
|
978
|
-
self._out_message.wire._set(0)
|
1059
|
+
self._out_message.wire._set(self._parsed_statement) # statement itself
|
1060
|
+
self._out_message.wire._set(0) # resultSetType != ResultSet.TYPE_SCROLL_INSENSITIVE
|
1061
|
+
self._out_message.wire._set(0) # query timeout
|
1062
|
+
self._out_message.wire._set(0) # maxRows (0 = all rows)
|
979
1063
|
self._write_stored_procedure_parameters()
|
980
1064
|
|
981
1065
|
# send
|
@@ -996,21 +1080,26 @@ class Cursor(_BaseCursor):
|
|
996
1080
|
|
997
1081
|
self._cache_prepared_statement()
|
998
1082
|
|
999
|
-
if self._statementType in [
|
1083
|
+
if self._statementType in [
|
1084
|
+
StatementType.UPDATE,
|
1085
|
+
StatementType.DIRECT_CALL_UPDATE,
|
1086
|
+
StatementType.PREPARED_CALL_UPDATE,
|
1087
|
+
]:
|
1000
1088
|
return False
|
1001
1089
|
|
1002
1090
|
except IndexError:
|
1003
1091
|
raise DatabaseError("Server response message terminated prematurely")
|
1004
1092
|
except TypeError:
|
1005
1093
|
raise DatabaseError("Unexpected server response message format")
|
1006
|
-
|
1094
|
+
|
1007
1095
|
def _prepared_stored_procedure_execute(self):
|
1008
1096
|
# send SU message
|
1009
1097
|
with self._connection._lock:
|
1010
1098
|
# message header
|
1011
1099
|
self._out_message.wire._write_header(_Message.PREPARED_UPDATE_EXECUTE)
|
1012
|
-
intersystems_iris._MessageHeader._MessageHeader._set_statement_id(
|
1013
|
-
|
1100
|
+
intersystems_iris._MessageHeader._MessageHeader._set_statement_id(
|
1101
|
+
self._out_message.wire.buffer, self._statement_id
|
1102
|
+
)
|
1014
1103
|
|
1015
1104
|
def _send_direct_query_request(self):
|
1016
1105
|
# send DQ message
|
@@ -1018,15 +1107,17 @@ class Cursor(_BaseCursor):
|
|
1018
1107
|
# message header
|
1019
1108
|
self._statement_id = self._connection._get_new_statement_id()
|
1020
1109
|
self._out_message.wire._write_header(_Message.DIRECT_QUERY)
|
1021
|
-
intersystems_iris._MessageHeader._MessageHeader._set_statement_id(
|
1110
|
+
intersystems_iris._MessageHeader._MessageHeader._set_statement_id(
|
1111
|
+
self._out_message.wire.buffer, self._statement_id
|
1112
|
+
)
|
1022
1113
|
|
1023
1114
|
# message body
|
1024
|
-
self._out_message.wire._set(1)
|
1025
|
-
self._out_message.wire._set(self._parsed_statement)
|
1026
|
-
self._out_message.wire._set_raw_bytes(self._paramInfo.getBuffer())
|
1115
|
+
self._out_message.wire._set(1) # number of statement chunks
|
1116
|
+
self._out_message.wire._set(self._parsed_statement) # statement itself
|
1117
|
+
self._out_message.wire._set_raw_bytes(self._paramInfo.getBuffer()) # paramInfo (from _PreParser)
|
1027
1118
|
self._write_parameters()
|
1028
|
-
self._out_message.wire._set(0)
|
1029
|
-
self._out_message.wire._set(0)
|
1119
|
+
self._out_message.wire._set(0) # query timeout
|
1120
|
+
self._out_message.wire._set(0) # maxRows (0 = all rows)
|
1030
1121
|
|
1031
1122
|
# send
|
1032
1123
|
sequence_number = self._connection._get_new_sequence_number()
|
@@ -1060,24 +1151,26 @@ class Cursor(_BaseCursor):
|
|
1060
1151
|
self._current_wire = self._in_message.wire
|
1061
1152
|
self._result_set = [self._current_wire]
|
1062
1153
|
self._rs_index = 0
|
1063
|
-
|
1154
|
+
|
1064
1155
|
self._rowcount = -1
|
1065
1156
|
if self.statementFeatureOption & Feature.optionFastSelect == Feature.optionFastSelect:
|
1066
1157
|
self._rsrow = _ResultSetRow(self._connection, self._columns, self.maxRowItemCount)
|
1067
1158
|
else:
|
1068
1159
|
self._rsrow = _ResultSetRow(self._connection, self._columns, 0)
|
1069
|
-
|
1160
|
+
|
1070
1161
|
def _prepared_update_execute(self):
|
1071
1162
|
# send PU message
|
1072
1163
|
with self._connection._lock:
|
1073
1164
|
# message header
|
1074
1165
|
self._out_message.wire._write_header(_Message.PREPARED_UPDATE_EXECUTE)
|
1075
|
-
intersystems_iris._MessageHeader._MessageHeader._set_statement_id(
|
1166
|
+
intersystems_iris._MessageHeader._MessageHeader._set_statement_id(
|
1167
|
+
self._out_message.wire.buffer, self._statement_id
|
1168
|
+
)
|
1076
1169
|
|
1077
1170
|
# message body
|
1078
1171
|
self._lastrowid = None
|
1079
|
-
self._out_message.wire._set(-1)
|
1080
|
-
self._out_message.wire._set(0)
|
1172
|
+
self._out_message.wire._set(-1) # autoGeneratedKeyColumn
|
1173
|
+
self._out_message.wire._set(0) # statement timeout always 0 for non-queries
|
1081
1174
|
self._write_parameters()
|
1082
1175
|
|
1083
1176
|
# send
|
@@ -1098,15 +1191,17 @@ class Cursor(_BaseCursor):
|
|
1098
1191
|
self._statement_id = self._connection._get_new_statement_id()
|
1099
1192
|
# message header
|
1100
1193
|
self._out_message.wire._write_header(_Message.DIRECT_UPDATE)
|
1101
|
-
intersystems_iris._MessageHeader._MessageHeader._set_statement_id(
|
1194
|
+
intersystems_iris._MessageHeader._MessageHeader._set_statement_id(
|
1195
|
+
self._out_message.wire.buffer, self._statement_id
|
1196
|
+
)
|
1102
1197
|
|
1103
1198
|
# message body
|
1104
1199
|
self._lastrowid = None
|
1105
|
-
self._out_message.wire._set(1)
|
1106
|
-
self._out_message.wire._set(self._parsed_statement)
|
1107
|
-
self._out_message.wire._set_raw_bytes(self._paramInfo.getBuffer())
|
1108
|
-
self._out_message.wire._set(-1)
|
1109
|
-
self._out_message.wire._set(0)
|
1200
|
+
self._out_message.wire._set(1) # number of statement chunks
|
1201
|
+
self._out_message.wire._set(self._parsed_statement) # statement itself
|
1202
|
+
self._out_message.wire._set_raw_bytes(self._paramInfo.getBuffer()) # paramInfo (from _PreParser)
|
1203
|
+
self._out_message.wire._set(-1) # autoGeneratedKeyColumn
|
1204
|
+
self._out_message.wire._set(0) # statement timeout always 0 for non-queries
|
1110
1205
|
self._write_parameters()
|
1111
1206
|
|
1112
1207
|
# send
|
@@ -1120,9 +1215,11 @@ class Cursor(_BaseCursor):
|
|
1120
1215
|
self._process_sqlcode(self._sqlcode)
|
1121
1216
|
|
1122
1217
|
addToCache = self._get_parameter_info(self._in_message.wire)
|
1123
|
-
|
1124
|
-
notDDL = bool(
|
1125
|
-
|
1218
|
+
|
1219
|
+
notDDL = bool(
|
1220
|
+
self._statementType != StatementType.DDL_ALTER_DROP
|
1221
|
+
and self._statementType != StatementType.DDL_OTHER
|
1222
|
+
)
|
1126
1223
|
if notDDL and addToCache:
|
1127
1224
|
self._cache_prepared_statement()
|
1128
1225
|
|
@@ -1136,12 +1233,14 @@ class Cursor(_BaseCursor):
|
|
1136
1233
|
# message header
|
1137
1234
|
self._statement_id = self._connection._get_new_statement_id()
|
1138
1235
|
self._out_message.wire._write_header(_Message.PREPARE_STORED_PROCEDURE)
|
1139
|
-
intersystems_iris._MessageHeader._MessageHeader._set_statement_id(
|
1236
|
+
intersystems_iris._MessageHeader._MessageHeader._set_statement_id(
|
1237
|
+
self._out_message.wire.buffer, self._statement_id
|
1238
|
+
)
|
1140
1239
|
|
1141
1240
|
# message body
|
1142
|
-
#self._out_message.wire._set(1) # number of statement chunks
|
1143
|
-
self._out_message.wire._set(self._parsed_statement)
|
1144
|
-
|
1241
|
+
# self._out_message.wire._set(1) # number of statement chunks
|
1242
|
+
self._out_message.wire._set(self._parsed_statement) # statement itself
|
1243
|
+
|
1145
1244
|
# send message
|
1146
1245
|
sequence_number = self._connection._get_new_sequence_number()
|
1147
1246
|
self._out_message._send(sequence_number)
|
@@ -1220,11 +1319,20 @@ class Cursor(_BaseCursor):
|
|
1220
1319
|
self._has_return_value = ServerReturnType.HAS_RETURN_VALUE
|
1221
1320
|
elif not server_has_return and self._has_return_value == ServerReturnType.NO_RETURN_VALUE:
|
1222
1321
|
self._has_return_value = ServerReturnType.NO_RETURN_VALUE
|
1223
|
-
elif (
|
1224
|
-
|
1225
|
-
|
1226
|
-
|
1227
|
-
|
1322
|
+
elif (
|
1323
|
+
size == 1
|
1324
|
+
and count == 1
|
1325
|
+
and (
|
1326
|
+
self._params._params_list[0].mode == ParameterMode.DEFAULT_PARAMETER
|
1327
|
+
and self._has_return_value == ServerReturnType.NO_RETURN_VALUE
|
1328
|
+
and server_has_return
|
1329
|
+
)
|
1330
|
+
or (
|
1331
|
+
self._params._params_list[0].mode == ParameterMode.UNKNOWN
|
1332
|
+
and self._has_return_value == ServerReturnType.IGNORE_RETURN_VALUE
|
1333
|
+
and server_has_return
|
1334
|
+
)
|
1335
|
+
):
|
1228
1336
|
self._params._params_list.pop(0)
|
1229
1337
|
self._params._params_list.insert(0, intersystems_iris.dbapi._Parameter._Parameter())
|
1230
1338
|
self._has_return_value = ServerReturnType.IGNORE_RETURN_VALUE
|
@@ -1256,7 +1364,9 @@ class Cursor(_BaseCursor):
|
|
1256
1364
|
self._params._params_list.insert(0, intersystems_iris.dbapi._Parameter._Parameter())
|
1257
1365
|
self._has_return_value = ServerReturnType.IGNORE_RETURN_VALUE
|
1258
1366
|
else:
|
1259
|
-
self._params._params_list.append(
|
1367
|
+
self._params._params_list.append(
|
1368
|
+
intersystems_iris.dbapi._Parameter._Parameter(ParameterMode.DEFAULT_PARAMETER, "c")
|
1369
|
+
)
|
1260
1370
|
else:
|
1261
1371
|
self._parameter_list_mismatch_exception = True
|
1262
1372
|
if server_has_return and self._has_return_value == ServerReturnType.NO_RETURN_VALUE:
|
@@ -1266,7 +1376,9 @@ class Cursor(_BaseCursor):
|
|
1266
1376
|
self._params._params_list.insert(0, param)
|
1267
1377
|
size = size + 1
|
1268
1378
|
while size < count:
|
1269
|
-
self._params._params_list.append(
|
1379
|
+
self._params._params_list.append(
|
1380
|
+
intersystems_iris.dbapi._Parameter._Parameter(ParameterMode.DEFAULT_PARAMETER, "c")
|
1381
|
+
)
|
1270
1382
|
size = size + 1
|
1271
1383
|
self._read_parameter_data(wire, count, True)
|
1272
1384
|
return True
|
@@ -1298,12 +1410,14 @@ class Cursor(_BaseCursor):
|
|
1298
1410
|
with self._connection._lock:
|
1299
1411
|
# message header
|
1300
1412
|
self._out_message.wire._write_header(_Message.STORED_PROCEDURE_UPDATE_EXECUTE)
|
1301
|
-
intersystems_iris._MessageHeader._MessageHeader._set_statement_id(
|
1413
|
+
intersystems_iris._MessageHeader._MessageHeader._set_statement_id(
|
1414
|
+
self._out_message.wire.buffer, self._statement_id
|
1415
|
+
)
|
1302
1416
|
|
1303
1417
|
# message body
|
1304
|
-
self._out_message.wire._set(0)
|
1305
|
-
self._out_message.wire._set(0)
|
1306
|
-
self._out_message.wire._set(0)
|
1418
|
+
self._out_message.wire._set(0) # isStatic should always be 0 for non-queries
|
1419
|
+
self._out_message.wire._set(0) # query timeout
|
1420
|
+
self._out_message.wire._set(0) # maxRows (0 = all rows)
|
1307
1421
|
self._write_stored_procedure_parameters()
|
1308
1422
|
|
1309
1423
|
# send
|
@@ -1327,12 +1441,14 @@ class Cursor(_BaseCursor):
|
|
1327
1441
|
with self._connection._lock:
|
1328
1442
|
# message header
|
1329
1443
|
self._out_message.wire._write_header(_Message.STORED_PROCEDURE_QUERY_EXECUTE)
|
1330
|
-
intersystems_iris._MessageHeader._MessageHeader._set_statement_id(
|
1444
|
+
intersystems_iris._MessageHeader._MessageHeader._set_statement_id(
|
1445
|
+
self._out_message.wire.buffer, self._statement_id
|
1446
|
+
)
|
1331
1447
|
|
1332
1448
|
# message body
|
1333
|
-
self._out_message.wire._set(0)
|
1334
|
-
self._out_message.wire._set(0)
|
1335
|
-
self._out_message.wire._set(0)
|
1449
|
+
self._out_message.wire._set(0) # ResultSet.TYPE_SCROLL_INSENSITIVE
|
1450
|
+
self._out_message.wire._set(0) # query timeout
|
1451
|
+
self._out_message.wire._set(0) # maxRows (0 = all rows)
|
1336
1452
|
self._write_stored_procedure_parameters()
|
1337
1453
|
|
1338
1454
|
# send
|
@@ -1365,8 +1481,8 @@ class Cursor(_BaseCursor):
|
|
1365
1481
|
self._validate_parameters()
|
1366
1482
|
with self._connection._lock:
|
1367
1483
|
self._out_message.wire._write_header(_Message.EXECUTE_MULTIPLE_RESULT_SETS)
|
1368
|
-
self._out_message.wire._set(0)
|
1369
|
-
self._out_message.wire._set(0)
|
1484
|
+
self._out_message.wire._set(0) # resultSetType != ResultSet.TYPE_SCROLL_INSENSITIVE
|
1485
|
+
self._out_message.wire._set(0) # query timeout
|
1370
1486
|
self._write_stored_procedure_parameters()
|
1371
1487
|
|
1372
1488
|
# send
|
@@ -1389,7 +1505,7 @@ class Cursor(_BaseCursor):
|
|
1389
1505
|
self._rs_index = 0
|
1390
1506
|
|
1391
1507
|
results = self._in_message.wire._get()
|
1392
|
-
if results >= 0
|
1508
|
+
if results >= 0:
|
1393
1509
|
self._update_cnt = results
|
1394
1510
|
return False
|
1395
1511
|
elif results == -1:
|
@@ -1397,7 +1513,7 @@ class Cursor(_BaseCursor):
|
|
1397
1513
|
elif results == -2:
|
1398
1514
|
self._update_cnt = -1
|
1399
1515
|
self._mrs_done = True
|
1400
|
-
#self._rsrow._is_after_last = True
|
1516
|
+
# self._rsrow._is_after_last = True
|
1401
1517
|
return False
|
1402
1518
|
else:
|
1403
1519
|
raise Exception("Invalid result type value")
|
@@ -1446,7 +1562,11 @@ class Cursor(_BaseCursor):
|
|
1446
1562
|
if i == 1:
|
1447
1563
|
i = 0
|
1448
1564
|
continue
|
1449
|
-
if
|
1565
|
+
if (
|
1566
|
+
param.mode == ParameterMode.INPUT_OUTPUT
|
1567
|
+
or param.mode == ParameterMode.OUTPUT
|
1568
|
+
or param.mode == ParameterMode.RETURN_VALUE
|
1569
|
+
):
|
1450
1570
|
wire._next_unless_undefined()
|
1451
1571
|
else:
|
1452
1572
|
wire._next()
|
@@ -1456,7 +1576,9 @@ class Cursor(_BaseCursor):
|
|
1456
1576
|
else:
|
1457
1577
|
self._output_parameter_list = wire._get_output_parameter_list(beg, False)
|
1458
1578
|
if self._statementType not in [StatementType.DIRECT_CALL_UPDATE]:
|
1459
|
-
self._params._prep_list_index(
|
1579
|
+
self._params._prep_list_index(
|
1580
|
+
False, self._output_parameter_list
|
1581
|
+
) # fast select not supported for stored procedures
|
1460
1582
|
return
|
1461
1583
|
|
1462
1584
|
def _handle_error_504(self, error):
|
@@ -1475,7 +1597,11 @@ class Cursor(_BaseCursor):
|
|
1475
1597
|
def stored_results(self):
|
1476
1598
|
if self._closed:
|
1477
1599
|
raise InterfaceError("Cursor is closed")
|
1478
|
-
if self._statementType not in [
|
1600
|
+
if self._statementType not in [
|
1601
|
+
StatementType.QUERY,
|
1602
|
+
StatementType.DIRECT_CALL_QUERY,
|
1603
|
+
StatementType.PREPARED_CALL_QUERY,
|
1604
|
+
]:
|
1479
1605
|
return None
|
1480
1606
|
# getResultSet()
|
1481
1607
|
if self._multiple_result_sets:
|
@@ -1503,16 +1629,21 @@ class Cursor(_BaseCursor):
|
|
1503
1629
|
raise InterfaceError("Cursor is closed")
|
1504
1630
|
if self._connection == None or self._connection.isClosed():
|
1505
1631
|
raise InterfaceError("Connection not open")
|
1506
|
-
if (
|
1507
|
-
|
1508
|
-
|
1509
|
-
|
1510
|
-
|
1511
|
-
|
1632
|
+
if (
|
1633
|
+
self._mrs_done
|
1634
|
+
or not self._multiple_result_sets
|
1635
|
+
or (
|
1636
|
+
self._statementType != StatementType.PREPARED_CALL_QUERY
|
1637
|
+
and self._statementType != StatementType.DIRECT_CALL_QUERY
|
1638
|
+
and self._statementType != StatementType.CALL
|
1639
|
+
and self._statementType != StatementType.CALLWITHRESULT
|
1640
|
+
and not (self._statementType == StatementType.QUERY and self._cursor_type == CursorType.CALLABLE)
|
1641
|
+
)
|
1642
|
+
):
|
1512
1643
|
return False
|
1513
1644
|
with self._connection._lock:
|
1514
1645
|
self._out_message.wire._write_header(_Message.GET_MORE_RESULTS)
|
1515
|
-
self._out_message.wire._set(1)
|
1646
|
+
self._out_message.wire._set(1) # current = CLOSE_CURRENT_RESULT
|
1516
1647
|
|
1517
1648
|
# send
|
1518
1649
|
sequence_number = self._connection._get_new_sequence_number()
|
@@ -1526,7 +1657,7 @@ class Cursor(_BaseCursor):
|
|
1526
1657
|
self._rs_index = 0
|
1527
1658
|
|
1528
1659
|
results = self._in_message.wire._get()
|
1529
|
-
if results >= 0
|
1660
|
+
if results >= 0:
|
1530
1661
|
self._update_cnt = results
|
1531
1662
|
return False
|
1532
1663
|
elif results == -1:
|
@@ -1554,11 +1685,11 @@ class Cursor(_BaseCursor):
|
|
1554
1685
|
def _get_result_set(self, oref):
|
1555
1686
|
if oref == None:
|
1556
1687
|
return None
|
1557
|
-
|
1688
|
+
|
1558
1689
|
with self._connection._lock:
|
1559
1690
|
self._out_message.wire._write_header(_Message.GET_RESULT_SET_OBJECT)
|
1560
1691
|
self._out_message.wire._set(oref)
|
1561
|
-
self._out_message.wire._set(0)
|
1692
|
+
self._out_message.wire._set(0) # IRISResultSet.GET_RESULT_SET_OBJECT_INIT
|
1562
1693
|
|
1563
1694
|
# send
|
1564
1695
|
sequence_number = self._connection._get_new_sequence_number()
|
@@ -1584,16 +1715,16 @@ class Cursor(_BaseCursor):
|
|
1584
1715
|
self.params = params
|
1585
1716
|
|
1586
1717
|
self._params.set_input_params(self.params)
|
1587
|
-
|
1718
|
+
|
1588
1719
|
self._cursor_type = CursorType.CALLABLE
|
1589
1720
|
self._cleanup()
|
1590
1721
|
self._preparse()
|
1591
1722
|
self._stored_results = []
|
1592
|
-
|
1723
|
+
|
1593
1724
|
if not self._get_cached_info():
|
1594
1725
|
self._prepare_stored_procedure()
|
1595
1726
|
|
1596
|
-
#execute() in IrisPreparedStatement
|
1727
|
+
# execute() in IrisPreparedStatement
|
1597
1728
|
if self._multiple_result_sets:
|
1598
1729
|
return self._execute_multiple_result_sets(True)
|
1599
1730
|
if self._statementType == StatementType.QUERY or self._statementType == StatementType.PREPARED_CALL_QUERY:
|
@@ -1614,12 +1745,12 @@ class Cursor(_BaseCursor):
|
|
1614
1745
|
if param.mode in [ParameterMode.RETURN_VALUE, ParameterMode.OUTPUT, ParameterMode.INPUT]:
|
1615
1746
|
offset = self._params._get_user_list_offset(i + 1)
|
1616
1747
|
val = self._output_parameter_list._get_at_offset(offset)
|
1617
|
-
if param.type == -51:
|
1748
|
+
if param.type == -51: # RESULT_SET_TYPE
|
1618
1749
|
self._get_result_set(val)
|
1619
1750
|
self.nextset()
|
1620
1751
|
return_args.append(self._stored_results[0])
|
1621
1752
|
else:
|
1622
|
-
if val ==
|
1753
|
+
if val == "\x01": # Either represents the number 1 or a null/None value
|
1623
1754
|
# maybe move this to _grab_ascii_string in DBList?
|
1624
1755
|
off = self._output_parameter_list.list_item.data_offset
|
1625
1756
|
buf = self._output_parameter_list.list_item.buffer
|
@@ -1628,7 +1759,7 @@ class Cursor(_BaseCursor):
|
|
1628
1759
|
else:
|
1629
1760
|
return_args.append(val)
|
1630
1761
|
if len(return_args) > 0:
|
1631
|
-
if any(i != None for i in return_args):
|
1762
|
+
if any(i != None for i in return_args):
|
1632
1763
|
return return_args
|
1633
1764
|
else:
|
1634
1765
|
return
|
@@ -1647,7 +1778,7 @@ class Cursor(_BaseCursor):
|
|
1647
1778
|
|
1648
1779
|
if self._statementType is not StatementType.UPDATE:
|
1649
1780
|
return None
|
1650
|
-
|
1781
|
+
|
1651
1782
|
# In multivalue inserts it returns the first inserted value, not the last one
|
1652
1783
|
# with self._connection._lock:
|
1653
1784
|
# self._out_message.wire._write_header(_Message.GET_AUTO_GENERATED_KEYS)
|
@@ -1660,7 +1791,7 @@ class Cursor(_BaseCursor):
|
|
1660
1791
|
# self._get_column_info(self._in_message.wire)
|
1661
1792
|
# self._lastrowid = self._in_message.wire._get()
|
1662
1793
|
|
1663
|
-
self.execute(
|
1794
|
+
self.execute("SELECT LAST_IDENTITY()")
|
1664
1795
|
self._lastrowid = self.fetchone()[0]
|
1665
1796
|
return self._lastrowid
|
1666
1797
|
|
@@ -1707,7 +1838,7 @@ class Cursor(_BaseCursor):
|
|
1707
1838
|
self._params = None
|
1708
1839
|
self._parsed_statement = None
|
1709
1840
|
self._cursor_type = CursorType.DEFAULT
|
1710
|
-
self._statementType = StatementType.UPDATE
|
1841
|
+
self._statementType = StatementType.UPDATE # default
|
1711
1842
|
self._paramInfo = None
|
1712
1843
|
self.statement = None
|
1713
1844
|
self.statementFeatureOption = Feature.optionNone
|
@@ -1737,15 +1868,15 @@ class Cursor(_BaseCursor):
|
|
1737
1868
|
return self._rowcount
|
1738
1869
|
|
1739
1870
|
def scroll(self, value, mode):
|
1740
|
-
if mode == None or mode ==
|
1741
|
-
mode =
|
1871
|
+
if mode == None or mode == "":
|
1872
|
+
mode = "relative"
|
1742
1873
|
mode = mode.lower()
|
1743
|
-
if mode !=
|
1874
|
+
if mode != "absolute" and mode != "relative":
|
1744
1875
|
raise ValueError("This mode is not supported - use 'relative' or 'absolute'.")
|
1745
1876
|
|
1746
1877
|
# Backward Scrolling
|
1747
1878
|
if value < 0:
|
1748
|
-
if mode ==
|
1879
|
+
if mode == "relative":
|
1749
1880
|
self._rownumber = self._cursor_ptr + value - 1
|
1750
1881
|
else:
|
1751
1882
|
raise ValueError("Negative values with absolute scrolling are not allowed.")
|
@@ -1764,13 +1895,13 @@ class Cursor(_BaseCursor):
|
|
1764
1895
|
return self._warehouse[self._rownumber - self._last_row_in_warehouse_dict - 1]
|
1765
1896
|
# Forward Scrolling
|
1766
1897
|
else:
|
1767
|
-
if mode ==
|
1898
|
+
if mode == "absolute":
|
1768
1899
|
self._cursor_ptr = 0
|
1769
1900
|
self._scroll_flag = True
|
1770
1901
|
self._rownumber = self._cursor_ptr + value - 1
|
1771
1902
|
if self._rs_index == 0:
|
1772
1903
|
if self._rownumber >= len(self._warehouse):
|
1773
|
-
if mode ==
|
1904
|
+
if mode == "absolute":
|
1774
1905
|
self._cursor_ptr = len(self._warehouse)
|
1775
1906
|
return self.fetchone()
|
1776
1907
|
else:
|
@@ -1792,7 +1923,7 @@ class Cursor(_BaseCursor):
|
|
1792
1923
|
self._cursor_ptr = self._rownumber + 1
|
1793
1924
|
return self._warehouse[self._rownumber - self._last_row_in_warehouse_dict - 1]
|
1794
1925
|
else:
|
1795
|
-
if mode ==
|
1926
|
+
if mode == "absolute":
|
1796
1927
|
self._cursor_ptr = rows_available + 1
|
1797
1928
|
return self.fetchone()
|
1798
1929
|
|
@@ -1808,7 +1939,9 @@ class Cursor(_BaseCursor):
|
|
1808
1939
|
if self._sqlcode == 0:
|
1809
1940
|
with self._connection._lock:
|
1810
1941
|
self._out_message.wire._write_header(_Message.FETCH_DATA)
|
1811
|
-
intersystems_iris._MessageHeader._MessageHeader._set_statement_id(
|
1942
|
+
intersystems_iris._MessageHeader._MessageHeader._set_statement_id(
|
1943
|
+
self._out_message.wire.buffer, self._statement_id
|
1944
|
+
)
|
1812
1945
|
|
1813
1946
|
sequence_number = self._connection._get_new_sequence_number()
|
1814
1947
|
self._out_message._send(sequence_number)
|
@@ -1842,7 +1975,7 @@ class Cursor(_BaseCursor):
|
|
1842
1975
|
list_item = self._current_wire.list_item
|
1843
1976
|
buffer = list_item.buffer
|
1844
1977
|
length = list_item.list_buffer_end
|
1845
|
-
|
1978
|
+
|
1846
1979
|
if self._rsrow._new_buffer:
|
1847
1980
|
prev_offset = list_item.next_offset
|
1848
1981
|
self._rsrow._new_buffer = False
|
@@ -1859,10 +1992,10 @@ class Cursor(_BaseCursor):
|
|
1859
1992
|
intersystems_iris._DBList._DBList._get_list_element(list_item)
|
1860
1993
|
length = list_item.next_offset
|
1861
1994
|
prev_offset = list_item.data_offset
|
1862
|
-
if list_item.data_length == 0:
|
1995
|
+
if list_item.data_length == 0: #
|
1863
1996
|
for j in range(self._rsrow.colCount):
|
1864
1997
|
rowItems[j] = -1
|
1865
|
-
self._rsrow._offsets = self._rsrow.update(rowItems)
|
1998
|
+
self._rsrow._offsets = self._rsrow.update(rowItems) # ???
|
1866
1999
|
return True
|
1867
2000
|
else:
|
1868
2001
|
if self._rsrow.rowItems != None:
|
@@ -1889,10 +2022,12 @@ class Cursor(_BaseCursor):
|
|
1889
2022
|
|
1890
2023
|
self._cursor_ptr += 1
|
1891
2024
|
return row_indexing
|
1892
|
-
|
2025
|
+
|
1893
2026
|
def fetchone(self):
|
1894
2027
|
if self._result_set == None:
|
1895
|
-
raise InterfaceError(
|
2028
|
+
raise InterfaceError(
|
2029
|
+
"Either execute has not yet been called, or the previous call of execute did not return a result set"
|
2030
|
+
)
|
1896
2031
|
|
1897
2032
|
if self._current_wire == None and self._cursor_ptr > self._last_row_in_warehouse_dict:
|
1898
2033
|
return None
|
@@ -1931,9 +2066,11 @@ class Cursor(_BaseCursor):
|
|
1931
2066
|
return retval.as_tuple()
|
1932
2067
|
# return tuple(retval[:])
|
1933
2068
|
|
1934
|
-
def fetchmany(self, size
|
2069
|
+
def fetchmany(self, size=None):
|
1935
2070
|
if self._result_set == None:
|
1936
|
-
raise InterfaceError(
|
2071
|
+
raise InterfaceError(
|
2072
|
+
"Either execute has not yet been called, or the previous call of execute did not return a result set"
|
2073
|
+
)
|
1937
2074
|
|
1938
2075
|
if self._current_wire == None:
|
1939
2076
|
if self._cursor_ptr > self._last_row_in_warehouse_dict:
|
@@ -1961,7 +2098,7 @@ class Cursor(_BaseCursor):
|
|
1961
2098
|
break
|
1962
2099
|
self._cursor_ptr += 1
|
1963
2100
|
return rows
|
1964
|
-
|
2101
|
+
|
1965
2102
|
if size is None:
|
1966
2103
|
size = self.arraysize
|
1967
2104
|
|
@@ -1975,8 +2112,10 @@ class Cursor(_BaseCursor):
|
|
1975
2112
|
|
1976
2113
|
def fetchall(self):
|
1977
2114
|
if self._result_set == None:
|
1978
|
-
raise InterfaceError(
|
1979
|
-
|
2115
|
+
raise InterfaceError(
|
2116
|
+
"Either execute has not yet been called, or the previous call of execute did not return a result set"
|
2117
|
+
)
|
2118
|
+
|
1980
2119
|
if self._current_wire == None:
|
1981
2120
|
if self._cursor_ptr > self._last_row_in_warehouse_dict:
|
1982
2121
|
return []
|
@@ -2001,15 +2140,17 @@ class Cursor(_BaseCursor):
|
|
2001
2140
|
break
|
2002
2141
|
self._cursor_ptr += 1
|
2003
2142
|
return rows
|
2004
|
-
|
2143
|
+
|
2005
2144
|
rows = []
|
2006
2145
|
while self._current_wire is not None:
|
2007
2146
|
row = self.fetchone()
|
2008
|
-
if not row:
|
2147
|
+
if not row:
|
2148
|
+
break
|
2009
2149
|
rows.append(row)
|
2010
|
-
|
2150
|
+
|
2011
2151
|
return rows
|
2012
2152
|
|
2153
|
+
|
2013
2154
|
class EmbdeddedCursor(_BaseCursor):
|
2014
2155
|
embedded = True
|
2015
2156
|
_result_set = None
|
@@ -2019,7 +2160,7 @@ class EmbdeddedCursor(_BaseCursor):
|
|
2019
2160
|
self._sql = connection.iris.sql
|
2020
2161
|
self._iris = connection.iris
|
2021
2162
|
self._closed = False
|
2022
|
-
|
2163
|
+
|
2023
2164
|
# $System.SQL.SetSelectMode(1 /* ODBC */)
|
2024
2165
|
# $System.SQL.Util.SetOption("SelectMode", 1 /* ODBC */)
|
2025
2166
|
connection.iris.system.SQL.SetSelectMode(1)
|
@@ -2027,12 +2168,12 @@ class EmbdeddedCursor(_BaseCursor):
|
|
2027
2168
|
def _get_cached_info(self):
|
2028
2169
|
return False
|
2029
2170
|
|
2030
|
-
def _get_parameters(self, params_set
|
2171
|
+
def _get_parameters(self, params_set=0):
|
2031
2172
|
params = self._params.collect(params_set)
|
2032
2173
|
# None = '', '' = b'\x00'
|
2033
2174
|
_conv = {
|
2034
|
-
type(None): lambda v:
|
2035
|
-
str: lambda v: v or b
|
2175
|
+
type(None): lambda v: "",
|
2176
|
+
str: lambda v: v or b"\x00",
|
2036
2177
|
decimal.Decimal: lambda v: float(v),
|
2037
2178
|
}
|
2038
2179
|
params = [_conv[type(v)](v) if type(v) in _conv else v for v in params]
|
@@ -2042,9 +2183,9 @@ class EmbdeddedCursor(_BaseCursor):
|
|
2042
2183
|
self._columns = []
|
2043
2184
|
if self._result_set is None:
|
2044
2185
|
return
|
2045
|
-
|
2186
|
+
|
2046
2187
|
metadata = self._result_set.ResultSet._GetMetadata()
|
2047
|
-
count = metadata.columnCount if metadata !=
|
2188
|
+
count = metadata.columnCount if metadata != "" and metadata is not None else 0
|
2048
2189
|
for i in range(count):
|
2049
2190
|
slotPosition = i + 1
|
2050
2191
|
_column_info = metadata.columns.GetAt(slotPosition)
|
@@ -2076,7 +2217,21 @@ class EmbdeddedCursor(_BaseCursor):
|
|
2076
2217
|
_column_info.isKeyColumn,
|
2077
2218
|
_column_info.isRowId,
|
2078
2219
|
]
|
2079
|
-
self._columns.append(
|
2220
|
+
self._columns.append(
|
2221
|
+
intersystems_iris.dbapi._Column._Column(
|
2222
|
+
name,
|
2223
|
+
odbctype,
|
2224
|
+
precision,
|
2225
|
+
scale,
|
2226
|
+
nullable,
|
2227
|
+
label,
|
2228
|
+
tableName,
|
2229
|
+
schema,
|
2230
|
+
catalog,
|
2231
|
+
additionalData,
|
2232
|
+
slotPosition,
|
2233
|
+
)
|
2234
|
+
)
|
2080
2235
|
|
2081
2236
|
@property
|
2082
2237
|
def lastrowid(self):
|
@@ -2166,8 +2321,8 @@ class EmbdeddedCursor(_BaseCursor):
|
|
2166
2321
|
sqlproc = self._parsed_statement
|
2167
2322
|
self._rowcount = 0
|
2168
2323
|
params = self._get_parameters()
|
2169
|
-
params_marks =
|
2170
|
-
statement = f
|
2324
|
+
params_marks = ", ".join(["?"] * len(params))
|
2325
|
+
statement = f"CALL {sqlproc} ({params_marks})"
|
2171
2326
|
|
2172
2327
|
sqlcode = 0
|
2173
2328
|
message = None
|
@@ -2183,22 +2338,25 @@ class EmbdeddedCursor(_BaseCursor):
|
|
2183
2338
|
@property
|
2184
2339
|
def rowcount(self):
|
2185
2340
|
return self._rowcount
|
2186
|
-
|
2341
|
+
|
2187
2342
|
def fetchone(self):
|
2188
2343
|
if self._result_set == None:
|
2189
|
-
raise InterfaceError(
|
2190
|
-
|
2344
|
+
raise InterfaceError(
|
2345
|
+
"Either execute has not yet been called, or the previous call of execute did not return a result set"
|
2346
|
+
)
|
2347
|
+
|
2191
2348
|
try:
|
2192
2349
|
values = self._result_set.__next__()
|
2193
2350
|
except:
|
2194
2351
|
return None
|
2195
2352
|
|
2196
|
-
values = [None if v ==
|
2197
|
-
row = namedtuple(
|
2353
|
+
values = [None if v == "" else "" if v == "\x00" else v for v in values]
|
2354
|
+
row = namedtuple("Row", [col.name for col in self._columns], rename=True)
|
2198
2355
|
|
2199
2356
|
_types = {
|
2200
2357
|
SQLType.BIGINT: int,
|
2201
2358
|
SQLType.BINARY: bytes,
|
2359
|
+
SQLType.VARBINARY: bytes,
|
2202
2360
|
SQLType.BIT: bool,
|
2203
2361
|
SQLType.FLOAT: float,
|
2204
2362
|
SQLType.NUMERIC: decimal.Decimal,
|
@@ -2207,7 +2365,7 @@ class EmbdeddedCursor(_BaseCursor):
|
|
2207
2365
|
SQLType.LONGVARBINARY: IRISBinaryStream,
|
2208
2366
|
SQLType.LONGVARCHAR: IRISStream,
|
2209
2367
|
}
|
2210
|
-
|
2368
|
+
|
2211
2369
|
if self._columns:
|
2212
2370
|
for _column in self._columns:
|
2213
2371
|
value = values[_column.slotPosition - 1]
|
@@ -2220,6 +2378,8 @@ class EmbdeddedCursor(_BaseCursor):
|
|
2220
2378
|
value = decimal.Decimal(str(value))
|
2221
2379
|
elif value is None or value_type is None:
|
2222
2380
|
pass
|
2381
|
+
elif value_type is bytes:
|
2382
|
+
value = bytes(map(ord, value))
|
2223
2383
|
elif value_type is decimal.Decimal:
|
2224
2384
|
value = decimal.Decimal(str(value))
|
2225
2385
|
elif issubclass(value_type, IRISStream):
|
@@ -2235,18 +2395,23 @@ class EmbdeddedCursor(_BaseCursor):
|
|
2235
2395
|
|
2236
2396
|
def fetchall(self):
|
2237
2397
|
if self._result_set == None:
|
2238
|
-
raise InterfaceError(
|
2398
|
+
raise InterfaceError(
|
2399
|
+
"Either execute has not yet been called, or the previous call of execute did not return a result set"
|
2400
|
+
)
|
2239
2401
|
|
2240
2402
|
rows = []
|
2241
2403
|
while True:
|
2242
2404
|
row = self.fetchone()
|
2243
|
-
if not row:
|
2405
|
+
if not row:
|
2406
|
+
break
|
2244
2407
|
rows.append(row)
|
2245
2408
|
return rows
|
2246
|
-
|
2247
|
-
def fetchmany(self, size
|
2409
|
+
|
2410
|
+
def fetchmany(self, size=None):
|
2248
2411
|
if self._result_set == None:
|
2249
|
-
raise InterfaceError(
|
2412
|
+
raise InterfaceError(
|
2413
|
+
"Either execute has not yet been called, or the previous call of execute did not return a result set"
|
2414
|
+
)
|
2250
2415
|
|
2251
2416
|
if size is None:
|
2252
2417
|
size = self.arraysize
|
@@ -2267,21 +2432,27 @@ class EmbdeddedCursor(_BaseCursor):
|
|
2267
2432
|
def Date(year, month, day):
|
2268
2433
|
raise NotImplementedErrorDBAPI()
|
2269
2434
|
|
2435
|
+
|
2270
2436
|
def Time(hour, minutes, second):
|
2271
2437
|
raise NotImplementedErrorDBAPI()
|
2272
2438
|
|
2439
|
+
|
2273
2440
|
def Timestamp(year, month, day, hour, minute, second):
|
2274
2441
|
raise NotImplementedErrorDBAPI()
|
2275
2442
|
|
2443
|
+
|
2276
2444
|
def DateFromTicks(ticks):
|
2277
2445
|
raise NotImplementedErrorDBAPI()
|
2278
2446
|
|
2447
|
+
|
2279
2448
|
def TimeFromTicks(ticks):
|
2280
2449
|
raise NotImplementedErrorDBAPI()
|
2281
2450
|
|
2451
|
+
|
2282
2452
|
def TimestampFromTicks(ticks):
|
2283
2453
|
raise NotImplementedErrorDBAPI()
|
2284
2454
|
|
2455
|
+
|
2285
2456
|
# def Binary(string):
|
2286
2457
|
# return string
|
2287
2458
|
|
@@ -2295,33 +2466,43 @@ ROWID = str
|
|
2295
2466
|
|
2296
2467
|
# still needs type singletons (?)
|
2297
2468
|
|
2469
|
+
|
2298
2470
|
# Exception architecture
|
2299
2471
|
class Error(Exception):
|
2300
2472
|
pass
|
2301
2473
|
|
2474
|
+
|
2302
2475
|
class Warning(Exception):
|
2303
|
-
|
2476
|
+
pass
|
2477
|
+
|
2304
2478
|
|
2305
2479
|
class InterfaceError(Error):
|
2306
2480
|
pass
|
2307
2481
|
|
2482
|
+
|
2308
2483
|
class DatabaseError(Error):
|
2309
2484
|
pass
|
2310
2485
|
|
2486
|
+
|
2311
2487
|
class InternalError(DatabaseError):
|
2312
2488
|
pass
|
2313
2489
|
|
2490
|
+
|
2314
2491
|
class OperationalError(DatabaseError):
|
2315
2492
|
pass
|
2316
2493
|
|
2494
|
+
|
2317
2495
|
class ProgrammingError(DatabaseError):
|
2318
2496
|
pass
|
2319
2497
|
|
2498
|
+
|
2320
2499
|
class IntegrityError(DatabaseError):
|
2321
2500
|
pass
|
2322
2501
|
|
2502
|
+
|
2323
2503
|
class DataError(DatabaseError):
|
2324
2504
|
pass
|
2325
2505
|
|
2506
|
+
|
2326
2507
|
class NotSupportedError(DatabaseError):
|
2327
2508
|
pass
|