ruby-mysql 2.11.0 → 3.0.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 40bdb4e1eba4eca2ed1e93524260bd9407f91ee5f65b8c32b8c38524ef05ebdd
4
- data.tar.gz: 224ad0bdf2050dca6e5d7a603bd64cb44a5f414270aa06b9dd89690cd2665a32
3
+ metadata.gz: 37cc4956fc000b612b24fe104acf96abf27e0a7016cbd05c2c5e7b4ae5e0bade
4
+ data.tar.gz: b2c4ded73325a5c4aadce1d81af507e2a7d4144764150fde183f0e541e25e8b8
5
5
  SHA512:
6
- metadata.gz: a73e1ab248a44935cd4115c0d2de16f491d51b2eb7ab7a9b33185a0f478be8753cc226ea78d645a2bb1ae0b09cb15a7432f9e8d5a1dfa82af3ef016783689544
7
- data.tar.gz: 37db0a8b13b5a543cf9d552801aa0419c4ccce9fbe287d8df0335002df728e5e5ab5a9d82c873c174dec547b1077730cd265a4a6ace1714c88cb984b3d5f4134
6
+ metadata.gz: c81163849e312cb8cb861a1c5add93fba0973d1fbf01b9296513914931134230dbf7d2d6437e72097c8426d24daab316c2756621d3302d5ee91efb72ab951cc3
7
+ data.tar.gz: c4e13cea550e4659db986772663b04364c8c18f51abc9442516058cbe5ebc420dd19a95e324e149ae0966edefa1259fff9274677295849834029f827667547c2
data/CHANGELOG.md ADDED
@@ -0,0 +1,58 @@
1
+ ## [3.0.1] - 2022-06-18
2
+
3
+ - LICENSE: correct author
4
+ - FIX: correct LOAD DATA LOCAL INFILE result information.
5
+ - FIX: reset SERVER_MORE_RESULTS_EXISTS when error packet is received.
6
+ - FIX: close the socket when the connection is disconnected.
7
+ - FIX: allow multiple results by default.
8
+
9
+ ## [3.0.0] - 2021-11-16
10
+
11
+ - `Mysql.new` no longer connect. use `Mysql.connect` or `Mysql#connect`.
12
+
13
+ - `Mysql.init` is removed. use `Mysql.new` instead.
14
+
15
+ - `Mysql.new`, `Mysql.conncet` and `Mysql#connect` takes URI object or URI string or Hash object.
16
+ example:
17
+ Mysql.connect('mysql://user:password@hostname:port/dbname?charset=ascii')
18
+ Mysql.connect('mysql://user:password@%2Ftmp%2Fmysql.sock/dbname?charset=ascii') # for UNIX socket
19
+ Mysql.connect('hostname', 'user', 'password', 'dbname')
20
+ Mysql.connect(host: 'hostname', username: 'user', password: 'password', database: 'dbname')
21
+
22
+ - `Mysql.options` is removed. use `Mysql#param = value` instead.
23
+ For example:
24
+ m = Mysql.init
25
+ m.options(Mysql::OPT_LOCAL_INFILE, true)
26
+ m.connect(host, user, passwd)
27
+ change to
28
+ m = Mysql.new
29
+ m.local_infile = true
30
+ m.connect(host, user, passwd)
31
+ or
32
+ m = Mysql.connect(host, user, passwd, local_infile: true)
33
+
34
+ - `Mysql::Time` is removed.
35
+ Instead, `Time` object is returned for the DATE, DATETIME, TIMESTAMP data,
36
+ and `Integer` object is returned for the TIME data.
37
+ If DATE, DATETIME, TIMESTAMP are invalid values for Time, nil is returned.
38
+
39
+ - meaningless methods are removed:
40
+ * `bind_result`
41
+ * `client_info`
42
+ * `client_version`
43
+ * `get_proto_info`
44
+ * `get_server_info`
45
+ * `get_server_version`
46
+ * `proto_info`
47
+ * `query_with_result`
48
+
49
+ - alias method are removed:
50
+ * `get_host_info`: use `host_info`
51
+ * `real_connect`: use `connect`
52
+ * `real_query`: use `query`
53
+
54
+ - methods corresponding to deprecated APIs in MySQL are removed:
55
+ * `list_dbs`: use `SHOW DATABASES`
56
+ * `list_fields`: use `SHOW COLUMNS`
57
+ * `list_processes`: use `SHOW PROCESSLIST`
58
+ * `list_tables`: use `SHOW TABLES`
data/README.md ADDED
@@ -0,0 +1,28 @@
1
+ # ruby-mysql
2
+
3
+ ## Description
4
+
5
+ MySQL connector for Ruby.
6
+
7
+ ## Installation
8
+
9
+ ```
10
+ gem install ruby-mysql
11
+ ```
12
+
13
+ ## Synopsis
14
+
15
+ ```ruby
16
+ my = Mysql.connect('mysql://username:password@hostname:port/dbname?charset=utf8mb4')
17
+ my.query("select col1, col2 from tblname").each do |col1, col2|
18
+ p col1, col2
19
+ end
20
+ stmt = my.prepare('insert into tblname (col1,col2) values (?,?)')
21
+ stmt.execute 123, 'abc'
22
+ ```
23
+
24
+ ## Copyright
25
+
26
+ * Author: TOMITA Masahiro <tommy@tmtm.org>
27
+ * Copyright: Copyright 2008 TOMITA Masahiro
28
+ * License: MIT
@@ -15,12 +15,10 @@ class Mysql
15
15
  MAX_PACKET_LENGTH = 2**24-1
