mysql2 0.4.2 → 0.5.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +231 -86
  3. data/ext/mysql2/client.c +527 -128
  4. data/ext/mysql2/client.h +11 -52
  5. data/ext/mysql2/extconf.rb +100 -21
  6. data/ext/mysql2/mysql2_ext.c +8 -2
  7. data/ext/mysql2/mysql2_ext.h +21 -8
  8. data/ext/mysql2/mysql_enc_name_to_ruby.h +60 -56
  9. data/ext/mysql2/mysql_enc_to_ruby.h +64 -3
  10. data/ext/mysql2/result.c +333 -109
  11. data/ext/mysql2/result.h +1 -0
  12. data/ext/mysql2/statement.c +247 -90
  13. data/ext/mysql2/statement.h +0 -2
  14. data/ext/mysql2/wait_for_single_fd.h +2 -1
  15. data/lib/mysql2/client.rb +71 -31
  16. data/lib/mysql2/em.rb +2 -4
  17. data/lib/mysql2/error.rb +52 -22
  18. data/lib/mysql2/result.rb +2 -0
  19. data/lib/mysql2/statement.rb +3 -11
  20. data/lib/mysql2/version.rb +1 -1
  21. data/lib/mysql2.rb +19 -15
  22. data/support/3A79BD29.asc +49 -0
  23. data/support/5072E1F5.asc +432 -0
  24. data/support/C74CD1D8.asc +104 -0
  25. data/support/mysql_enc_to_ruby.rb +8 -3
  26. data/support/ruby_enc_to_mysql.rb +7 -5
  27. metadata +19 -61
  28. data/examples/eventmachine.rb +0 -21
  29. data/examples/threaded.rb +0 -18
  30. data/spec/configuration.yml.example +0 -17
  31. data/spec/em/em_spec.rb +0 -135
  32. data/spec/my.cnf.example +0 -9
  33. data/spec/mysql2/client_spec.rb +0 -939
  34. data/spec/mysql2/error_spec.rb +0 -84
  35. data/spec/mysql2/result_spec.rb +0 -510
  36. data/spec/mysql2/statement_spec.rb +0 -684
  37. data/spec/rcov.opts +0 -3
  38. data/spec/spec_helper.rb +0 -94
  39. data/spec/ssl/ca-cert.pem +0 -17
  40. data/spec/ssl/ca-key.pem +0 -27
  41. data/spec/ssl/ca.cnf +0 -22
  42. data/spec/ssl/cert.cnf +0 -22
  43. data/spec/ssl/client-cert.pem +0 -17
  44. data/spec/ssl/client-key.pem +0 -27
  45. data/spec/ssl/client-req.pem +0 -15
  46. data/spec/ssl/gen_certs.sh +0 -48
  47. data/spec/ssl/pkcs8-client-key.pem +0 -28
  48. data/spec/ssl/pkcs8-server-key.pem +0 -28
  49. data/spec/ssl/server-cert.pem +0 -17
  50. data/spec/ssl/server-key.pem +0 -27
  51. data/spec/ssl/server-req.pem +0 -15
  52. data/spec/test_data +0 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: bfe50d56c4b02379320402f6c9a50e1c004855b1
4
- data.tar.gz: 495a7a40b1a1fc006e8f3816b0b215c8a82f4585
2
+ SHA256:
3
+ metadata.gz: 9532497d6cec810bf247db1d89f9792d712f69802363e3365cd92f832933f65e
4
+ data.tar.gz: 469ef49b3d79efebfa9b716b8e7e833962fdf94be89955d0252311398b7c33c6
5
5
  SHA512:
6
- metadata.gz: 076e0ae48e790418cc2272bf14f3f93859b751452eeaaefd43537a22266bf5cab6d443645b06d2e3bcaab3be2768e65bc5b699bb5e100e10e5a35911d4e96c33
7
- data.tar.gz: b921cb3b96ef7428db4870ca82719a52b7921d24fed356ba6765ff1890a98ae8c0c1351e8c158fa098d8652aebf4b958ec1cb3eeb46ff2e8c2b9e58d69dde1d7
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
- Travis CI [![Travis CI Status](https://travis-ci.org/brianmario/mysql2.png)](https://travis-ci.org/brianmario/mysql2)
4
- Appveyor CI [![Appveyor CI Status](https://ci.appveyor.com/api/projects/status/github/sodabrew/mysql2)](https://ci.appveyor.com/project/sodabrew/mysql2)
3
+ GitHub Actions
4
+ [![GitHub Actions Status: Build](https://github.com/brianmario/mysql2/actions/workflows/build.yml/badge.svg)](https://github.com/brianmario/mysql2/actions/workflows/build.yml)
5
+ [![GitHub Actions Status: Container](https://github.com/brianmario/mysql2/actions/workflows/container.yml/badge.svg)](https://github.com/brianmario/mysql2/actions/workflows/container.yml)
6
+ Travis CI
7
+ [![Travis CI Status](https://travis-ci.org/brianmario/mysql2.png)](https://travis-ci.org/brianmario/mysql2)
8
+ Appveyor CI
9
+ [![Appveyor CI Status](https://ci.appveyor.com/api/projects/status/github/sodabrew/mysql2)](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 [and all strings in 1.9, unless Encoding.default_internal is set then it'll convert from UTF-8 to that encoding] and uses encoding-aware MySQL API calls where it can.
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 `libmysqlclient-dev`, `mysql-devel`,
29
- or other appropriate package for your system. See below for system-specific
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 `libmysqlclient-dev` or `mysql-devel`;
78
- refer to your distribution's package guide to find the particular package.
79
- The most common issue we see is a user who has the library file `libmysqlclient.so` but is
80
- missing the header file `mysql.h` -- double check that you have the _-dev_ packages installed.
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 MacPorts, Homebrew, or a native MySQL installer package. The most
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/MysqlAdapter.html
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"].class == Fixnum
139
- if row["dne"] # non-existant hash entry is nil
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 columns in the order that they were returned
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
- ### SSL options
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
- Setting any of the following options will enable an SSL connection, but only if
216
- your MySQL client library and server have been compiled with SSL support.
217
- MySQL client library defaults will be used for any parameters that are left out
218
- or set to nil. Relative paths are allowed, and may be required by managed
219
- hosting providers such as Heroku. Set `:sslverify => true` to require that the
220
- server presents a valid certificate.
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
- ### Multiple result sets
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
- You can also retrieve multiple result sets. For this to work you need to
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
- ``` ruby
259
- result = client.query('SELECT 1; SELECT 2; SELECT A; SELECT 3')
260
- p result.first
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
- while client.next_result
263
- result = client.store_result
264
- p result.first
265
- end
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 wih MySQL 5.6.5, secure_auth is enabled by default on servers (it was disabled by default prior to this).
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
- This allows easier use with ActiveRecord's database.yml, avoiding the need for magic flag numbers.
294
- For example, to disable protocol compression, and enable multiple statements and result sets:
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 :hash, but you can override a previous setting to something else with :as => :hash
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
- * Ruby MRI 1.8.7, 1.9.3, 2.0.0, 2.1.x, 2.2.x
488
- * Ruby Enterprise Edition (based on MRI 1.8.7)
489
- * Rubinius 2.x
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
- * MySQL 5.5, 5.7
494
- * MySQL Connector/C 6.0 and 6.1 (primarily on Windows)
495
- * MariaDB 5.5, 10.0
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
- * mysql2 0.2.x includes an Active Record driver compatible with AR 2.3 and 3.0
500
- * mysql2 0.3.x does not include an AR driver because it is included in AR 3.1 and above
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 (http://github.com/yury) - for TONS of help testing the Active Record adapter
584
- * Aaron Patterson (http://github.com/tenderlove) - tons of contributions, suggestions and general badassness
585
- * Mike Perham (http://github.com/mperham) - Async Active Record adapter (uses Fibers and EventMachine)
586
- * Aaron Stone (http://github.com/sodabrew) - additional client settings, local files, microsecond time, maintenance support
587
- * Kouhei Ueno (https://github.com/nyaxt) - for the original work on Prepared Statements way back in 2012
588
- * John Cant (http://github.com/johncant) - polishing and updating Prepared Statements support
589
- * Justin Case (http://github.com/justincase) - polishing and updating Prepared Statements support and getting it merged
590
- * Tamir Duberstein (http://github.com/tamird) - for help with timeouts and all around updates and cleanups
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