mysql2 0.3.13 → 0.3.14
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 +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: c05c6f7a1476667b0e6f1f8b94288a70e82cad15
|
4
|
+
data.tar.gz: b28cb5dcccf46727e60e0d30971a8e25183c4df2
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: fa54239e2f7a16ecd4bd3481274f71619c97f61e607245e17aa091e654dc2334cb89b4d604999156aa7d7cb6905f5342aed97c99a5caca1fb32773ca22e7e01d
|
7
|
+
data.tar.gz: 65d9be8d59967b977b09f95321a00e67fbfb0822da39a57a1dfb18164cd109d7a4f966174800fbc0e1d864727b7ba463deee2a123c4f9cbbf2cd05508b93b9e0
|
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.3.
|
5
|
-
prerelease:
|
4
|
+
version: 0.3.14
|
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
|
@@ -107,6 +98,7 @@ files:
|
|
107
98
|
- examples/threaded.rb
|
108
99
|
- spec/configuration.yml.example
|
109
100
|
- spec/em/em_spec.rb
|
101
|
+
- spec/my.cnf.example
|
110
102
|
- spec/mysql2/client_spec.rb
|
111
103
|
- spec/mysql2/error_spec.rb
|
112
104
|
- spec/mysql2/result_spec.rb
|
@@ -115,34 +107,34 @@ files:
|
|
115
107
|
homepage: http://github.com/brianmario/mysql2
|
116
108
|
licenses:
|
117
109
|
- MIT
|
110
|
+
metadata: {}
|
118
111
|
post_install_message:
|
119
112
|
rdoc_options:
|
120
113
|
- --charset=UTF-8
|
121
114
|
require_paths:
|
122
115
|
- lib
|
123
116
|
required_ruby_version: !ruby/object:Gem::Requirement
|
124
|
-
none: false
|
125
117
|
requirements:
|
126
|
-
- -
|
118
|
+
- - '>='
|
127
119
|
- !ruby/object:Gem::Version
|
128
120
|
version: '0'
|
129
121
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
130
|
-
none: false
|
131
122
|
requirements:
|
132
|
-
- -
|
123
|
+
- - '>='
|
133
124
|
- !ruby/object:Gem::Version
|
134
125
|
version: '0'
|
135
126
|
requirements: []
|
136
127
|
rubyforge_project:
|
137
|
-
rubygems_version:
|
128
|
+
rubygems_version: 2.0.3
|
138
129
|
signing_key:
|
139
|
-
specification_version:
|
130
|
+
specification_version: 4
|
140
131
|
summary: A simple, fast Mysql library for Ruby, binding to libmysql
|
141
132
|
test_files:
|
142
133
|
- examples/eventmachine.rb
|
143
134
|
- examples/threaded.rb
|
144
135
|
- spec/configuration.yml.example
|
145
136
|
- spec/em/em_spec.rb
|
137
|
+
- spec/my.cnf.example
|
146
138
|
- spec/mysql2/client_spec.rb
|
147
139
|
- spec/mysql2/error_spec.rb
|
148
140
|
- spec/mysql2/result_spec.rb
|