mysql2 0.4.2 → 0.5.5
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 +5 -5
- data/README.md +231 -86
- data/ext/mysql2/client.c +527 -128
- data/ext/mysql2/client.h +11 -52
- data/ext/mysql2/extconf.rb +100 -21
- data/ext/mysql2/mysql2_ext.c +8 -2
- data/ext/mysql2/mysql2_ext.h +21 -8
- data/ext/mysql2/mysql_enc_name_to_ruby.h +60 -56
- data/ext/mysql2/mysql_enc_to_ruby.h +64 -3
- data/ext/mysql2/result.c +333 -109
- data/ext/mysql2/result.h +1 -0
- data/ext/mysql2/statement.c +247 -90
- data/ext/mysql2/statement.h +0 -2
- data/ext/mysql2/wait_for_single_fd.h +2 -1
- data/lib/mysql2/client.rb +71 -31
- data/lib/mysql2/em.rb +2 -4
- data/lib/mysql2/error.rb +52 -22
- data/lib/mysql2/result.rb +2 -0
- data/lib/mysql2/statement.rb +3 -11
- data/lib/mysql2/version.rb +1 -1
- data/lib/mysql2.rb +19 -15
- data/support/3A79BD29.asc +49 -0
- data/support/5072E1F5.asc +432 -0
- data/support/C74CD1D8.asc +104 -0
- data/support/mysql_enc_to_ruby.rb +8 -3
- data/support/ruby_enc_to_mysql.rb +7 -5
- metadata +19 -61
- data/examples/eventmachine.rb +0 -21
- data/examples/threaded.rb +0 -18
- data/spec/configuration.yml.example +0 -17
- data/spec/em/em_spec.rb +0 -135
- data/spec/my.cnf.example +0 -9
- data/spec/mysql2/client_spec.rb +0 -939
- data/spec/mysql2/error_spec.rb +0 -84
- data/spec/mysql2/result_spec.rb +0 -510
- data/spec/mysql2/statement_spec.rb +0 -684
- data/spec/rcov.opts +0 -3
- data/spec/spec_helper.rb +0 -94
- data/spec/ssl/ca-cert.pem +0 -17
- data/spec/ssl/ca-key.pem +0 -27
- data/spec/ssl/ca.cnf +0 -22
- data/spec/ssl/cert.cnf +0 -22
- data/spec/ssl/client-cert.pem +0 -17
- data/spec/ssl/client-key.pem +0 -27
- data/spec/ssl/client-req.pem +0 -15
- data/spec/ssl/gen_certs.sh +0 -48
- data/spec/ssl/pkcs8-client-key.pem +0 -28
- data/spec/ssl/pkcs8-server-key.pem +0 -28
- data/spec/ssl/server-cert.pem +0 -17
- data/spec/ssl/server-key.pem +0 -27
- data/spec/ssl/server-req.pem +0 -15
- data/spec/test_data +0 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 9532497d6cec810bf247db1d89f9792d712f69802363e3365cd92f832933f65e
|
4
|
+
data.tar.gz: 469ef49b3d79efebfa9b716b8e7e833962fdf94be89955d0252311398b7c33c6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '076963e960177838a9b0438efa04e0a2c34ef90d1c4b85542b9f510b6c4016a9032e3f1d08be3e987fcf1427da741f2e1ba02c27b58a8ca3a4b071cb16de255c'
|
7
|
+
data.tar.gz: 04227cd2b437d2af587d9411cf77776e9ef3dda1bdf31273e3ba1cf0958d060459096a9ab1a8ba2fb927004a6bcf0a0e941ae07fd0d172a3b56464125c9d31e7
|
data/README.md
CHANGED
@@ -1,13 +1,18 @@
|
|
1
1
|
# Mysql2 - A modern, simple and very fast MySQL library for Ruby - binding to libmysql
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
GitHub Actions
|
4
|
+
[](https://github.com/brianmario/mysql2/actions/workflows/build.yml)
|
5
|
+
[](https://github.com/brianmario/mysql2/actions/workflows/container.yml)
|
6
|
+
Travis CI
|
7
|
+
[](https://travis-ci.org/brianmario/mysql2)
|
8
|
+
Appveyor CI
|
9
|
+
[](https://ci.appveyor.com/project/sodabrew/mysql2)
|
5
10
|
|
6
11
|
The Mysql2 gem is meant to serve the extremely common use-case of connecting, querying and iterating on results.
|
7
12
|
Some database libraries out there serve as direct 1:1 mappings of the already complex C APIs available.
|
8
13
|
This one is not.
|
9
14
|
|
10
|
-
It also forces the use of UTF-8 [or binary] for the connection
|
15
|
+
It also forces the use of UTF-8 [or binary] for the connection and uses encoding-aware MySQL API calls where it can.
|
11
16
|
|
12
17
|
The API consists of three classes:
|
13
18
|
|
@@ -18,16 +23,18 @@ The API consists of three classes:
|
|
18
23
|
`Mysql2::Statement` - returned from issuing a #prepare on the connection. Execute the statement to get a Result.
|
19
24
|
|
20
25
|
## Installing
|
26
|
+
|
21
27
|
### General Instructions
|
28
|
+
|
22
29
|
``` sh
|
23
30
|
gem install mysql2
|
24
31
|
```
|
25
32
|
|
26
33
|
This gem links against MySQL's `libmysqlclient` library or `Connector/C`
|
27
34
|
library, and compatible alternatives such as MariaDB.
|
28
|
-
You may need to install a package such as `
|
29
|
-
or other appropriate package for your system. See below for
|
30
|
-
instructions.
|
35
|
+
You may need to install a package such as `libmariadb-dev`, `libmysqlclient-dev`,
|
36
|
+
`mysql-devel`, or other appropriate package for your system. See below for
|
37
|
+
system-specific instructions.
|
31
38
|
|
32
39
|
By default, the mysql2 gem will try to find a copy of MySQL in this order:
|
33
40
|
|
@@ -58,6 +65,11 @@ This may be needed if you deploy to a system where these libraries
|
|
58
65
|
are located somewhere different than on your build system.
|
59
66
|
This overrides any rpath calculated by default or by the options above.
|
60
67
|
|
68
|
+
* `--with-openssl-dir[=/path/to/openssl]` - Specify the directory where OpenSSL
|
69
|
+
is installed. In most cases, the Ruby runtime and MySQL client libraries will
|
70
|
+
link against a system-installed OpenSSL library and this option is not needed.
|
71
|
+
Use this option when non-default library paths are needed.
|
72
|
+
|
61
73
|
* `--with-sanitize[=address,cfi,integer,memory,thread,undefined]` -
|
62
74
|
Enable sanitizers for Clang / GCC. If no argument is given, try to enable
|
63
75
|
all sanitizers or fail if none are available. If a command-separated list of
|
@@ -74,18 +86,58 @@ To see line numbers in backtraces, declare these environment variables
|
|
74
86
|
|
75
87
|
### Linux and other Unixes
|
76
88
|
|
77
|
-
You may need to install a package such as `
|
78
|
-
refer to your distribution's package guide to
|
79
|
-
The most common issue we see is a user who has
|
80
|
-
|
89
|
+
You may need to install a package such as `libmariadb-dev`, `libmysqlclient-dev`,
|
90
|
+
`mysql-devel`, or `default-libmysqlclient-dev`; refer to your distribution's package guide to
|
91
|
+
find the particular package. The most common issue we see is a user who has
|
92
|
+
the library file `libmysqlclient.so` but is missing the header file `mysql.h`
|
93
|
+
-- double check that you have the _-dev_ packages installed.
|
81
94
|
|
82
95
|
### Mac OS X
|
83
96
|
|
84
|
-
You may use
|
97
|
+
You may use Homebew, MacPorts, or a native MySQL installer package. The most
|
85
98
|
common paths will be automatically searched. If you want to select a specific
|
86
99
|
MySQL directory, use the `--with-mysql-dir` or `--with-mysql-config` options above.
|
87
100
|
|
101
|
+
If you have not done so already, you will need to install the XCode select tools by running
|
102
|
+
`xcode-select --install`.
|
103
|
+
|
104
|
+
Later versions of MacOS no longer distribute a linkable OpenSSL library. It is
|
105
|
+
common to use Homebrew or MacPorts to install OpenSSL. Make sure that both the
|
106
|
+
Ruby runtime and MySQL client libraries are compiled with the same OpenSSL
|
107
|
+
family, 1.0 or 1.1 or 3.0, since only one can be loaded at runtime.
|
108
|
+
|
109
|
+
``` sh
|
110
|
+
$ brew install openssl@1.1
|
111
|
+
$ gem install mysql2 -- --with-openssl-dir=$(brew --prefix openssl@1.1)
|
112
|
+
|
113
|
+
or
|
114
|
+
|
115
|
+
$ sudo port install openssl11
|
116
|
+
```
|
117
|
+
|
118
|
+
Since most Ruby projects use Bundler, you can set build options in the Bundler
|
119
|
+
config rather than manually installing a global mysql2 gem. This example shows
|
120
|
+
how to set build arguments with [Bundler config](https://bundler.io/man/bundle-config.1.html):
|
121
|
+
|
122
|
+
``` sh
|
123
|
+
$ bundle config --local build.mysql2 -- --with-openssl-dir=$(brew --prefix openssl@1.1)
|
124
|
+
```
|
125
|
+
|
126
|
+
Another helpful trick is to use the same OpenSSL library that your Ruby was
|
127
|
+
built with, if it was built with an alternate OpenSSL path. This example finds
|
128
|
+
the argument `--with-openssl-dir=/some/path` from the Ruby build and adds that
|
129
|
+
to the [Bundler config](https://bundler.io/man/bundle-config.1.html):
|
130
|
+
|
131
|
+
``` sh
|
132
|
+
$ bundle config --local build.mysql2 -- $(ruby -r rbconfig -e 'puts RbConfig::CONFIG["configure_args"]' | xargs -n1 | grep with-openssl-dir)
|
133
|
+
```
|
134
|
+
|
135
|
+
Note the additional double dashes (`--`) these separate command-line arguments
|
136
|
+
that `gem` or `bundler` interpret from the addiitonal arguments that are passed
|
137
|
+
to the mysql2 build process.
|
138
|
+
|
88
139
|
### Windows
|
140
|
+
|
89
141
|
Make sure that you have Ruby and the DevKit compilers installed. We recommend
|
90
142
|
the [Ruby Installer](http://rubyinstaller.org) distribution.
|
91
143
|
|
@@ -109,7 +161,7 @@ Connect to a database:
|
|
109
161
|
``` ruby
|
110
162
|
# this takes a hash of options, almost all of which map directly
|
111
163
|
# to the familiar database.yml in rails
|
112
|
-
# See http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/
|
164
|
+
# See http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/Mysql2Adapter.html
|
113
165
|
client = Mysql2::Client.new(:host => "localhost", :username => "root")
|
114
166
|
```
|
115
167
|
|
@@ -135,8 +187,8 @@ results.each do |row|
|
|
135
187
|
# conveniently, row is a hash
|
136
188
|
# the keys are the fields, as you'd expect
|
137
189
|
# the values are pre-built ruby primitives mapped from their corresponding field types in MySQL
|
138
|
-
puts row["id"] # row["id"].
|
139
|
-
if row["dne"] # non-
|
190
|
+
puts row["id"] # row["id"].is_a? Integer
|
191
|
+
if row["dne"] # non-existent hash entry is nil
|
140
192
|
puts row["dne"]
|
141
193
|
end
|
142
194
|
end
|
@@ -153,26 +205,31 @@ end
|
|
153
205
|
How about with symbolized keys?
|
154
206
|
|
155
207
|
``` ruby
|
156
|
-
client.query("SELECT * FROM users WHERE group='githubbers'", :symbolize_keys => true) do |row|
|
208
|
+
client.query("SELECT * FROM users WHERE group='githubbers'", :symbolize_keys => true).each do |row|
|
157
209
|
# do something with row, it's ready to rock
|
158
210
|
end
|
159
211
|
```
|
160
212
|
|
161
|
-
You can get the headers and the
|
213
|
+
You can get the headers, columns, and the field types in the order that they were returned
|
162
214
|
by the query like this:
|
163
215
|
|
164
216
|
``` ruby
|
165
217
|
headers = results.fields # <= that's an array of field names, in order
|
218
|
+
types = results.field_types # <= that's an array of field types, in order
|
166
219
|
results.each(:as => :array) do |row|
|
167
|
-
# Each row is an array, ordered the same as the query results
|
168
|
-
# An otter's den is called a "holt" or "couch"
|
220
|
+
# Each row is an array, ordered the same as the query results
|
221
|
+
# An otter's den is called a "holt" or "couch"
|
169
222
|
end
|
170
223
|
```
|
171
224
|
|
172
225
|
Prepared statements are supported, as well. In a prepared statement, use a `?`
|
173
226
|
in place of each value and then execute the statement to retrieve a result set.
|
174
227
|
Pass your arguments to the execute method in the same number and order as the
|
175
|
-
question marks in the statement.
|
228
|
+
question marks in the statement. Query options can be passed as keyword arguments
|
229
|
+
to the execute method.
|
230
|
+
|
231
|
+
Be sure to read about the known limitations of prepared statements at
|
232
|
+
[https://dev.mysql.com/doc/refman/5.6/en/c-api-prepared-statement-problems.html](https://dev.mysql.com/doc/refman/5.6/en/c-api-prepared-statement-problems.html)
|
176
233
|
|
177
234
|
``` ruby
|
178
235
|
statement = @client.prepare("SELECT * FROM users WHERE login_count = ?")
|
@@ -181,8 +238,28 @@ result2 = statement.execute(2)
|
|
181
238
|
|
182
239
|
statement = @client.prepare("SELECT * FROM users WHERE last_login >= ? AND location LIKE ?")
|
183
240
|
result = statement.execute(1, "CA")
|
241
|
+
|
242
|
+
statement = @client.prepare("SELECT * FROM users WHERE last_login >= ? AND location LIKE ?")
|
243
|
+
result = statement.execute(1, "CA", :as => :array)
|
244
|
+
```
|
245
|
+
|
246
|
+
Session Tracking information can be accessed with
|
247
|
+
|
248
|
+
``` ruby
|
249
|
+
c = Mysql2::Client.new(
|
250
|
+
host: "127.0.0.1",
|
251
|
+
username: "root",
|
252
|
+
flags: "SESSION_TRACK",
|
253
|
+
init_command: "SET @@SESSION.session_track_schema=ON"
|
254
|
+
)
|
255
|
+
c.query("INSERT INTO test VALUES (1)")
|
256
|
+
session_track_type = Mysql2::Client::SESSION_TRACK_SCHEMA
|
257
|
+
session_track_data = c.session_track(session_track_type)
|
184
258
|
```
|
185
259
|
|
260
|
+
The types of session track types can be found at
|
261
|
+
[https://dev.mysql.com/doc/refman/5.7/en/session-state-tracking.html](https://dev.mysql.com/doc/refman/5.7/en/session-state-tracking.html)
|
262
|
+
|
186
263
|
## Connection options
|
187
264
|
|
188
265
|
You may set the following connection options in Mysql2::Client.new(...):
|
@@ -200,24 +277,37 @@ Mysql2::Client.new(
|
|
200
277
|
:read_timeout = seconds,
|
201
278
|
:write_timeout = seconds,
|
202
279
|
:connect_timeout = seconds,
|
280
|
+
:connect_attrs = {:program_name => $PROGRAM_NAME, ...},
|
203
281
|
:reconnect = true/false,
|
204
282
|
:local_infile = true/false,
|
205
283
|
:secure_auth = true/false,
|
206
284
|
:default_file = '/path/to/my.cfg',
|
207
285
|
:default_group = 'my.cfg section',
|
286
|
+
:default_auth = 'authentication_windows_client'
|
208
287
|
:init_command => sql
|
209
288
|
)
|
210
289
|
```
|
211
290
|
|
291
|
+
### Connecting to MySQL on localhost and elsewhere
|
212
292
|
|
213
|
-
|
293
|
+
The underlying MySQL client library uses the `:host` parameter to determine the
|
294
|
+
type of connection to make, with special interpretation you should be aware of:
|
214
295
|
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
296
|
+
* An empty value or `"localhost"` will attempt a local connection:
|
297
|
+
* On Unix, connect to the default local socket path. (To set a custom socket
|
298
|
+
path, use the `:socket` parameter).
|
299
|
+
* On Windows, connect using a shared-memory connection, if enabled, or TCP.
|
300
|
+
* A value of `"."` on Windows specifies a named-pipe connection.
|
301
|
+
* An IPv4 or IPv6 address will result in a TCP connection.
|
302
|
+
* Any other value will be looked up as a hostname for a TCP connection.
|
303
|
+
|
304
|
+
### SSL/TLS options
|
305
|
+
|
306
|
+
Setting any of the following options will enable an SSL/TLS connection, but
|
307
|
+
only if your MySQL client library and server have been compiled with SSL
|
308
|
+
support. MySQL client library defaults will be used for any parameters that are
|
309
|
+
left out or set to nil. Relative paths are allowed, and may be required by
|
310
|
+
managed hosting providers such as Heroku.
|
221
311
|
|
222
312
|
``` ruby
|
223
313
|
Mysql2::Client.new(
|
@@ -227,54 +317,32 @@ Mysql2::Client.new(
|
|
227
317
|
:sslca => '/path/to/ca-cert.pem',
|
228
318
|
:sslcapath => '/path/to/cacerts',
|
229
319
|
:sslcipher => 'DHE-RSA-AES256-SHA',
|
230
|
-
:sslverify => true,
|
320
|
+
:sslverify => true, # Removed in MySQL 8.0
|
321
|
+
:ssl_mode => :disabled / :preferred / :required / :verify_ca / :verify_identity,
|
231
322
|
)
|
232
323
|
```
|
233
324
|
|
234
|
-
|
325
|
+
For MySQL versions 5.7.11 and higher, use `:ssl_mode` to prefer or require an
|
326
|
+
SSL connection and certificate validation. For earlier versions of MySQL, use
|
327
|
+
the `:sslverify` boolean. For details on each of the `:ssl_mode` options, see
|
328
|
+
[https://dev.mysql.com/doc/refman/8.0/en/connection-options.html](https://dev.mysql.com/doc/refman/8.0/en/connection-options.html#option_general_ssl-mode).
|
235
329
|
|
236
|
-
|
237
|
-
connect with flags `Mysql2::Client::MULTI_STATEMENTS`. Multiple result sets can
|
238
|
-
be used with stored procedures that return more than one result set, and for
|
239
|
-
bundling several SQL statements into a single call to `client.query`.
|
240
|
-
|
241
|
-
``` ruby
|
242
|
-
client = Mysql2::Client.new(:host => "localhost", :username => "root", :flags => Mysql2::Client::MULTI_STATEMENTS)
|
243
|
-
result = client.query('CALL sp_customer_list( 25, 10 )')
|
244
|
-
# result now contains the first result set
|
245
|
-
while client.next_result
|
246
|
-
result = client.store_result
|
247
|
-
# result now contains the next result set
|
248
|
-
end
|
249
|
-
```
|
250
|
-
|
251
|
-
Repeated calls to `client.next_result` will return true, false, or raise an
|
252
|
-
exception if the respective query erred. When `client.next_result` returns true,
|
253
|
-
call `client.store_result` to retrieve a result object. Exceptions are not
|
254
|
-
raised until `client.next_result` is called to find the status of the respective
|
255
|
-
query. Subsequent queries are not executed if an earlier query raised an
|
256
|
-
exception. Subsequent calls to `client.next_result` will return false.
|
330
|
+
The `:ssl_mode` option will also set the appropriate MariaDB connection flags:
|
257
331
|
|
258
|
-
|
259
|
-
|
260
|
-
|
332
|
+
| `:ssl_mode` | MariaDB option value |
|
333
|
+
| --- | --- |
|
334
|
+
| `:disabled` | MYSQL_OPT_SSL_ENFORCE = 0 |
|
335
|
+
| `:required` | MYSQL_OPT_SSL_ENFORCE = 1 |
|
336
|
+
| `:verify_identity` | MYSQL_OPT_SSL_VERIFY_SERVER_CERT = 1 |
|
261
337
|
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
```
|
267
|
-
|
268
|
-
Yields:
|
269
|
-
```
|
270
|
-
{"1"=>1}
|
271
|
-
{"2"=>2}
|
272
|
-
next_result: Unknown column 'A' in 'field list' (Mysql2::Error)
|
273
|
-
```
|
338
|
+
MariaDB does not support the `:preferred` or `:verify_ca` options. For more
|
339
|
+
information about SSL/TLS in MariaDB, see
|
340
|
+
[https://mariadb.com/kb/en/securing-connections-for-client-and-server/](https://mariadb.com/kb/en/securing-connections-for-client-and-server/)
|
341
|
+
and [https://mariadb.com/kb/en/mysql_optionsv/#tls-options](https://mariadb.com/kb/en/mysql_optionsv/#tls-options)
|
274
342
|
|
275
343
|
### Secure auth
|
276
344
|
|
277
|
-
Starting
|
345
|
+
Starting with MySQL 5.6.5, secure_auth is enabled by default on servers (it was disabled by default prior to this).
|
278
346
|
When secure_auth is enabled, the server will refuse a connection if the account password is stored in old pre-MySQL 4.1 format.
|
279
347
|
The MySQL 5.6.5 client library may also refuse to attempt a connection if provided an older format password.
|
280
348
|
To bypass this restriction in the client, pass the option `:secure_auth => false` to Mysql2::Client.new().
|
@@ -290,8 +358,10 @@ The string form will be split on whitespace and parsed as with the array form:
|
|
290
358
|
Plain flags are added to the default flags, while flags prefixed with `-`
|
291
359
|
(minus) are removed from the default flags.
|
292
360
|
|
293
|
-
|
294
|
-
|
361
|
+
### Using Active Record's database.yml
|
362
|
+
|
363
|
+
Active Record typically reads its configuration from a file named `database.yml` or an environment variable `DATABASE_URL`.
|
364
|
+
Use the value `mysql2` as the adapter name. For example:
|
295
365
|
|
296
366
|
``` yaml
|
297
367
|
development:
|
@@ -309,6 +379,17 @@ development:
|
|
309
379
|
secure_auth: false
|
310
380
|
```
|
311
381
|
|
382
|
+
In this example, the compression flag is negated with `-COMPRESS`.
|
383
|
+
|
384
|
+
### Using Active Record's DATABASE_URL
|
385
|
+
|
386
|
+
Active Record typically reads its configuration from a file named `database.yml` or an environment variable `DATABASE_URL`.
|
387
|
+
Use the value `mysql2` as the protocol name. For example:
|
388
|
+
|
389
|
+
``` sh
|
390
|
+
DATABASE_URL=mysql2://sql_user:sql_pass@sql_host_name:port/sql_db_name?option1=value1&option2=value2
|
391
|
+
```
|
392
|
+
|
312
393
|
### Reading a MySQL config file
|
313
394
|
|
314
395
|
You may read configuration options from a MySQL configuration file by passing
|
@@ -328,6 +409,48 @@ It is useful if you want to provide session options which survive reconnection.
|
|
328
409
|
Mysql2::Client.new(:init_command => "SET @@SESSION.sql_mode = 'STRICT_ALL_TABLES'")
|
329
410
|
```
|
330
411
|
|
412
|
+
### Multiple result sets
|
413
|
+
|
414
|
+
You can also retrieve multiple result sets. For this to work you need to
|
415
|
+
connect with flags `Mysql2::Client::MULTI_STATEMENTS`. Multiple result sets can
|
416
|
+
be used with stored procedures that return more than one result set, and for
|
417
|
+
bundling several SQL statements into a single call to `client.query`.
|
418
|
+
|
419
|
+
``` ruby
|
420
|
+
client = Mysql2::Client.new(:host => "localhost", :username => "root", :flags => Mysql2::Client::MULTI_STATEMENTS)
|
421
|
+
result = client.query('CALL sp_customer_list( 25, 10 )')
|
422
|
+
# result now contains the first result set
|
423
|
+
while client.next_result
|
424
|
+
result = client.store_result
|
425
|
+
# result now contains the next result set
|
426
|
+
end
|
427
|
+
```
|
428
|
+
|
429
|
+
Repeated calls to `client.next_result` will return true, false, or raise an
|
430
|
+
exception if the respective query erred. When `client.next_result` returns true,
|
431
|
+
call `client.store_result` to retrieve a result object. Exceptions are not
|
432
|
+
raised until `client.next_result` is called to find the status of the respective
|
433
|
+
query. Subsequent queries are not executed if an earlier query raised an
|
434
|
+
exception. Subsequent calls to `client.next_result` will return false.
|
435
|
+
|
436
|
+
``` ruby
|
437
|
+
result = client.query('SELECT 1; SELECT 2; SELECT A; SELECT 3')
|
438
|
+
p result.first
|
439
|
+
|
440
|
+
while client.next_result
|
441
|
+
result = client.store_result
|
442
|
+
p result.first
|
443
|
+
end
|
444
|
+
```
|
445
|
+
|
446
|
+
Yields:
|
447
|
+
|
448
|
+
``` ruby
|
449
|
+
{"1"=>1}
|
450
|
+
{"2"=>2}
|
451
|
+
next_result: Unknown column 'A' in 'field list' (Mysql2::Error)
|
452
|
+
```
|
453
|
+
|
331
454
|
## Cascading config
|
332
455
|
|
333
456
|
The default config hash is at:
|
@@ -365,6 +488,15 @@ c = Mysql2::Client.new
|
|
365
488
|
c.query(sql, :symbolize_keys => true)
|
366
489
|
```
|
367
490
|
|
491
|
+
or
|
492
|
+
|
493
|
+
``` ruby
|
494
|
+
# this will set the options for the Mysql2::Result instance returned from the #execute method
|
495
|
+
c = Mysql2::Client.new
|
496
|
+
s = c.prepare(sql)
|
497
|
+
s.execute(arg1, args2, :symbolize_keys => true)
|
498
|
+
```
|
499
|
+
|
368
500
|
## Result types
|
369
501
|
|
370
502
|
### Array of Arrays
|
@@ -373,7 +505,7 @@ Pass the `:as => :array` option to any of the above methods of configuration
|
|
373
505
|
|
374
506
|
### Array of Hashes
|
375
507
|
|
376
|
-
The default result type is set to
|
508
|
+
The default result type is set to `:hash`, but you can override a previous setting to something else with `:as => :hash`
|
377
509
|
|
378
510
|
### Timezones
|
379
511
|
|
@@ -398,6 +530,15 @@ client = Mysql2::Client.new
|
|
398
530
|
result = client.query("SELECT * FROM table_with_boolean_field", :cast_booleans => true)
|
399
531
|
```
|
400
532
|
|
533
|
+
Keep in mind that this works only with fields and not with computed values, e.g. this result will contain `1`, not `true`:
|
534
|
+
|
535
|
+
``` ruby
|
536
|
+
client = Mysql2::Client.new
|
537
|
+
result = client.query("SELECT true", :cast_booleans => true)
|
538
|
+
```
|
539
|
+
|
540
|
+
CAST function wouldn't help here as there's no way to cast to TINYINT(1). Apparently the only way to solve this is to use a stored procedure with return type set to TINYINT(1).
|
541
|
+
|
401
542
|
### Skipping casting
|
402
543
|
|
403
544
|
Mysql2 casting is fast, but not as fast as not casting data. In rare cases where typecasting is not needed, it will be faster to disable it by providing :cast => false. (Note that :cast => false overrides :cast_booleans => true.)
|
@@ -463,7 +604,7 @@ There are a few things that need to be kept in mind while using streaming:
|
|
463
604
|
* `:cache_rows` is ignored currently. (if you want to use `:cache_rows` you probably don't want to be using `:stream`)
|
464
605
|
* You must fetch all rows in the result set of your query before you can make new queries. (i.e. with `Mysql2::Result#each`)
|
465
606
|
|
466
|
-
Read more about the consequences of using `mysql_use_result` (what streaming is implemented with) here: http://dev.mysql.com/doc/refman/5.0/en/mysql-use-result.html.
|
607
|
+
Read more about the consequences of using `mysql_use_result` (what streaming is implemented with) here: [http://dev.mysql.com/doc/refman/5.0/en/mysql-use-result.html](http://dev.mysql.com/doc/refman/5.0/en/mysql-use-result.html).
|
467
608
|
|
468
609
|
### Lazy Everything
|
469
610
|
|
@@ -484,20 +625,23 @@ As for field values themselves, I'm workin on it - but expect that soon.
|
|
484
625
|
|
485
626
|
This gem is tested with the following Ruby versions on Linux and Mac OS X:
|
486
627
|
|
487
|
-
|
488
|
-
|
489
|
-
|
628
|
+
* Ruby MRI 2.0 through 2.7 (all versions to date)
|
629
|
+
* Ruby MRI 3.0, 3.1, 3.2 (all versions to date)
|
630
|
+
* Rubinius 2.x and 3.x do work but may fail under some workloads
|
490
631
|
|
491
632
|
This gem is tested with the following MySQL and MariaDB versions:
|
492
633
|
|
493
|
-
|
494
|
-
|
495
|
-
|
634
|
+
* MySQL 5.5, 5.6, 5.7, 8.0
|
635
|
+
* MySQL Connector/C 6.0, 6.1, 8.0 (primarily on Windows)
|
636
|
+
* MariaDB 5.5, 10.x, with a focus on 10.6 LTS and 10.11 LTS
|
637
|
+
* MariaDB Connector/C 2.x, 3.x
|
496
638
|
|
497
|
-
### Active Record
|
639
|
+
### Ruby on Rails / Active Record
|
498
640
|
|
499
|
-
|
500
|
-
|
641
|
+
* mysql2 0.5.x works with Rails / Active Record 4.2.11, 5.0.7, 5.1.6, and higher.
|
642
|
+
* mysql2 0.4.x works with Rails / Active Record 4.2.5 - 5.0 and higher.
|
643
|
+
* mysql2 0.3.x works with Rails / Active Record 3.1, 3.2, 4.x, 5.0.
|
644
|
+
* mysql2 0.2.x works with Rails / Active Record 2.3 - 3.0.
|
501
645
|
|
502
646
|
### Asynchronous Active Record
|
503
647
|
|
@@ -580,11 +724,12 @@ though.
|
|
580
724
|
## Special Thanks
|
581
725
|
|
582
726
|
* Eric Wong - for the contribution (and the informative explanations) of some thread-safety, non-blocking I/O and cleanup patches. You rock dude
|
583
|
-
* Yury Korolev
|
584
|
-
* Aaron Patterson
|
585
|
-
* Mike Perham
|
586
|
-
* Aaron Stone
|
587
|
-
* Kouhei Ueno
|
588
|
-
* John Cant
|
589
|
-
* Justin Case
|
590
|
-
* Tamir Duberstein
|
727
|
+
* [Yury Korolev](http://github.com/yury) - for TONS of help testing the Active Record adapter
|
728
|
+
* [Aaron Patterson](http://github.com/tenderlove) - tons of contributions, suggestions and general badassness
|
729
|
+
* [Mike Perham](http://github.com/mperham) - Async Active Record adapter (uses Fibers and EventMachine)
|
730
|
+
* [Aaron Stone](http://github.com/sodabrew) - additional client settings, local files, microsecond time, maintenance support
|
731
|
+
* [Kouhei Ueno](https://github.com/nyaxt) - for the original work on Prepared Statements way back in 2012
|
732
|
+
* [John Cant](http://github.com/johncant) - polishing and updating Prepared Statements support
|
733
|
+
* [Justin Case](http://github.com/justincase) - polishing and updating Prepared Statements support and getting it merged
|
734
|
+
* [Tamir Duberstein](http://github.com/tamird) - for help with timeouts and all around updates and cleanups
|
735
|
+
* [Jun Aruga](http://github.com/junaruga) - for migrating CI tests to GitHub Actions and other improvements
|