16
16
 
17
17
  # Convert netdata to Ruby value
18
- # === Argument
19
- # data :: [Packet] packet data
20
- # type :: [Integer] field type
21
- # unsigned :: [true or false] true if value is unsigned
22
- # === Return
23
- # Object :: converted value.
18
+ # @param data [Packet] packet data
19
+ # @param type [Integer] field type
20
+ # @param unsigned [true or false] true if value is unsigned
21
+ # @return [Object] converted value.
24
22
  def self.net2value(pkt, type, unsigned)
25
23
  case type
26
24
  when Field::TYPE_STRING, Field::TYPE_VAR_STRING, Field::TYPE_NEWDECIMAL, Field::TYPE_BLOB, Field::TYPE_JSON
@@ -45,17 +43,18 @@ class Mysql
45
43
  when Field::TYPE_DATE
46
44
  len = pkt.utiny
47
45
  y, m, d = pkt.read(len).unpack("vCC")
48
- t = Mysql::Time.new(y, m, d, nil, nil, nil)
46
+ t = Time.new(y, m, d) rescue nil
49
47
  return t
50
48
  when Field::TYPE_DATETIME, Field::TYPE_TIMESTAMP
51
49
  len = pkt.utiny
52
50
  y, m, d, h, mi, s, sp = pkt.read(len).unpack("vCCCCCV")
53
- return Mysql::Time.new(y, m, d, h, mi, s, false, sp)
51
+ return Time.new(y, m, d, h, mi, Rational((s.to_i*1000000+sp.to_i)/1000000)) rescue nil
54
52
  when Field::TYPE_TIME
55
53
  len = pkt.utiny
56
54
  sign, d, h, mi, s, sp = pkt.read(len).unpack("CVCCCV")
57
- h = d.to_i * 24 + h.to_i
58
- return Mysql::Time.new(0, 0, 0, h, mi, s, sign!=0, sp)
55
+ r = d.to_i*86400 + h.to_i*3600 + mi.to_i*60 + s.to_i + sp.to_f/1000000
56
+ r *= -1 if sign != 0
57
+ return r
59
58
  when Field::TYPE_YEAR
60
59
  return pkt.ushort
61
60
  when Field::TYPE_BIT
@@ -66,13 +65,10 @@ class Mysql
66
65
  end
67
66
 
68
67
  # convert Ruby value to netdata
