@@ -24,6 +24,11 @@ cdef class CoreProtocol:
24
24
25
25
self ._skip_discard = False
26
26
27
+ # executemany support data
28
+ self ._execute_iter = None
29
+ self ._execute_portal_name = None
30
+ self ._execute_stmt_name = None
31
+
27
32
self ._reset_result()
28
33
29
34
cdef _write(self , buf):
@@ -60,6 +65,9 @@ cdef class CoreProtocol:
60
65
elif state == PROTOCOL_BIND_EXECUTE:
61
66
self ._process__bind_execute(mtype)
62
67
68
+ elif state == PROTOCOL_BIND_EXECUTE_MANY:
69
+ self ._process__bind_execute_many(mtype)
70
+
63
71
elif state == PROTOCOL_EXECUTE:
64
72
self ._process__bind_execute(mtype)
65
73
@@ -194,6 +202,49 @@ cdef class CoreProtocol:
194
202
# EmptyQueryResponse
195
203
self .buffer.consume_message()
196
204
205
+ cdef _process__bind_execute_many(self , char mtype):
206
+ cdef WriteBuffer buf
207
+
208
+ if mtype == b' D' :
209
+ # DataRow
210
+ self ._parse_data_msgs()
211
+
212
+ elif mtype == b' s' :
213
+ # PortalSuspended
214
+ self .buffer.consume_message()
215
+
216
+ elif mtype == b' C' :
217
+ # CommandComplete
218
+ self ._parse_msg_command_complete()
219
+
220
+ elif mtype == b' E' :
221
+ # ErrorResponse
222
+ self ._parse_msg_error_response(True )
223
+
224
+ elif mtype == b' 2' :
225
+ # BindComplete
226
+ self .buffer.consume_message()
227
+
228
+ elif mtype == b' Z' :
229
+ # ReadyForQuery
230
+ self ._parse_msg_ready_for_query()
231
+ if self .result_type == RESULT_FAILED:
232
+ self ._push_result()
233
+ else :
234
+ try :
235
+ buf = < WriteBuffer> next(self ._execute_iter)
236
+ except StopIteration :
237
+ self ._push_result()
238
+ else :
239
+ # Next iteration over the executemany() arg sequence
240
+ self ._send_bind_message(
241
+ self ._execute_portal_name, self ._execute_stmt_name,
242
+ buf, 0 )
243
+
244
+ elif mtype == b' I' :
245
+ # EmptyQueryResponse
246
+ self .buffer.consume_message()
247
+
197
248
cdef _process__bind(self , char mtype):
198
249
if mtype == b' E' :
199
250
# ErrorResponse
@@ -275,6 +326,14 @@ cdef class CoreProtocol:
275
326
raise RuntimeError (
276
327
' _parse_data_msgs: first message is not "D"' )
277
328
329
+ if self ._discard_data:
330
+ while True :
331
+ buf.consume_message()
332
+ if not buf.has_message() or buf.get_message_type() != b' D' :
333
+ self ._skip_discard = True
334
+ return
335
+
336
+ if ASYNCPG_DEBUG:
278
337
if type (self .result) is not list :
279
338
raise RuntimeError (
280
339
' _parse_data_msgs: result is not a list, but {!r}' .
@@ -424,6 +483,7 @@ cdef class CoreProtocol:
424
483
self .result_row_desc = None
425
484
self .result_status_msg = None
426
485
self .result_execute_completed = False
486
+ self ._discard_data = False
427
487
428
488
cdef _set_state(self , ProtocolState new_state):
429
489
if new_state == PROTOCOL_IDLE:
@@ -537,16 +597,11 @@ cdef class CoreProtocol:
537
597
538
598
self .transport.write(memoryview(packet))
539
599
540
- cdef _bind_execute (self , str portal_name, str stmt_name,
541
- WriteBuffer bind_data, int32_t limit):
600
+ cdef _send_bind_message (self , str portal_name, str stmt_name,
601
+ WriteBuffer bind_data, int32_t limit):
542
602
543
603
cdef WriteBuffer buf
544
604
545
- self ._ensure_connected()
546
- self ._set_state(PROTOCOL_BIND_EXECUTE)
547
-
548
- self .result = []
549
-
550
605
buf = self ._build_bind_message(portal_name, stmt_name, bind_data)
551
606
self ._write(buf)
552
607
@@ -558,6 +613,39 @@ cdef class CoreProtocol:
558
613
559
614
self ._write_sync_message()
560
615
616
+ cdef _bind_execute(self , str portal_name, str stmt_name,
617
+ WriteBuffer bind_data, int32_t limit):
618
+
619
+ cdef WriteBuffer buf
620
+
621
+ self ._ensure_connected()
622
+ self ._set_state(PROTOCOL_BIND_EXECUTE)
623
+
624
+ self .result = []
625
+
626
+ self ._send_bind_message(portal_name, stmt_name, bind_data, limit)
627
+
628
+ cdef _bind_execute_many(self , str portal_name, str stmt_name,
629
+ object bind_data):
630
+
631
+ cdef WriteBuffer buf
632
+
633
+ self ._ensure_connected()
634
+ self ._set_state(PROTOCOL_BIND_EXECUTE_MANY)
635
+
636
+ self .result = None
637
+ self ._discard_data = True
638
+ self ._execute_iter = bind_data
639
+ self ._execute_portal_name = portal_name
640
+ self ._execute_stmt_name = stmt_name
641
+
642
+ try :
643
+ buf = < WriteBuffer> next(bind_data)
644
+ except StopIteration :
645
+ self ._push_result()
646
+ else :
647
+ self ._send_bind_message(portal_name, stmt_name, buf, 0 )
648
+
561
649
cdef _execute(self , str portal_name, int32_t limit):
562
650
cdef WriteBuffer buf
563
651
0 commit comments