mysql-pr 2.9.11 → 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.
data/lib/mysql-pr.rb CHANGED
@@ -1,47 +1,49 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright (C) 2008-2012 TOMITA Masahiro
2
4
  # mailto:tommy@tmtm.org
3
5
 
4
6
  # MySQL connection class.
5
7
  # @example
6
- # my = Mysql.connect('hostname', 'user', 'password', 'dbname')
8
+ # my = MysqlPR.connect('hostname', 'user', 'password', 'dbname')
7
9
  # res = my.query 'select col1,col2 from tbl where id=123'
8
10
  # res.each do |c1, c2|
9
11
  # p c1, c2
10
12
  # end
11
13
  class MysqlPR
12
-
14
+ require "mysql-pr/version"
13
15
  require "mysql-pr/constants"
14
16
  require "mysql-pr/error"
15
17
  require "mysql-pr/charset"
16
18
  require "mysql-pr/protocol"
17
- require "mysql-pr/packet.rb"
18
-
19
- VERSION = 20910 # Version number of this library
20
- MYSQL_UNIX_PORT = "/tmp/mysql.sock" # UNIX domain socket filename
21
- MYSQL_TCP_PORT = 3306 # TCP socket port number
19
+ require "mysql-pr/packet"
20
+
21
+ MYSQL_UNIX_PORT = "/tmp/mysql.sock"
22
+ MYSQL_TCP_PORT = 3306
22
23
 
23
24
  # @return [MysqlPR::Charset] character set of MySQL connection
24
25
  attr_reader :charset
25
- # @private
26
+
27
+ # @return [MysqlPR::Protocol] protocol handler
26
28
  attr_reader :protocol
27
29
 
28
- # @return [Boolean] if true, {#query} return {MysqlPR::Result}.
30
+ # @return [Boolean] if true, {#query} returns {MysqlPR::Result}
29
31
  attr_accessor :query_with_result
30
32
 
31
33
  class << self
32
- # Make Mysql object without connecting.
33
- # @return [Mysql]
34
+ # Make MysqlPR object without connecting.
35
+ # @return [MysqlPR]
34
36
  def init
35
- my = self.allocate
36
- my.instance_eval{initialize}
37
+ my = allocate
38
+ my.send(:initialize)
37
39
  my
38
40
  end
39
41
 
40
- # Make Mysql object and connect to mysqld.
41
- # @param args same as arguments for {#connect}.
42
- # @return [Mysql]
42
+ # Make MysqlPR object and connect to mysqld.
43
+ # @param args same as arguments for {#connect}
44
+ # @return [MysqlPR]
43
45
  def new(*args)
44
- my = self.init
46
+ my = init
45
47
  my.connect(*args)
46
48
  end
47
49
 
@@ -52,7 +54,7 @@ class MysqlPR
52
54
  # @param [String] str
53
55
  # @return [String]
54
56
  def escape_string(str)