69
- # === Argument
70
- # v :: [Object] Ruby value.
71
- # === Return
72
- # Integer :: type of column. Field::TYPE_*
73
- # String :: netdata
74
- # === Exception
75
- # ProtocolError :: value too large / value is not supported
68
+ # @param v [Object] Ruby value.
69
+ # @return [Integer] type of column. Field::TYPE_*
70
+ # @return [String] netdata
71
+ # @raise [ProtocolError] value too large / value is not supported
76
72
  def self.value2net(v)
77
73
  case v
78
74
  when nil
@@ -97,12 +93,9 @@ class Mysql
97
93
  when String
98
94
  type = Field::TYPE_STRING
99
95
  val = Packet.lcs(v)
100
- when ::Time
96
+ when Time
101
97
  type = Field::TYPE_DATETIME
102
98
  val = [11, v.year, v.month, v.day, v.hour, v.min, v.sec, v.usec].pack("CvCCCCCV")
103
- when Mysql::Time
104
- type = Field::TYPE_DATETIME
105
- val = [11, v.year, v.month, v.day, v.hour, v.min, v.sec, v.second_part].pack("CvCCCCCV")
106
99
  else
107
100
  raise ProtocolError, "class #{v.class} is not supported"
108
101
  end
@@ -129,30 +122,38 @@ class Mysql
129
122
  # :RESULT :: After retr_fields(), retr_all_records() or stmt_retr_all_records() is needed.
130
123
 
131
124
  # make socket connection to server.
132
- # @param host [String] if "localhost" or "" or nil then use UNIX socket. Otherwise use TCP socket
133
- # @param port [Integer] port number using by TCP socket
134
- # @param socket [String] socket file name using by UNIX socket
135
- # @param [Hash] opts
136
- # @option opts :conn_timeout [Integer] connect timeout (sec).
137
- # @option opts :read_timeout [Integer] read timeout (sec).
138
- # @option opts :write_timeout [Integer] write timeout (sec).
139
- # @option opts :local_infile [String] local infile path
140
- # @option opts :get_server_public_key [Boolean]
125
+ # @param opts [Hash]
126
+ # @option :host [String] hostname mysqld running
127
+ # @option :username [String] username to connect to mysqld
128
+ # @option :password [String] password to connect to mysqld
129
+ # @option :database [String] initial database name
130
+ # @option :port [String] port number (used if host is not 'localhost' or nil)
131
+ # @option :socket [String] socket filename (used if host is 'localhost' or nil)
132
+ # @option :flags [Integer] connection flag. Mysql::CLIENT_* ORed
133
+ # @option :charset [Mysql::Charset] character set
134
+ # @option :connect_timeout [Numeric, nil]
135
+ # @option :read_timeout [Numeric, nil]
136
+ # @option :write_timeout [Numeric, nil]
137
+ # @option :local_infile [Boolean]
138
+ # @option :load_data_local_dir [String]
139
+ # @option :ssl_mode [Integer]
140
+ # @option :get_server_public_key [Boolean]
141
141
  # @raise [ClientError] connection timeout
142
- def initialize(host, port, socket, opts)
142
+ def initialize(opts)
143
143
  @opts = opts
144
+ @charset = Mysql::Charset.by_name("utf8mb4")
144
145
  @insert_id = 0
145
146
  @warning_count = 0
146
147
  @gc_stmt_queue = [] # stmt id list which GC destroy.
147
148
  set_state :INIT
148
149
  @get_server_public_key = @opts[:get_server_public_key]
149
150
  begin
150
- if host.nil? or host.empty? or host == "localhost"
151
- socket ||= ENV["MYSQL_UNIX_PORT"] || MYSQL_UNIX_PORT
151
+ if @opts[:host].nil? or @opts[:host].empty? or @opts[:host] == "localhost"
152
+ socket = @opts[:socket] || ENV["MYSQL_UNIX_PORT"] || MYSQL_UNIX_PORT
152
153
  @socket = Socket.unix(socket)
153
154
  else
