mysql2 0.4.2 → 0.5.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: bfe50d56c4b02379320402f6c9a50e1c004855b1
4
- data.tar.gz: 495a7a40b1a1fc006e8f3816b0b215c8a82f4585
3
+ metadata.gz: 62ba5d2530e40ed2dcefd98c2219c95b166a7385
4
+ data.tar.gz: c17840a416a95f241cd9259c57aaacac100d17f8
5
5
  SHA512:
6
- metadata.gz: 076e0ae48e790418cc2272bf14f3f93859b751452eeaaefd43537a22266bf5cab6d443645b06d2e3bcaab3be2768e65bc5b699bb5e100e10e5a35911d4e96c33
7
- data.tar.gz: b921cb3b96ef7428db4870ca82719a52b7921d24fed356ba6765ff1890a98ae8c0c1351e8c158fa098d8652aebf4b958ec1cb3eeb46ff2e8c2b9e58d69dde1d7
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 [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.
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` 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.
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
 
@@ -85,6 +86,9 @@ You may use MacPorts, Homebrew, or a native MySQL installer package. The most
85
86
  common paths will be automatically searched. If you want to select a specific
86
87
  MySQL directory, use the `--with-mysql-dir` or `--with-mysql-config` options above.
87
88
 
89
+ If you have not done so already, you will need to install the XCode select tools by running
90
+ `xcode-select --install`.
91
+
88
92
  ### Windows
89
93
  Make sure that you have Ruby and the DevKit compilers installed. We recommend
90
94
  the [Ruby Installer](http://rubyinstaller.org) distribution.
@@ -109,7 +113,7 @@ Connect to a database:
109
113
  ``` ruby
110
114
  # this takes a hash of options, almost all of which map directly
111
115
  # to the familiar database.yml in rails
112
- # See http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/MysqlAdapter.html
116
+ # See http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/Mysql2Adapter.html
113
117
  client = Mysql2::Client.new(:host => "localhost", :username => "root")
114
118
  ```
115
119
 
@@ -135,7 +139,7 @@ results.each do |row|
135
139
  # conveniently, row is a hash
136
140
  # the keys are the fields, as you'd expect
137
141
  # the values are pre-built ruby primitives mapped from their corresponding field types in MySQL
138
- puts row["id"] # row["id"].class == Fixnum
142
+ puts row["id"] # row["id"].is_a? Integer
139
143
  if row["dne"] # non-existant hash entry is nil
140
144
  puts row["dne"]
141
145
  end
@@ -164,15 +168,19 @@ by the query like this:
164
168
  ``` ruby
165
169
  headers = results.fields # <= that's an array of field names, in order
166
170
  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"
171
+ # Each row is an array, ordered the same as the query results
172
+ # An otter's den is called a "holt" or "couch"
169
173
  end
170
174
  ```
171
175
 
172
176
  Prepared statements are supported, as well. In a prepared statement, use a `?`
173
177
  in place of each value and then execute the statement to retrieve a result set.
174
178
  Pass your arguments to the execute method in the same number and order as the
175
- 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
176
184
 
177
185
  ``` ruby
178
186
  statement = @client.prepare("SELECT * FROM users WHERE login_count = ?")
@@ -181,6 +189,9 @@ result2 = statement.execute(2)
181
189
 
182
190
  statement = @client.prepare("SELECT * FROM users WHERE last_login >= ? AND location LIKE ?")
183
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)
184
195
  ```
185
196
 
186
197
  ## Connection options
@@ -200,15 +211,29 @@ Mysql2::Client.new(
200
211
  :read_timeout = seconds,
201
212
  :write_timeout = seconds,
202
213
  :connect_timeout = seconds,
214
+ :connect_attrs = {:program_name => $PROGRAM_NAME, ...},
203
215
  :reconnect = true/false,
204
216
  :local_infile = true/false,
205
217
  :secure_auth = true/false,
218
+ :ssl_mode = :disabled / :preferred / :required / :verify_ca / :verify_identity,
206
219
  :default_file = '/path/to/my.cfg',
207
220
  :default_group = 'my.cfg section',
208
221
  :init_command => sql
209
222
  )
210
223
  ```
