ruby-mysql 2.11.1 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/lib/mysql.rb CHANGED
@@ -2,6 +2,8 @@
2
2
  # Copyright (C) 2008 TOMITA Masahiro
3
3
  # mailto:tommy@tmtm.org
4
4
 
5
+ require 'uri'
6
+
5
7
  # MySQL connection class.
6
8
  # @example
7
9
  # my = Mysql.connect('hostname', 'user', 'password', 'dbname')
@@ -11,44 +13,76 @@
11
13
  # end
12
14
  class Mysql
13
15
 
14
- require "mysql/constants"
15
- require "mysql/error"
16
- require "mysql/charset"
17
- require "mysql/protocol"
18
- require "mysql/packet.rb"
16
+ require_relative "mysql/constants"
17
+ require_relative "mysql/error"
18
+ require_relative "mysql/charset"
19
+ require_relative "mysql/protocol"
20
+ require_relative "mysql/packet.rb"
19
21
 
20
- VERSION = 21101 # Version number of this library
22
+ VERSION = '3.0.0' # Version number of this library
21
23
  MYSQL_UNIX_PORT = "/tmp/mysql.sock" # UNIX domain socket filename
22
24
  MYSQL_TCP_PORT = 3306 # TCP socket port number
23
25
 
24
- # @return [Mysql::Charset] character set of MySQL connection
25
- attr_reader :charset
26
+ # @!attribute [rw] host
27
+ # @return [String, nil]
28
+ # @!attribute [rw] username
29
+ # @return [String, nil]
30
+ # @!attribute [rw] password
31
+ # @return [String, nil]
32
+ # @!attribute [rw] database
33
+ # @return [String, nil]
34
+ # @!attribute [rw] port
35
+ # @return [Integer, String, nil]
36
+ # @!attribute [rw] socket
37
+ # @return [String, nil] socket filename
38
+ # @!attribute [rw] flags
39
+ # @return [Integer, nil]
40
+ # @!attribute [rw] connect_timeout
41
+ # @return [Numeric, nil]
42
+ # @!attribute [rw] read_timeout
43
+ # @return [Numeric, nil]
44
+ # @!attribute [rw] write_timeout
45
+ # @return [Numeric, nil]
46
+ # @!attribute [rw] init_command
47
+ # @return [String, nil]
48
+ # @!attribute [rw] local_infile
49
+ # @return [Boolean]
50
+ # @!attribute [rw] load_data_local_dir
51
+ # @return [String, nil]
52
+ # @!attribute [rw] ssl_mode
53
+ # @return [String, Integer] 1 or "disabled" / 2 or "preferred" / 3 or "required"
54
+ # @!attribute [rw] get_server_public_key
55
+ # @return [Boolean]
56
+ DEFAULT_OPTS = {
57
+ host: nil,
58
+ username: nil,
59
+ password: nil,
60
+ database: nil,
61
+ port: nil,
62
+ socket: nil,
63
+ flags: 0,
64
+ charset: nil,
65
+ connect_timeout: nil,
66
+ read_timeout: nil,
67
+ write_timeout: nil,
68
+ init_command: nil,
69
+ local_infile: nil,
70
+ load_data_local_dir: nil,
71
+ ssl_mode: SSL_MODE_PREFERRED,
72
+ get_server_public_key: false,
73
+ }.freeze
74
+
26
75
  # @private
27
76
  attr_reader :protocol
28
77
 
29
- # @return [Boolean] if true, {#query} return {Mysql::Result}.
30
- attr_accessor :query_with_result
31
-
32
78
  class << self
33
- # Make Mysql object without connecting.
34
- # @return [Mysql]
35
- def init
36
- my = self.allocate
37
- my.instance_eval{initialize}
38
- my
39
- end
40
-
41
79
  # Make Mysql object and connect to mysqld.
42
- # @param args same as arguments for {#connect}.
80
+ # parameter is same as arguments for {#initialize}.
43
81
  # @return [Mysql]
44
- def new(*args)
45
- my = self.init
46
- my.connect(*args)
82
+ def connect(*args, **opts)
83
+ self.new(*args, **opts).connect
47
84
  end
48
85
 
49
- alias real_connect new
50
- alias connect new
51
-
52
86
  # Escape special character in string.
53
87
  # @param [String] str
54
88
  # @return [String]
@@ -64,62 +98,116 @@ class Mysql
64
98
  end