154
- port ||= ENV["MYSQL_TCP_PORT"] || (Socket.getservbyname("mysql","tcp") rescue MYSQL_TCP_PORT)
155
- @socket = Socket.tcp(host, port, connect_timeout: @opts[:connect_timeout])
155
+ port = @opts[:port] || ENV["MYSQL_TCP_PORT"] || (Socket.getservbyname("mysql","tcp") rescue MYSQL_TCP_PORT)
156
+ @socket = Socket.tcp(@opts[:host], port, connect_timeout: @opts[:connect_timeout])
156
157
  end
157
158
  rescue Errno::ETIMEDOUT
158
159
  raise ClientError, "connection timeout"
@@ -164,45 +165,39 @@ class Mysql
164
165
  end
165
166
 
166
167
  # initial negotiate and authenticate.
167
- # === Argument
168
- # user :: [String / nil] username
169
- # passwd :: [String / nil] password
170
- # db :: [String / nil] default database name. nil: no default.
171
- # flag :: [Integer] client flag
172
- # charset :: [Mysql::Charset / nil] charset for connection. nil: use server's charset
173
- # === Exception
174
- # ProtocolError :: The old style password is not supported
175
- def authenticate(user, passwd, db, flag, charset)
168
+ # @param charset [Mysql::Charset, nil] charset for connection. nil: use server's charset
169
+ # @raise [ProtocolError] The old style password is not supported
170
+ def authenticate
176
171
  check_state :INIT
177
- @authinfo = [user, passwd, db, flag, charset]
178
172
  reset
179
173
  init_packet = InitialPacket.parse read
180
174
  @server_info = init_packet.server_version
181
175
  @server_version = init_packet.server_version.split(/\D/)[0,3].inject{|a,b|a.to_i*100+b.to_i}
182
176
  @server_capabilities = init_packet.server_capabilities
183
177
  @thread_id = init_packet.thread_id
184
- @client_flags = CLIENT_LONG_PASSWORD | CLIENT_LONG_FLAG | CLIENT_TRANSACTIONS | CLIENT_PROTOCOL_41 | CLIENT_SECURE_CONNECTION | CLIENT_PLUGIN_AUTH
185
- @client_flags |= CLIENT_LOCAL_FILES if @opts[:local_infile]
186
- @client_flags |= CLIENT_CONNECT_WITH_DB if db
187
- @client_flags |= flag
188
- @charset = charset
189
- unless @charset
178
+ @client_flags = CLIENT_LONG_PASSWORD | CLIENT_LONG_FLAG | CLIENT_TRANSACTIONS | CLIENT_PROTOCOL_41 | CLIENT_SECURE_CONNECTION | CLIENT_MULTI_RESULTS | CLIENT_PS_MULTI_RESULTS | CLIENT_PLUGIN_AUTH
179
+ @client_flags |= CLIENT_LOCAL_FILES if @opts[:local_infile] || @opts[:load_data_local_dir]
180
+ @client_flags |= CLIENT_CONNECT_WITH_DB if @opts[:database]
181
+ @client_flags |= @opts[:flags]
182
+ if @opts[:charset]
183
+ @charset = @opts[:charset].is_a?(Charset) ? @opts[:charset] : Charset.by_name(@opts[:charset])
184
+ else
190
185
  @charset = Charset.by_number(init_packet.server_charset)
191
186
  @charset.encoding # raise error if unsupported charset
192
187
  end
193
188
  enable_ssl
194
- Authenticator.new(self).authenticate(user, passwd, db, init_packet.scramble_buff, init_packet.auth_plugin)
189
+ Authenticator.new(self).authenticate(@opts[:username], @opts[:password].to_s, @opts[:database], init_packet.scramble_buff, init_packet.auth_plugin)
195
190
  set_state :READY
196
191
  end
197
192
 
198
193
  def enable_ssl
199
194
  case @opts[:ssl_mode]
200
- when SSL_MODE_DISABLED
195
+ when SSL_MODE_DISABLED, '1', 'disabled'
201
196
  return
202
- when SSL_MODE_PREFERRED
197
+ when SSL_MODE_PREFERRED, '2', 'preferred'
203
198
  return if @socket.local_address.unix?