211
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.
212
237
 
213
238
  ### SSL options
214
239
 
@@ -231,47 +256,6 @@ Mysql2::Client.new(
231
256
  )
232
257
  ```
233
258
 
234
- ### Multiple result sets
235
-
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.
257
-
258
- ``` ruby
259
- result = client.query('SELECT 1; SELECT 2; SELECT A; SELECT 3')
260
- p result.first
261
-
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
- ```
274
-
275
259
  ### Secure auth
276
260
 
277
261
  Starting wih MySQL 5.6.5, secure_auth is enabled by default on servers (it was disabled by default prior to this).
@@ -328,6 +312,47 @@ It is useful if you want to provide session options which survive reconnection.
328
312
  Mysql2::Client.new(:init_command => "SET @@SESSION.sql_mode = 'STRICT_ALL_TABLES'")
329
313
  ```
330
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
+
331
356
  ## Cascading config
332
357
 
333
358
  The default config hash is at:
@@ -365,6 +390,15 @@ c = Mysql2::Client.new
365
390
  c.query(sql, :symbolize_keys => true)
366
391
  ```
367
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
+
368
402
  ## Result types
369
403
 
370
404
  ### Array of Arrays
@@ -398,6 +432,15 @@ client = Mysql2::Client.new
398
432
  result = client.query("SELECT * FROM table_with_boolean_field", :cast_booleans => true)
399
433
  ```
400
434
 
435
+ Keep in mind that this works only with fields and not with computed values, e.g. this result will contain `1`, not `true`:
436
+
437
+ ``` ruby
438
+ client = Mysql2::Client.new
439
+ result = client.query("SELECT true", :cast_booleans => true)
440
+ ```
441
+
442
+ 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).
443
+
401
444
  ### Skipping casting
402
445
 
403
446
  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.)
@@ -484,20 +527,21 @@ As for field values themselves, I'm workin on it - but expect that soon.
484
527
 
485
528
  This gem is tested with the following Ruby versions on Linux and Mac OS X:
486
529
 
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
530
+ * Ruby MRI 2.0.0, 2.1.x, 2.2.x, 2.3.x, 2.4.x, 2.5.x, 2.6.x
531
+ * Rubinius 2.x and 3.x do work but may fail under some workloads
490
532
 
491
533
  This gem is tested with the following MySQL and MariaDB versions:
492
534
 
493
- * MySQL 5.5, 5.7
535
+ * MySQL 5.5, 5.6, 5.7, 8.0
494
536
  * MySQL Connector/C 6.0 and 6.1 (primarily on Windows)
495
- * MariaDB 5.5, 10.0
537
+ * MariaDB 5.5, 10.0, 10.1, 10.2, 10.3
496
538
 
497
- ### Active Record
539
+ ### Ruby on Rails / Active Record
498
540
 
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
541
+ * mysql2 0.5.x works with Rails / Active Record 5.0.7, 5.1.6, and higher.
542
+ * mysql2 0.4.x works with Rails / Active Record 4.2.5 - 5.0 and higher.
543
+ * mysql2 0.3.x works with Rails / Active Record 3.1, 3.2, 4.x, 5.0.
544
+ * mysql2 0.2.x works with Rails / Active Record 2.3 - 3.0.
501
545
 
502
546
  ### Asynchronous Active Record
503
547
 
@@ -1,5 +1,3 @@
1
- # encoding: utf-8
2
-
3
1
  $LOAD_PATH.unshift 'lib'
4
2
 
5
3
  require 'rubygems'
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.times.map do
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(:host => "localhost", :username => "root").query("SELECT sleep(#{overhead}) as result")
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)