65
99
  end
66
100
  alias quote escape_string
67
-
68
- # @return [String] client version. This value is dummy for MySQL/Ruby compatibility.
69
- def client_info
70
- "5.0.0"
71
- end
72
- alias get_client_info client_info
73
-
74
- # @return [Integer] client version. This value is dummy for MySQL/Ruby compatibility.
75
- def client_version
76
- 50000
77
- end
78
- alias get_client_version client_version
79
101
  end
80
102
 
81
- def initialize
103
+ # @overload initialize(uri, **opts)
104
+ # @param uri [String, URI] "mysql://username:password@host:port/database?param=value&..." / "mysql://username:password@%2Ftmp%2Fmysql.sock/database" / "mysql://username:password@/database?socket=/tmp/mysql.sock"
105
+ # @param opts [Hash] options
106
+ # @overload initialize(host, username, password, database, port, socket, flags, **opts)
107
+ # @param host [String] hostname mysqld running
108
+ # @param username [String] username to connect to mysqld
109
+ # @param password [String] password to connect to mysqld
110
+ # @param database [String] initial database name
111
+ # @param port [String] port number (used if host is not 'localhost' or nil)
112
+ # @param socket [String] socket filename (used if host is 'localhost' or nil)
113
+ # @param flags [Integer] connection flag. Mysql::CLIENT_* ORed
114
+ # @param opts [Hash] options
115
+ # @overload initialize(host: nil, username: nil, password: nil, database: nil, port: nil, socket: nil, flags: nil, **opts)
116
+ # @param host [String] hostname mysqld running
117
+ # @param username [String] username to connect to mysqld
118
+ # @param password [String] password to connect to mysqld
119
+ # @param database [String] initial database name
120
+ # @param port [String] port number (used if host is not 'localhost' or nil)
121
+ # @param socket [String] socket filename (used if host is 'localhost' or nil)
122
+ # @param flags [Integer] connection flag. Mysql::CLIENT_* ORed
123
+ # @param opts [Hash] options
124
+ # @option opts :host [String] hostname mysqld running
125
+ # @option opts :username [String] username to connect to mysqld
126
+ # @option opts :password [String] password to connect to mysqld
127
+ # @option opts :database [String] initial database name
128
+ # @option opts :port [String] port number (used if host is not 'localhost' or nil)
129
+ # @option opts :socket [String] socket filename (used if host is 'localhost' or nil)
130
+ # @option opts :flags [Integer] connection flag. Mysql::CLIENT_* ORed
131
+ # @option opts :charset [Mysql::Charset, String] character set
132
+ # @option opts :connect_timeout [Numeric, nil]
133
+ # @option opts :read_timeout [Numeric, nil]
134
+ # @option opts :write_timeout [Numeric, nil]
135
+ # @option opts :local_infile [Boolean]
136
+ # @option opts :load_data_local_dir [String]
137
+ # @option opts :ssl_mode [Integer]
138
+ # @option opts :get_server_public_key [Boolean]
139
+ def initialize(*args, **opts)
82
140
  @fields = nil
83
141
  @protocol = nil
84
- @charset = nil
85
- @init_command = nil
86
142
  @sqlstate = "00000"
87
- @query_with_result = true
88
143
  @host_info = nil
89
144
  @last_error = nil
90
145
  @result_exist = false
91
- @opts = {
92
- connect_timeout: nil,
93
- read_timeout: nil,
94
- write_timeout: nil,
95
- local_infile: nil,
96
- ssl_mode: SSL_MODE_PREFERRED,
97
- get_server_public_key: false,
98
- }
146
+ @opts = DEFAULT_OPTS.dup
147
+ parse_args(args, opts)
99
148
  end
100
149
 
101
150
  # Connect to mysqld.
102
- # @param [String / nil] host hostname mysqld running
103
- # @param [String / nil] user username to connect to mysqld
104
- # @param [String / nil] passwd password to connect to mysqld
105
- # @param [String / nil] db initial database name
106
- # @param [Integer / nil] port port number (used if host is not 'localhost' or nil)
107
- # @param [String / nil] socket socket file name (used if host is 'localhost' or nil)
108
- # @param [Integer / nil] flag connection flag. Mysql::CLIENT_* ORed
109
- # @return self
110
- def connect(host=nil, user=nil, passwd=nil, db=nil, port=nil, socket=nil, flag=0)
111
- if flag & CLIENT_COMPRESS != 0
151
+ # parameter is same as arguments for {#initialize}.
152
+ # @return [Mysql] self
153
+ def connect(*args, **opts)
154
+ parse_args(args, opts)
155
+ if @opts[:flags] & CLIENT_COMPRESS != 0
112
156
  warn 'unsupported flag: CLIENT_COMPRESS' if $VERBOSE