204
199
  return if @server_capabilities & CLIENT_SSL == 0
205
- when SSL_MODE_REQUIRED
200
+ when SSL_MODE_REQUIRED, '3', 'required'
206
201
  if @server_capabilities & CLIENT_SSL == 0
207
202
  raise ClientError::SslConnectionError, "SSL is required but the server doesn't support it"
208
203
  end
@@ -232,10 +227,8 @@ class Mysql
232
227
  end
233
228
 
234
229
  # Query command
235
- # === Argument
236
- # query :: [String] query string
237
- # === Return
238
- # [Integer / nil] number of fields of results. nil if no results.
230
+ # @param query [String] query string
231
+ # @return [Integer, nil] number of fields of results. nil if no results.
239
232
  def query_command(query)
240
233
  check_state :READY
241
234
  begin
@@ -249,8 +242,7 @@ class Mysql
249
242
  end
250
243
 
251
244
  # get result of query.
252
- # === Return
253
- # [integer / nil] number of fields of results. nil if no results.
245
+ # @return [integer, nil] number of fields of results. nil if no results.
254
246
  def get_result
255
247
  begin
256
248
  res_packet = ResultPacket.parse read
@@ -260,6 +252,7 @@ class Mysql
260
252
  end
261
253
  if res_packet.field_count.nil? # LOAD DATA LOCAL INFILE
262
254
  send_local_file(res_packet.message)
255
+ res_packet = ResultPacket.parse read
263
256
  end
264
257
  @affected_rows, @insert_id, @server_status, @warning_count, @message =
265
258
  res_packet.affected_rows, res_packet.insert_id, res_packet.server_status, res_packet.warning_count, res_packet.message
@@ -274,21 +267,18 @@ class Mysql
274
267
  # send local file to server
275
268
  def send_local_file(filename)
276
269
  filename = File.absolute_path(filename)
277
- if filename.start_with? @opts[:local_infile]
270
+ if @opts[:local_infile] || @opts[:load_data_local_dir] && filename.start_with?(@opts[:load_data_local_dir])
278
271
  File.open(filename){|f| write f}
279
272
  else
280
273
  raise ClientError::LoadDataLocalInfileRejected, 'LOAD DATA LOCAL INFILE file request rejected due to restrictions on access.'
281
274
  end
282
275
  ensure
283
276
  write nil # EOF mark
284
- read
285
277
  end
286
278
 
287
279
  # Retrieve n fields
288
- # === Argument
289
- # n :: [Integer] number of fields
290
- # === Return
291
- # [Array of Mysql::Field] field list
280
+ # @param n [Integer] number of fields
281
+ # @return [Array<Mysql::Field>] field list
292
282
  def retr_fields(n)
293
283
  check_state :FIELD
294
284
  begin
@@ -303,10 +293,8 @@ class Mysql
303
293
  end
304
294
 
305
295
  # Retrieve all records for simple query
306
- # === Argument
307
- # fields :: [Array<Mysql::Field>] number of fields
308
- # === Return
309
- # [Array of Array of String] all records
296
+ # @param fields [Array<Mysql::Field>] number of fields
297
+ # @return [Array<Array<String>>] all records
310
298
  def retr_all_records(fields)
311
299
  check_state :RESULT
312
300
  enc = charset.encoding
@@ -323,43 +311,6 @@ class Mysql
323
311
  end
324
312
  end
325
313
 
326
- # Field list command
327
- # === Argument
328
- # table :: [String] table name.
329
- # field :: [String / nil] field name that may contain wild card.
330
- # === Return
331
- # [Array of Field] field list
332
- def field_list_command(table, field)
333
- synchronize do
334
- reset
335
- write [COM_FIELD_LIST, table, 0, field].pack("Ca*Ca*")
336
- fields = []
337
- until (data = read).eof?
338
- fields.push Field.new(FieldPacket.parse(data))
339
- end
340
- return fields
341
- end
342
- end
343
-
344
- # Process info command
345
- # === Return
346
- # [Array of Field] field list
347
- def process_info_command
348
- check_state :READY
349
- begin
350
- reset
351
- write [COM_PROCESS_INFO].pack("C")
352
- field_count = read.lcb
353
- fields = field_count.times.map{Field.new FieldPacket.parse(read)}
354
- read_eof_packet
355
- set_state :RESULT
356
- return fields
357
- rescue
358
- set_state :READY
359
- raise
360
- end
361
- end
362
-
363
314
  # Ping command
