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 +4 -4
- data/CHANGELOG.md +58 -0
- data/README.md +28 -0
- data/lib/mysql/protocol.rb +86 -149
- data/lib/mysql.rb +182 -359
- data/test/test_mysql.rb +255 -551
- metadata +10 -7
- data/README.rdoc +0 -69
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
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
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 =
|
22
|
+
VERSION = '3.0.1' # 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
|
-
#
|
25
|
-
|
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
|
-
#
|
80
|
+
# parameter is same as arguments for {#initialize}.
|
43
81
|
# @return [Mysql]
|
44
|
-
def
|
45
|
-
|
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
|
-
|
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
|
-
|
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
|
-
#
|
103
|
-
# @
|
104
|
-
|
105
|
-
|
106
|
-
|
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
|
-
|
157
|
+
@opts[:flags] &= ~CLIENT_COMPRESS
|
114
158
|
end
|
115
|
-
@protocol = Protocol.new(
|
116
|
-
@protocol.authenticate
|
117
|
-
@
|
118
|
-
@
|
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
|
-
|
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 [
|
225
|
-
def
|
226
|
-
|
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
|
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
|
-
# @
|
338
|
-
#
|
339
|
-
#
|
340
|
-
#
|
341
|
-
# @
|
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
|
-
|
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
|
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
|
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
|
437
|
-
Stmt.new @protocol
|
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
|
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
|
-
|
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
|
-
|
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
|
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
|
-
|
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
|