113
- flag &= ~CLIENT_COMPRESS
157
+ @opts[:flags] &= ~CLIENT_COMPRESS
114
158
  end
115
- @protocol = Protocol.new(host, port, socket, @opts)
116
- @protocol.authenticate user, passwd.to_s, db, flag, @charset
117
- @charset ||= @protocol.charset
118
- @host_info = (host.nil? || host == "localhost") ? 'Localhost via UNIX socket' : "#{host} via TCP/IP"
119
- query @init_command if @init_command
159
+ @protocol = Protocol.new(@opts)
160
+ @protocol.authenticate
161
+ @host_info = (@opts[:host].nil? || @opts[:host] == "localhost") ? 'Localhost via UNIX socket' : "#{@opts[:host]} via TCP/IP"
162
+ query @opts[:init_command] if @opts[:init_command]
120
163
  return self
121
164
  end
122
- alias real_connect connect
165
+
166
+ def parse_args(args, opts)
167
+ case args[0]
168
+ when URI
169
+ uri = args[0]
170
+ when /\Amysql:\/\//
171
+ uri = URI.parse(args[0])
172
+ when String
173
+ @opts[:host], user, passwd, dbname, port, socket, flags = *args
174
+ @opts[:username] = user if user
175
+ @opts[:password] = passwd if passwd
176
+ @opts[:database] = dbname if dbname
177
+ @opts[:port] = port if port
178
+ @opts[:socket] = socket if socket
179
+ @opts[:flags] = flags if flags
180
+ when Hash
181
+ # skip
182
+ when nil
183
+ # skip
184
+ end
185
+ if uri
186
+ host = uri.hostname.to_s
187
+ host = URI.decode_www_form_component(host)
188
+ if host.start_with?('/')
189
+ @opts[:socket] = host
190
+ host = ''
191
+ end
192
+ @opts[:host] = host
193
+ @opts[:username] = URI.decode_www_form_component(uri.user.to_s)
194
+ @opts[:password] = URI.decode_www_form_component(uri.password.to_s)
195
+ @opts[:database] = uri.path.sub(/\A\/+/, '')
196
+ @opts[:port] = uri.port
197
+ opts = URI.decode_www_form(uri.query).to_h.transform_keys(&:intern).merge(opts) if uri.query
198
+ opts[:flags] = opts[:flags].to_i if opts[:flags]
199
+ end
200
+ if args.last.kind_of? Hash
201
+ opts = opts.merge(args.last)
202
+ end
203
+ @opts.update(opts)
204
+ end
205
+
206
+ DEFAULT_OPTS.each_key do |var|
207
+ next if var == :charset
208
+ define_method(var){@opts[var]}
209
+ define_method("#{var}="){|val| @opts[var] = val}
210
+ end
123
211
 
124
212
  # Disconnect from mysql.
125
213
  # @return [Mysql] self
@@ -141,77 +229,6 @@ class Mysql
141
229
  return self
142
230
  end
143
231
 