364
315
  def ping_command
365
316
  simple_command [COM_PING].pack("C")
@@ -391,12 +342,8 @@ class Mysql
391
342
  end
392
343
 
393
344
  # Stmt prepare command
394
- # === Argument
395
- # stmt :: [String] prepared statement
396
- # === Return
397
- # [Integer] statement id
398
- # [Integer] number of parameters
399
- # [Array of Field] field list
345
+ # @param stmt [String] prepared statement
346
+ # @return [Array<Integer, Integer, Array<Field>>] statement id, number of parameters, field list
400
347
  def stmt_prepare_command(stmt)
401
348
  synchronize do
402
349
  reset
@@ -417,11 +364,9 @@ class Mysql
417
364
  end
418
365
 
419
366
  # Stmt execute command
420
- # === Argument
421
- # stmt_id :: [Integer] statement id
422
- # values :: [Array] parameters
423
- # === Return
424
- # [Integer] number of fields
367
+ # @param stmt_id [Integer] statement id
368
+ # @param values [Array] parameters
369
+ # @return [Integer] number of fields
425
370
  def stmt_execute_command(stmt_id, values)
426
371
  check_state :READY
427
372
  begin
@@ -435,11 +380,9 @@ class Mysql
435
380
  end
436
381
 
437
382
  # Retrieve all records for prepared statement
438
- # === Argument
439
- # fields :: [Array of Mysql::Fields] field list
440
- # charset :: [Mysql::Charset]
441
- # === Return
442
- # [Array of Array of Object] all records
383
+ # @param fields [Array of Mysql::Fields] field list
384
+ # @param charset [Mysql::Charset]
385
+ # @return [Array<Array<Object>>] all records
443
386
  def stmt_retr_all_records(fields, charset)
444
387
  check_state :RESULT
445
388
  enc = charset.encoding
@@ -455,8 +398,7 @@ class Mysql
455
398
  end
456
399
 
457
400
  # Stmt close command
458
- # === Argument
459
- # stmt_id :: [Integer] statement id
401
+ # @param stmt_id [Integer] statement id
460
402
  def stmt_close_command(stmt_id)
461
403
  synchronize do
462
404
  reset
@@ -502,10 +444,8 @@ class Mysql
502
444
  end
503
445
 
504
446
  # Read one packet data
505
- # === Return
506
- # [Packet] packet data
507
- # === Exception
508
- # [ProtocolError] invalid packet sequence number
447
+ # @return [Packet] packet data
448
+ # @rails [ProtocolError] invalid packet sequence number
509
449
  def read
510
450
  data = ''
511
451
  len = nil
@@ -520,6 +460,7 @@ class Mysql
520
460
  raise EOFError unless ret && ret.length == len
521
461
  data.concat ret
522
462
  rescue EOFError
463
+ @socket.close rescue nil
523
464
  raise ClientError::ServerGoneError, 'MySQL server has gone away'
524
465
  rescue Errno::ETIMEDOUT
525
466
  raise ClientError, "read timeout"
@@ -534,6 +475,7 @@ class Mysql
534
475
  _, errno, message = data.unpack("Cva*") # Version 4.0 Error
535
476
  @sqlstate = ""
536
477
  end
478
+ @server_status &= ~SERVER_MORE_RESULTS_EXISTS
537
479
  message.force_encoding(@charset.encoding)
538
480
  if Mysql::ServerError::ERROR_MAP.key? errno
539
481
  raise Mysql::ServerError::ERROR_MAP[errno].new(message, @sqlstate)