55
- str.gsub(/[\0\n\r\\\'\"\x1a]/) do |s|
57
+ str.gsub(/[\0\n\r\\'"\x1a]/) do |s|
56
58
  case s
57
59
  when "\0" then "\\0"
58
60
  when "\n" then "\\n"
@@ -64,15 +66,15 @@ class MysqlPR
64
66
  end
65
67
  alias quote escape_string
66
68
 
67
- # @return [String] client version. This value is dummy for MySQL/Ruby compatibility.
69
+ # @return [String] client version (dummy for MySQL/Ruby compatibility)
68
70
  def client_info
69
71
  "5.0.0"
70
72
  end
71
73
  alias get_client_info client_info
72
74
 
73
- # @return [Integer] client version. This value is dummy for MySQL/Ruby compatibility.
75
+ # @return [Integer] client version (dummy for MySQL/Ruby compatibility)
74
76
  def client_version
75
- 50000
77
+ 50_000
76
78
  end
77
79
  alias get_client_version client_version
78
80
  end
@@ -91,49 +93,50 @@ class MysqlPR
91
93
  @last_error = nil
92
94
  @result_exist = false
93
95
  @local_infile = nil
96
+ @ssl_options = nil
94
97
  end
95
98
 
96
99
  # Connect to mysqld.
97
- # @param [String / nil] host hostname mysqld running
98
- # @param [String / nil] user username to connect to mysqld
99
- # @param [String / nil] passwd password to connect to mysqld
100
- # @param [String / nil] db initial database name
101
- # @param [Integer / nil] port port number (used if host is not 'localhost' or nil)
102
- # @param [String / nil] socket socket file name (used if host is 'localhost' or nil)
103
- # @param [Integer / nil] flag connection flag. MysqlPR::CLIENT_* ORed
104
- # @return self
105
- def connect(host=nil, user=nil, passwd=nil, db=nil, port=nil, socket=nil, flag=0)
106
- if flag & CLIENT_COMPRESS != 0
107
- warn 'unsupported flag: CLIENT_COMPRESS'
100
+ # @param [String, nil] host hostname mysqld running
101
+ # @param [String, nil] user username to connect to mysqld
102
+ # @param [String, nil] passwd password to connect to mysqld
103
+ # @param [String, nil] db initial database name
104
+ # @param [Integer, nil] port port number (used if host is not 'localhost' or nil)
105
+ # @param [String, nil] socket socket file name (used if host is 'localhost' or nil)
106
+ # @param [Integer] flag connection flag. MysqlPR::CLIENT_* ORed
107
+ # @return [MysqlPR] self
108
+ def connect(host = nil, user = nil, passwd = nil, db = nil, port = nil, socket = nil, flag = 0)
109
+ if (flag & CLIENT_COMPRESS) != 0
110
+ warn "unsupported flag: CLIENT_COMPRESS"
108
111
  flag &= ~CLIENT_COMPRESS
109
112
  end
110
- @protocol = Protocol.new host, port, socket, @connect_timeout, @read_timeout, @write_timeout
111
- @protocol.authenticate user, passwd, db, (@local_infile ? CLIENT_LOCAL_FILES : 0) | flag, @charset
113
+ @protocol = Protocol.new(host, port, socket, @connect_timeout, @read_timeout, @write_timeout, @ssl_options)
114
+ @protocol.authenticate(user, passwd, db, (@local_infile ? CLIENT_LOCAL_FILES : 0) | flag, @charset)
112
115
  @charset ||= @protocol.charset
113
- @host_info = (host.nil? || host == "localhost") ? 'Localhost via UNIX socket' : "#{host} via TCP/IP"
114
- query @init_command if @init_command
115
- return self
116
+ @host_info = host.nil? || host == "localhost" ? "Localhost via UNIX socket" : "#{host} via TCP/IP"
117
+ query(@init_command) if @init_command
118
+ self
116
119
  end
117
120
  alias real_connect connect
118
121
 
119
122
  # Disconnect from mysql.
120
- # @return [Mysql] self
123
+ # @return [MysqlPR] self
121
124
  def close
122
125
  if @protocol
123
126
  @protocol.quit_command
124
127
  @protocol = nil
125
128
  end
126
- return self
129
+ self
127
130
  end
128
131
 
129
132
  # Disconnect from mysql without QUIT packet.
130
- # @return [Mysql] self
133
+ # @return [MysqlPR] self
131
134
  def close!
132
135
  if @protocol
133
136
  @protocol.close
134
137
  @protocol = nil
135
138
  end
136
- return self
139
+ self
137
140
  end
138
141
 
139
142
  # Set option for connection.
@@ -142,54 +145,79 @@ class MysqlPR
142
145
  # MysqlPR::INIT_COMMAND, MysqlPR::OPT_CONNECT_TIMEOUT, MysqlPR::OPT_READ_TIMEOUT,
143
146
  # MysqlPR::OPT_WRITE_TIMEOUT, MysqlPR::SET_CHARSET_NAME
144
147
  # @param [Integer] opt option
145
- # @param [Integer] value option value that is depend on opt
146
- # @return [Mysql] self
147
- def options(opt, value=nil)
148
+ # @param [Object] value option value that depends on opt
149
+ # @return [MysqlPR] self
150
+ def options(opt, value = nil)
148
151
  case opt
149
152
  when MysqlPR::INIT_COMMAND
150
153
  @init_command = value.to_s
151
- # when MysqlPR::OPT_COMPRESS
152
154
  when MysqlPR::OPT_CONNECT_TIMEOUT
153
155
  @connect_timeout = value
154
- # when MysqlPR::GUESS_CONNECTION
155
156
  when MysqlPR::OPT_LOCAL_INFILE
156
157
  @local_infile = value
157
- # when MysqlPR::OPT_NAMED_PIPE
158
- # when MysqlPR::OPT_PROTOCOL
159
158
  when MysqlPR::OPT_READ_TIMEOUT
160
159
  @read_timeout = value.to_i
161
- # when MysqlPR::OPT_RECONNECT
162
- # when MysqlPR::SET_CLIENT_IP
163
- # when MysqlPR::OPT_SSL_VERIFY_SERVER_CERT
164
- # when MysqlPR::OPT_USE_EMBEDDED_CONNECTION
165
- # when MysqlPR::OPT_USE_REMOTE_CONNECTION
166
160
  when MysqlPR::OPT_WRITE_TIMEOUT
167
161
  @write_timeout = value.to_i
168
- # when MysqlPR::READ_DEFAULT_FILE
169
- # when MysqlPR::READ_DEFAULT_GROUP
170
- # when MysqlPR::REPORT_DATA_TRUNCATION
171
- # when MysqlPR::SECURE_AUTH
172
- # when MysqlPR::SET_CHARSET_DIR
173
162
  when MysqlPR::SET_CHARSET_NAME
174
- @charset = Charset.by_name value.to_s
175
- # when MysqlPR::SHARED_MEMORY_BASE_NAME
163
+ @charset = Charset.by_name(value.to_s)
176
164
  else
177
165
  warn "option not implemented: #{opt}"
178
166
  end
179
167
  self
180
168
  end
181
169
 
170
+ # Configure SSL options for the connection.
171
+ # Must be called before connect.
172
+ # @param [String, nil] key path to client private key file
173
+ # @param [String, nil] cert path to client certificate file
174
+ # @param [String, nil] ca path to CA certificate file
175
+ # @param [String, nil] ca_path path to directory with CA certificates
176
+ # @param [String, nil] cipher list of allowed ciphers (not currently used)
177
+ # @return [MysqlPR] self
178
+ def ssl_set(key = nil, cert = nil, ca = nil, ca_path = nil, cipher = nil)
179
+ @ssl_options = {
180
+ key: key,
181
+ cert: cert,
182
+ ca: ca,
183
+ ca_path: ca_path,
184
+ cipher: cipher,
185
+ verify: ca || ca_path ? true : false
186
+ }
187
+ self
188
+ end
189
+
190
+ # Configure SSL with additional options.
191
+ # Must be called before connect.
192
+ # @param [Hash] options SSL configuration options
193
+ # @option options [String] :key path to client private key file
194
+ # @option options [String] :cert path to client certificate file
195
+ # @option options [String] :ca path to CA certificate file
196
+ # @option options [String] :ca_path path to directory with CA certificates
197
+ # @option options [Boolean] :verify whether to verify server certificate (default: true if ca provided)
198
+ # @option options [Boolean] :required raise error if server doesn't support SSL
199
+ # @option options [String] :hostname hostname for SNI
200
+ # @option options [Symbol] :min_version minimum TLS version (:TLS1_2, :TLS1_3, etc.)
201
+ # @return [Hash] the options hash
202
+ attr_writer :ssl_options
203
+
204
+ # Check if SSL is enabled for the current connection.
205
+ # @return [Boolean] true if SSL is enabled
206
+ def ssl_enabled?
207
+ @protocol&.ssl_enabled? || false
208
+ end
209
+
210
+ # Get the SSL cipher being used.
211
+ # @return [Array, nil] cipher info if SSL is enabled, nil otherwise
212
+ def ssl_cipher
213
+ @protocol&.ssl_cipher
214
+ end
215
+
182
216
  # Escape special character in MySQL.
183
- #
184
- # In Ruby 1.8, this is not safe for multibyte charset such as 'SJIS'.
185
- # You should use place-holder in prepared-statement.
186
217
  # @param [String] str
187
- # return [String]
218
+ # @return [String]
188
219
  def escape_string(str)
189
- if not defined? Encoding and @charset.unsafe
190
- raise ClientError, 'Mysql#escape_string is called for unsafe multibyte charset'
191
- end
192
- self.class.escape_string str
220
+ self.class.escape_string(str)
193
221
  end
194
222
  alias quote escape_string
195
223
 
@@ -206,15 +234,15 @@ class MysqlPR
206
234
  alias get_client_version client_version
207
235
 
208
236
  # Set charset of MySQL connection.
209
- # @param [String / MysqlPR::Charset] cs
237
+ # @param [String, MysqlPR::Charset] cs
238
+ # @return [MysqlPR::Charset] the charset
210
239
  def charset=(cs)
211
240
  charset = cs.is_a?(Charset) ? cs : Charset.by_name(cs)
212
241
  if @protocol
213
242
  @protocol.charset = charset
214
- query "SET NAMES #{charset.name}"
243
+ query("SET NAMES #{charset.name}")
215
244
  end
216
245
  @charset = charset
217
- cs
218
246
  end
219
247
 
220
248
  # @return [String] charset name
@@ -229,7 +257,7 @@ class MysqlPR
229
257
 
230
258
  # @return [String] last error message
231
259
  def error
232
- @last_error && @last_error.error
260
+ @last_error&.error
233
261
  end
234
262
 
235
263
  # @return [String] sqlstate for last error
@@ -243,9 +271,7 @@ class MysqlPR
243
271
  end
244
272
 
245
273
  # @return [String] connection type
246
- def host_info
247
- @host_info
248
- end
274
+ attr_reader :host_info
249
275
  alias get_host_info host_info
250
276
 
251
277
  # @return [Integer] protocol version
@@ -270,10 +296,10 @@ class MysqlPR
270
296
 
271
297
  # @return [String] information for last query
272
298
  def info
273
- @protocol && @protocol.message
299
+ @protocol&.message
274
300
  end
275
301
 
276
- # @return [Integer] number of affected records by insert/update/delete.
302
+ # @return [Integer] number of affected records by insert/update/delete
277
303
  def affected_rows
278
304
  @protocol ? @protocol.affected_rows : 0
279
305
  end
@@ -290,50 +316,48 @@ class MysqlPR
290
316
 
291
317
  # Kill query.
292
318
  # @param [Integer] pid thread id
293
- # @return [Mysql] self
319
+ # @return [MysqlPR] self
294
320
  def kill(pid)
295
321
  check_connection
296
- @protocol.kill_command pid
322
+ @protocol.kill_command(pid)
297
323
  self
298
324
  end
299
325
 
300
- # database list.
301
- # @param [String] db database name that may contain wild card.
326
+ # Database list.
327
+ # @param [String] db database name that may contain wild card
302
328
  # @return [Array<String>] database list
303
- def list_dbs(db=nil)
304
- db &&= db.gsub(/[\\\']/){"\\#{$&}"}
329
+ def list_dbs(db = nil)
330
+ db &&= db.gsub(/[\\']/) { "\\#{::Regexp.last_match(0)}" }
305
331
  query(db ? "show databases like '#{db}'" : "show databases").map(&:first)
306
332
  end
307
333
 
308
334
  # Execute query string.
309
- # @param [String] str Query.
310
- # @yield [MysqlPR::Result] evaluated per query.
311
- # @return [MysqlPR::Result] If {#query_with_result} is true and result set exist.
312
- # @return [nil] If {#query_with_result} is true and the query does not return result set.
313
- # @return [Mysql] If {#query_with_result} is false or block is specified
335
+ # @param [String] str Query
336
+ # @yield [MysqlPR::Result] evaluated per query
337
+ # @return [MysqlPR::Result] If {#query_with_result} is true and result set exist
338
+ # @return [nil] If {#query_with_result} is true and the query does not return result set
339
+ # @return [MysqlPR] If {#query_with_result} is false or block is specified
314
340
  # @example
315
341
  # my.query("select 1,NULL,'abc'").fetch # => [1, nil, "abc"]
316
342
  def query(str, &block)
317
343
  check_connection
318
344
  @fields = nil
319
345
  begin
320
- nfields = @protocol.query_command str
346
+ nfields = @protocol.query_command(str)
321
347
  if nfields
322
- @fields = @protocol.retr_fields nfields
348
+ @fields = @protocol.retr_fields(nfields)
323
349
  @result_exist = true
324
350
  end
325
351
  if block
326
- while true
327
- block.call store_result if @fields
352
+ loop do
353
+ block.call(store_result) if @fields
328
354
  break unless next_result
329
355
  end
330
356
  return self
331
357
  end
332
- if @query_with_result
333
- return @fields ? store_result : nil
334
- else
335
- return self
336
- end
358
+ return @fields ? store_result : nil if @query_with_result
359
+
360
+ self
337
361
  rescue ServerError => e
338
362
  @last_error = e
339
363
  @sqlstate = e.sqlstate
@@ -346,8 +370,9 @@ class MysqlPR
346
370
  # @return [MysqlPR::Result]
347
371
  def store_result
348
372
  check_connection
349
- raise ClientError, 'invalid usage' unless @result_exist
350
- res = Result.new @fields, @protocol
373
+ raise ClientError, "invalid usage" unless @result_exist
374
+
375
+ res = Result.new(@fields, @protocol)
351
376
  @result_exist = false
352
377
  res
353
378
  end
@@ -366,59 +391,59 @@ class MysqlPR
366
391
 
367
392
  # Set server option.
368
393
  # @param [Integer] opt {MysqlPR::OPTION_MULTI_STATEMENTS_ON} or {MysqlPR::OPTION_MULTI_STATEMENTS_OFF}
369
- # @return [Mysql] self
394
+ # @return [MysqlPR] self
370
395
  def set_server_option(opt)
371
396
  check_connection
372
- @protocol.set_option_command opt
397
+ @protocol.set_option_command(opt)
373
398
  self
374
399
  end
375
400
 
376
- # @return [Boolean] true if multiple queries are specified and unexecuted queries exists.
401
+ # @return [Boolean] true if multiple queries are specified and unexecuted queries exist
377
402
  def more_results
378
- @protocol.server_status & SERVER_MORE_RESULTS_EXISTS != 0
403
+ (@protocol.server_status & SERVER_MORE_RESULTS_EXISTS) != 0
379
404
  end
380
405
  alias more_results? more_results
381
406
 
382
- # execute next query if multiple queries are specified.
383
- # @return [Boolean] true if next query exists.
407
+ # Execute next query if multiple queries are specified.
408
+ # @return [Boolean] true if next query exists
384
409
  def next_result
385
410
  return false unless more_results
411
+
386
412
  check_connection
387
413
  @fields = nil
388
414
  nfields = @protocol.get_result
389
415
  if nfields
390
- @fields = @protocol.retr_fields nfields
416
+ @fields = @protocol.retr_fields(nfields)
391
417
  @result_exist = true
392
418
  end
393
- return true
419
+ true
394
420
  end
395
421
 
396
422
  # Parse prepared-statement.
397
423
  # @param [String] str query string
398
424
  # @return [MysqlPR::Stmt] Prepared-statement object
399
425
  def prepare(str)
400
- st = Stmt.new @protocol, @charset
401
- st.prepare str
426
+ st = Stmt.new(@protocol, @charset)
427
+ st.prepare(str)
402
428
  st
403
429
  end
404
430
 
405
- # @private
406
431
  # Make empty prepared-statement object.
407
- # @return [MysqlPR::Stmt] If block is not specified.
432
+ # @return [MysqlPR::Stmt]
408
433
  def stmt_init
409
- Stmt.new @protocol, @charset
434
+ Stmt.new(@protocol, @charset)
410
435
  end
411
436
 
412
437
  # Returns MysqlPR::Result object that is empty.
413
438
  # Use fetch_fields to get list of fields.
414
- # @param [String] table table name.
415
- # @param [String] field field name that may contain wild card.
439
+ # @param [String] table table name
440
+ # @param [String] field field name that may contain wild card
416
441
  # @return [MysqlPR::Result]
417
- def list_fields(table, field=nil)
442
+ def list_fields(table, field = nil)
418
443
  check_connection
419
444
  begin
420
- fields = @protocol.field_list_command table, field
421
- return Result.new fields
445
+ fields = @protocol.field_list_command(table, field)
446
+ Result.new(fields)
422
447
  rescue ServerError => e
423
448
  @last_error = e
424
449
  @sqlstate = e.sqlstate
@@ -434,16 +459,15 @@ class MysqlPR
434
459
  store_result
435
460
  end
436
461
 
437
- # @note for Ruby 1.8: This is not multi-byte safe. Don't use for multi-byte charset such as cp932.
438
- # @param [String] table database name that may contain wild card.
439
- # @return [Array<String>] list of table name.
440
- def list_tables(table=nil)
441
- q = table ? "show tables like '#{quote table}'" : "show tables"
462
+ # @param [String] table database name that may contain wild card
463
+ # @return [Array<String>] list of table name
464
+ def list_tables(table = nil)
465
+ q = table ? "show tables like '#{quote(table)}'" : "show tables"
442
466
  query(q).map(&:first)
443
467
  end
444
468
 
445
- # Check whether the connection is available.
446
- # @return [Mysql] self
469
+ # Check whether the connection is available.
470
+ # @return [MysqlPR] self
447
471
  def ping
448
472
  check_connection
449
473
  @protocol.ping_command
@@ -451,69 +475,68 @@ class MysqlPR
451
475
  end
452
476
 
453
477
  # Flush tables or caches.
454
- # @param [Integer] op operation. Use MysqlPR::REFRESH_* value.
455
- # @return [Mysql] self
478
+ # @param [Integer] op operation. Use MysqlPR::REFRESH_* value
479
+ # @return [MysqlPR] self
456
480
  def refresh(op)
457
481
  check_connection
458
- @protocol.refresh_command op
482
+ @protocol.refresh_command(op)
459
483
  self
460
484
  end
461
485
 
462
486
  # Reload grant tables.
463
- # @return [Mysql] self
487
+ # @return [MysqlPR] self
464
488
  def reload
465
- refresh MysqlPR::REFRESH_GRANT
489
+ refresh(MysqlPR::REFRESH_GRANT)
466
490
  end
467
491
 
468
492
  # Select default database
469
- # @return [Mysql] self
493
+ # @return [MysqlPR] self
470
494
  def select_db(db)
471
- query "use #{db}"
495
+ query("use #{db}")
472
496
  self
473
497
  end
474
498
 
475
- # shutdown server.
476
- # @return [Mysql] self
477
- def shutdown(level=0)
499
+ # Shutdown server.
500
+ # @return [MysqlPR] self
501
+ def shutdown(level = 0)
478
502
  check_connection
479
- @protocol.shutdown_command level
503
+ @protocol.shutdown_command(level)
480
504
  self
481
505
  end
482
506
 
483
507
  # @return [String] statistics message
484
508
  def stat
485
- @protocol ? @protocol.statistics_command : 'MySQL server has gone away'
509
+ @protocol ? @protocol.statistics_command : "MySQL server has gone away"
486
510
  end
487
511
 
488
512
  # Commit transaction
489
- # @return [Mysql] self
513
+ # @return [MysqlPR] self
490
514
  def commit
491
- query 'commit'
515
+ query("commit")
492
516
  self
493
517
  end
494
518
 
495
519
  # Rollback transaction
496
- # @return [Mysql] self
520
+ # @return [MysqlPR] self
497
521
  def rollback
498
- query 'rollback'
522
+ query("rollback")
499
523
  self
500
524
  end
501
525
 
502
526
  # Set autocommit mode
503
527
  # @param [Boolean] flag
504
- # @return [Mysql] self
528
+ # @return [MysqlPR] self
505
529
  def autocommit(flag)
506
- query "set autocommit=#{flag ? 1 : 0}"
530
+ query("set autocommit=#{flag ? 1 : 0}")
507
531
  self
508
532
  end
509
533
 
510
534
  private
511
535
 
512
536
  def check_connection
513
- raise ClientError::ServerGoneError, 'The MySQL server has gone away' unless @protocol
537
+ raise ClientError::ServerGoneError, "The MySQL server has gone away" unless @protocol
514
538
  end
515
539
 
516
- # @!visibility public
517
540
  # Field class
518
541
  class Field
519
542
  # @return [String] database name
@@ -536,123 +559,130 @@ class MysqlPR
536
559
  attr_reader :flags
537
560
  # @return [Integer] number of decimals
538
561
  attr_reader :decimals
539
- # @return [String] defualt value
562
+ # @return [String] default value
540
563
  attr_reader :default
541
- alias :def :default
542
564
 
543
- # @private
565
+ alias def default
566
+
544
567
  attr_accessor :result
568
+ attr_writer :max_length
545
569
 
546
- # @attr [Protocol::FieldPacket] packet
570
+ # @param [Protocol::FieldPacket] packet
547
571
  def initialize(packet)
548
- @db, @table, @org_table, @name, @org_name, @charsetnr, @length, @type, @flags, @decimals, @default =
549
- packet.db, packet.table, packet.org_table, packet.name, packet.org_name, packet.charsetnr, packet.length, packet.type, packet.flags, packet.decimals, packet.default
550
- @flags |= NUM_FLAG if is_num_type?
572
+ @db = packet.db
573
+ @table = packet.table
574
+ @org_table = packet.org_table
575
+ @name = packet.name
576
+ @org_name = packet.org_name
577
+ @charsetnr = packet.charsetnr
578
+ @length = packet.length
579
+ @type = packet.type
580
+ @flags = packet.flags
581
+ @decimals = packet.decimals
582
+ @default = packet.default
583
+ @flags |= NUM_FLAG if num_type?
551
584
  @max_length = nil
585
+ @result = nil
552
586
  end
553
587
 
554
588
  # @return [Hash] field information
555
- def hash
589
+ def to_hash
556
590
  {
557
- "name" => @name,
558
- "table" => @table,
559
- "def" => @default,
560
- "type" => @type,
561
- "length" => @length,
591
+ "name" => @name,
592
+ "table" => @table,
593
+ "def" => @default,
594
+ "type" => @type,
595
+ "length" => @length,
562
596
  "max_length" => max_length,
563
- "flags" => @flags,
564
- "decimals" => @decimals
597
+ "flags" => @flags,
598
+ "decimals" => @decimals
565
599
  }
566
600
  end
601
+ alias hash to_hash
567
602
 
568
- # @private
569
603
  def inspect
570
604
  "#<MysqlPR::Field:#{@name}>"
571
605
  end
572
606
 
573
- # @return [Boolean] true if numeric field.
607
+ # @return [Boolean] true if numeric field
574
608
  def is_num?
575
- @flags & NUM_FLAG != 0
609
+ (@flags & NUM_FLAG) != 0
576
610
  end
577
611
 
578
- # @return [Boolean] true if not null field.
612
+ # @return [Boolean] true if not null field
579
613
  def is_not_null?
580
- @flags & NOT_NULL_FLAG != 0
614
+ (@flags & NOT_NULL_FLAG) != 0
581
615
  end
582
616
 
583
- # @return [Boolean] true if primary key field.
617
+ # @return [Boolean] true if primary key field
584
618
  def is_pri_key?
585
- @flags & PRI_KEY_FLAG != 0
619
+ (@flags & PRI_KEY_FLAG) != 0
586
620
  end
587
621
 
588
622
  # @return [Integer] maximum width of the field for the result set
589
623
  def max_length
590
624
  return @max_length if @max_length
625
+
591
626
  @max_length = 0
592
- @result.calculate_field_max_length if @result
627
+ @result&.calculate_field_max_length
593
628
  @max_length
594
629
  end
595
630
 
596
- attr_writer :max_length
597
-
598
631
  private
599
632
 
600
- def is_num_type?
601
- [TYPE_DECIMAL, TYPE_TINY, TYPE_SHORT, TYPE_LONG, TYPE_FLOAT, TYPE_DOUBLE, TYPE_LONGLONG, TYPE_INT24].include?(@type) || (@type == TYPE_TIMESTAMP && (@length == 14 || @length == 8))
633
+ def num_type?
634
+ [TYPE_DECIMAL, TYPE_TINY, TYPE_SHORT, TYPE_LONG, TYPE_FLOAT,
635
+ TYPE_DOUBLE, TYPE_LONGLONG, TYPE_INT24].include?(@type) ||
636
+ (@type == TYPE_TIMESTAMP && (@length == 14 || @length == 8))
602
637
  end
603
-
604
638
  end
605
639
 
606
- # @!visibility public
607
- # Result set
640
+ # Result set base class
608
641
  class ResultBase
609
642
  include Enumerable
610
643
 
611
644
  # @return [Array<MysqlPR::Field>] field list
612
645
  attr_reader :fields
613
646
 
614
- # @param [Array of MysqlPR::Field] fields
647
+ # @param [Array<MysqlPR::Field>] fields
615
648
  def initialize(fields)
616
649
  @fields = fields
617
- @field_index = 0 # index of field
618
- @records = [] # all records
619
- @index = 0 # index of record
650
+ @field_index = 0
651
+ @records = []
652
+ @index = 0
620
653
  @fieldname_with_table = nil
621
654
  @fetched_record = nil
622
655
  end
623
656
 
624
- # ignore
625
657
  # @return [void]
626
- def free
627
- end
658
+ def free; end
628
659
 
629
- # @return [Integer] number of record
660
+ # @return [Integer] number of records
630
661
  def size
631
662
  @records.size
632
663
  end
633
664
  alias num_rows size
634
665
 
635
- # @return [Array] current record data
666
+ # @return [Array, nil] current record data
636
667
  def fetch
637
668
  @fetched_record = nil
638
669
  return nil if @index >= @records.size
639
- @records[@index] = @records[@index].to_a unless @records[@index].is_a? Array
670
+
671
+ @records[@index] = @records[@index].to_a unless @records[@index].is_a?(Array)
640
672
  @fetched_record = @records[@index]
641
673
  @index += 1
642
- return @fetched_record
674
+ @fetched_record
643
675
  end
644
676
  alias fetch_row fetch
645
677
 
646
678
  # Return data of current record as Hash.
647
- # The hash key is field name.
648
- # @param [Boolean] with_table if true, hash key is "table_name.field_name".
649
- # @return [Hash] current record data
650
- def fetch_hash(with_table=nil)
679
+ # @param [Boolean] with_table if true, hash key is "table_name.field_name"
680
+ # @return [Hash, nil] current record data
681
+ def fetch_hash(with_table = nil)
651
682
  row = fetch
652
683
  return nil unless row
653
- if with_table and @fieldname_with_table.nil?
654
- @fieldname_with_table = @fields.map{|f| [f.table, f.name].join(".")}
655
- end
684
+
685
+ @fieldname_with_table = @fields.map { |f| "#{f.table}.#{f.name}" } if with_table && @fieldname_with_table.nil?
656
686
  ret = {}
657
687
  @fields.each_index do |i|
658
688
  fname = with_table ? @fieldname_with_table[i] : @fields[i].name
@@ -663,30 +693,32 @@ class MysqlPR
663
693
 
664
694
  # Iterate block with record.
665
695
  # @yield [Array] record data
666
- # @return [self] self. If block is not specified, this returns Enumerator.
696
+ # @return [self, Enumerator]
667
697
  def each(&block)
668
698
  return enum_for(:each) unless block
669
- while rec = fetch
670
- block.call rec
699
+
700
+ while (rec = fetch)
701
+ block.call(rec)
671
702
  end
672
703
  self
673
704
  end
674
705
 
675
706
  # Iterate block with record as Hash.
676
- # @param [Boolean] with_table if true, hash key is "table_name.field_name".
707
+ # @param [Boolean] with_table if true, hash key is "table_name.field_name"
677
708
  # @yield [Hash] record data
678
- # @return [self] self. If block is not specified, this returns Enumerator.
679
- def each_hash(with_table=nil, &block)
709
+ # @return [self, Enumerator]
710
+ def each_hash(with_table = nil, &block)
680
711
  return enum_for(:each_hash, with_table) unless block
681
- while rec = fetch_hash(with_table)
682
- block.call rec
712
+
713
+ while (rec = fetch_hash(with_table))
714
+ block.call(rec)
683
715
  end
684
716
  self
685
717
  end
686
718
 
687
719
  # Set record position
688
720
  # @param [Integer] n record index
689
- # @return [self] self
721
+ # @return [self]
690
722
  def data_seek(n)
691
723
  @index = n
692
724
  self
@@ -707,27 +739,25 @@ class MysqlPR
707
739
  end
708
740
  end
709
741
 
710
- # @!visibility public
711
742
  # Result set for simple query
712
743
  class Result < ResultBase
713
- # @private
714
744
  # @param [Array<MysqlPR::Field>] fields
715
- # @param [MysqlPR::Protocol] protocol
716
- def initialize(fields, protocol=nil)
717
- super fields
745
+ # @param [MysqlPR::Protocol, nil] protocol
746
+ def initialize(fields, protocol = nil)
747
+ super(fields)
718
748
  return unless protocol
719
- @records = protocol.retr_all_records fields.size
720
- fields.each{|f| f.result = self} # for calculating max_field
749
+
750
+ @records = protocol.retr_all_records(fields.size)
751
+ fields.each { |f| f.result = self }
721
752
  end
722
753
 
723
- # @private
724
- # calculate max_length of all fields
754
+ # Calculate max_length of all fields
725
755
  def calculate_field_max_length
726
756
  max_length = Array.new(@fields.size, 0)
727
757
  @records.each_with_index do |rec, i|
728
- rec = @records[i] = rec.to_a if rec.is_a? RawRecord
729
- max_length.each_index do |i|
730
- max_length[i] = rec[i].length if rec[i] && rec[i].length > max_length[i]
758
+ rec = @records[i] = rec.to_a if rec.is_a?(RawRecord)
759
+ max_length.each_index do |j|
760
+ max_length[j] = rec[j].length if rec[j] && rec[j].length > max_length[j]
731
761
  end
732
762
  end
733
763
  max_length.each_with_index do |len, i|
@@ -735,9 +765,10 @@ class MysqlPR
735
765
  end
736
766
  end
737
767
 
738
- # @return [MysqlPR::Field] current field
768
+ # @return [MysqlPR::Field, nil] current field
739
769
  def fetch_field
740
770
  return nil if @field_index >= @fields.length
771
+
741
772
  ret = @fields[@field_index]
742
773
  @field_index += 1
743
774
  ret
@@ -761,7 +792,8 @@ class MysqlPR
761
792
  # @param [Integer] n field index
762
793
  # @return [MysqlPR::Field] field
763
794
  def fetch_field_direct(n)
764
- raise ClientError, "invalid argument: #{n}" if n < 0 or n >= @fields.length
795
+ raise ClientError, "invalid argument: #{n}" if n.negative? || n >= @fields.length
796
+
765
797
  @fields[n]
766
798
  end
767
799
 
@@ -770,10 +802,11 @@ class MysqlPR
770
802
  @fields
771
803
  end
772
804
 
773
- # @return [Array<Integer>] length of each fields
805
+ # @return [Array<Integer>, nil] length of each field
774
806
  def fetch_lengths
775
807
  return nil unless @fetched_record
776
- @fetched_record.map{|c|c.nil? ? 0 : c.length}
808
+
809
+ @fetched_record.map { |c| c.nil? ? 0 : c.length }
777
810
  end
778
811
 
779
812
  # @return [Integer] number of fields
@@ -782,20 +815,17 @@ class MysqlPR
782
815
  end
783
816
  end
784
817
 
785
- # @!visibility private
786
818
  # Result set for prepared statement
787
819
  class StatementResult < ResultBase
788
- # @private
789
820
  # @param [Array<MysqlPR::Field>] fields
790
821
  # @param [MysqlPR::Protocol] protocol
791
822
  # @param [MysqlPR::Charset] charset
792
823
  def initialize(fields, protocol, charset)
793
- super fields
794
- @records = protocol.stmt_retr_all_records @fields, charset
824
+ super(fields)
825
+ @records = protocol.stmt_retr_all_records(@fields, charset)
795
826
  end
796
827
  end
797
828
 
798
- # @!visibility public
799
829
  # Prepared statement
800
830
  # @!attribute [r] affected_rows
801
831
  # @return [Integer]
@@ -814,33 +844,35 @@ class MysqlPR
814
844
  class Stmt
815
845
  include Enumerable
816
846
 
817
- attr_reader :affected_rows, :insert_id, :server_status, :warning_count
818
- attr_reader :param_count, :fields, :sqlstate
847
+ attr_reader :affected_rows, :insert_id, :server_status, :warning_count, :param_count, :fields, :sqlstate
819
848
 
820
- # @private
821
849
  def self.finalizer(protocol, statement_id)
822
850
  proc do
823
- protocol.gc_stmt statement_id
851
+ protocol.gc_stmt(statement_id)
824
852
  end
825
853
  end
826
854
 
827
- # @private
828
855
  # @param [MysqlPR::Protocol] protocol
829
856
  # @param [MysqlPR::Charset] charset
830
857
  def initialize(protocol, charset)
831
858
  @protocol = protocol
832
859
  @charset = charset
833
860
  @statement_id = nil
834
- @affected_rows = @insert_id = @server_status = @warning_count = 0
861
+ @affected_rows = 0
862
+ @insert_id = 0
863
+ @server_status = 0
864
+ @warning_count = 0
835
865
  @sqlstate = "00000"
836
866
  @param_count = nil
837
867
  @bind_result = nil
868
+ @result = nil
869
+ @fields = nil
870
+ @last_error = nil
838
871
  end
839
872
 
840
- # @private
841
- # parse prepared-statement and return {MysqlPR::Stmt} object
873
+ # Parse prepared-statement and return {MysqlPR::Stmt} object
842
874
  # @param [String] str query string
843
- # @return self
875
+ # @return [MysqlPR::Stmt] self
844
876
  def prepare(str)
845
877
  close
846
878
  begin
@@ -861,18 +893,22 @@ class MysqlPR
861
893
  def execute(*values)
862
894
  raise ClientError, "not prepared" unless @param_count
863
895
  raise ClientError, "parameter count mismatch" if values.length != @param_count
864
- values = values.map{|v| @charset.convert v}
896
+
897
+ values = values.map { |v| @charset.convert(v) }
865
898
  begin
866
899
  @sqlstate = "00000"
867
- nfields = @protocol.stmt_execute_command @statement_id, values
900
+ nfields = @protocol.stmt_execute_command(@statement_id, values)
868
901
  if nfields
869
- @fields = @protocol.retr_fields nfields
870
- @result = StatementResult.new @fields, @protocol, @charset
902
+ @fields = @protocol.retr_fields(nfields)
903
+ @result = StatementResult.new(@fields, @protocol, @charset)
871
904
  else
872
- @affected_rows, @insert_id, @server_status, @warning_count, @info =
873
- @protocol.affected_rows, @protocol.insert_id, @protocol.server_status, @protocol.warning_count, @protocol.message
905
+ @affected_rows = @protocol.affected_rows
906
+ @insert_id = @protocol.insert_id
907
+ @server_status = @protocol.server_status
908
+ @warning_count = @protocol.warning_count
909
+ @info = @protocol.message
874
910
  end
875
- return self
911
+ self
876
912
  rescue ServerError => e
877
913
  @last_error = e
878
914
  @sqlstate = e.sqlstate
@@ -884,48 +920,26 @@ class MysqlPR
884
920
  # @return [void]
885
921
  def close
886
922
  ObjectSpace.undefine_finalizer(self)
887
- @protocol.stmt_close_command @statement_id if @statement_id
923
+ @protocol.stmt_close_command(@statement_id) if @statement_id
888
924
  @statement_id = nil
889
925
  end
890
926
 
891
- # @return [Array] current record data
927
+ # @return [Array, nil] current record data
892
928
  def fetch
893
929
  row = @result.fetch
894
930
  return row unless @bind_result
931
+
895
932
  row.zip(@bind_result).map do |col, type|
896
933
  if col.nil?
897
934
  nil
898
- elsif [Numeric, Integer, Fixnum].include? type
935
+ elsif [Numeric, Integer].include?(type)
899
936
  col.to_i
900
937
  elsif type == String
901
938
  col.to_s
902
939
  elsif type == Float && !col.is_a?(Float)
903
940
  col.to_i.to_f
904
941
  elsif type == MysqlPR::Time && !col.is_a?(MysqlPR::Time)
905
- if col.to_s =~ /\A\d+\z/
906
- i = col.to_s.to_i
907
- if i < 100000000
908
- y = i/10000
909
- m = i/100%100
910
- d = i%100
911
- h, mm, s = 0
912
- else
913
- y = i/10000000000
914
- m = i/100000000%100
915
- d = i/1000000%100
916
- h = i/10000%100
917
- mm= i/100%100
918
- s = i%100
919
- end
920
- if y < 70
921
- y += 2000
922
- elsif y < 100
923
- y += 1900
924
- end
925
- MysqlPR::Time.new(y, m, d, h, mm, s)
926
- else
927
- MysqlPR::Time.new
928
- end
942
+ parse_time_value(col)
929
943
  else
930
944
  col
931
945
  end
@@ -933,22 +947,24 @@ class MysqlPR
933
947
  end
934
948
 
935
949
  # Return data of current record as Hash.
936
- # The hash key is field name.
937
- # @param [Boolean] with_table if true, hash key is "table_name.field_name".
938
- # @return [Hash] record data
939
- def fetch_hash(with_table=nil)
940
- @result.fetch_hash with_table
950
+ # @param [Boolean] with_table if true, hash key is "table_name.field_name"
951
+ # @return [Hash, nil] record data
952
+ def fetch_hash(with_table = nil)
953
+ @result.fetch_hash(with_table)
941
954
  end
942
955
 
943
956
  # Set retrieve type of value
944
- # @param [Numeric / Fixnum / Integer / Float / String / MysqlPR::Time / nil] args value type
957
+ # @param [Class] args value type (Numeric, Integer, Float, String, MysqlPR::Time, or nil)
945
958
  # @return [MysqlPR::Stmt] self
946
959
  def bind_result(*args)
947
960
  if @fields.length != args.length
948
961
  raise ClientError, "bind_result: result value count(#{@fields.length}) != number of argument(#{args.length})"
949
962
  end
963
+
950
964
  args.each do |a|
951
- raise TypeError unless [Numeric, Fixnum, Integer, Float, String, MysqlPR::Time, nil].include? a
965
+ unless [Numeric, Integer, Float, String, MysqlPR::Time, nil].include?(a)
966
+ raise TypeError, "unsupported type: #{a}"
967
+ end
952
968
  end
953
969
  @bind_result = args
954
970
  self
@@ -956,30 +972,30 @@ class MysqlPR
956
972
 
957
973
  # Iterate block with record.
958
974
  # @yield [Array] record data
959
- # @return [MysqlPR::Stmt] self
960
- # @return [Enumerator] If block is not specified
975
+ # @return [MysqlPR::Stmt, Enumerator] self or Enumerator if block not specified
961
976
  def each(&block)
962
977
  return enum_for(:each) unless block
963
- while rec = fetch
964
- block.call rec
978
+
979
+ while (rec = fetch)
980
+ block.call(rec)
965
981
  end
966
982
  self
967
983
  end
968
984
 
969
985
  # Iterate block with record as Hash.
970
- # @param [Boolean] with_table if true, hash key is "table_name.field_name".
986
+ # @param [Boolean] with_table if true, hash key is "table_name.field_name"
971
987
  # @yield [Hash] record data
972
- # @return [MysqlPR::Stmt] self
973
- # @return [Enumerator] If block is not specified
974
- def each_hash(with_table=nil, &block)
988
+ # @return [MysqlPR::Stmt, Enumerator] self or Enumerator if block not specified
989
+ def each_hash(with_table = nil, &block)
975
990
  return enum_for(:each_hash, with_table) unless block
976
- while rec = fetch_hash(with_table)
977
- block.call rec
991
+
992
+ while (rec = fetch_hash(with_table))
993
+ block.call(rec)
978
994
  end
979
995
  self
980
996
  end
981
997
 
982
- # @return [Integer] number of record
998
+ # @return [Integer] number of records
983
999
  def size
984
1000
  @result.size
985
1001
  end
@@ -1009,21 +1025,44 @@ class MysqlPR
1009
1025
  @fields.length
1010
1026
  end
1011
1027
 
1012
- # ignore
1013
1028
  # @return [void]
1014
- def free_result
1015
- end
1029
+ def free_result; end
1016
1030
 
1017
1031
  # Returns MysqlPR::Result object that is empty.
1018
1032
  # Use fetch_fields to get list of fields.
1019
- # @return [MysqlPR::Result]
1033
+ # @return [MysqlPR::Result, nil]
1020
1034
  def result_metadata
1021
1035
  return nil if @fields.empty?
1022
- Result.new @fields
1036
+
1037
+ Result.new(@fields)
1038
+ end
1039
+
1040
+ private
1041
+
1042
+ def parse_time_value(col)
1043
+ return MysqlPR::Time.new unless col.to_s =~ /\A\d+\z/
1044
+
1045
+ i = col.to_s.to_i
1046
+ if i < 100_000_000
1047
+ y = i / 10_000
1048
+ m = (i / 100) % 100
1049
+ d = i % 100
1050
+ h = mm = s = 0
1051
+ else
1052
+ y = i / 10_000_000_000
1053
+ m = (i / 100_000_000) % 100
1054
+ d = (i / 1_000_000) % 100
1055
+ h = (i / 10_000) % 100
1056
+ mm = (i / 100) % 100
1057
+ s = i % 100
1058
+ end
1059
+ y += 2000 if y < 70
1060
+ y += 1900 if y >= 70 && y < 100
1061
+ MysqlPR::Time.new(y, m, d, h, mm, s)
1023
1062
  end
1024
1063
  end
1025
1064
 
1026
- # @!visibility public
1065
+ # MySQL Time class
1027
1066
  # @!attribute [rw] year
1028
1067
  # @return [Integer]
1029
1068
  # @!attribute [rw] month
@@ -1041,6 +1080,12 @@ class MysqlPR
1041
1080
  # @!attribute [rw] second_part
1042
1081
  # @return [Integer]
1043
1082
  class Time
1083
+ attr_accessor :year, :month, :day, :hour, :minute, :second, :neg, :second_part
1084
+
1085
+ alias mon month
1086
+ alias min minute
1087
+ alias sec second
1088
+
1044
1089
  # @param [Integer] year
1045
1090
  # @param [Integer] month
1046
1091
  # @param [Integer] day
@@ -1049,25 +1094,25 @@ class MysqlPR
1049
1094
  # @param [Integer] second
1050
1095
  # @param [Boolean] neg negative flag
1051
1096
  # @param [Integer] second_part
1052
- def initialize(year=0, month=0, day=0, hour=0, minute=0, second=0, neg=false, second_part=0)
1097
+ def initialize(year = 0, month = 0, day = 0, hour = 0, minute = 0, second = 0, neg = false, second_part = 0)
1053
1098
  @date_flag = !(hour && minute && second)
1054
- @year, @month, @day, @hour, @minute, @second, @neg, @second_part =
1055
- year.to_i, month.to_i, day.to_i, hour.to_i, minute.to_i, second.to_i, neg, second_part.to_i
1099
+ @year = year.to_i
1100
+ @month = month.to_i
1101
+ @day = day.to_i
1102
+ @hour = hour.to_i
1103
+ @minute = minute.to_i
1104
+ @second = second.to_i
1105
+ @neg = neg
1106
+ @second_part = second_part.to_i
1056
1107
  end
1057
- attr_accessor :year, :month, :day, :hour, :minute, :second, :neg, :second_part
1058
- alias mon month
1059
- alias min minute
1060
- alias sec second
1061
1108
 
1062
- # @private
1063
1109
  def ==(other)
1064
1110
  other.is_a?(MysqlPR::Time) &&
1065
1111
  @year == other.year && @month == other.month && @day == other.day &&
1066
1112
  @hour == other.hour && @minute == other.minute && @second == other.second &&
1067
- @neg == neg && @second_part == other.second_part
1113
+ @neg == other.neg && @second_part == other.second_part
1068
1114
  end
1069
1115
 
1070
- # @private
1071
1116
  def eql?(other)
1072
1117
  self == other
1073
1118
  end
@@ -1075,25 +1120,22 @@ class MysqlPR
1075
1120
  # @return [String] "yyyy-mm-dd HH:MM:SS"
1076
1121
  def to_s
1077
1122
  if @date_flag
1078
- sprintf "%04d-%02d-%02d", year, mon, day
1079
- elsif year == 0 and mon == 0 and day == 0
1123
+ format("%04d-%02d-%02d", year, mon, day)
1124
+ elsif year.zero? && mon.zero? && day.zero?
1080
1125
  h = neg ? hour * -1 : hour
1081
- sprintf "%02d:%02d:%02d", h, min, sec
1126
+ format("%02d:%02d:%02d", h, min, sec)
1082
1127
  else
1083
- sprintf "%04d-%02d-%02d %02d:%02d:%02d", year, mon, day, hour, min, sec
1128
+ format("%04d-%02d-%02d %02d:%02d:%02d", year, mon, day, hour, min, sec)
1084
1129
  end
1085
1130
  end
1086
1131
 
1087
1132
  # @return [Integer] yyyymmddHHMMSS
1088
1133
  def to_i
1089
- sprintf("%04d%02d%02d%02d%02d%02d", year, mon, day, hour, min, sec).to_i
1134
+ format("%04d%02d%02d%02d%02d%02d", year, mon, day, hour, min, sec).to_i
1090
1135
  end
1091
1136
 
1092
- # @private
1093
1137
  def inspect
1094
- sprintf "#<#{self.class.name}:%04d-%02d-%02d %02d:%02d:%02d>", year, mon, day, hour, min, sec
1138
+ format("#<#{self.class.name}:%04d-%02d-%02d %02d:%02d:%02d>", year, mon, day, hour, min, sec)
1095
1139
  end
1096
-
1097
1140
  end
1098
-
1099
1141
  end