11# coding: ascii-8bit
2- # Copyright (C) 2008-2012 TOMITA Masahiro
2+ # Copyright (C) 2008 TOMITA Masahiro
3344
55require "socket"
@@ -134,15 +134,17 @@ def self.value2net(v)
134134 # conn_timeout :: [Integer] connect timeout (sec).
135135 # read_timeout :: [Integer] read timeout (sec).
136136 # write_timeout :: [Integer] write timeout (sec).
137+ # local_infile :: [String] local infile path
137138 # === Exception
138139 # [ClientError] :: connection timeout
139- def initialize ( host , port , socket , conn_timeout , read_timeout , write_timeout )
140+ def initialize ( host , port , socket , conn_timeout , read_timeout , write_timeout , local_infile )
140141 @insert_id = 0
141142 @warning_count = 0
142143 @gc_stmt_queue = [ ] # stmt id list which GC destroy.
143144 set_state :INIT
144145 @read_timeout = read_timeout
145146 @write_timeout = write_timeout
147+ @local_infile = local_infile
146148 begin
147149 Timeout . timeout conn_timeout do
148150 if host . nil? or host . empty? or host == "localhost"
@@ -180,6 +182,7 @@ def authenticate(user, passwd, db, flag, charset)
180182 @server_version = init_packet . server_version . split ( /\D / ) [ 0 , 3 ] . inject { |a , b |a . to_i *100 +b . to_i }
181183 @thread_id = init_packet . thread_id
182184 client_flags = CLIENT_LONG_PASSWORD | CLIENT_LONG_FLAG | CLIENT_TRANSACTIONS | CLIENT_PROTOCOL_41 | CLIENT_SECURE_CONNECTION
185+ client_flags |= CLIENT_LOCAL_FILES if @local_infile
183186 client_flags |= CLIENT_CONNECT_WITH_DB if db
184187 client_flags |= flag
185188 @charset = charset
@@ -230,10 +233,7 @@ def get_result
230233 return res_packet . field_count
231234 end
232235 if res_packet . field_count . nil? # LOAD DATA LOCAL INFILE
233- filename = res_packet . message
234- File . open ( filename ) { |f | write f }
235- write nil # EOF mark
236- read
236+ send_local_file ( res_packet . message )
237237 end
238238 @affected_rows , @insert_id , @server_status , @warning_count , @message =
239239 res_packet . affected_rows , res_packet . insert_id , res_packet . server_status , res_packet . warning_count , res_packet . message
@@ -245,6 +245,19 @@ def get_result
245245 end
246246 end
247247
248+ # send local file to server
249+ def send_local_file ( filename )
250+ filename = File . absolute_path ( filename )
251+ if filename . start_with? @local_infile
252+ File . open ( filename ) { |f | write f }
253+ else
254+ raise ClientError ::LoadDataLocalInfileRejected , 'LOAD DATA LOCAL INFILE file request rejected due to restrictions on access.'
255+ end
256+ ensure
257+ write nil # EOF mark
258+ read
259+ end
260+
248261 # Retrieve n fields
249262 # === Argument
250263 # n :: [Integer] number of fields
0 commit comments