@@ -5,7 +5,7 @@ use bytes::{Buf, Bytes, BytesMut};
55
66use crate :: error:: Error ;
77use crate :: io:: MySqlBufExt ;
8- use crate :: io:: { ProtocolDecode , ProtocolEncode } ;
8+ use crate :: io:: { AsyncRead , ProtocolDecode , ProtocolEncode } ;
99use crate :: net:: { BufferedSocket , Socket } ;
1010use crate :: protocol:: response:: { EofPacket , ErrPacket , OkPacket , Status } ;
1111use crate :: protocol:: { Capabilities , Packet } ;
@@ -43,7 +43,8 @@ impl<S: Socket> MySqlStream<S> {
4343 | Capabilities :: MULTI_RESULTS
4444 | Capabilities :: PLUGIN_AUTH
4545 | Capabilities :: PS_MULTI_RESULTS
46- | Capabilities :: SSL ;
46+ | Capabilities :: SSL
47+ | Capabilities :: LOCAL_FILES ;
4748
4849 if options. database . is_some ( ) {
4950 capabilities |= Capabilities :: CONNECT_WITH_DB ;
@@ -108,6 +109,41 @@ impl<S: Socket> MySqlStream<S> {
108109 Ok ( ( ) )
109110 }
110111
112+ /// Send data from a stream to the database server as MySQL packets
113+ ///
114+ /// This is used to send data for a LOCAL INFILE query
115+ pub ( crate ) async fn send_stream (
116+ & mut self ,
117+ mut source : impl AsyncRead + Unpin ,
118+ ) -> Result < ( ) , Error > {
119+ loop {
120+ let buf = self . socket . write_buffer_mut ( ) ;
121+
122+ // Write the CopyData format code and reserve space for the length + sequence_id
123+ // This is safe even if empty, since we always need to send an empty packet at the end
124+ buf. put_slice ( b"\0 \0 \0 \0 " ) ;
125+
126+ let read = buf. read_from ( & mut source) . await ?;
127+ let read32 = i32:: try_from ( read)
128+ . map_err ( |_| err_protocol ! ( "number of bytes read exceeds 2^31 - 1: {}" , read) ) ?;
129+
130+ // rewrite header (len + sequenceid)
131+ let mut header = read32. to_le_bytes ( ) ;
132+ header[ 3 ] = self . sequence_id ;
133+ self . sequence_id = self . sequence_id . wrapping_add ( 1 ) ;
134+
135+ buf. get_mut ( ) [ ..4 ] . copy_from_slice ( & header) ;
136+
137+ self . socket . flush ( ) . await ?;
138+
139+ if read32 == 0 {
140+ break ;
141+ }
142+ }
143+
144+ Ok ( ( ) )
145+ }
146+
111147 pub ( crate ) fn write_packet < ' en , T > ( & mut self , payload : T ) -> Result < ( ) , Error >
112148 where
113149 T : ProtocolEncode < ' en , Capabilities > ,
0 commit comments