mysql2 0.3.21-x86-mswin32-60 → 0.4.0-x86-mswin32-60
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +1 -0
- data/README.md +28 -6
- data/examples/threaded.rb +4 -6
- data/ext/mysql2/client.c +54 -46
- data/ext/mysql2/client.h +21 -0
- data/ext/mysql2/extconf.rb +20 -23
- data/ext/mysql2/mysql2_ext.c +1 -0
- data/ext/mysql2/mysql2_ext.h +1 -0
- data/ext/mysql2/mysql_enc_name_to_ruby.h +6 -6
- data/ext/mysql2/result.c +473 -94
- data/ext/mysql2/result.h +8 -1
- data/ext/mysql2/statement.c +454 -0
- data/ext/mysql2/statement.h +22 -0
- data/lib/mysql2.rb +2 -18
- data/lib/mysql2/1.8/mysql2.so +0 -0
- data/lib/mysql2/1.9/mysql2.so +0 -0
- data/lib/mysql2/2.0/mysql2.so +0 -0
- data/lib/mysql2/2.1/mysql2.so +0 -0
- data/lib/mysql2/2.2/mysql2.so +0 -0
- data/lib/mysql2/client.rb +9 -2
- data/lib/mysql2/error.rb +8 -20
- data/lib/mysql2/field.rb +4 -0
- data/lib/mysql2/statement.rb +5 -0
- data/lib/mysql2/version.rb +1 -1
- data/spec/em/em_spec.rb +13 -13
- data/spec/mysql2/client_spec.rb +284 -277
- data/spec/mysql2/error_spec.rb +37 -36
- data/spec/mysql2/result_spec.rb +184 -193
- data/spec/mysql2/statement_spec.rb +598 -0
- data/spec/spec_helper.rb +7 -0
- metadata +15 -48
- data/lib/mysql2/2.3/mysql2.so +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3ad88f1815544a3523efa5b66aa683c263ed1e93
|
4
|
+
data.tar.gz: 3edac0bd615e99cb27acf956c955bde32064776d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c9675bbe962f5c997de812c6b04f0721432acf117d0ac95fdb6e9e3e5bf169067b1fdc5ed74df8b62876d96afbf242c092902abc2bb0f6004a8f11e204b09df5
|
7
|
+
data.tar.gz: 8e0332496c23a375c4a939056f08f5de5682007f641836388aa49c745fd54086a8230921baf8d490b349ec8dc24582f945e8f399ef81429dd4db1c822334ccdc
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
Changes are maintained under [Releases](https://github.com/brianmario/mysql2/releases)
|
data/README.md
CHANGED
@@ -9,12 +9,14 @@ This one is not.
|
|
9
9
|
|
10
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.
|
11
11
|
|
12
|
-
The API consists of
|
12
|
+
The API consists of three classes:
|
13
13
|
|
14
14
|
`Mysql2::Client` - your connection to the database.
|
15
15
|
|
16
16
|
`Mysql2::Result` - returned from issuing a #query on the connection. It includes Enumerable.
|
17
17
|
|
18
|
+
`Mysql2::Statement` - returned from issuing a #prepare on the connection. Execute the statement to get a Result.
|
19
|
+
|
18
20
|
## Installing
|
19
21
|
### General Instructions
|
20
22
|
``` sh
|
@@ -153,6 +155,20 @@ results.each(:as => :array) do |row|
|
|
153
155
|
end
|
154
156
|
```
|
155
157
|
|
158
|
+
Prepared statements are supported, as well. In a prepared statement, use a `?`
|
159
|
+
in place of each value and then execute the statement to retrieve a result set.
|
160
|
+
Pass your arguments to the execute method in the same number and order as the
|
161
|
+
question marks in the statement.
|
162
|
+
|
163
|
+
``` ruby
|
164
|
+
statement = @client.prepare("SELECT * FROM users WHERE login_count = ?")
|
165
|
+
result1 = statement.execute(1)
|
166
|
+
result2 = statement.execute(2)
|
167
|
+
|
168
|
+
statement = @client.prepare("SELECT * FROM users WHERE last_login >= ? AND location LIKE ?")
|
169
|
+
result = statement.execute(1, "CA")
|
170
|
+
```
|
171
|
+
|
156
172
|
## Connection options
|
157
173
|
|
158
174
|
You may set the following connection options in Mysql2::Client.new(...):
|
@@ -186,7 +202,8 @@ Setting any of the following options will enable an SSL connection, but only if
|
|
186
202
|
your MySQL client library and server have been compiled with SSL support.
|
187
203
|
MySQL client library defaults will be used for any parameters that are left out
|
188
204
|
or set to nil. Relative paths are allowed, and may be required by managed
|
189
|
-
hosting providers such as Heroku.
|
205
|
+
hosting providers such as Heroku. Set `:sslverify => true` to require that the
|
206
|
+
server presents a valid certificate.
|
190
207
|
|
191
208
|
``` ruby
|
192
209
|
Mysql2::Client.new(
|
@@ -195,7 +212,8 @@ Mysql2::Client.new(
|
|
195
212
|
:sslcert => '/path/to/client-cert.pem',
|
196
213
|
:sslca => '/path/to/ca-cert.pem',
|
197
214
|
:sslcapath => '/path/to/cacerts',
|
198
|
-
:sslcipher => 'DHE-RSA-AES256-SHA'
|
215
|
+
:sslcipher => 'DHE-RSA-AES256-SHA',
|
216
|
+
:sslverify => true,
|
199
217
|
)
|
200
218
|
```
|
201
219
|
|
@@ -437,13 +455,13 @@ As for field values themselves, I'm workin on it - but expect that soon.
|
|
437
455
|
|
438
456
|
This gem is tested with the following Ruby versions on Linux and Mac OS X:
|
439
457
|
|
440
|
-
* Ruby MRI 1.8.7, 1.9.
|
458
|
+
* Ruby MRI 1.8.7, 1.9.3, 2.0.0, 2.1.x, 2.2.x
|
441
459
|
* Ruby Enterprise Edition (based on MRI 1.8.7)
|
442
460
|
* Rubinius 2.x
|
443
461
|
|
444
462
|
This gem is tested with the following MySQL and MariaDB versions:
|
445
463
|
|
446
|
-
* MySQL 5.
|
464
|
+
* MySQL 5.5, 5.7
|
447
465
|
* MySQL Connector/C 6.0 and 6.1 (primarily on Windows)
|
448
466
|
* MariaDB 5.5, 10.0
|
449
467
|
|
@@ -536,4 +554,8 @@ though.
|
|
536
554
|
* Yury Korolev (http://github.com/yury) - for TONS of help testing the Active Record adapter
|
537
555
|
* Aaron Patterson (http://github.com/tenderlove) - tons of contributions, suggestions and general badassness
|
538
556
|
* Mike Perham (http://github.com/mperham) - Async Active Record adapter (uses Fibers and EventMachine)
|
539
|
-
* Aaron Stone (http://github.com/sodabrew) - additional client settings, local files, microsecond time, maintenance support
|
557
|
+
* Aaron Stone (http://github.com/sodabrew) - additional client settings, local files, microsecond time, maintenance support
|
558
|
+
* Kouhei Ueno (https://github.com/nyaxt) - for the original work on Prepared Statements way back in 2012
|
559
|
+
* John Cant (http://github.com/johncant) - polishing and updating Prepared Statements support
|
560
|
+
* Justin Case (http://github.com/justincase) - polishing and updating Prepared Statements support and getting it merged
|
561
|
+
* Tamir Duberstein (http://github.com/tamird) - for help with timeouts and all around updates and cleanups
|
data/examples/threaded.rb
CHANGED
@@ -4,17 +4,15 @@ $LOAD_PATH.unshift 'lib'
|
|
4
4
|
require 'mysql2'
|
5
5
|
require 'timeout'
|
6
6
|
|
7
|
-
threads = []
|
8
7
|
# Should never exceed worst case 3.5 secs across all 20 threads
|
9
8
|
Timeout.timeout(3.5) do
|
10
|
-
20.times do
|
11
|
-
|
9
|
+
20.times.map do
|
10
|
+
Thread.new do
|
12
11
|
overhead = rand(3)
|
13
12
|
puts ">> thread #{Thread.current.object_id} query, #{overhead} sec overhead"
|
14
13
|
# 3 second overhead per query
|
15
14
|
Mysql2::Client.new(:host => "localhost", :username => "root").query("SELECT sleep(#{overhead}) as result")
|
16
15
|
puts "<< thread #{Thread.current.object_id} result, #{overhead} sec overhead"
|
17
16
|
end
|
18
|
-
end
|
19
|
-
|
20
|
-
end
|
17
|
+
end.each(&:join)
|
18
|
+
end
|
data/ext/mysql2/client.c
CHANGED
@@ -18,10 +18,11 @@ VALUE cMysql2Client;
|
|
18
18
|
extern VALUE mMysql2, cMysql2Error;
|
19
19
|
static VALUE sym_id, sym_version, sym_header_version, sym_async, sym_symbolize_keys, sym_as, sym_array, sym_stream;
|
20
20
|
static ID intern_merge, intern_merge_bang, intern_error_number_eql, intern_sql_state_eql;
|
21
|
+
static ID intern_brackets, intern_new;
|
21
22
|
|
22
23
|
#ifndef HAVE_RB_HASH_DUP
|
23
|
-
|
24
|
-
return rb_funcall(rb_cHash,
|
24
|
+
VALUE rb_hash_dup(VALUE other) {
|
25
|
+
return rb_funcall(rb_cHash, intern_brackets, 1, other);
|
25
26
|
}
|
26
27
|
#endif
|
27
28
|
|
@@ -30,25 +31,12 @@ static VALUE rb_hash_dup(VALUE other) {
|
|
30
31
|
rb_raise(cMysql2Error, "MySQL client is not initialized"); \
|
31
32
|
}
|
32
33
|
|
33
|
-
#define REQUIRE_CONNECTED(wrapper) \
|
34
|
-
REQUIRE_INITIALIZED(wrapper) \
|
35
|
-
if (!wrapper->connected && !wrapper->reconnect_enabled) { \
|
36
|
-
rb_raise(cMysql2Error, "closed MySQL connection"); \
|
37
|
-
}
|
38
|
-
|
39
34
|
#define REQUIRE_NOT_CONNECTED(wrapper) \
|
40
35
|
REQUIRE_INITIALIZED(wrapper) \
|
41
36
|
if (wrapper->connected) { \
|
42
37
|
rb_raise(cMysql2Error, "MySQL connection is already open"); \
|
43
38
|
}
|
44
39
|
|
45
|
-
#define MARK_CONN_INACTIVE(conn) \
|
46
|
-
wrapper->active_thread = Qnil;
|
47
|
-
|
48
|
-
#define GET_CLIENT(self) \
|
49
|
-
mysql_client_wrapper *wrapper; \
|
50
|
-
Data_Get_Struct(self, mysql_client_wrapper, wrapper)
|
51
|
-
|
52
40
|
/*
|
53
41
|
* compatability with mysql-connector-c, where LIBMYSQL_VERSION is the correct
|
54
42
|
* variable to use, but MYSQL_SERVER_VERSION gives the correct numbers when
|
@@ -136,7 +124,7 @@ static VALUE rb_raise_mysql2_error(mysql_client_wrapper *wrapper) {
|
|
136
124
|
rb_enc_associate(rb_sql_state, rb_usascii_encoding());
|
137
125
|
#endif
|
138
126
|
|
139
|
-
e = rb_funcall(cMysql2Error,
|
127
|
+
e = rb_funcall(cMysql2Error, intern_new, 2, rb_error_msg, LONG2FIX(wrapper->server_version));
|
140
128
|
rb_funcall(e, intern_error_number_eql, 1, UINT2NUM(mysql_errno(wrapper->client)));
|
141
129
|
rb_funcall(e, intern_sql_state_eql, 1, rb_sql_state);
|
142
130
|
rb_exc_raise(e);
|
@@ -255,6 +243,7 @@ static void rb_mysql_client_free(void *ptr) {
|
|
255
243
|
void decr_mysql2_client(mysql_client_wrapper *wrapper)
|
256
244
|
{
|
257
245
|
wrapper->refcount--;
|
246
|
+
|
258
247
|
if (wrapper->refcount == 0) {
|
259
248
|
nogvl_close(wrapper);
|
260
249
|
xfree(wrapper->client);
|
@@ -275,6 +264,7 @@ static VALUE allocate(VALUE klass) {
|
|
275
264
|
wrapper->initialized = 0; /* means that that the wrapper is initialized */
|
276
265
|
wrapper->refcount = 1;
|
277
266
|
wrapper->client = (MYSQL*)xmalloc(sizeof(MYSQL));
|
267
|
+
|
278
268
|
return obj;
|
279
269
|
}
|
280
270
|
|
@@ -340,8 +330,7 @@ static VALUE rb_mysql_info(VALUE self) {
|
|
340
330
|
|
341
331
|
static VALUE rb_connect(VALUE self, VALUE user, VALUE pass, VALUE host, VALUE port, VALUE database, VALUE socket, VALUE flags) {
|
342
332
|
struct nogvl_connect_args args;
|
343
|
-
time_t start_time, end_time;
|
344
|
-
unsigned int elapsed_time, connect_timeout;
|
333
|
+
time_t start_time, end_time, elapsed_time, connect_timeout;
|
345
334
|
VALUE rv;
|
346
335
|
GET_CLIENT(self);
|
347
336
|
|
@@ -368,7 +357,7 @@ static VALUE rb_connect(VALUE self, VALUE user, VALUE pass, VALUE host, VALUE po
|
|
368
357
|
/* avoid an early timeout due to time truncating milliseconds off the start time */
|
369
358
|
if (elapsed_time > 0)
|
370
359
|
elapsed_time--;
|
371
|
-
if (elapsed_time >= wrapper->connect_timeout)
|
360
|
+
if (elapsed_time >= (time_t)wrapper->connect_timeout)
|
372
361
|
break;
|
373
362
|
connect_timeout = wrapper->connect_timeout - elapsed_time;
|
374
363
|
mysql_options(wrapper->client, MYSQL_OPT_CONNECT_TIMEOUT, &connect_timeout);
|
@@ -423,7 +412,7 @@ static VALUE do_send_query(void *args) {
|
|
423
412
|
mysql_client_wrapper *wrapper = query_args->wrapper;
|
424
413
|
if ((VALUE)rb_thread_call_without_gvl(nogvl_send_query, args, RUBY_UBF_IO, 0) == Qfalse) {
|
425
414
|
/* an error occurred, we're not active anymore */
|
426
|
-
|
415
|
+
wrapper->active_thread = Qnil;
|
427
416
|
return rb_raise_mysql2_error(wrapper);
|
428
417
|
}
|
429
418
|
return Qnil;
|
@@ -507,9 +496,9 @@ static VALUE rb_mysql_client_async_result(VALUE self) {
|
|
507
496
|
}
|
508
497
|
|
509
498
|
current = rb_hash_dup(rb_iv_get(self, "@current_query_options"));
|
510
|
-
RB_GC_GUARD(current);
|
499
|
+
(void)RB_GC_GUARD(current);
|
511
500
|
Check_Type(current, T_HASH);
|
512
|
-
resultObj = rb_mysql_result_to_obj(self, wrapper->encoding, current, result);
|
501
|
+
resultObj = rb_mysql_result_to_obj(self, wrapper->encoding, current, result, Qnil);
|
513
502
|
|
514
503
|
return resultObj;
|
515
504
|
}
|
@@ -606,6 +595,25 @@ static VALUE finish_and_mark_inactive(void *args) {
|
|
606
595
|
}
|
607
596
|
#endif
|
608
597
|
|
598
|
+
void rb_mysql_client_set_active_thread(VALUE self) {
|
599
|
+
VALUE thread_current = rb_thread_current();
|
600
|
+
GET_CLIENT(self);
|
601
|
+
|
602
|
+
// see if this connection is still waiting on a result from a previous query
|
603
|
+
if (NIL_P(wrapper->active_thread)) {
|
604
|
+
// mark this connection active
|
605
|
+
wrapper->active_thread = thread_current;
|
606
|
+
} else if (wrapper->active_thread == thread_current) {
|
607
|
+
rb_raise(cMysql2Error, "This connection is still waiting for a result, try again once you have the result");
|
608
|
+
} else {
|
609
|
+
VALUE inspect = rb_inspect(wrapper->active_thread);
|
610
|
+
const char *thr = StringValueCStr(inspect);
|
611
|
+
|
612
|
+
rb_raise(cMysql2Error, "This connection is in use by: %s", thr);
|
613
|
+
(void)RB_GC_GUARD(inspect);
|
614
|
+
}
|
615
|
+
}
|
616
|
+
|
609
617
|
/* call-seq:
|
610
618
|
* client.abandon_results!
|
611
619
|
*
|
@@ -647,13 +655,12 @@ static VALUE rb_query(VALUE self, VALUE sql, VALUE current) {
|
|
647
655
|
struct async_query_args async_args;
|
648
656
|
#endif
|
649
657
|
struct nogvl_send_query_args args;
|
650
|
-
VALUE thread_current = rb_thread_current();
|
651
658
|
GET_CLIENT(self);
|
652
659
|
|
653
660
|
REQUIRE_CONNECTED(wrapper);
|
654
661
|
args.mysql = wrapper->client;
|
655
662
|
|
656
|
-
RB_GC_GUARD(current);
|
663
|
+
(void)RB_GC_GUARD(current);
|
657
664
|
Check_Type(current, T_HASH);
|
658
665
|
rb_iv_set(self, "@current_query_options", current);
|
659
666
|
|
@@ -666,23 +673,10 @@ static VALUE rb_query(VALUE self, VALUE sql, VALUE current) {
|
|
666
673
|
#endif
|
667
674
|
args.sql_ptr = RSTRING_PTR(args.sql);
|
668
675
|
args.sql_len = RSTRING_LEN(args.sql);
|
669
|
-
|
670
|
-
/* see if this connection is still waiting on a result from a previous query */
|
671
|
-
if (NIL_P(wrapper->active_thread)) {
|
672
|
-
/* mark this connection active */
|
673
|
-
wrapper->active_thread = thread_current;
|
674
|
-
} else if (wrapper->active_thread == thread_current) {
|
675
|
-
rb_raise(cMysql2Error, "This connection is still waiting for a result, try again once you have the result");
|
676
|
-
} else {
|
677
|
-
VALUE inspect = rb_inspect(wrapper->active_thread);
|
678
|
-
const char *thr = StringValueCStr(inspect);
|
679
|
-
|
680
|
-
rb_raise(cMysql2Error, "This connection is in use by: %s", thr);
|
681
|
-
RB_GC_GUARD(inspect);
|
682
|
-
}
|
683
|
-
|
684
676
|
args.wrapper = wrapper;
|
685
677
|
|
678
|
+
rb_mysql_client_set_active_thread(self);
|
679
|
+
|
686
680
|
#ifndef _WIN32
|
687
681
|
rb_rescue2(do_send_query, (VALUE)&args, disconnect_and_raise, self, rb_eException, (VALUE)0);
|
688
682
|
|
@@ -899,15 +893,17 @@ static VALUE rb_mysql_client_server_info(VALUE self) {
|
|
899
893
|
*
|
900
894
|
* Return the file descriptor number for this client.
|
901
895
|
*/
|
902
|
-
static VALUE rb_mysql_client_socket(VALUE self) {
|
903
896
|
#ifndef _WIN32
|
897
|
+
static VALUE rb_mysql_client_socket(VALUE self) {
|
904
898
|
GET_CLIENT(self);
|
905
899
|
REQUIRE_CONNECTED(wrapper);
|
906
900
|
return INT2NUM(wrapper->client->net.fd);
|
901
|
+
}
|
907
902
|
#else
|
903
|
+
static VALUE rb_mysql_client_socket(RB_MYSQL_UNUSED VALUE self) {
|
908
904
|
rb_raise(cMysql2Error, "Raw access to the mysql file descriptor isn't supported on Windows");
|
909
|
-
#endif
|
910
905
|
}
|
906
|
+
#endif
|
911
907
|
|
912
908
|
/* call-seq:
|
913
909
|
* client.last_id
|
@@ -1067,9 +1063,9 @@ static VALUE rb_mysql_client_store_result(VALUE self)
|
|
1067
1063
|
}
|
1068
1064
|
|
1069
1065
|
current = rb_hash_dup(rb_iv_get(self, "@current_query_options"));
|
1070
|
-
RB_GC_GUARD(current);
|
1066
|
+
(void)RB_GC_GUARD(current);
|
1071
1067
|
Check_Type(current, T_HASH);
|
1072
|
-
resultObj = rb_mysql_result_to_obj(self, wrapper->encoding, current, result);
|
1068
|
+
resultObj = rb_mysql_result_to_obj(self, wrapper->encoding, current, result, Qnil);
|
1073
1069
|
|
1074
1070
|
return resultObj;
|
1075
1071
|
}
|
@@ -1138,7 +1134,6 @@ static VALUE set_write_timeout(VALUE self, VALUE value) {
|
|
1138
1134
|
static VALUE set_charset_name(VALUE self, VALUE value) {
|
1139
1135
|
char *charset_name;
|
1140
1136
|
#ifdef HAVE_RUBY_ENCODING_H
|
1141
|
-
size_t charset_name_len;
|
1142
1137
|
const struct mysql2_mysql_enc_name_to_rb_map *mysql2rb;
|
1143
1138
|
rb_encoding *enc;
|
1144
1139
|
VALUE rb_enc;
|
@@ -1148,8 +1143,7 @@ static VALUE set_charset_name(VALUE self, VALUE value) {
|
|
1148
1143
|
charset_name = RSTRING_PTR(value);
|
1149
1144
|
|
1150
1145
|
#ifdef HAVE_RUBY_ENCODING_H
|
1151
|
-
|
1152
|
-
mysql2rb = mysql2_mysql_enc_name_to_rb(charset_name, charset_name_len);
|
1146
|
+
mysql2rb = mysql2_mysql_enc_name_to_rb(charset_name, (unsigned int)RSTRING_LEN(value));
|
1153
1147
|
if (mysql2rb == NULL || mysql2rb->rb_name == NULL) {
|
1154
1148
|
VALUE inspect = rb_inspect(value);
|
1155
1149
|
rb_raise(cMysql2Error, "Unsupported charset: '%s'", RSTRING_PTR(inspect));
|
@@ -1209,6 +1203,17 @@ static VALUE initialize_ext(VALUE self) {
|
|
1209
1203
|
return self;
|
1210
1204
|
}
|
1211
1205
|
|
1206
|
+
/* call-seq: client.prepare # => Mysql2::Statement
|
1207
|
+
*
|
1208
|
+
* Create a new prepared statement.
|
1209
|
+
*/
|
1210
|
+
static VALUE rb_mysql_client_prepare_statement(VALUE self, VALUE sql) {
|
1211
|
+
GET_CLIENT(self);
|
1212
|
+
REQUIRE_CONNECTED(wrapper);
|
1213
|
+
|
1214
|
+
return rb_mysql_stmt_new(self, sql);
|
1215
|
+
}
|
1216
|
+
|
1212
1217
|
void init_mysql2_client() {
|
1213
1218
|
/* verify the libmysql we're about to use was the version we were built against
|
1214
1219
|
https://github.com/luislavena/mysql-gem/commit/a600a9c459597da0712f70f43736e24b484f8a99 */
|
@@ -1253,6 +1258,7 @@ void init_mysql2_client() {
|
|
1253
1258
|
rb_define_method(cMysql2Client, "async_result", rb_mysql_client_async_result, 0);
|
1254
1259
|
rb_define_method(cMysql2Client, "last_id", rb_mysql_client_last_id, 0);
|
1255
1260
|
rb_define_method(cMysql2Client, "affected_rows", rb_mysql_client_affected_rows, 0);
|
1261
|
+
rb_define_method(cMysql2Client, "prepare", rb_mysql_client_prepare_statement, 1);
|
1256
1262
|
rb_define_method(cMysql2Client, "thread_id", rb_mysql_client_thread_id, 0);
|
1257
1263
|
rb_define_method(cMysql2Client, "ping", rb_mysql_client_ping, 0);
|
1258
1264
|
rb_define_method(cMysql2Client, "select_db", rb_mysql_client_select_db, 1);
|
@@ -1289,6 +1295,8 @@ void init_mysql2_client() {
|
|
1289
1295
|
sym_array = ID2SYM(rb_intern("array"));
|
1290
1296
|
sym_stream = ID2SYM(rb_intern("stream"));
|
1291
1297
|
|
1298
|
+
intern_brackets = rb_intern("[]");
|
1299
|
+
intern_new = rb_intern("new");
|
1292
1300
|
intern_merge = rb_intern("merge");
|
1293
1301
|
intern_merge_bang = rb_intern("merge!");
|
1294
1302
|
intern_error_number_eql = rb_intern("error_number=");
|
data/ext/mysql2/client.h
CHANGED
@@ -50,7 +50,28 @@ typedef struct {
|
|
50
50
|
MYSQL *client;
|
51
51
|
} mysql_client_wrapper;
|
52
52
|
|
53
|
+
#define REQUIRE_CONNECTED(wrapper) \
|
54
|
+
REQUIRE_INITIALIZED(wrapper) \
|
55
|
+
if (!wrapper->connected && !wrapper->reconnect_enabled) { \
|
56
|
+
rb_raise(cMysql2Error, "closed MySQL connection"); \
|
57
|
+
}
|
58
|
+
|
59
|
+
void rb_mysql_client_set_active_thread(VALUE self);
|
60
|
+
|
61
|
+
#define MARK_CONN_INACTIVE(conn) do {\
|
62
|
+
GET_CLIENT(conn); \
|
63
|
+
wrapper->active_thread = Qnil; \
|
64
|
+
} while(0)
|
65
|
+
|
66
|
+
#define GET_CLIENT(self) \
|
67
|
+
mysql_client_wrapper *wrapper; \
|
68
|
+
Data_Get_Struct(self, mysql_client_wrapper, wrapper);
|
69
|
+
|
53
70
|
void init_mysql2_client();
|
54
71
|
void decr_mysql2_client(mysql_client_wrapper *wrapper);
|
55
72
|
|
56
73
|
#endif
|
74
|
+
|
75
|
+
#ifndef HAVE_RB_HASH_DUP
|
76
|
+
VALUE rb_hash_dup(VALUE other);
|
77
|
+
#endif
|
data/ext/mysql2/extconf.rb
CHANGED
@@ -33,6 +33,7 @@ dirs = ENV['PATH'].split(File::PATH_SEPARATOR) + %w[
|
|
33
33
|
/usr/local/mysql
|
34
34
|
/usr/local/mysql-*
|
35
35
|
/usr/local/lib/mysql5*
|
36
|
+
/usr/local/opt/mysql5*
|
36
37
|
].map{|dir| "#{dir}/bin" }
|
37
38
|
|
38
39
|
GLOB = "{#{dirs.join(',')}}/{mysql_config,mysql_config5,mariadb_config}"
|
@@ -72,21 +73,8 @@ elsif mc = (with_config('mysql-config') || Dir[GLOB].first)
|
|
72
73
|
rpath_dir = libs
|
73
74
|
else
|
74
75
|
inc, lib = dir_config('mysql', '/usr/local')
|
75
|
-
|
76
|
-
|
77
|
-
# For some systems and some versions of libmysqlclient, there were extra
|
78
|
-
# libraries needed to link. Try each typical extra library, add it to the
|
79
|
-
# global compile flags, and see if that allows us to link libmysqlclient.
|
80
|
-
warn "-----\nlibmysqlclient is missing. Trying again with extra runtime libraries...\n-----"
|
81
|
-
|
82
|
-
%w{ m z socket nsl mygcc }.each do |extra_lib|
|
83
|
-
if have_library(extra_lib) && find_library('mysqlclient', 'mysql_query', lib, "#{lib}/mysql")
|
84
|
-
found = true
|
85
|
-
break
|
86
|
-
end
|
87
|
-
end
|
88
|
-
asplode('libmysqlclient') unless found
|
89
|
-
end
|
76
|
+
|
77
|
+
asplode("mysql client") unless find_library('mysqlclient', 'mysql_query', lib, "#{lib}/mysql")
|
90
78
|
|
91
79
|
rpath_dir = lib
|
92
80
|
end
|
@@ -104,11 +92,20 @@ end
|
|
104
92
|
asplode h unless have_header h
|
105
93
|
end
|
106
94
|
|
107
|
-
#
|
108
|
-
#
|
109
|
-
|
110
|
-
|
111
|
-
|
95
|
+
# This is our wishlist. We use whichever flags work on the host.
|
96
|
+
# TODO: fix statement.c and remove -Wno-declaration-after-statement
|
97
|
+
# TODO: fix gperf mysql_enc_name_to_ruby.h and remove -Wno-missing-field-initializers
|
98
|
+
%w(
|
99
|
+
-Wall
|
100
|
+
-Wextra
|
101
|
+
-Werror
|
102
|
+
-Wno-unused-function
|
103
|
+
-Wno-declaration-after-statement
|
104
|
+
-Wno-missing-field-initializers
|
105
|
+
).select do |flag|
|
106
|
+
try_link('int main() {return 0;}', flag)
|
107
|
+
end.each do |flag|
|
108
|
+
$CFLAGS << ' ' << flag
|
112
109
|
end
|
113
110
|
|
114
111
|
if RUBY_PLATFORM =~ /mswin|mingw/
|
@@ -125,9 +122,9 @@ if RUBY_PLATFORM =~ /mswin|mingw/
|
|
125
122
|
# Maybe in the future Ruby could provide RbConfig::CONFIG['DLLTOOL'] directly.
|
126
123
|
dlltool = RbConfig::CONFIG['DLLWRAP'].gsub('dllwrap', 'dlltool')
|
127
124
|
sh dlltool, '--kill-at',
|
128
|
-
|
129
|
-
|
130
|
-
|
125
|
+
'--dllname', 'libmysql.dll',
|
126
|
+
'--output-lib', 'libmysql.a',
|
127
|
+
'--input-def', deffile, libfile
|
131
128
|
end
|
132
129
|
end
|
133
130
|
|