144
- # Set option for connection.
145
- #
146
- # Available options:
147
- # Mysql::INIT_COMMAND, Mysql::OPT_CONNECT_TIMEOUT, Mysql::OPT_GET_SERVER_PUBLIC_KEY,
148
- # Mysql::OPT_LOAD_DATA_LOCAL_DIR, Mysql::OPT_LOCAL_INFILE, Mysql::OPT_READ_TIMEOUT,
149
- # Mysql::OPT_SSL_MODE, Mysql::OPT_WRITE_TIMEOUT, Mysql::SET_CHARSET_NAME
150
- # @param [Integer] opt option
151
- # @param [Integer] value option value that is depend on opt
152
- # @return [Mysql] self
153
- def options(opt, value=nil)
154
- case opt
155
- # when Mysql::DEFAULT_AUTH
156
- # when Mysql::ENABLE_CLEARTEXT_PLUGIN
157
- when Mysql::INIT_COMMAND
158
- @init_command = value.to_s
159
- # when Mysql::OPT_BIND
160
- # when Mysql::OPT_CAN_HANDLE_EXPIRED_PASSWORDS
161
- # when Mysql::OPT_COMPRESS
162
- # when Mysql::OPT_COMPRESSION_ALGORITHMS
163
- # when Mysql::OPT_CONNECT_ATTR_ADD
164
- # when Mysql::OPT_CONNECT_ATTR_DELETE
165
- # when Mysql::OPT_CONNECT_ATTR_RESET
166
- when Mysql::OPT_CONNECT_TIMEOUT
167
- @opts[:connect_timeout] = value
168
- when Mysql::OPT_GET_SERVER_PUBLIC_KEY
169
- @opts[:get_server_public_key] = value
170
- when Mysql::OPT_LOAD_DATA_LOCAL_DIR
171
- @opts[:local_infile] = value
172
- when Mysql::OPT_LOCAL_INFILE
173
- @opts[:local_infile] = value ? '' : nil
174
- # when Mysql::OPT_MAX_ALLOWED_PACKET
175
- # when Mysql::OPT_NAMED_PIPE
176
- # when Mysql::OPT_NET_BUFFER_LENGTH
177
- # when Mysql::OPT_OPTIONAL_RESULTSET_METADATA
178
- # when Mysql::OPT_PROTOCOL
179
- when Mysql::OPT_READ_TIMEOUT
180
- @opts[:read_timeout] = value
181
- # when Mysql::OPT_RECONNECT
182
- # when Mysql::OPT_RETRY_COUNT
183
- # when Mysql::SET_CLIENT_IP
184
- # when Mysql::OPT_SSL_CA
185
- # when Mysql::OPT_SSL_CAPATH
186
- # when Mysql::OPT_SSL_CERT
187
- # when Mysql::OPT_SSL_CIPHER
188
- # when Mysql::OPT_SSL_CRL
189
- # when Mysql::OPT_SSL_CRLPATH
190
- # when Mysql::OPT_SSL_FIPS_MODE
191
- # when Mysql::OPT_SSL_KEY
192
- when Mysql::OPT_SSL_MODE
193
- @opts[:ssl_mode] = value
194
- # when Mysql::OPT_TLS_CIPHERSUITES
195
- # when Mysql::OPT_TLS_VERSION
196
- # when Mysql::OPT_USE_RESULT
197
- when Mysql::OPT_WRITE_TIMEOUT
198
- @opts[:write_timeout] = value
199
- # when Mysql::OPT_ZSTD_COMPRESSION_LEVEL
200
- # when Mysql::PLUGIN_DIR
201
- # when Mysql::READ_DEFAULT_FILE
202
- # when Mysql::READ_DEFAULT_GROUP
203
- # when Mysql::REPORT_DATA_TRUNCATION
204
- # when Mysql::SERVER_PUBLIC_KEY
205
- # when Mysql::SET_CHARSET_DIR
206
- when Mysql::SET_CHARSET_NAME
207
- @charset = Charset.by_name value.to_s
208
- # when Mysql::SHARED_MEMORY_BASE_NAME
209
- else
210
- warn "option not implemented: #{opt}" if $VERBOSE
211
- end
212
- self
213
- end
214
-
215
232
  # Escape special character in MySQL.
216
233
  #
217
234
  # @param [String] str
@@ -221,33 +238,26 @@ class Mysql
221
238
  end
222
239
  alias quote escape_string
223
240
 
224
- # @return [String] client version
225
- def client_info
226
- self.class.client_info
227
- end
228
- alias get_client_info client_info
229
-
230
- # @return [Integer] client version
231
- def client_version
232
- self.class.client_version
241
+ # @return [Mysql::Charset] character set of MySQL connection
242
+ def charset
243
+ @opts[:charset]
233
244
  end
234
- alias get_client_version client_version
235
245
 
236
246
  # Set charset of MySQL connection.
237
- # @param [String / Mysql::Charset] cs
247
+ # @param [String, Mysql::Charset] cs
238
248
  def charset=(cs)
239
249
  charset = cs.is_a?(Charset) ? cs : Charset.by_name(cs)
240
250
  if @protocol
241
251
  @protocol.charset = charset
242
252
  query "SET NAMES #{charset.name}"
243
253
  end
244
- @charset = charset
254
+ @opts[:charset] = charset
245
255
  cs
246
256
  end
247
257
 
248
258
  # @return [String] charset name
249
259
  def character_set_name
