mysql2 0.2.20 → 0.2.21
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +82 -2
- data/ext/mysql2/client.c +83 -48
- data/ext/mysql2/client.h +14 -7
- data/ext/mysql2/extconf.rb +58 -19
- data/ext/mysql2/mysql2_ext.h +3 -0
- data/ext/mysql2/result.c +18 -3
- data/lib/mysql2/client.rb +15 -6
- data/lib/mysql2/version.rb +1 -1
- data/spec/configuration.yml.example +6 -0
- data/spec/my.cnf.example +9 -0
- data/spec/mysql2/client_spec.rb +26 -0
- metadata +11 -19
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 5973bd9a37d27c37169e315c5b73df1fcd3b1ce4
|
4
|
+
data.tar.gz: f5e1c5e6bb844649e2b07c640d7ab061ad03519c
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ea791db6c0c353cc4f1f3adbd1875018bd27c6a4b602de992ec47c3691ac966723c8917d7dad33f32f720448a54f351a1136f64bb25ccdd29ec16b87e9e2d39f
|
7
|
+
data.tar.gz: d22086793bef4d4c3e7e6c2bec39dd22135015d692ac4b36c89d0755b4ac0837ccdf87f5d77c466474da08639a228bab2f29cd38926668dc21e3bf8dc21f21fa
|
data/README.md
CHANGED
@@ -15,14 +15,61 @@ Mysql2::Client - your connection to the database
|
|
15
15
|
Mysql2::Result - returned from issuing a #query on the connection. It includes Enumerable.
|
16
16
|
|
17
17
|
## Installing
|
18
|
-
|
18
|
+
### OSX / Linux
|
19
19
|
``` sh
|
20
20
|
gem install mysql2
|
21
21
|
```
|
22
22
|
|
23
23
|
This gem links against MySQL's `libmysqlclient` C shared library. You may need to install a package such as `libmysqlclient-dev`, `mysql-devel`, or other appropriate package for your system.
|
24
24
|
|
25
|
-
|
25
|
+
By default, the mysql2 gem will try to find a copy of MySQL in this order:
|
26
|
+
|
27
|
+
* Option `--with-mysql-dir`, if provided (see below).
|
28
|
+
* Option `--with-mysql-config`, if provided (see below).
|
29
|
+
* Several typical paths for `msyql_config` (default for the majority of users).
|
30
|
+
* The directory `/usr/local`.
|
31
|
+
|
32
|
+
### Configuration options
|
33
|
+
|
34
|
+
Use these options by `gem install mysql2 -- [--optionA] [--optionB=argument]`.
|
35
|
+
|
36
|
+
* `--with-mysql-dir[=/path/to/mysqldir]` -
|
37
|
+
Specify the directory where MySQL is installed. The mysql2 gem will not use
|
38
|
+
`mysql_config`, but will instead look at `mysqldir/lib` and `mysqldir/include`
|
39
|
+
for the library and header files.
|
40
|
+
This option is mutually exclusive with `--with-mysql-config`.
|
41
|
+
|
42
|
+
* `--with-mysql-config[=/path/to/mysql_config]` -
|
43
|
+
Specify a path to the `mysql_config` binary provided by your copy of MySQL. The
|
44
|
+
mysql2 gem will ask this `mysql_config` binary about the compiler and linker
|
45
|
+
arguments needed.
|
46
|
+
This option is mutually exclusive with `--with-mysql-dir`.
|
47
|
+
|
48
|
+
* `--with-mysql-rpath=/path/to/mysql/lib` / `--without-mysql-rpath` -
|
49
|
+
Override the runtime path used to find the MySQL libraries.
|
50
|
+
This may be needed if you deploy to a system where these libraries
|
51
|
+
are located somewhere different than on your build system.
|
52
|
+
This overrides any rpath calculated by default or by the options above.
|
53
|
+
|
54
|
+
### Windows
|
55
|
+
First, make sure you have the DevKit installed (http://rubyinstaller.org/downloads/) and its variables
|
56
|
+
are loaded by running devkit\devktvars.bat .
|
57
|
+
|
58
|
+
Next, you need a MySQL library to link against. If you have MySQL loaded on your development machine,
|
59
|
+
you can use that. If not, you will need to either copy the MySQL directory from your server, or else
|
60
|
+
obtain a copy of the MySQL C connector: http://dev.mysql.com/downloads/connector/c/
|
61
|
+
|
62
|
+
If you're using the connector, I recommend just getting the .zip file and unzipping it someplace convenient.
|
63
|
+
|
64
|
+
Now you can install mysql2. You must use the `--with-mysql-dir` option to tell gem where your MySQL library
|
65
|
+
files are. For example, if you unzipped the connector to c:\mysql-connector-c-6.1.1-win32 you would install
|
66
|
+
the gem like this:
|
67
|
+
|
68
|
+
gem install mysql2 -- --with-mysql-dir=c:\mysql-connector-c-6.1.1-win32
|
69
|
+
|
70
|
+
Finally, you must copy libmysql.dll from the lib subdirectory of your MySQL or MySQL connector directory into
|
71
|
+
your ruby\bin directory. In the above example, libmysql.dll would be located at
|
72
|
+
c:\mysql-connector-c-6.1.1-win32\lib .
|
26
73
|
|
27
74
|
## Usage
|
28
75
|
|
@@ -108,8 +155,12 @@ Mysql2::Client.new(
|
|
108
155
|
:connect_timeout = seconds,
|
109
156
|
:reconnect = true/false,
|
110
157
|
:local_infile = true/false,
|
158
|
+
:secure_auth = true/false,
|
159
|
+
:default_file = '/path/to/my.cfg',
|
160
|
+
:default_group = 'my.cfg section'
|
111
161
|
)
|
112
162
|
```
|
163
|
+
### Multiple result sets
|
113
164
|
|
114
165
|
You can also retrieve multiple result sets. For this to work you need to connect with
|
115
166
|
flags `Mysql2::Client::MULTI_STATEMENTS`. Using multiple result sets is normally used
|
@@ -127,6 +178,35 @@ end
|
|
127
178
|
|
128
179
|
See https://gist.github.com/1367987 for using MULTI_STATEMENTS with Active Record.
|
129
180
|
|
181
|
+
### Secure auth
|
182
|
+
|
183
|
+
Starting wih MySQL 5.6.5, secure_auth is enabled by default on servers (it was disabled by default prior to this).
|
184
|
+
When secure_auth is enabled, the server will refuse a connection if the account password is stored in old pre-MySQL 4.1 format.
|
185
|
+
The MySQL 5.6.5 client library may also refuse to attempt a connection if provided an older format password.
|
186
|
+
To bypass this restriction in the client, pass the option :secure_auth => false to Mysql2::Client.new().
|
187
|
+
If using ActiveRecord, your database.yml might look something like this:
|
188
|
+
|
189
|
+
```
|
190
|
+
development:
|
191
|
+
adapter: mysql2
|
192
|
+
encoding: utf8
|
193
|
+
database: my_db_name
|
194
|
+
username: root
|
195
|
+
password: my_password
|
196
|
+
host: 127.0.0.1
|
197
|
+
port: 3306
|
198
|
+
secure_auth: false
|
199
|
+
```
|
200
|
+
|
201
|
+
### Reading a MySQL config file
|
202
|
+
You may read configuration options from a MySQL configuration file by passing
|
203
|
+
the `:default_file` and `:default_group` paramters. For example:
|
204
|
+
|
205
|
+
```
|
206
|
+
client = Mysql2::Client.new(:default_file => '/user/.my.cnf', :default_group => 'client')
|
207
|
+
```
|
208
|
+
|
209
|
+
|
130
210
|
## Cascading config
|
131
211
|
|
132
212
|
The default config hash is at:
|
data/ext/mysql2/client.c
CHANGED
@@ -57,7 +57,7 @@ static VALUE rb_hash_dup(VALUE other) {
|
|
57
57
|
|
58
58
|
/*
|
59
59
|
* used to pass all arguments to mysql_real_connect while inside
|
60
|
-
*
|
60
|
+
* rb_thread_call_without_gvl
|
61
61
|
*/
|
62
62
|
struct nogvl_connect_args {
|
63
63
|
MYSQL *mysql;
|
@@ -72,7 +72,7 @@ struct nogvl_connect_args {
|
|
72
72
|
|
73
73
|
/*
|
74
74
|
* used to pass all arguments to mysql_send_query while inside
|
75
|
-
*
|
75
|
+
* rb_thread_call_without_gvl
|
76
76
|
*/
|
77
77
|
struct nogvl_send_query_args {
|
78
78
|
MYSQL *mysql;
|
@@ -84,7 +84,7 @@ struct nogvl_send_query_args {
|
|
84
84
|
|
85
85
|
/*
|
86
86
|
* used to pass all arguments to mysql_select_db while inside
|
87
|
-
*
|
87
|
+
* rb_thread_call_without_gvl
|
88
88
|
*/
|
89
89
|
struct nogvl_select_db_args {
|
90
90
|
MYSQL *mysql;
|
@@ -124,6 +124,7 @@ static void rb_mysql_client_mark(void * wrapper) {
|
|
124
124
|
static VALUE rb_raise_mysql2_error(mysql_client_wrapper *wrapper) {
|
125
125
|
VALUE rb_error_msg = rb_str_new2(mysql_error(wrapper->client));
|
126
126
|
VALUE rb_sql_state = rb_tainted_str_new2(mysql_sqlstate(wrapper->client));
|
127
|
+
VALUE e;
|
127
128
|
#ifdef HAVE_RUBY_ENCODING_H
|
128
129
|
rb_encoding *default_internal_enc = rb_default_internal_encoding();
|
129
130
|
rb_encoding *conn_enc = rb_to_encoding(wrapper->encoding);
|
@@ -136,22 +137,22 @@ static VALUE rb_raise_mysql2_error(mysql_client_wrapper *wrapper) {
|
|
136
137
|
}
|
137
138
|
#endif
|
138
139
|
|
139
|
-
|
140
|
+
e = rb_exc_new3(cMysql2Error, rb_error_msg);
|
140
141
|
rb_funcall(e, intern_error_number_eql, 1, UINT2NUM(mysql_errno(wrapper->client)));
|
141
142
|
rb_funcall(e, intern_sql_state_eql, 1, rb_sql_state);
|
142
143
|
rb_exc_raise(e);
|
143
144
|
return Qnil;
|
144
145
|
}
|
145
146
|
|
146
|
-
static
|
147
|
+
static void *nogvl_init(void *ptr) {
|
147
148
|
MYSQL *client;
|
148
149
|
|
149
150
|
/* may initialize embedded server and read /etc/services off disk */
|
150
151
|
client = mysql_init((MYSQL *)ptr);
|
151
|
-
return client ? Qtrue : Qfalse;
|
152
|
+
return (void*)(client ? Qtrue : Qfalse);
|
152
153
|
}
|
153
154
|
|
154
|
-
static
|
155
|
+
static void *nogvl_connect(void *ptr) {
|
155
156
|
struct nogvl_connect_args *args = ptr;
|
156
157
|
MYSQL *client;
|
157
158
|
|
@@ -160,10 +161,10 @@ static VALUE nogvl_connect(void *ptr) {
|
|
160
161
|
args->db, args->port, args->unix_socket,
|
161
162
|
args->client_flag);
|
162
163
|
|
163
|
-
return client ? Qtrue : Qfalse;
|
164
|
+
return (void *)(client ? Qtrue : Qfalse);
|
164
165
|
}
|
165
166
|
|
166
|
-
static
|
167
|
+
static void *nogvl_close(void *ptr) {
|
167
168
|
mysql_client_wrapper *wrapper;
|
168
169
|
#ifndef _WIN32
|
169
170
|
int flags;
|
@@ -190,7 +191,7 @@ static VALUE nogvl_close(void *ptr) {
|
|
190
191
|
mysql_close(wrapper->client);
|
191
192
|
}
|
192
193
|
|
193
|
-
return
|
194
|
+
return NULL;
|
194
195
|
}
|
195
196
|
|
196
197
|
static void rb_mysql_client_free(void *ptr) {
|
@@ -283,20 +284,20 @@ static VALUE rb_connect(VALUE self, VALUE user, VALUE pass, VALUE host, VALUE po
|
|
283
284
|
VALUE rv;
|
284
285
|
GET_CLIENT(self);
|
285
286
|
|
286
|
-
args.host = NIL_P(host) ?
|
287
|
+
args.host = NIL_P(host) ? NULL : StringValuePtr(host);
|
287
288
|
args.unix_socket = NIL_P(socket) ? NULL : StringValuePtr(socket);
|
288
|
-
args.port = NIL_P(port) ?
|
289
|
+
args.port = NIL_P(port) ? 0 : NUM2INT(port);
|
289
290
|
args.user = NIL_P(user) ? NULL : StringValuePtr(user);
|
290
291
|
args.passwd = NIL_P(pass) ? NULL : StringValuePtr(pass);
|
291
292
|
args.db = NIL_P(database) ? NULL : StringValuePtr(database);
|
292
293
|
args.mysql = wrapper->client;
|
293
294
|
args.client_flag = NUM2ULONG(flags);
|
294
295
|
|
295
|
-
rv =
|
296
|
+
rv = (VALUE) rb_thread_call_without_gvl(nogvl_connect, &args, RUBY_UBF_IO, 0);
|
296
297
|
if (rv == Qfalse) {
|
297
298
|
while (rv == Qfalse && errno == EINTR && !mysql_errno(wrapper->client)) {
|
298
299
|
errno = 0;
|
299
|
-
rv =
|
300
|
+
rv = (VALUE) rb_thread_call_without_gvl(nogvl_connect, &args, RUBY_UBF_IO, 0);
|
300
301
|
}
|
301
302
|
if (rv == Qfalse)
|
302
303
|
return rb_raise_mysql2_error(wrapper);
|
@@ -316,7 +317,7 @@ static VALUE rb_mysql_client_close(VALUE self) {
|
|
316
317
|
GET_CLIENT(self);
|
317
318
|
|
318
319
|
if (wrapper->connected) {
|
319
|
-
|
320
|
+
rb_thread_call_without_gvl(nogvl_close, wrapper, RUBY_UBF_IO, 0);
|
320
321
|
}
|
321
322
|
|
322
323
|
return Qnil;
|
@@ -327,19 +328,19 @@ static VALUE rb_mysql_client_close(VALUE self) {
|
|
327
328
|
* enough to fit in a socket buffer, but sometimes large UPDATE and
|
328
329
|
* INSERTs will cause the process to block
|
329
330
|
*/
|
330
|
-
static
|
331
|
+
static void *nogvl_send_query(void *ptr) {
|
331
332
|
struct nogvl_send_query_args *args = ptr;
|
332
333
|
int rv;
|
333
334
|
|
334
335
|
rv = mysql_send_query(args->mysql, args->sql_ptr, args->sql_len);
|
335
336
|
|
336
|
-
return rv == 0 ? Qtrue : Qfalse;
|
337
|
+
return (void*)(rv == 0 ? Qtrue : Qfalse);
|
337
338
|
}
|
338
339
|
|
339
340
|
static VALUE do_send_query(void *args) {
|
340
341
|
struct nogvl_send_query_args *query_args = args;
|
341
342
|
mysql_client_wrapper *wrapper = query_args->wrapper;
|
342
|
-
if (
|
343
|
+
if ((VALUE)rb_thread_call_without_gvl(nogvl_send_query, args, RUBY_UBF_IO, 0) == Qfalse) {
|
343
344
|
/* an error occurred, we're not active anymore */
|
344
345
|
MARK_CONN_INACTIVE(self);
|
345
346
|
return rb_raise_mysql2_error(wrapper);
|
@@ -352,14 +353,14 @@ static VALUE do_send_query(void *args) {
|
|
352
353
|
* response can overflow the socket buffers and cause us to eventually
|
353
354
|
* block while calling mysql_read_query_result
|
354
355
|
*/
|
355
|
-
static
|
356
|
+
static void *nogvl_read_query_result(void *ptr) {
|
356
357
|
MYSQL * client = ptr;
|
357
358
|
my_bool res = mysql_read_query_result(client);
|
358
359
|
|
359
|
-
return res == 0 ? Qtrue : Qfalse;
|
360
|
+
return (void *)(res == 0 ? Qtrue : Qfalse);
|
360
361
|
}
|
361
362
|
|
362
|
-
static
|
363
|
+
static void *nogvl_do_result(void *ptr, char use_result) {
|
363
364
|
mysql_client_wrapper *wrapper;
|
364
365
|
MYSQL_RES *result;
|
365
366
|
|
@@ -374,15 +375,15 @@ static VALUE nogvl_do_result(void *ptr, char use_result) {
|
|
374
375
|
ready for another command to be issued */
|
375
376
|
wrapper->active_thread = Qnil;
|
376
377
|
|
377
|
-
return
|
378
|
+
return result;
|
378
379
|
}
|
379
380
|
|
380
381
|
/* mysql_store_result may (unlikely) read rows off the socket */
|
381
|
-
static
|
382
|
+
static void *nogvl_store_result(void *ptr) {
|
382
383
|
return nogvl_do_result(ptr, 0);
|
383
384
|
}
|
384
385
|
|
385
|
-
static
|
386
|
+
static void *nogvl_use_result(void *ptr) {
|
386
387
|
return nogvl_do_result(ptr, 1);
|
387
388
|
}
|
388
389
|
|
@@ -402,7 +403,7 @@ static VALUE rb_mysql_client_async_result(VALUE self) {
|
|
402
403
|
return Qnil;
|
403
404
|
|
404
405
|
REQUIRE_CONNECTED(wrapper);
|
405
|
-
if (
|
406
|
+
if ((VALUE)rb_thread_call_without_gvl(nogvl_read_query_result, wrapper->client, RUBY_UBF_IO, 0) == Qfalse) {
|
406
407
|
/* an error occurred, mark this connection inactive */
|
407
408
|
MARK_CONN_INACTIVE(self);
|
408
409
|
return rb_raise_mysql2_error(wrapper);
|
@@ -410,9 +411,9 @@ static VALUE rb_mysql_client_async_result(VALUE self) {
|
|
410
411
|
|
411
412
|
is_streaming = rb_hash_aref(rb_iv_get(self, "@current_query_options"), sym_stream);
|
412
413
|
if(is_streaming == Qtrue) {
|
413
|
-
result = (MYSQL_RES *)
|
414
|
+
result = (MYSQL_RES *)rb_thread_call_without_gvl(nogvl_use_result, wrapper, RUBY_UBF_IO, 0);
|
414
415
|
} else {
|
415
|
-
result = (MYSQL_RES *)
|
416
|
+
result = (MYSQL_RES *)rb_thread_call_without_gvl(nogvl_store_result, wrapper, RUBY_UBF_IO, 0);
|
416
417
|
}
|
417
418
|
|
418
419
|
if (result == NULL) {
|
@@ -511,7 +512,7 @@ static VALUE finish_and_mark_inactive(void *args) {
|
|
511
512
|
/* if we got here, the result hasn't been read off the wire yet
|
512
513
|
so lets do that and then throw it away because we have no way
|
513
514
|
of getting it back up to the caller from here */
|
514
|
-
result = (MYSQL_RES *)
|
515
|
+
result = (MYSQL_RES *)rb_thread_call_without_gvl(nogvl_store_result, wrapper, RUBY_UBF_IO, 0);
|
515
516
|
mysql_free_result(result);
|
516
517
|
|
517
518
|
wrapper->active_thread = Qnil;
|
@@ -530,18 +531,18 @@ static VALUE finish_and_mark_inactive(void *args) {
|
|
530
531
|
* again.
|
531
532
|
*/
|
532
533
|
static VALUE rb_mysql_client_abandon_results(VALUE self) {
|
533
|
-
GET_CLIENT(self);
|
534
|
-
|
535
534
|
MYSQL_RES *result;
|
536
535
|
int ret;
|
537
536
|
|
537
|
+
GET_CLIENT(self);
|
538
|
+
|
538
539
|
while (mysql_more_results(wrapper->client) == 1) {
|
539
540
|
ret = mysql_next_result(wrapper->client);
|
540
541
|
if (ret > 0) {
|
541
542
|
rb_raise_mysql2_error(wrapper);
|
542
543
|
}
|
543
544
|
|
544
|
-
result = (MYSQL_RES *)
|
545
|
+
result = (MYSQL_RES *)rb_thread_call_without_gvl(nogvl_store_result, wrapper, RUBY_UBF_IO, 0);
|
545
546
|
|
546
547
|
if (result != NULL) {
|
547
548
|
mysql_free_result(result);
|
@@ -679,8 +680,9 @@ static VALUE rb_mysql_client_real_escape(VALUE self, VALUE str) {
|
|
679
680
|
|
680
681
|
static VALUE _mysql_client_options(VALUE self, int opt, VALUE value) {
|
681
682
|
int result;
|
682
|
-
void *retval = NULL;
|
683
|
+
const void *retval = NULL;
|
683
684
|
unsigned int intval = 0;
|
685
|
+
const char * charval = NULL;
|
684
686
|
my_bool boolval;
|
685
687
|
|
686
688
|
GET_CLIENT(self);
|
@@ -716,6 +718,21 @@ static VALUE _mysql_client_options(VALUE self, int opt, VALUE value) {
|
|
716
718
|
retval = &boolval;
|
717
719
|
break;
|
718
720
|
|
721
|
+
case MYSQL_SECURE_AUTH:
|
722
|
+
boolval = (value == Qfalse ? 0 : 1);
|
723
|
+
retval = &boolval;
|
724
|
+
break;
|
725
|
+
|
726
|
+
case MYSQL_READ_DEFAULT_FILE:
|
727
|
+
charval = (const char *)StringValuePtr(value);
|
728
|
+
retval = charval;
|
729
|
+
break;
|
730
|
+
|
731
|
+
case MYSQL_READ_DEFAULT_GROUP:
|
732
|
+
charval = (const char *)StringValuePtr(value);
|
733
|
+
retval = charval;
|
734
|
+
break;
|
735
|
+
|
719
736
|
default:
|
720
737
|
return Qfalse;
|
721
738
|
}
|
@@ -744,8 +761,8 @@ static VALUE rb_mysql_client_info(VALUE self) {
|
|
744
761
|
#ifdef HAVE_RUBY_ENCODING_H
|
745
762
|
rb_encoding *default_internal_enc;
|
746
763
|
rb_encoding *conn_enc;
|
747
|
-
#endif
|
748
764
|
GET_CLIENT(self);
|
765
|
+
#endif
|
749
766
|
version = rb_hash_new();
|
750
767
|
|
751
768
|
#ifdef HAVE_RUBY_ENCODING_H
|
@@ -805,9 +822,12 @@ static VALUE rb_mysql_client_server_info(VALUE self) {
|
|
805
822
|
static VALUE rb_mysql_client_socket(VALUE self) {
|
806
823
|
GET_CLIENT(self);
|
807
824
|
#ifndef _WIN32
|
808
|
-
|
809
|
-
|
810
|
-
|
825
|
+
{
|
826
|
+
int fd_set_fd;
|
827
|
+
REQUIRE_CONNECTED(wrapper);
|
828
|
+
fd_set_fd = wrapper->client->net.fd;
|
829
|
+
return INT2NUM(fd_set_fd);
|
830
|
+
}
|
811
831
|
#else
|
812
832
|
rb_raise(cMysql2Error, "Raw access to the mysql file descriptor isn't supported on Windows");
|
813
833
|
#endif
|
@@ -857,13 +877,13 @@ static VALUE rb_mysql_client_thread_id(VALUE self) {
|
|
857
877
|
return ULL2NUM(retVal);
|
858
878
|
}
|
859
879
|
|
860
|
-
static
|
880
|
+
static void *nogvl_select_db(void *ptr) {
|
861
881
|
struct nogvl_select_db_args *args = ptr;
|
862
882
|
|
863
883
|
if (mysql_select_db(args->mysql, args->db) == 0)
|
864
|
-
return Qtrue;
|
884
|
+
return (void *)Qtrue;
|
865
885
|
else
|
866
|
-
return Qfalse;
|
886
|
+
return (void *)Qfalse;
|
867
887
|
}
|
868
888
|
|
869
889
|
/* call-seq:
|
@@ -882,16 +902,16 @@ static VALUE rb_mysql_client_select_db(VALUE self, VALUE db)
|
|
882
902
|
args.mysql = wrapper->client;
|
883
903
|
args.db = StringValuePtr(db);
|
884
904
|
|
885
|
-
if (
|
905
|
+
if (rb_thread_call_without_gvl(nogvl_select_db, &args, RUBY_UBF_IO, 0) == Qfalse)
|
886
906
|
rb_raise_mysql2_error(wrapper);
|
887
907
|
|
888
908
|
return db;
|
889
909
|
}
|
890
910
|
|
891
|
-
static
|
911
|
+
static void *nogvl_ping(void *ptr) {
|
892
912
|
MYSQL *client = ptr;
|
893
913
|
|
894
|
-
return mysql_ping(client) == 0 ? Qtrue : Qfalse;
|
914
|
+
return (void *)(mysql_ping(client) == 0 ? Qtrue : Qfalse);
|
895
915
|
}
|
896
916
|
|
897
917
|
/* call-seq:
|
@@ -908,7 +928,7 @@ static VALUE rb_mysql_client_ping(VALUE self) {
|
|
908
928
|
if (!wrapper->connected) {
|
909
929
|
return Qfalse;
|
910
930
|
} else {
|
911
|
-
return
|
931
|
+
return (VALUE)rb_thread_call_without_gvl(nogvl_ping, wrapper->client, RUBY_UBF_IO, 0);
|
912
932
|
}
|
913
933
|
}
|
914
934
|
|
@@ -934,8 +954,8 @@ static VALUE rb_mysql_client_more_results(VALUE self)
|
|
934
954
|
*/
|
935
955
|
static VALUE rb_mysql_client_next_result(VALUE self)
|
936
956
|
{
|
937
|
-
GET_CLIENT(self);
|
938
957
|
int ret;
|
958
|
+
GET_CLIENT(self);
|
939
959
|
ret = mysql_next_result(wrapper->client);
|
940
960
|
if (ret > 0) {
|
941
961
|
rb_raise_mysql2_error(wrapper);
|
@@ -960,7 +980,7 @@ static VALUE rb_mysql_client_store_result(VALUE self)
|
|
960
980
|
VALUE current;
|
961
981
|
GET_CLIENT(self);
|
962
982
|
|
963
|
-
result = (MYSQL_RES *)
|
983
|
+
result = (MYSQL_RES *)rb_thread_call_without_gvl(nogvl_store_result, wrapper, RUBY_UBF_IO, 0);
|
964
984
|
|
965
985
|
if (result == NULL) {
|
966
986
|
if (mysql_errno(wrapper->client) != 0) {
|
@@ -1041,18 +1061,18 @@ static VALUE set_write_timeout(VALUE self, VALUE value) {
|
|
1041
1061
|
|
1042
1062
|
static VALUE set_charset_name(VALUE self, VALUE value) {
|
1043
1063
|
char *charset_name;
|
1064
|
+
#ifdef HAVE_RUBY_ENCODING_H
|
1044
1065
|
size_t charset_name_len;
|
1045
1066
|
const struct mysql2_mysql_enc_name_to_rb_map *mysql2rb;
|
1046
|
-
#ifdef HAVE_RUBY_ENCODING_H
|
1047
1067
|
rb_encoding *enc;
|
1048
1068
|
VALUE rb_enc;
|
1049
1069
|
#endif
|
1050
1070
|
GET_CLIENT(self);
|
1051
1071
|
|
1052
1072
|
charset_name = RSTRING_PTR(value);
|
1053
|
-
charset_name_len = RSTRING_LEN(value);
|
1054
1073
|
|
1055
1074
|
#ifdef HAVE_RUBY_ENCODING_H
|
1075
|
+
charset_name_len = RSTRING_LEN(value);
|
1056
1076
|
mysql2rb = mysql2_mysql_enc_name_to_rb(charset_name, charset_name_len);
|
1057
1077
|
if (mysql2rb == NULL || mysql2rb->rb_name == NULL) {
|
1058
1078
|
VALUE inspect = rb_inspect(value);
|
@@ -1085,10 +1105,22 @@ static VALUE set_ssl_options(VALUE self, VALUE key, VALUE cert, VALUE ca, VALUE
|
|
1085
1105
|
return self;
|
1086
1106
|
}
|
1087
1107
|
|
1108
|
+
static VALUE set_secure_auth(VALUE self, VALUE value) {
|
1109
|
+
return _mysql_client_options(self, MYSQL_SECURE_AUTH, value);
|
1110
|
+
}
|
1111
|
+
|
1112
|
+
static VALUE set_read_default_file(VALUE self, VALUE value) {
|
1113
|
+
return _mysql_client_options(self, MYSQL_READ_DEFAULT_FILE, value);
|
1114
|
+
}
|
1115
|
+
|
1116
|
+
static VALUE set_read_default_group(VALUE self, VALUE value) {
|
1117
|
+
return _mysql_client_options(self, MYSQL_READ_DEFAULT_GROUP, value);
|
1118
|
+
}
|
1119
|
+
|
1088
1120
|
static VALUE initialize_ext(VALUE self) {
|
1089
1121
|
GET_CLIENT(self);
|
1090
1122
|
|
1091
|
-
if (
|
1123
|
+
if ((VALUE)rb_thread_call_without_gvl(nogvl_init, wrapper->client, RUBY_UBF_IO, 0) == Qfalse) {
|
1092
1124
|
/* TODO: warning - not enough memory? */
|
1093
1125
|
return rb_raise_mysql2_error(wrapper);
|
1094
1126
|
}
|
@@ -1153,6 +1185,9 @@ void init_mysql2_client() {
|
|
1153
1185
|
rb_define_private_method(cMysql2Client, "write_timeout=", set_write_timeout, 1);
|
1154
1186
|
rb_define_private_method(cMysql2Client, "local_infile=", set_local_infile, 1);
|
1155
1187
|
rb_define_private_method(cMysql2Client, "charset_name=", set_charset_name, 1);
|
1188
|
+
rb_define_private_method(cMysql2Client, "secure_auth=", set_secure_auth, 1);
|
1189
|
+
rb_define_private_method(cMysql2Client, "default_file=", set_read_default_file, 1);
|
1190
|
+
rb_define_private_method(cMysql2Client, "default_group=", set_read_default_group, 1);
|
1156
1191
|
rb_define_private_method(cMysql2Client, "ssl_set", set_ssl_options, 5);
|
1157
1192
|
rb_define_private_method(cMysql2Client, "initialize_ext", initialize_ext, 0);
|
1158
1193
|
rb_define_private_method(cMysql2Client, "connect", rb_connect, 7);
|
data/ext/mysql2/client.h
CHANGED
@@ -1,24 +1,30 @@
|
|
1
1
|
#ifndef MYSQL2_CLIENT_H
|
2
2
|
#define MYSQL2_CLIENT_H
|
3
3
|
|
4
|
+
#ifndef HAVE_RB_THREAD_CALL_WITHOUT_GVL
|
5
|
+
#ifdef HAVE_RB_THREAD_BLOCKING_REGION
|
6
|
+
|
7
|
+
/* emulate rb_thread_call_without_gvl with rb_thread_blocking_region */
|
8
|
+
#define rb_thread_call_without_gvl(func, data1, ubf, data2) \
|
9
|
+
rb_thread_blocking_region((rb_blocking_function_t *)func, data1, ubf, data2)
|
10
|
+
|
11
|
+
#else /* ! HAVE_RB_THREAD_BLOCKING_REGION */
|
4
12
|
/*
|
5
|
-
* partial emulation of the
|
13
|
+
* partial emulation of the 2.0 rb_thread_call_without_gvl under 1.8,
|
6
14
|
* this is enough for dealing with blocking I/O functions in the
|
7
15
|
* presence of threads.
|
8
16
|
*/
|
9
|
-
#ifndef HAVE_RB_THREAD_BLOCKING_REGION
|
10
17
|
|
11
18
|
#include <rubysig.h>
|
12
19
|
#define RUBY_UBF_IO ((rb_unblock_function_t *)-1)
|
13
20
|
typedef void rb_unblock_function_t(void *);
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
rb_blocking_function_t *func, void *data1,
|
21
|
+
static void *
|
22
|
+
rb_thread_call_without_gvl(
|
23
|
+
void *(*func)(void *), void *data1,
|
18
24
|
RB_MYSQL_UNUSED rb_unblock_function_t *ubf,
|
19
25
|
RB_MYSQL_UNUSED void *data2)
|
20
26
|
{
|
21
|
-
|
27
|
+
void *rv;
|
22
28
|
|
23
29
|
TRAP_BEG;
|
24
30
|
rv = func(data1);
|
@@ -28,6 +34,7 @@ rb_thread_blocking_region(
|
|
28
34
|
}
|
29
35
|
|
30
36
|
#endif /* ! HAVE_RB_THREAD_BLOCKING_REGION */
|
37
|
+
#endif /* ! HAVE_RB_THREAD_CALL_WITHOUT_GVL */
|
31
38
|
|
32
39
|
void init_mysql2_client();
|
33
40
|
|
data/ext/mysql2/extconf.rb
CHANGED
@@ -5,6 +5,9 @@ def asplode lib
|
|
5
5
|
abort "-----\n#{lib} is missing. please check your installation of mysql and try again.\n-----"
|
6
6
|
end
|
7
7
|
|
8
|
+
# 2.0-only
|
9
|
+
have_header('ruby/thread.h') && have_func('rb_thread_call_without_gvl', 'ruby/thread.h')
|
10
|
+
|
8
11
|
# 1.9-only
|
9
12
|
have_func('rb_thread_blocking_region')
|
10
13
|
have_func('rb_wait_for_single_fd')
|
@@ -28,21 +31,29 @@ dirs = ENV['PATH'].split(File::PATH_SEPARATOR) + %w[
|
|
28
31
|
|
29
32
|
GLOB = "{#{dirs.join(',')}}/{mysql_config,mysql_config5}"
|
30
33
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
+
# If the user has provided a --with-mysql-dir argument, we must respect it or fail.
|
35
|
+
inc, lib = dir_config('mysql')
|
36
|
+
if inc && lib
|
34
37
|
# Ruby versions not incorporating the mkmf fix at
|
35
38
|
# https://bugs.ruby-lang.org/projects/ruby-trunk/repository/revisions/39717
|
36
39
|
# do not properly search for lib directories, and must be corrected
|
37
|
-
unless lib[-3, 3] == 'lib'
|
40
|
+
unless lib && lib[-3, 3] == 'lib'
|
38
41
|
@libdir_basename = 'lib'
|
39
42
|
inc, lib = dir_config('mysql')
|
40
43
|
end
|
41
|
-
|
42
|
-
|
44
|
+
abort "-----\nCannot find include dir at #{inc}\n-----" unless inc && File.directory?(inc)
|
45
|
+
abort "-----\nCannot find library dir at #{lib}\n-----" unless lib && File.directory?(lib)
|
46
|
+
warn "-----\nUsing --with-mysql-dir=#{File.dirname inc}\n-----"
|
47
|
+
rpath_dir = lib
|
48
|
+
elsif mc = (with_config('mysql-config') || Dir[GLOB].first)
|
49
|
+
# If the user has provided a --with-mysql-config argument, we must respect it or fail.
|
50
|
+
# If the user gave --with-mysql-config with no argument means we should try to find it.
|
43
51
|
mc = Dir[GLOB].first if mc == true
|
52
|
+
abort "-----\nCannot find mysql_config at #{mc}\n-----" unless mc && File.exists?(mc)
|
53
|
+
abort "-----\nCannot execute mysql_config at #{mc}\n-----" unless File.executable?(mc)
|
54
|
+
warn "-----\nUsing mysql_config at #{mc}\n-----"
|
44
55
|
ver = `#{mc} --version`.chomp.to_f
|
45
|
-
|
56
|
+
includes = `#{mc} --include`.chomp
|
46
57
|
exit 1 if $? != 0
|
47
58
|
libs = `#{mc} --libs_r`.chomp
|
48
59
|
# MySQL 5.5 and above already have re-entrant code in libmysqlclient (no _r).
|
@@ -50,8 +61,9 @@ elsif mc = (with_config('mysql-config') || Dir[GLOB].first) then
|
|
50
61
|
libs = `#{mc} --libs`.chomp
|
51
62
|
end
|
52
63
|
exit 1 if $? != 0
|
53
|
-
$
|
64
|
+
$INCFLAGS += ' ' + includes
|
54
65
|
$libs = libs + " " + $libs
|
66
|
+
rpath_dir = libs
|
55
67
|
else
|
56
68
|
inc, lib = dir_config('mysql', '/usr/local')
|
57
69
|
libs = ['m', 'z', 'socket', 'nsl', 'mygcc']
|
@@ -59,11 +71,16 @@ else
|
|
59
71
|
exit 1 if libs.empty?
|
60
72
|
have_library(libs.shift)
|
61
73
|
end
|
74
|
+
rpath_dir = lib
|
75
|
+
end
|
76
|
+
|
77
|
+
if RUBY_PLATFORM =~ /mswin|mingw/
|
78
|
+
exit 1 unless have_library('libmysql')
|
62
79
|
end
|
63
80
|
|
64
|
-
if have_header('mysql.h')
|
81
|
+
if have_header('mysql.h')
|
65
82
|
prefix = nil
|
66
|
-
elsif have_header('mysql/mysql.h')
|
83
|
+
elsif have_header('mysql/mysql.h')
|
67
84
|
prefix = 'mysql'
|
68
85
|
else
|
69
86
|
asplode 'mysql.h'
|
@@ -74,16 +91,38 @@ end
|
|
74
91
|
asplode h unless have_header h
|
75
92
|
end
|
76
93
|
|
77
|
-
#
|
78
|
-
|
79
|
-
|
94
|
+
# These gcc style flags are also supported by clang and xcode compilers,
|
95
|
+
# so we'll use a does-it-work test instead of an is-it-gcc test.
|
96
|
+
gcc_flags = ' -Wall -funroll-loops'
|
97
|
+
if try_link('int main() {return 0;}', gcc_flags)
|
98
|
+
$CFLAGS << gcc_flags
|
99
|
+
end
|
80
100
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
101
|
+
case explicit_rpath = with_config('mysql-rpath')
|
102
|
+
when true
|
103
|
+
abort "-----\nOption --with-mysql-rpath must have an argument\n-----"
|
104
|
+
when false
|
105
|
+
warn "-----\nOption --with-mysql-rpath has been disabled at your request\n-----"
|
106
|
+
when String
|
107
|
+
# The user gave us a value so use it
|
108
|
+
rpath_flags = " -Wl,-rpath,#{explicit_rpath}"
|
109
|
+
warn "-----\nSetting mysql rpath to #{explicit_rpath}\n-----"
|
110
|
+
$LDFLAGS << rpath_flags
|
111
|
+
else
|
112
|
+
if libdir = rpath_dir[%r{(-L)?(/[^ ]+)}, 2]
|
113
|
+
rpath_flags = " -Wl,-rpath,#{libdir}"
|
114
|
+
if RbConfig::CONFIG["RPATHFLAG"].to_s.empty? && try_link('int main() {return 0;}', rpath_flags)
|
115
|
+
# Usually Ruby sets RPATHFLAG the right way for each system, but not on OS X.
|
116
|
+
warn "-----\nSetting rpath to #{libdir}\n-----"
|
117
|
+
$LDFLAGS << rpath_flags
|
118
|
+
else
|
119
|
+
if RbConfig::CONFIG["RPATHFLAG"].to_s.empty?
|
120
|
+
# If we got here because try_link failed, warn the user
|
121
|
+
warn "-----\nDon't know how to set rpath on your system, if MySQL libraries are not in path mysql2 may not load\n-----"
|
122
|
+
end
|
123
|
+
# Make sure that LIBPATH gets set if we didn't explicitly set the rpath.
|
124
|
+
warn "-----\nSetting libpath to #{libdir}\n-----"
|
125
|
+
$LIBPATH << libdir unless $LIBPATH.include?(libdir)
|
87
126
|
end
|
88
127
|
end
|
89
128
|
end
|
data/ext/mysql2/mysql2_ext.h
CHANGED
@@ -29,6 +29,9 @@ typedef unsigned int uint;
|
|
29
29
|
#ifdef HAVE_RUBY_ENCODING_H
|
30
30
|
#include <ruby/encoding.h>
|
31
31
|
#endif
|
32
|
+
#ifdef HAVE_RUBY_THREAD_H
|
33
|
+
#include <ruby/thread.h>
|
34
|
+
#endif
|
32
35
|
|
33
36
|
#if defined(__GNUC__) && (__GNUC__ >= 3)
|
34
37
|
#define RB_MYSQL_UNUSED __attribute__ ((unused))
|
data/ext/mysql2/result.c
CHANGED
@@ -99,10 +99,10 @@ static void rb_mysql_result_free(void *ptr) {
|
|
99
99
|
* reliable way for us to tell this so we'll always release the GVL
|
100
100
|
* to be safe
|
101
101
|
*/
|
102
|
-
static
|
102
|
+
static void *nogvl_fetch_row(void *ptr) {
|
103
103
|
MYSQL_RES *result = ptr;
|
104
104
|
|
105
|
-
return
|
105
|
+
return mysql_fetch_row(result);
|
106
106
|
}
|
107
107
|
|
108
108
|
static VALUE rb_mysql_result_fetch_field(VALUE self, unsigned int idx, short int symbolize_keys) {
|
@@ -157,6 +157,9 @@ static VALUE mysql2_set_field_string_encoding(VALUE val, MYSQL_FIELD field, rb_e
|
|
157
157
|
/* if binary flag is set, respect it's wishes */
|
158
158
|
if (field.flags & BINARY_FLAG && field.charsetnr == 63) {
|
159
159
|
rb_enc_associate(val, binaryEncoding);
|
160
|
+
} else if (!field.charsetnr) {
|
161
|
+
/* MySQL 4.x may not provide an encoding, binary will get the bytes through */
|
162
|
+
rb_enc_associate(val, binaryEncoding);
|
160
163
|
} else {
|
161
164
|
/* lookup the encoding configured on this field */
|
162
165
|
const char *enc_name;
|
@@ -200,7 +203,7 @@ static VALUE rb_mysql_result_fetch_row(VALUE self, ID db_timezone, ID app_timezo
|
|
200
203
|
#endif
|
201
204
|
|
202
205
|
ptr = wrapper->result;
|
203
|
-
row = (MYSQL_ROW)
|
206
|
+
row = (MYSQL_ROW)rb_thread_call_without_gvl(nogvl_fetch_row, ptr, RUBY_UBF_IO, 0);
|
204
207
|
if (row == NULL) {
|
205
208
|
return Qnil;
|
206
209
|
}
|
@@ -280,6 +283,10 @@ static VALUE rb_mysql_result_fetch_row(VALUE self, ID db_timezone, ID app_timezo
|
|
280
283
|
int tokens;
|
281
284
|
unsigned int hour=0, min=0, sec=0;
|
282
285
|
tokens = sscanf(row[i], "%2u:%2u:%2u", &hour, &min, &sec);
|
286
|
+
if (tokens < 3) {
|
287
|
+
val = Qnil;
|
288
|
+
break;
|
289
|
+
}
|
283
290
|
val = rb_funcall(rb_cTime, db_timezone, 6, opt_time_year, opt_time_month, opt_time_month, UINT2NUM(hour), UINT2NUM(min), UINT2NUM(sec));
|
284
291
|
if (!NIL_P(app_timezone)) {
|
285
292
|
if (app_timezone == intern_local) {
|
@@ -297,6 +304,10 @@ static VALUE rb_mysql_result_fetch_row(VALUE self, ID db_timezone, ID app_timezo
|
|
297
304
|
uint64_t seconds;
|
298
305
|
|
299
306
|
tokens = sscanf(row[i], "%4u-%2u-%2u %2u:%2u:%2u.%6u", &year, &month, &day, &hour, &min, &sec, &msec);
|
307
|
+
if (tokens < 6) { /* msec might be empty */
|
308
|
+
val = Qnil;
|
309
|
+
break;
|
310
|
+
}
|
300
311
|
seconds = (year*31557600ULL) + (month*2592000ULL) + (day*86400ULL) + (hour*3600ULL) + (min*60ULL) + sec;
|
301
312
|
|
302
313
|
if (seconds == 0) {
|
@@ -339,6 +350,10 @@ static VALUE rb_mysql_result_fetch_row(VALUE self, ID db_timezone, ID app_timezo
|
|
339
350
|
int tokens;
|
340
351
|
unsigned int year=0, month=0, day=0;
|
341
352
|
tokens = sscanf(row[i], "%4u-%2u-%2u", &year, &month, &day);
|
353
|
+
if (tokens < 3) {
|
354
|
+
val = Qnil;
|
355
|
+
break;
|
356
|
+
}
|
342
357
|
if (year+month+day == 0) {
|
343
358
|
val = Qnil;
|
344
359
|
} else {
|
data/lib/mysql2/client.rb
CHANGED
@@ -10,7 +10,9 @@ module Mysql2
|
|
10
10
|
:application_timezone => nil, # timezone Mysql2 will convert to before handing the object back to the caller
|
11
11
|
:cache_rows => true, # tells Mysql2 to use it's internal row cache for results
|
12
12
|
:connect_flags => REMEMBER_OPTIONS | LONG_PASSWORD | LONG_FLAG | TRANSACTIONS | PROTOCOL_41 | SECURE_CONNECTION,
|
13
|
-
:cast => true
|
13
|
+
:cast => true,
|
14
|
+
:default_file => nil,
|
15
|
+
:default_group => nil
|
14
16
|
}
|
15
17
|
|
16
18
|
def initialize(opts = {})
|
@@ -21,11 +23,10 @@ module Mysql2
|
|
21
23
|
|
22
24
|
initialize_ext
|
23
25
|
|
24
|
-
|
25
|
-
[:reconnect, :connect_timeout, :local_infile, :read_timeout, :write_timeout].each do |key|
|
26
|
+
[:reconnect, :connect_timeout, :local_infile, :read_timeout, :write_timeout, :default_file, :default_group, :secure_auth].each do |key|
|
26
27
|
next unless opts.key?(key)
|
27
28
|
case key
|
28
|
-
when :reconnect, :local_infile
|
29
|
+
when :reconnect, :local_infile, :secure_auth
|
29
30
|
send(:"#{key}=", !!opts[key])
|
30
31
|
when :connect_timeout, :read_timeout, :write_timeout
|
31
32
|
send(:"#{key}=", opts[key].to_i)
|
@@ -49,12 +50,20 @@ module Mysql2
|
|
49
50
|
|
50
51
|
user = opts[:username] || opts[:user]
|
51
52
|
pass = opts[:password] || opts[:pass]
|
52
|
-
host = opts[:host] || opts[:hostname]
|
53
|
-
port = opts[:port]
|
53
|
+
host = opts[:host] || opts[:hostname]
|
54
|
+
port = opts[:port]
|
54
55
|
database = opts[:database] || opts[:dbname] || opts[:db]
|
55
56
|
socket = opts[:socket] || opts[:sock]
|
56
57
|
flags = opts[:flags] ? opts[:flags] | @query_options[:connect_flags] : @query_options[:connect_flags]
|
57
58
|
|
59
|
+
# Correct the data types before passing these values down to the C level
|
60
|
+
user = user.to_s unless user.nil?
|
61
|
+
pass = pass.to_s unless pass.nil?
|
62
|
+
host = host.to_s unless host.nil?
|
63
|
+
port = port.to_i unless port.nil?
|
64
|
+
database = database.to_s unless database.nil?
|
65
|
+
socket = socket.to_s unless socket.nil?
|
66
|
+
|
58
67
|
connect user, pass, host, port, database, socket, flags
|
59
68
|
end
|
60
69
|
|
data/lib/mysql2/version.rb
CHANGED
data/spec/my.cnf.example
ADDED
data/spec/mysql2/client_spec.rb
CHANGED
@@ -2,6 +2,22 @@
|
|
2
2
|
require 'spec_helper'
|
3
3
|
|
4
4
|
describe Mysql2::Client do
|
5
|
+
context "using defaults file" do
|
6
|
+
let(:cnf_file) { File.expand_path('../../my.cnf', __FILE__) }
|
7
|
+
|
8
|
+
it "should not raise an exception for valid defaults group" do
|
9
|
+
lambda {
|
10
|
+
@client = Mysql2::Client.new(:default_file => cnf_file, :default_group => "test")
|
11
|
+
}.should_not raise_error(Mysql2::Error)
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should not raise an exception without default group" do
|
15
|
+
lambda {
|
16
|
+
@client = Mysql2::Client.new(:default_file => cnf_file)
|
17
|
+
}.should_not raise_error(Mysql2::Error)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
5
21
|
it "should raise an exception upon connection failure" do
|
6
22
|
lambda {
|
7
23
|
# The odd local host IP address forces the mysql client library to
|
@@ -88,6 +104,16 @@ describe Mysql2::Client do
|
|
88
104
|
ssl_client.close
|
89
105
|
end
|
90
106
|
|
107
|
+
it "should be able to connect to database with numeric-only name" do
|
108
|
+
lambda {
|
109
|
+
creds = DatabaseCredentials['numericuser']
|
110
|
+
@client.query "CREATE DATABASE IF NOT EXISTS `#{creds['database']}`"
|
111
|
+
@client.query "GRANT ALL ON `#{creds['database']}`.* TO #{creds['username']}@`#{creds['host']}`"
|
112
|
+
client = Mysql2::Client.new creds
|
113
|
+
@client.query "DROP DATABASE IF EXISTS `#{creds['database']}`"
|
114
|
+
}.should_not raise_error
|
115
|
+
end
|
116
|
+
|
91
117
|
it "should respond to #close" do
|
92
118
|
@client.should respond_to(:close)
|
93
119
|
end
|
metadata
CHANGED
@@ -1,36 +1,32 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mysql2
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
5
|
-
prerelease:
|
4
|
+
version: 0.2.21
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Brian Lopez
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date: 2013-07
|
11
|
+
date: 2013-11-07 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: eventmachine
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
|
-
- -
|
17
|
+
- - '>='
|
20
18
|
- !ruby/object:Gem::Version
|
21
19
|
version: '0'
|
22
20
|
type: :development
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
|
-
- -
|
24
|
+
- - '>='
|
28
25
|
- !ruby/object:Gem::Version
|
29
26
|
version: '0'
|
30
27
|
- !ruby/object:Gem::Dependency
|
31
28
|
name: rake-compiler
|
32
29
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
30
|
requirements:
|
35
31
|
- - ~>
|
36
32
|
- !ruby/object:Gem::Version
|
@@ -38,7 +34,6 @@ dependencies:
|
|
38
34
|
type: :development
|
39
35
|
prerelease: false
|
40
36
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
37
|
requirements:
|
43
38
|
- - ~>
|
44
39
|
- !ruby/object:Gem::Version
|
@@ -46,7 +41,6 @@ dependencies:
|
|
46
41
|
- !ruby/object:Gem::Dependency
|
47
42
|
name: rake
|
48
43
|
requirement: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
44
|
requirements:
|
51
45
|
- - ~>
|
52
46
|
- !ruby/object:Gem::Version
|
@@ -54,7 +48,6 @@ dependencies:
|
|
54
48
|
type: :development
|
55
49
|
prerelease: false
|
56
50
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
none: false
|
58
51
|
requirements:
|
59
52
|
- - ~>
|
60
53
|
- !ruby/object:Gem::Version
|
@@ -62,7 +55,6 @@ dependencies:
|
|
62
55
|
- !ruby/object:Gem::Dependency
|
63
56
|
name: rspec
|
64
57
|
requirement: !ruby/object:Gem::Requirement
|
65
|
-
none: false
|
66
58
|
requirements:
|
67
59
|
- - ~>
|
68
60
|
- !ruby/object:Gem::Version
|
@@ -70,7 +62,6 @@ dependencies:
|
|
70
62
|
type: :development
|
71
63
|
prerelease: false
|
72
64
|
version_requirements: !ruby/object:Gem::Requirement
|
73
|
-
none: false
|
74
65
|
requirements:
|
75
66
|
- - ~>
|
76
67
|
- !ruby/object:Gem::Version
|
@@ -109,6 +100,7 @@ files:
|
|
109
100
|
- examples/threaded.rb
|
110
101
|
- spec/configuration.yml.example
|
111
102
|
- spec/em/em_spec.rb
|
103
|
+
- spec/my.cnf.example
|
112
104
|
- spec/mysql2/client_spec.rb
|
113
105
|
- spec/mysql2/error_spec.rb
|
114
106
|
- spec/mysql2/result_spec.rb
|
@@ -117,34 +109,34 @@ files:
|
|
117
109
|
homepage: http://github.com/brianmario/mysql2
|
118
110
|
licenses:
|
119
111
|
- MIT
|
112
|
+
metadata: {}
|
120
113
|
post_install_message:
|
121
114
|
rdoc_options:
|
122
115
|
- --charset=UTF-8
|
123
116
|
require_paths:
|
124
117
|
- lib
|
125
118
|
required_ruby_version: !ruby/object:Gem::Requirement
|
126
|
-
none: false
|
127
119
|
requirements:
|
128
|
-
- -
|
120
|
+
- - '>='
|
129
121
|
- !ruby/object:Gem::Version
|
130
122
|
version: '0'
|
131
123
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
132
|
-
none: false
|
133
124
|
requirements:
|
134
|
-
- -
|
125
|
+
- - '>='
|
135
126
|
- !ruby/object:Gem::Version
|
136
127
|
version: '0'
|
137
128
|
requirements: []
|
138
129
|
rubyforge_project:
|
139
|
-
rubygems_version:
|
130
|
+
rubygems_version: 2.0.3
|
140
131
|
signing_key:
|
141
|
-
specification_version:
|
132
|
+
specification_version: 4
|
142
133
|
summary: A simple, fast Mysql library for Ruby, binding to libmysql
|
143
134
|
test_files:
|
144
135
|
- examples/eventmachine.rb
|
145
136
|
- examples/threaded.rb
|
146
137
|
- spec/configuration.yml.example
|
147
138
|
- spec/em/em_spec.rb
|
139
|
+
- spec/my.cnf.example
|
148
140
|
- spec/mysql2/client_spec.rb
|
149
141
|
- spec/mysql2/error_spec.rb
|
150
142
|
- spec/mysql2/result_spec.rb
|