@@ -546,9 +488,9 @@ class Mysql
546
488
  def read_timeout(len, timeout)
547
489
  return @socket.read(len) if timeout.nil? || timeout == 0
548
490
  result = ''
549
- e = ::Time.now + timeout
491
+ e = Time.now + timeout
550
492
  while result.size < len
551
- now = ::Time.now
493
+ now = Time.now
552
494
  raise Errno::ETIMEDOUT if now > e
553
495
  r = @socket.read_nonblock(len - result.size, exception: false)
554
496
  case r
@@ -566,8 +508,7 @@ class Mysql
566
508
  end
567
509
 
568
510
  # Write one packet data
569
- # === Argument
570
- # data :: [String / IO] packet data. If data is nil, write empty packet.
511
+ # @param data [String, IO, nil] packet data. If data is nil, write empty packet.
571
512
  def write(data)
572
513
  begin
573
514
  @socket.sync = false
@@ -584,6 +525,7 @@ class Mysql
584
525
  @socket.sync = true
585
526
  @socket.flush
586
527
  rescue Errno::EPIPE
528
+ @socket.close rescue nil
587
529
  raise ClientError::ServerGoneError, 'MySQL server has gone away'
588
530
  rescue Errno::ETIMEDOUT
589
531
  raise ClientError, "write timeout"
@@ -593,9 +535,9 @@ class Mysql
593
535
  def write_timeout(data, timeout)
594
536
  return @socket.write(data) if timeout.nil? || timeout == 0
595
537
  len = 0
596
- e = ::Time.now + timeout
538
+ e = Time.now + timeout
597
539
  while len < data.size
598
- now = ::Time.now
540
+ now = Time.now
599
541
  raise Errno::ETIMEDOUT if now > e
600
542
  l = @socket.write_nonblock(data[len..-1], exception: false)
601
543
  case l
@@ -611,17 +553,14 @@ class Mysql
611
553
  end
612
554
 
613
555
  # Read EOF packet
614
- # === Exception
615
- # [ProtocolError] packet is not EOF
556
+ # @raise [ProtocolError] packet is not EOF
616
557
  def read_eof_packet
617
558
  raise ProtocolError, "packet is not EOF" unless read.eof?
618
559
  end
619
560
 
620
561
  # Send simple command
621
- # === Argument
622
- # packet :: [String] packet data
623
- # === Return
624
- # [String] received data
562
+ # @param packet :: [String] packet data
563
+ # @return [String] received data
625
564
  def simple_command(packet)
626
565
  synchronize do
627
566
  reset
@@ -831,17 +770,15 @@ class Mysql
831
770
  end
832
771
 
833
772
  class StmtRawRecord
834
- # === Argument
835
- # pkt :: [Packet]
836
- # fields :: [Array of Fields]
837
- # encoding:: [Encoding]
773
+ # @param pkt [Packet]
774
+ # @param fields [Array of Fields]
775
+ # @param encoding [Encoding]
838
776
  def initialize(packet, fields, encoding)
839
777
  @packet, @fields, @encoding = packet, fields, encoding
840
778
  end
841
779
 
842
780
  # Parse statement result packet
843
- # === Return
844
- # [Array of Object] one record
781
+ # @return [Array<Object>] one record
845
782
  def parse_record_packet
846
783
  @packet.utiny # skip first byte
847
784
  null_bit_map = @packet.read((@fields.length+7+2)/8).unpack("b*").first
@@ -851,7 +788,7 @@ class Mysql
851
788
  else
852
789
  unsigned = f.flags & Field::UNSIGNED_FLAG != 0
853
790
  v = Protocol.net2value(@packet, f.type, unsigned)
854
- if v.is_a? Numeric or v.is_a? Mysql::Time
791
+ if v.nil? or v.is_a? Numeric or v.is_a? Time
855
792
  v
856
793
  elsif f.type == Field::TYPE_BIT or f.charsetnr == Charset::BINARY_CHARSET_NUMBER
857
794
  Charset.to_binary(v)