250
- @charset.name
260
+ @protocol.charset.name
251
261
  end
252
262
 
253
263
  # @return [Integer] last error number
@@ -274,27 +284,18 @@ class Mysql
274
284
  def host_info
275
285
  @host_info
276
286
  end
277
- alias get_host_info host_info
278
-
279
- # @return [Integer] protocol version
280
- def proto_info
281
- Mysql::Protocol::VERSION
282
- end
283
- alias get_proto_info proto_info
284
287
 
285
288
  # @return [String] server version
286
289
  def server_info
287
290
  check_connection
288
291
  @protocol.server_info
289
292
  end
290
- alias get_server_info server_info
291
293
 
292
294
  # @return [Integer] server version
293
295
  def server_version
294
296
  check_connection
295
297
  @protocol.server_version
296
298
  end
297
- alias get_server_version server_version
298
299
 
299
300
  # @return [String] information for last query
300
301
  def info
@@ -325,22 +326,18 @@ class Mysql
325
326
  self
326
327
  end
327
328
 
328
- # database list.
329
- # @param [String] db database name that may contain wild card.
330
- # @return [Array<String>] database list
331
- def list_dbs(db=nil)
332
- db &&= db.gsub(/[\\\']/){"\\#{$&}"}
333
- query(db ? "show databases like '#{db}'" : "show databases").map(&:first)
334
- end
335
-
336
329
  # Execute query string.
337
- # @param [String] str Query.
338
- # @yield [Mysql::Result] evaluated per query.
339
- # @return [Mysql::Result] If {#query_with_result} is true and result set exist.
340
- # @return [nil] If {#query_with_result} is true and the query does not return result set.
341
- # @return [Mysql] If {#query_with_result} is false or block is specified
330
+ # @overload query(str)
331
+ # @param [String] str Query.
332
+ # @return [Mysql::Result]
333
+ # @return [nil] if the query does not return result set.
334
+ # @overload query(str, &block)
335
+ # @param [String] str Query.
336
+ # @yield [Mysql::Result] evaluated per query.
337
+ # @return [self]
342
338
  # @example
343
339
  # my.query("select 1,NULL,'abc'").fetch # => [1, nil, "abc"]
340
+ # my.query("select 1,NULL,'abc'"){|res| res.fetch}
344
341
  def query(str, &block)
345
342
  check_connection
346
343
  @fields = nil
@@ -357,20 +354,15 @@ class Mysql
357
354
  end
358
355
  return self
359
356
  end
360
- if @query_with_result
361
- return @fields ? store_result : nil
362
- else
363
- return self
364
- end
357
+ return @fields ? store_result : nil
365
358
  rescue ServerError => e
366
359
  @last_error = e
367
360
  @sqlstate = e.sqlstate
368
361
  raise
369
362
  end
370
363
  end
371
- alias real_query query
372
364
 
373
- # Get all data for last query if query_with_result is false.
365
+ # Get all data for last query.
374
366
  # @return [Mysql::Result]
375
367
  def store_result
376
368
  check_connection
@@ -386,12 +378,6 @@ class Mysql
386
378
  @protocol.thread_id
387
379
  end
388
380
 
389
- # Use result of query. The result data is retrieved when you use Mysql::Result#fetch.
390
- # @return [Mysql::Result]
391
- def use_result
392
- store_result
393
- end
394
-
395
381
  # Set server option.
396
382
  # @param [Integer] opt {Mysql::OPTION_MULTI_STATEMENTS_ON} or {Mysql::OPTION_MULTI_STATEMENTS_OFF}
397
383
  # @return [Mysql] self
@@ -425,7 +411,7 @@ class Mysql
425
411
  # @param [String] str query string
426
412
  # @return [Mysql::Stmt] Prepared-statement object
427
413
  def prepare(str)
428
- st = Stmt.new @protocol, @charset
414
+ st = Stmt.new @protocol
429
415
  st.prepare str
430
416
  st
431
417
  end
@@ -433,40 +419,8 @@ class Mysql
433
419
  # @private
434
420
  # Make empty prepared-statement object.
435
421
  # @return [Mysql::Stmt] If block is not specified.
436
- def stmt_init
437
- Stmt.new @protocol, @charset
438
- end
439
-
440
- # Returns Mysql::Result object that is empty.
441
- # Use fetch_fields to get list of fields.
442
- # @param [String] table table name.
443
- # @param [String] field field name that may contain wild card.
444
- # @return [Mysql::Result]
445
- def list_fields(table, field=nil)
446
- check_connection
447
- begin
448
- fields = @protocol.field_list_command table, field
449
- return Result.new fields
450
- rescue ServerError => e
451
- @last_error = e
452
- @sqlstate = e.sqlstate
453
- raise
454
- end
455
- end
456
-
457
- # @return [Mysql::Result] containing process list
458
- def list_processes
459
- check_connection
460
- @fields = @protocol.process_info_command
461
- @result_exist = true
462
- store_result
463
- end
464
-
465
- # @param [String] table database name that may contain wild card.
466
- # @return [Array<String>] list of table name.
467
- def list_tables(table=nil)
468
- q = table ? "show tables like '#{quote table}'" : "show tables"
469
- query(q).map(&:first)
422
+ def stmt
423
+ Stmt.new @protocol
470
424
  end
471
425
 
472
426
  # Check whether the connection is available.
@@ -579,7 +533,7 @@ class Mysql
579
533
  end
580
534
 
581
535
  # @return [Hash] field information
582
- def hash
536
+ def to_hash
583
537
  {
584
538
  "name" => @name,
585
539
  "table" => @table,
@@ -815,10 +769,9 @@ class Mysql
815
769
  # @private
816
770
  # @param [Array<Mysql::Field>] fields
817
771
  # @param [Mysql::Protocol] protocol
818
- # @param [Mysql::Charset] charset
819
- def initialize(fields, protocol, charset)
772
+ def initialize(fields, protocol)
820
773
  super fields
821
- @records = protocol.stmt_retr_all_records @fields, charset
774
+ @records = protocol.stmt_retr_all_records @fields, protocol.charset
822
775
  end
823
776
  end
824
777
 
@@ -853,15 +806,12 @@ class Mysql
853
806
 
854
807
  # @private
855
808
  # @param [Mysql::Protocol] protocol
856
- # @param [Mysql::Charset] charset
857
- def initialize(protocol, charset)
809
+ def initialize(protocol)
858
810
  @protocol = protocol
859
- @charset = charset
860
811
  @statement_id = nil
861
812
  @affected_rows = @insert_id = @server_status = @warning_count = 0
862
813
  @sqlstate = "00000"
863
814
  @param_count = nil
864
- @bind_result = nil
865
815
  end
866
816
 
867
817
  # @private
@@ -888,13 +838,13 @@ class Mysql
888
838
  def execute(*values)
889
839
  raise ClientError, "not prepared" unless @param_count
890
840
  raise ClientError, "parameter count mismatch" if values.length != @param_count
891
- values = values.map{|v| @charset.convert v}
841
+ values = values.map{|v| @protocol.charset.convert v}
892
842
  begin
893
843
  @sqlstate = "00000"
894
844
  nfields = @protocol.stmt_execute_command @statement_id, values
895
845
  if nfields
896
846
  @fields = @protocol.retr_fields nfields
897
- @result = StatementResult.new @fields, @protocol, @charset
847
+ @result = StatementResult.new @fields, @protocol
898
848
  else
899
849
  @affected_rows, @insert_id, @server_status, @warning_count, @info =
900
850
  @protocol.affected_rows, @protocol.insert_id, @protocol.server_status, @protocol.warning_count, @protocol.message
@@ -917,46 +867,7 @@ class Mysql
917
867
 
918
868
  # @return [Array] current record data
919
869
  def fetch
920
- row = @result.fetch
921
- return row unless @bind_result
922
- row.zip(@bind_result).map do |col, type|
923
- if col.nil?
924
- nil
925
- elsif [Numeric, Integer].include? type
926
- col.to_i
927
- elsif type == String
928
- col.to_s
929
- elsif type == Float && !col.is_a?(Float)
930
- col.to_i.to_f
931
- elsif type == Mysql::Time && !col.is_a?(Mysql::Time)
932
- if col.to_s =~ /\A\d+\z/
933
- i = col.to_s.to_i
934
- if i < 100000000
935
- y = i/10000
936
- m = i/100%100
937
- d = i%100
938
- h, mm, s = 0
939
- else
940
- y = i/10000000000
941
- m = i/100000000%100
942
- d = i/1000000%100
943
- h = i/10000%100
944
- mm= i/100%100
945
- s = i%100
946
- end
947
- if y < 70
948
- y += 2000
949
- elsif y < 100
950
- y += 1900
951
- end
952
- Mysql::Time.new(y, m, d, h, mm, s)
953
- else
954
- Mysql::Time.new
955
- end
956
- else
957
- col
958
- end
959
- end
870
+ @result.fetch
960
871
  end
961
872
 
962
873
  # Return data of current record as Hash.
@@ -967,20 +878,6 @@ class Mysql
967
878
  @result.fetch_hash with_table
968
879
  end
969
880
 
970
- # Set retrieve type of value
971
- # @param [Numeric / Fixnum / Integer / Float / String / Mysql::Time / nil] args value type
972
- # @return [Mysql::Stmt] self
973
- def bind_result(*args)
974
- if @fields.length != args.length
975
- raise ClientError, "bind_result: result value count(#{@fields.length}) != number of argument(#{args.length})"
976
- end
977
- args.each do |a|
978
- raise TypeError unless [Numeric, Integer, Float, String, Mysql::Time, nil].include? a
979
- end
980
- @bind_result = args
981
- self
982
- end
983
-
984
881
  # Iterate block with record.
985
882
  # @yield [Array] record data
986
883
  # @return [Mysql::Stmt] self
@@ -1049,78 +946,4 @@ class Mysql
1049
946
  Result.new @fields
1050
947
  end
1051
948
  end
1052
-
1053
- # @!visibility public
1054
- # @!attribute [rw] year
1055
- # @return [Integer]
1056
- # @!attribute [rw] month
1057
- # @return [Integer]
1058
- # @!attribute [rw] day
1059
- # @return [Integer]
1060
- # @!attribute [rw] hour
1061
- # @return [Integer]
1062
- # @!attribute [rw] minute
1063
- # @return [Integer]
1064
- # @!attribute [rw] second
1065
- # @return [Integer]
1066
- # @!attribute [rw] neg
1067
- # @return [Boolean] negative flag
1068
- # @!attribute [rw] second_part
1069
- # @return [Integer]
1070
- class Time
1071
- # @param [Integer] year
1072
- # @param [Integer] month
1073
- # @param [Integer] day
1074
- # @param [Integer] hour
1075
- # @param [Integer] minute
1076
- # @param [Integer] second
1077
- # @param [Boolean] neg negative flag
1078
- # @param [Integer] second_part
1079
- def initialize(year=0, month=0, day=0, hour=0, minute=0, second=0, neg=false, second_part=0)
1080
- @date_flag = !(hour && minute && second)
1081
- @year, @month, @day, @hour, @minute, @second, @neg, @second_part =
1082
- year.to_i, month.to_i, day.to_i, hour.to_i, minute.to_i, second.to_i, neg, second_part.to_i
1083
- end
1084
- attr_accessor :year, :month, :day, :hour, :minute, :second, :neg, :second_part
1085
- alias mon month
1086
- alias min minute
1087
- alias sec second
1088
-
1089
- # @private
1090
- def ==(other)
1091
- other.is_a?(Mysql::Time) &&
1092
- @year == other.year && @month == other.month && @day == other.day &&
1093
- @hour == other.hour && @minute == other.minute && @second == other.second &&
1094
- @neg == neg && @second_part == other.second_part
1095
- end
1096
-
1097
- # @private
1098
- def eql?(other)
1099
- self == other
1100
- end
1101
-
1102
- # @return [String] "yyyy-mm-dd HH:MM:SS"
1103
- def to_s
1104
- if @date_flag
1105
- sprintf "%04d-%02d-%02d", year, mon, day
1106
- elsif year == 0 and mon == 0 and day == 0
1107
- h = neg ? hour * -1 : hour
1108
- sprintf "%02d:%02d:%02d", h, min, sec
1109
- else
1110
- sprintf "%04d-%02d-%02d %02d:%02d:%02d", year, mon, day, hour, min, sec
1111
- end
1112
- end
1113
-
1114
- # @return [Integer] yyyymmddHHMMSS
1115
- def to_i
1116
- sprintf("%04d%02d%02d%02d%02d%02d", year, mon, day, hour, min, sec).to_i
1117
- end
1118
-
1119
- # @private
1120
- def inspect
1121
- sprintf "#<#{self.class.name}:%04d-%02d-%02d %02d:%02d:%02d>", year, mon, day, hour, min, sec
1122
- end
1123
-
1124
- end
1125
-
1126
949
  end