mysql2 0.4.6 → 0.5.2
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/README.md +82 -52
- data/examples/eventmachine.rb +0 -2
- data/examples/threaded.rb +2 -4
- data/ext/mysql2/client.c +171 -75
- data/ext/mysql2/client.h +2 -41
- data/ext/mysql2/extconf.rb +30 -23
- data/ext/mysql2/mysql2_ext.c +2 -1
- data/ext/mysql2/mysql2_ext.h +8 -8
- data/ext/mysql2/mysql_enc_to_ruby.h +10 -0
- data/ext/mysql2/result.c +24 -77
- data/ext/mysql2/result.h +2 -3
- data/ext/mysql2/statement.c +101 -73
- data/ext/mysql2/statement.h +0 -2
- data/ext/mysql2/wait_for_single_fd.h +2 -1
- data/lib/mysql2/client.rb +37 -31
- data/lib/mysql2/em.rb +2 -4
- data/lib/mysql2/error.rb +49 -20
- data/lib/mysql2/result.rb +2 -0
- data/lib/mysql2/statement.rb +3 -9
- data/lib/mysql2/version.rb +1 -1
- data/lib/mysql2.rb +14 -15
- data/spec/em/em_spec.rb +6 -6
- data/spec/mysql2/client_spec.rb +300 -215
- data/spec/mysql2/error_spec.rb +3 -9
- data/spec/mysql2/result_spec.rb +124 -158
- data/spec/mysql2/statement_spec.rb +138 -185
- data/spec/spec_helper.rb +79 -61
- data/support/5072E1F5.asc +432 -0
- data/support/mysql_enc_to_ruby.rb +2 -2
- data/support/ruby_enc_to_mysql.rb +5 -5
- metadata +16 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 62ba5d2530e40ed2dcefd98c2219c95b166a7385
|
4
|
+
data.tar.gz: c17840a416a95f241cd9259c57aaacac100d17f8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 50d8ecc5c61d004953d4da51b69ca0d8166c1c665757f677eedea84c62173490a6b0b1b67cec9e661397306fb0607930f6cf5b062fd8f77c2d9c2ea02b8d2d69
|
7
|
+
data.tar.gz: d62e82ffffe4e1a84d37f1a3745c58c0d5b0f88d0cc1403b93a452a0af454e6aa1a49653cb70b494b092ffa7f924ed66293c58ec0ddbe2e8497eedcf631ffd7c
|
data/README.md
CHANGED
@@ -7,7 +7,7 @@ The Mysql2 gem is meant to serve the extremely common use-case of connecting, qu
|
|
7
7
|
Some database libraries out there serve as direct 1:1 mappings of the already complex C APIs available.
|
8
8
|
This one is not.
|
9
9
|
|
10
|
-
It also forces the use of UTF-8 [or binary] for the connection
|
10
|
+
It also forces the use of UTF-8 [or binary] for the connection and uses encoding-aware MySQL API calls where it can.
|
11
11
|
|
12
12
|
The API consists of three classes:
|
13
13
|
|
@@ -74,10 +74,11 @@ To see line numbers in backtraces, declare these environment variables
|
|
74
74
|
|
75
75
|
### Linux and other Unixes
|
76
76
|
|
77
|
-
You may need to install a package such as `libmysqlclient-dev
|
78
|
-
refer to your distribution's package guide to
|
79
|
-
The most common issue we see is a user who has
|
80
|
-
|
77
|
+
You may need to install a package such as `libmysqlclient-dev`, `mysql-devel`,
|
78
|
+
or `default-libmysqlclient-dev`; refer to your distribution's package guide to
|
79
|
+
find the particular package. The most common issue we see is a user who has
|
80
|
+
the library file `libmysqlclient.so` but is missing the header file `mysql.h`
|
81
|
+
-- double check that you have the _-dev_ packages installed.
|
81
82
|
|
82
83
|
### Mac OS X
|
83
84
|
|
@@ -112,7 +113,7 @@ Connect to a database:
|
|
112
113
|
``` ruby
|
113
114
|
# this takes a hash of options, almost all of which map directly
|
114
115
|
# to the familiar database.yml in rails
|
115
|
-
# See http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/
|
116
|
+
# See http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/Mysql2Adapter.html
|
116
117
|
client = Mysql2::Client.new(:host => "localhost", :username => "root")
|
117
118
|
```
|
118
119
|
|
@@ -138,7 +139,7 @@ results.each do |row|
|
|
138
139
|
# conveniently, row is a hash
|
139
140
|
# the keys are the fields, as you'd expect
|
140
141
|
# the values are pre-built ruby primitives mapped from their corresponding field types in MySQL
|
141
|
-
puts row["id"] # row["id"].
|
142
|
+
puts row["id"] # row["id"].is_a? Integer
|
142
143
|
if row["dne"] # non-existant hash entry is nil
|
143
144
|
puts row["dne"]
|
144
145
|
end
|
@@ -175,7 +176,11 @@ end
|
|
175
176
|
Prepared statements are supported, as well. In a prepared statement, use a `?`
|
176
177
|
in place of each value and then execute the statement to retrieve a result set.
|
177
178
|
Pass your arguments to the execute method in the same number and order as the
|
178
|
-
question marks in the statement.
|
179
|
+
question marks in the statement. Query options can be passed as keyword arguments
|
180
|
+
to the execute method.
|
181
|
+
|
182
|
+
Be sure to read about the known limitations of prepared statements at
|
183
|
+
https://dev.mysql.com/doc/refman/5.6/en/c-api-prepared-statement-problems.html
|
179
184
|
|
180
185
|
``` ruby
|
181
186
|
statement = @client.prepare("SELECT * FROM users WHERE login_count = ?")
|
@@ -184,6 +189,9 @@ result2 = statement.execute(2)
|
|
184
189
|
|
185
190
|
statement = @client.prepare("SELECT * FROM users WHERE last_login >= ? AND location LIKE ?")
|
186
191
|
result = statement.execute(1, "CA")
|
192
|
+
|
193
|
+
statement = @client.prepare("SELECT * FROM users WHERE last_login >= ? AND location LIKE ?")
|
194
|
+
result = statement.execute(1, "CA", :as => :array)
|
187
195
|
```
|
188
196
|
|
189
197
|
## Connection options
|
@@ -203,6 +211,7 @@ Mysql2::Client.new(
|
|
203
211
|
:read_timeout = seconds,
|
204
212
|
:write_timeout = seconds,
|
205
213
|
:connect_timeout = seconds,
|
214
|
+
:connect_attrs = {:program_name => $PROGRAM_NAME, ...},
|
206
215
|
:reconnect = true/false,
|
207
216
|
:local_infile = true/false,
|
208
217
|
:secure_auth = true/false,
|
@@ -213,6 +222,18 @@ Mysql2::Client.new(
|
|
213
222
|
)
|
214
223
|
```
|
215
224
|
|
225
|
+
### Connecting to MySQL on localhost and elsewhere
|
226
|
+
|
227
|
+
The underlying MySQL client library uses the `:host` parameter to determine the
|
228
|
+
type of connection to make, with special interpretation you should be aware of:
|
229
|
+
|
230
|
+
* An empty value or `"localhost"` will attempt a local connection:
|
231
|
+
* On Unix, connect to the default local socket path. (To set a custom socket
|
232
|
+
path, use the `:socket` parameter).
|
233
|
+
* On Windows, connect using a shared-memory connection, if enabled, or TCP.
|
234
|
+
* A value of `"."` on Windows specifies a named-pipe connection.
|
235
|
+
* An IPv4 or IPv6 address will result in a TCP connection.
|
236
|
+
* Any other value will be looked up as a hostname for a TCP connection.
|
216
237
|
|
217
238
|
### SSL options
|
218
239
|
|
@@ -235,47 +256,6 @@ Mysql2::Client.new(
|
|
235
256
|
)
|
236
257
|
```
|
237
258
|
|
238
|
-
### Multiple result sets
|
239
|
-
|
240
|
-
You can also retrieve multiple result sets. For this to work you need to
|
241
|
-
connect with flags `Mysql2::Client::MULTI_STATEMENTS`. Multiple result sets can
|
242
|
-
be used with stored procedures that return more than one result set, and for
|
243
|
-
bundling several SQL statements into a single call to `client.query`.
|
244
|
-
|
245
|
-
``` ruby
|
246
|
-
client = Mysql2::Client.new(:host => "localhost", :username => "root", :flags => Mysql2::Client::MULTI_STATEMENTS)
|
247
|
-
result = client.query('CALL sp_customer_list( 25, 10 )')
|
248
|
-
# result now contains the first result set
|
249
|
-
while client.next_result
|
250
|
-
result = client.store_result
|
251
|
-
# result now contains the next result set
|
252
|
-
end
|
253
|
-
```
|
254
|
-
|
255
|
-
Repeated calls to `client.next_result` will return true, false, or raise an
|
256
|
-
exception if the respective query erred. When `client.next_result` returns true,
|
257
|
-
call `client.store_result` to retrieve a result object. Exceptions are not
|
258
|
-
raised until `client.next_result` is called to find the status of the respective
|
259
|
-
query. Subsequent queries are not executed if an earlier query raised an
|
260
|
-
exception. Subsequent calls to `client.next_result` will return false.
|
261
|
-
|
262
|
-
``` ruby
|
263
|
-
result = client.query('SELECT 1; SELECT 2; SELECT A; SELECT 3')
|
264
|
-
p result.first
|
265
|
-
|
266
|
-
while client.next_result
|
267
|
-
result = client.store_result
|
268
|
-
p result.first
|
269
|
-
end
|
270
|
-
```
|
271
|
-
|
272
|
-
Yields:
|
273
|
-
```
|
274
|
-
{"1"=>1}
|
275
|
-
{"2"=>2}
|
276
|
-
next_result: Unknown column 'A' in 'field list' (Mysql2::Error)
|
277
|
-
```
|
278
|
-
|
279
259
|
### Secure auth
|
280
260
|
|
281
261
|
Starting wih MySQL 5.6.5, secure_auth is enabled by default on servers (it was disabled by default prior to this).
|
@@ -332,6 +312,47 @@ It is useful if you want to provide session options which survive reconnection.
|
|
332
312
|
Mysql2::Client.new(:init_command => "SET @@SESSION.sql_mode = 'STRICT_ALL_TABLES'")
|
333
313
|
```
|
334
314
|
|
315
|
+
### Multiple result sets
|
316
|
+
|
317
|
+
You can also retrieve multiple result sets. For this to work you need to
|
318
|
+
connect with flags `Mysql2::Client::MULTI_STATEMENTS`. Multiple result sets can
|
319
|
+
be used with stored procedures that return more than one result set, and for
|
320
|
+
bundling several SQL statements into a single call to `client.query`.
|
321
|
+
|
322
|
+
``` ruby
|
323
|
+
client = Mysql2::Client.new(:host => "localhost", :username => "root", :flags => Mysql2::Client::MULTI_STATEMENTS)
|
324
|
+
result = client.query('CALL sp_customer_list( 25, 10 )')
|
325
|
+
# result now contains the first result set
|
326
|
+
while client.next_result
|
327
|
+
result = client.store_result
|
328
|
+
# result now contains the next result set
|
329
|
+
end
|
330
|
+
```
|
331
|
+
|
332
|
+
Repeated calls to `client.next_result` will return true, false, or raise an
|
333
|
+
exception if the respective query erred. When `client.next_result` returns true,
|
334
|
+
call `client.store_result` to retrieve a result object. Exceptions are not
|
335
|
+
raised until `client.next_result` is called to find the status of the respective
|
336
|
+
query. Subsequent queries are not executed if an earlier query raised an
|
337
|
+
exception. Subsequent calls to `client.next_result` will return false.
|
338
|
+
|
339
|
+
``` ruby
|
340
|
+
result = client.query('SELECT 1; SELECT 2; SELECT A; SELECT 3')
|
341
|
+
p result.first
|
342
|
+
|
343
|
+
while client.next_result
|
344
|
+
result = client.store_result
|
345
|
+
p result.first
|
346
|
+
end
|
347
|
+
```
|
348
|
+
|
349
|
+
Yields:
|
350
|
+
```
|
351
|
+
{"1"=>1}
|
352
|
+
{"2"=>2}
|
353
|
+
next_result: Unknown column 'A' in 'field list' (Mysql2::Error)
|
354
|
+
```
|
355
|
+
|
335
356
|
## Cascading config
|
336
357
|
|
337
358
|
The default config hash is at:
|
@@ -369,6 +390,15 @@ c = Mysql2::Client.new
|
|
369
390
|
c.query(sql, :symbolize_keys => true)
|
370
391
|
```
|
371
392
|
|
393
|
+
or
|
394
|
+
|
395
|
+
``` ruby
|
396
|
+
# this will set the options for the Mysql2::Result instance returned from the #execute method
|
397
|
+
c = Mysql2::Client.new
|
398
|
+
s = c.prepare(sql)
|
399
|
+
s.execute(arg1, args2, :symbolize_keys => true)
|
400
|
+
```
|
401
|
+
|
372
402
|
## Result types
|
373
403
|
|
374
404
|
### Array of Arrays
|
@@ -497,18 +527,18 @@ As for field values themselves, I'm workin on it - but expect that soon.
|
|
497
527
|
|
498
528
|
This gem is tested with the following Ruby versions on Linux and Mac OS X:
|
499
529
|
|
500
|
-
* Ruby MRI
|
501
|
-
* Ruby Enterprise Edition (based on MRI 1.8.7)
|
530
|
+
* Ruby MRI 2.0.0, 2.1.x, 2.2.x, 2.3.x, 2.4.x, 2.5.x, 2.6.x
|
502
531
|
* Rubinius 2.x and 3.x do work but may fail under some workloads
|
503
532
|
|
504
533
|
This gem is tested with the following MySQL and MariaDB versions:
|
505
534
|
|
506
535
|
* MySQL 5.5, 5.6, 5.7, 8.0
|
507
536
|
* MySQL Connector/C 6.0 and 6.1 (primarily on Windows)
|
508
|
-
* MariaDB 5.5, 10.0, 10.1
|
537
|
+
* MariaDB 5.5, 10.0, 10.1, 10.2, 10.3
|
509
538
|
|
510
539
|
### Ruby on Rails / Active Record
|
511
540
|
|
541
|
+
* mysql2 0.5.x works with Rails / Active Record 5.0.7, 5.1.6, and higher.
|
512
542
|
* mysql2 0.4.x works with Rails / Active Record 4.2.5 - 5.0 and higher.
|
513
543
|
* mysql2 0.3.x works with Rails / Active Record 3.1, 3.2, 4.x, 5.0.
|
514
544
|
* mysql2 0.2.x works with Rails / Active Record 2.3 - 3.0.
|
data/examples/eventmachine.rb
CHANGED
data/examples/threaded.rb
CHANGED
@@ -1,17 +1,15 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
1
|
$LOAD_PATH.unshift 'lib'
|
4
2
|
require 'mysql2'
|
5
3
|
require 'timeout'
|
6
4
|
|
7
5
|
# Should never exceed worst case 3.5 secs across all 20 threads
|
8
6
|
Timeout.timeout(3.5) do
|
9
|
-
20
|
7
|
+
Array.new(20) do
|
10
8
|
Thread.new do
|
11
9
|
overhead = rand(3)
|
12
10
|
puts ">> thread #{Thread.current.object_id} query, #{overhead} sec overhead"
|
13
11
|
# 3 second overhead per query
|
14
|
-
Mysql2::Client.new(:
|
12
|
+
Mysql2::Client.new(host: "localhost", username: "root").query("SELECT sleep(#{overhead}) as result")
|
15
13
|
puts "<< thread #{Thread.current.object_id} result, #{overhead} sec overhead"
|
16
14
|
end
|
17
15
|
end.each(&:join)
|