@@ -391,36 +391,60 @@ package struct ProtocolPrepared
391
391
}
392
392
}
393
393
394
- static void sendCommand (Connection conn, uint hStmt, PreparedStmtHeaders psh,
394
+ static ubyte [] sendCommand (Connection conn, uint hStmt, PreparedStmtHeaders psh,
395
395
MySQLVal[] inParams, ParameterSpecialization[] psa)
396
396
{
397
- conn.autoPurge();
397
+ ubyte [] impl ()
398
+ {
399
+ conn.autoPurge();
398
400
399
- ubyte [] packet;
400
- conn.resetPacket();
401
+ ubyte [] packet;
402
+ conn.resetPacket();
403
+
404
+ ubyte [] prefix = makePSPrefix(hStmt, 0 );
405
+ size_t len = prefix.length;
406
+ bool longData;
407
+
408
+ if (psh.paramCount)
409
+ {
410
+ ubyte [] one = [ 1 ];
411
+ ubyte [] vals;
412
+ ubyte [] types = analyseParams(inParams, psa, vals, longData);
413
+ ubyte [] nbm = makeBitmap(inParams);
414
+ packet = prefix ~ nbm ~ one ~ types ~ vals;
415
+ }
416
+ else
417
+ packet = prefix;
401
418
402
- ubyte [] prefix = makePSPrefix(hStmt, 0 );
403
- size_t len = prefix.length;
404
- bool longData;
419
+ if (longData)
420
+ sendLongData(conn._socket, hStmt, psa);
405
421
406
- if (psh.paramCount)
422
+ assert (packet.length <= uint .max);
423
+ packet.setPacketHeader(conn.pktNumber);
424
+ conn.bumpPacket();
425
+ conn._socket.send(packet);
426
+
427
+ return conn.getPacket();
428
+ }
429
+
430
+ if (conn._socket.connected)
407
431
{
408
- ubyte [] one = [ 1 ];
409
- ubyte [] vals;
410
- ubyte [] types = analyseParams(inParams, psa, vals, longData);
411
- ubyte [] nbm = makeBitmap(inParams);
412
- packet = prefix ~ nbm ~ one ~ types ~ vals;
432
+ try
433
+ {
434
+ return impl ();
435
+ }
436
+ catch (Exception )
437
+ {
438
+ // convert all exceptions here as stale connections. This might be the
439
+ // first try to send a request to the server on an
440
+ // already-existing connection.
441
+ throw new MYXStaleConnection(" Possible stale connection" );
442
+ }
413
443
}
414
444
else
415
- packet = prefix;
416
-
417
- if (longData)
418
- sendLongData(conn._socket, hStmt, psa);
419
-
420
- assert (packet.length <= uint .max);
421
- packet.setPacketHeader(conn.pktNumber);
422
- conn.bumpPacket();
423
- conn._socket.send(packet);
445
+ {
446
+ return impl ();
447
+ }
424
448
}
425
449
}
426
450
@@ -454,22 +478,21 @@ package(mysql) bool execQueryImpl(Connection conn, ExecQueryImplInfo info, out u
454
478
scope (failure) conn.kill();
455
479
456
480
// Send data
481
+ ubyte [] packet;
457
482
if (info.isPrepared)
458
483
{
459
484
logTrace(" prepared SQL: %s" , info.hStmt);
460
485
461
- ProtocolPrepared.sendCommand(conn, info.hStmt, info.psh, info.inParams, info.psa);
486
+ packet = ProtocolPrepared.sendCommand(conn, info.hStmt, info.psh, info.inParams, info.psa);
462
487
}
463
488
else
464
489
{
465
490
logTrace(" exec query: %s" , info.sql);
466
491
467
- conn.sendCmd(CommandType.QUERY , info.sql);
492
+ packet = conn.sendCmd(CommandType.QUERY , info.sql);
468
493
conn._fieldCount = 0 ;
469
494
}
470
495
471
- // Handle response
472
- ubyte [] packet = conn.getPacket();
473
496
bool rv;
474
497
if (packet.front == ResultPacketMarker.ok || packet.front == ResultPacketMarker.error)
475
498
{
688
711
_socket.write(data);
689
712
}
690
713
691
- package (mysql) void sendCmd(T)(Connection conn, CommandType cmd, const (T)[] data)
714
+ // returns the first packet received
715
+ package (mysql) ubyte [] sendCmd(T)(Connection conn, CommandType cmd, const (T)[] data)
692
716
in
693
717
{
694
718
// Internal thread states. Clients shouldn't use this
709
733
out
710
734
{
711
735
// at this point we should have sent a command
712
- assert (conn.pktNumber == 1 );
736
+ // assert(conn.pktNumber == 1);
713
737
}
714
738
do
715
739
{
716
- scope (failure) conn.kill();
717
-
718
740
conn._lastCommandID++ ;
719
741
720
- if ( ! conn._socket.connected )
742
+ ubyte [] impl ( )
721
743
{
722
- if (cmd == CommandType.QUIT )
723
- return ; // Don't bother reopening connection just to quit
744
+ scope (failure) conn.kill();
724
745
725
- conn._open = Connection.OpenState.notConnected;
726
- conn.connect(conn._clientCapabilities);
727
- }
746
+ conn.autoPurge();
728
747
729
- conn.autoPurge ();
748
+ conn.resetPacket ();
730
749
731
- conn.resetPacket();
750
+ ubyte [] header;
751
+ header.length = 4 /* header*/ + 1 /* cmd*/ ;
752
+ header.setPacketHeader(conn.pktNumber, cast (uint )data.length + 1 /* cmd byte*/ );
753
+ header[4 ] = cmd;
754
+ conn.bumpPacket();
732
755
733
- ubyte [] header;
734
- header.length = 4 /* header*/ + 1 /* cmd*/ ;
735
- header.setPacketHeader(conn.pktNumber, cast (uint )data.length + 1 /* cmd byte*/ );
736
- header[4 ] = cmd;
737
- conn.bumpPacket();
756
+ conn._socket.send(header, cast (const (ubyte )[])data);
757
+
758
+ // now, get the first packet, but only if the command is not QUIT
759
+ if (cmd == CommandType.QUIT )
760
+ return null ;
761
+
762
+ return conn.getPacket();
763
+ }
764
+
765
+ if (conn._socket.connected)
766
+ {
767
+ try
768
+ {
769
+ return impl ();
770
+ }
771
+ catch (Exception )
772
+ {
773
+ // convert all exceptions here as stale connections. This is the
774
+ // first try to send a request to the server on an already-existing connection.
775
+ throw new MYXStaleConnection(" Possible stale connection" );
776
+ }
777
+ }
778
+ else
779
+ {
780
+ if (cmd == CommandType.QUIT )
781
+ return null ; // Don't bother reopening connection just to quit
738
782
739
- conn._socket.send(header, cast (const (ubyte )[])data);
783
+ conn._open = Connection.OpenState.notConnected;
784
+ conn.connect(conn._clientCapabilities);
785
+ return impl ();
786
+ }
740
787
}
741
788
742
- package (mysql) OKErrorPacket getCmdResponse(Connection conn, bool asString = false )
789
+ package (mysql) OKErrorPacket getCmdResponse(Connection conn, ubyte [] packet )
743
790
{
744
- auto okp = OKErrorPacket(conn.getPacket() );
791
+ auto okp = OKErrorPacket(packet );
745
792
enforcePacketOK(okp);
746
793
conn._serverStatus = okp.serverStatus;
747
794
return okp;
@@ -960,10 +1007,9 @@ package(mysql) PreparedServerInfo performRegister(Connection conn, const(char[])
960
1007
961
1008
PreparedServerInfo info;
962
1009
963
- conn.sendCmd(CommandType.STMT_PREPARE , sql);
1010
+ ubyte [] packet = conn.sendCmd(CommandType.STMT_PREPARE , sql);
964
1011
conn._fieldCount = 0 ;
965
1012
966
- ubyte [] packet = conn.getPacket();
967
1013
if (packet.front == ResultPacketMarker.ok)
968
1014
{
969
1015
packet.popFront();
@@ -1046,8 +1092,7 @@ Get a textual report on the server status.
1046
1092
+/
1047
1093
package (mysql) string serverStats(Connection conn)
1048
1094
{
1049
- conn.sendCmd(CommandType.STATISTICS , []);
1050
- auto result = conn.getPacket();
1095
+ auto result = conn.sendCmd(CommandType.STATISTICS , []);
1051
1096
return (() @trusted => cast (string )result)();
1052
1097
}
1053
1098
@@ -1071,10 +1116,8 @@ package(mysql) void enableMultiStatements(Connection conn, bool on)
1071
1116
t.length = 2 ;
1072
1117
t[0 ] = on ? 0 : 1 ;
1073
1118
t[1 ] = 0 ;
1074
- conn.sendCmd(CommandType.STMT_OPTION , t);
1075
-
1076
1119
// For some reason this command gets an EOF packet as response
1077
- auto packet = conn.getPacket( );
1120
+ auto packet = conn.sendCmd(CommandType. STMT_OPTION , t );
1078
1121
enforce! MYXProtocol(packet[0 ] == 254 && packet.length == 5 , " Unexpected response to SET_OPTION command" );
1079
1122
}
1080
1123
0 commit comments