mysql2 0.5.3 → 0.5.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +33 -7
- data/ext/mysql2/client.c +100 -19
- data/ext/mysql2/extconf.rb +22 -5
- data/ext/mysql2/mysql2_ext.c +6 -1
- data/ext/mysql2/result.c +213 -4
- data/ext/mysql2/result.h +1 -0
- data/ext/mysql2/statement.c +10 -2
- data/lib/mysql2/client.rb +19 -2
- data/lib/mysql2/error.rb +1 -0
- data/lib/mysql2/statement.rb +1 -3
- data/lib/mysql2/version.rb +1 -1
- data/lib/mysql2.rb +1 -0
- data/support/3A79BD29.asc +49 -0
- metadata +9 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f387f841adc885eb4000a960ee34f475c7edab79e276d17ce8889f370bdcf387
|
4
|
+
data.tar.gz: 0c8732c2a45ed8ac68aea92765daba5969f860f1fe5a95d44e89b76deae7108b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8d6afb1b661525183075d14046630195bc79a5f945b92489d3daa0aeea8582e8d17a0fa9d1781fadeaaefaaeac567ead5ad7d0266e1fb9aa96076d26f1c03ad1
|
7
|
+
data.tar.gz: 9b2202a06e36ca910a9648f71d8646e67a6e665153b3ac04dcd535cd768bb78942dd799893e205df841b0461aeb5810985704e18e4a045b540f2d272b11776cd
|
data/README.md
CHANGED
@@ -1,7 +1,12 @@
|
|
1
1
|
# Mysql2 - A modern, simple and very fast MySQL library for Ruby - binding to libmysql
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
GitHub Actions
|
4
|
+
[![GitHub Actions Status: Build](https://github.com/brianmario/mysql2/actions/workflows/build.yml/badge.svg)](https://github.com/brianmario/mysql2/actions/workflows/build.yml)
|
5
|
+
[![GitHub Actions Status: Container](https://github.com/brianmario/mysql2/actions/workflows/container.yml/badge.svg)](https://github.com/brianmario/mysql2/actions/workflows/container.yml)
|
6
|
+
Travis CI
|
7
|
+
[![Travis CI Status](https://travis-ci.org/brianmario/mysql2.png)](https://travis-ci.org/brianmario/mysql2)
|
8
|
+
Appveyor CI
|
9
|
+
[![Appveyor CI Status](https://ci.appveyor.com/api/projects/status/github/sodabrew/mysql2)](https://ci.appveyor.com/project/sodabrew/mysql2)
|
5
10
|
|
6
11
|
The Mysql2 gem is meant to serve the extremely common use-case of connecting, querying and iterating on results.
|
7
12
|
Some database libraries out there serve as direct 1:1 mappings of the already complex C APIs available.
|
@@ -143,7 +148,7 @@ results.each do |row|
|
|
143
148
|
# the keys are the fields, as you'd expect
|
144
149
|
# the values are pre-built ruby primitives mapped from their corresponding field types in MySQL
|
145
150
|
puts row["id"] # row["id"].is_a? Integer
|
146
|
-
if row["dne"] # non-
|
151
|
+
if row["dne"] # non-existent hash entry is nil
|
147
152
|
puts row["dne"]
|
148
153
|
end
|
149
154
|
end
|
@@ -165,11 +170,12 @@ client.query("SELECT * FROM users WHERE group='githubbers'", :symbolize_keys =>
|
|
165
170
|
end
|
166
171
|
```
|
167
172
|
|
168
|
-
You can get the headers and the
|
173
|
+
You can get the headers, columns, and the field types in the order that they were returned
|
169
174
|
by the query like this:
|
170
175
|
|
171
176
|
``` ruby
|
172
177
|
headers = results.fields # <= that's an array of field names, in order
|
178
|
+
types = results.field_types # <= that's an array of field types, in order
|
173
179
|
results.each(:as => :array) do |row|
|
174
180
|
# Each row is an array, ordered the same as the query results
|
175
181
|
# An otter's den is called a "holt" or "couch"
|
@@ -197,6 +203,23 @@ statement = @client.prepare("SELECT * FROM users WHERE last_login >= ? AND locat
|
|
197
203
|
result = statement.execute(1, "CA", :as => :array)
|
198
204
|
```
|
199
205
|
|
206
|
+
Session Tracking information can be accessed with
|
207
|
+
|
208
|
+
```ruby
|
209
|
+
c = Mysql2::Client.new(
|
210
|
+
host: "127.0.0.1",
|
211
|
+
username: "root",
|
212
|
+
flags: "SESSION_TRACK",
|
213
|
+
init_command: "SET @@SESSION.session_track_schema=ON"
|
214
|
+
)
|
215
|
+
c.query("INSERT INTO test VALUES (1)")
|
216
|
+
session_track_type = Mysql2::Client::SESSION_TRACK_SCHEMA
|
217
|
+
session_track_data = c.session_track(session_track_type)
|
218
|
+
```
|
219
|
+
|
220
|
+
The types of session track types can be found at
|
221
|
+
[https://dev.mysql.com/doc/refman/5.7/en/session-state-tracking.html](https://dev.mysql.com/doc/refman/5.7/en/session-state-tracking.html)
|
222
|
+
|
200
223
|
## Connection options
|
201
224
|
|
202
225
|
You may set the following connection options in Mysql2::Client.new(...):
|
@@ -262,7 +285,7 @@ Mysql2::Client.new(
|
|
262
285
|
|
263
286
|
### Secure auth
|
264
287
|
|
265
|
-
Starting
|
288
|
+
Starting with MySQL 5.6.5, secure_auth is enabled by default on servers (it was disabled by default prior to this).
|
266
289
|
When secure_auth is enabled, the server will refuse a connection if the account password is stored in old pre-MySQL 4.1 format.
|
267
290
|
The MySQL 5.6.5 client library may also refuse to attempt a connection if provided an older format password.
|
268
291
|
To bypass this restriction in the client, pass the option `:secure_auth => false` to Mysql2::Client.new().
|
@@ -299,6 +322,8 @@ development:
|
|
299
322
|
secure_auth: false
|
300
323
|
```
|
301
324
|
|
325
|
+
In this example, the compression flag is negated with `-COMPRESS`.
|
326
|
+
|
302
327
|
### Using Active Record's DATABASE_URL
|
303
328
|
|
304
329
|
Active Record typically reads its configuration from a file named `database.yml` or an environment variable `DATABASE_URL`.
|
@@ -423,7 +448,7 @@ Pass the `:as => :array` option to any of the above methods of configuration
|
|
423
448
|
|
424
449
|
### Array of Hashes
|
425
450
|
|
426
|
-
The default result type is set to
|
451
|
+
The default result type is set to `:hash`, but you can override a previous setting to something else with `:as => :hash`
|
427
452
|
|
428
453
|
### Timezones
|
429
454
|
|
@@ -554,7 +579,7 @@ This gem is tested with the following MySQL and MariaDB versions:
|
|
554
579
|
|
555
580
|
### Ruby on Rails / Active Record
|
556
581
|
|
557
|
-
* mysql2 0.5.x works with Rails / Active Record 5.0.7, 5.1.6, and higher.
|
582
|
+
* mysql2 0.5.x works with Rails / Active Record 4.2.11, 5.0.7, 5.1.6, and higher.
|
558
583
|
* mysql2 0.4.x works with Rails / Active Record 4.2.5 - 5.0 and higher.
|
559
584
|
* mysql2 0.3.x works with Rails / Active Record 3.1, 3.2, 4.x, 5.0.
|
560
585
|
* mysql2 0.2.x works with Rails / Active Record 2.3 - 3.0.
|
@@ -648,3 +673,4 @@ though.
|
|
648
673
|
* [John Cant](http://github.com/johncant) - polishing and updating Prepared Statements support
|
649
674
|
* [Justin Case](http://github.com/justincase) - polishing and updating Prepared Statements support and getting it merged
|
650
675
|
* [Tamir Duberstein](http://github.com/tamird) - for help with timeouts and all around updates and cleanups
|
676
|
+
* [Jun Aruga](http://github.com/junaruga) - for migrating CI tests to GitHub Actions and other improvements
|
data/ext/mysql2/client.c
CHANGED
@@ -45,7 +45,7 @@ static ID intern_brackets, intern_merge, intern_merge_bang, intern_new_with_args
|
|
45
45
|
}
|
46
46
|
|
47
47
|
/*
|
48
|
-
*
|
48
|
+
* compatibility with mysql-connector-c, where LIBMYSQL_VERSION is the correct
|
49
49
|
* variable to use, but MYSQL_SERVER_VERSION gives the correct numbers when
|
50
50
|
* linking against the server itself
|
51
51
|
*/
|
@@ -58,8 +58,23 @@ static ID intern_brackets, intern_merge, intern_merge_bang, intern_new_with_args
|
|
58
58
|
#endif
|
59
59
|
|
60
60
|
/*
|
61
|
-
*
|
61
|
+
* mariadb-connector-c defines CLIENT_SESSION_TRACKING and SESSION_TRACK_TRANSACTION_TYPE
|
62
|
+
* while mysql-connector-c defines CLIENT_SESSION_TRACK and SESSION_TRACK_TRANSACTION_STATE
|
63
|
+
* This is a hack to take care of both clients.
|
62
64
|
*/
|
65
|
+
#if defined(CLIENT_SESSION_TRACK)
|
66
|
+
#elif defined(CLIENT_SESSION_TRACKING)
|
67
|
+
#define CLIENT_SESSION_TRACK CLIENT_SESSION_TRACKING
|
68
|
+
#define SESSION_TRACK_TRANSACTION_STATE SESSION_TRACK_TRANSACTION_TYPE
|
69
|
+
#endif
|
70
|
+
|
71
|
+
/*
|
72
|
+
* compatibility with mysql-connector-c 6.1.x, MySQL 5.7.3 - 5.7.10 & with MariaDB 10.x and later.
|
73
|
+
*/
|
74
|
+
#ifdef HAVE_CONST_MYSQL_OPT_SSL_VERIFY_SERVER_CERT
|
75
|
+
#define SSL_MODE_VERIFY_IDENTITY 5
|
76
|
+
#define HAVE_CONST_SSL_MODE_VERIFY_IDENTITY
|
77
|
+
#endif
|
63
78
|
#ifdef HAVE_CONST_MYSQL_OPT_SSL_ENFORCE
|
64
79
|
#define SSL_MODE_DISABLED 1
|
65
80
|
#define SSL_MODE_REQUIRED 3
|
@@ -110,19 +125,27 @@ static VALUE rb_set_ssl_mode_option(VALUE self, VALUE setting) {
|
|
110
125
|
rb_warn( "Your mysql client library does not support setting ssl_mode; full support comes with 5.7.11." );
|
111
126
|
return Qnil;
|
112
127
|
}
|
113
|
-
#
|
128
|
+
#if defined(HAVE_CONST_MYSQL_OPT_SSL_VERIFY_SERVER_CERT) || defined(HAVE_CONST_MYSQL_OPT_SSL_ENFORCE)
|
114
129
|
GET_CLIENT(self);
|
115
130
|
int val = NUM2INT( setting );
|
116
|
-
// Either MySQL 5.7.3 - 5.7.10, or Connector/C 6.1.3 - 6.1.x
|
117
|
-
if ((version >= 50703 && version < 50711) || (version >= 60103 && version < 60200)) {
|
131
|
+
// Either MySQL 5.7.3 - 5.7.10, or Connector/C 6.1.3 - 6.1.x, or MariaDB 10.x and later
|
132
|
+
if ((version >= 50703 && version < 50711) || (version >= 60103 && version < 60200) || version >= 100000) {
|
133
|
+
#ifdef HAVE_CONST_MYSQL_OPT_SSL_VERIFY_SERVER_CERT
|
134
|
+
if (val == SSL_MODE_VERIFY_IDENTITY) {
|
135
|
+
my_bool b = 1;
|
136
|
+
int result = mysql_options( wrapper->client, MYSQL_OPT_SSL_VERIFY_SERVER_CERT, &b );
|
137
|
+
return INT2NUM(result);
|
138
|
+
}
|
139
|
+
#endif
|
140
|
+
#ifdef HAVE_CONST_MYSQL_OPT_SSL_ENFORCE
|
118
141
|
if (val == SSL_MODE_DISABLED || val == SSL_MODE_REQUIRED) {
|
119
142
|
my_bool b = ( val == SSL_MODE_REQUIRED );
|
120
143
|
int result = mysql_options( wrapper->client, MYSQL_OPT_SSL_ENFORCE, &b );
|
121
144
|
return INT2NUM(result);
|
122
|
-
} else {
|
123
|
-
rb_warn( "MySQL client libraries between 5.7.3 and 5.7.10 only support SSL_MODE_DISABLED and SSL_MODE_REQUIRED" );
|
124
|
-
return Qnil;
|
125
145
|
}
|
146
|
+
#endif
|
147
|
+
rb_warn( "Your mysql client library does not support ssl_mode %d.", val );
|
148
|
+
return Qnil;
|
126
149
|
} else {
|
127
150
|
rb_warn( "Your mysql client library does not support ssl_mode as expected." );
|
128
151
|
return Qnil;
|
@@ -140,6 +163,7 @@ static VALUE rb_set_ssl_mode_option(VALUE self, VALUE setting) {
|
|
140
163
|
return INT2NUM(result);
|
141
164
|
#endif
|
142
165
|
#ifdef NO_SSL_MODE_SUPPORT
|
166
|
+
rb_warn( "Your mysql client library does not support setting ssl_mode; full support comes with 5.7.11." );
|
143
167
|
return Qnil;
|
144
168
|
#endif
|
145
169
|
}
|
@@ -175,7 +199,7 @@ static void rb_mysql_client_mark(void * wrapper) {
|
|
175
199
|
|
176
200
|
static VALUE rb_raise_mysql2_error(mysql_client_wrapper *wrapper) {
|
177
201
|
VALUE rb_error_msg = rb_str_new2(mysql_error(wrapper->client));
|
178
|
-
VALUE rb_sql_state =
|
202
|
+
VALUE rb_sql_state = rb_str_new2(mysql_sqlstate(wrapper->client));
|
179
203
|
VALUE e;
|
180
204
|
|
181
205
|
rb_enc_associate(rb_error_msg, rb_utf8_encoding());
|
@@ -269,7 +293,7 @@ static VALUE invalidate_fd(int clientfd)
|
|
269
293
|
static void *nogvl_close(void *ptr) {
|
270
294
|
mysql_client_wrapper *wrapper = ptr;
|
271
295
|
|
272
|
-
if (!wrapper->closed) {
|
296
|
+
if (wrapper->initialized && !wrapper->closed) {
|
273
297
|
mysql_close(wrapper->client);
|
274
298
|
wrapper->closed = 1;
|
275
299
|
wrapper->reconnect_enabled = 0;
|
@@ -323,9 +347,9 @@ static VALUE allocate(VALUE klass) {
|
|
323
347
|
wrapper->server_version = 0;
|
324
348
|
wrapper->reconnect_enabled = 0;
|
325
349
|
wrapper->connect_timeout = 0;
|
326
|
-
wrapper->initialized = 0; /*
|
350
|
+
wrapper->initialized = 0; /* will be set true after calling mysql_init */
|
351
|
+
wrapper->closed = 1; /* will be set false after calling mysql_real_connect */
|
327
352
|
wrapper->refcount = 1;
|
328
|
-
wrapper->closed = 0;
|
329
353
|
wrapper->client = (MYSQL*)xmalloc(sizeof(MYSQL));
|
330
354
|
|
331
355
|
return obj;
|
@@ -467,6 +491,7 @@ static VALUE rb_mysql_connect(VALUE self, VALUE user, VALUE pass, VALUE host, VA
|
|
467
491
|
rb_raise_mysql2_error(wrapper);
|
468
492
|
}
|
469
493
|
|
494
|
+
wrapper->closed = 0;
|
470
495
|
wrapper->server_version = mysql_get_server_version(wrapper->client);
|
471
496
|
return self;
|
472
497
|
}
|
@@ -513,10 +538,10 @@ static void *nogvl_send_query(void *ptr) {
|
|
513
538
|
return (void*)(rv == 0 ? Qtrue : Qfalse);
|
514
539
|
}
|
515
540
|
|
516
|
-
static VALUE do_send_query(
|
517
|
-
struct nogvl_send_query_args *query_args = args;
|
541
|
+
static VALUE do_send_query(VALUE args) {
|
542
|
+
struct nogvl_send_query_args *query_args = (void *)args;
|
518
543
|
mysql_client_wrapper *wrapper = query_args->wrapper;
|
519
|
-
if ((VALUE)rb_thread_call_without_gvl(nogvl_send_query,
|
544
|
+
if ((VALUE)rb_thread_call_without_gvl(nogvl_send_query, query_args, RUBY_UBF_IO, 0) == Qfalse) {
|
520
545
|
/* an error occurred, we're not active anymore */
|
521
546
|
wrapper->active_thread = Qnil;
|
522
547
|
rb_raise_mysql2_error(wrapper);
|
@@ -636,8 +661,8 @@ static VALUE disconnect_and_raise(VALUE self, VALUE error) {
|
|
636
661
|
rb_exc_raise(error);
|
637
662
|
}
|
638
663
|
|
639
|
-
static VALUE do_query(
|
640
|
-
struct async_query_args *async_args = args;
|
664
|
+
static VALUE do_query(VALUE args) {
|
665
|
+
struct async_query_args *async_args = (void *)args;
|
641
666
|
struct timeval tv;
|
642
667
|
struct timeval *tvp;
|
643
668
|
long int sec;
|
@@ -785,6 +810,7 @@ static VALUE rb_mysql_query(VALUE self, VALUE sql, VALUE current) {
|
|
785
810
|
|
786
811
|
#ifndef _WIN32
|
787
812
|
rb_rescue2(do_send_query, (VALUE)&args, disconnect_and_raise, self, rb_eException, (VALUE)0);
|
813
|
+
(void)RB_GC_GUARD(sql);
|
788
814
|
|
789
815
|
if (rb_hash_aref(current, sym_async) == Qtrue) {
|
790
816
|
return Qnil;
|
@@ -797,7 +823,8 @@ static VALUE rb_mysql_query(VALUE self, VALUE sql, VALUE current) {
|
|
797
823
|
return rb_ensure(rb_mysql_client_async_result, self, disconnect_and_mark_inactive, self);
|
798
824
|
}
|
799
825
|
#else
|
800
|
-
do_send_query(&args);
|
826
|
+
do_send_query((VALUE)&args);
|
827
|
+
(void)RB_GC_GUARD(sql);
|
801
828
|
|
802
829
|
/* this will just block until the result is ready */
|
803
830
|
return rb_ensure(rb_mysql_client_async_result, self, disconnect_and_mark_inactive, self);
|
@@ -908,10 +935,12 @@ static VALUE _mysql_client_options(VALUE self, int opt, VALUE value) {
|
|
908
935
|
retval = charval;
|
909
936
|
break;
|
910
937
|
|
938
|
+
#ifdef HAVE_MYSQL_DEFAULT_AUTH
|
911
939
|
case MYSQL_DEFAULT_AUTH:
|
912
940
|
charval = (const char *)StringValueCStr(value);
|
913
941
|
retval = charval;
|
914
942
|
break;
|
943
|
+
#endif
|
915
944
|
|
916
945
|
#ifdef HAVE_CONST_MYSQL_ENABLE_CLEARTEXT_PLUGIN
|
917
946
|
case MYSQL_ENABLE_CLEARTEXT_PLUGIN:
|
@@ -1021,6 +1050,36 @@ static VALUE rb_mysql_client_last_id(VALUE self) {
|
|
1021
1050
|
return ULL2NUM(mysql_insert_id(wrapper->client));
|
1022
1051
|
}
|
1023
1052
|
|
1053
|
+
/* call-seq:
|
1054
|
+
* client.session_track
|
1055
|
+
*
|
1056
|
+
* Returns information about changes to the session state on the server.
|
1057
|
+
*/
|
1058
|
+
static VALUE rb_mysql_client_session_track(VALUE self, VALUE type) {
|
1059
|
+
#ifdef CLIENT_SESSION_TRACK
|
1060
|
+
const char *data;
|
1061
|
+
size_t length;
|
1062
|
+
my_ulonglong retVal;
|
1063
|
+
GET_CLIENT(self);
|
1064
|
+
|
1065
|
+
REQUIRE_CONNECTED(wrapper);
|
1066
|
+
retVal = mysql_session_track_get_first(wrapper->client, NUM2INT(type), &data, &length);
|
1067
|
+
if (retVal != 0) {
|
1068
|
+
return Qnil;
|
1069
|
+
}
|
1070
|
+
VALUE rbAry = rb_ary_new();
|
1071
|
+
VALUE rbFirst = rb_str_new(data, length);
|
1072
|
+
rb_ary_push(rbAry, rbFirst);
|
1073
|
+
while(mysql_session_track_get_next(wrapper->client, NUM2INT(type), &data, &length) == 0) {
|
1074
|
+
VALUE rbNext = rb_str_new(data, length);
|
1075
|
+
rb_ary_push(rbAry, rbNext);
|
1076
|
+
}
|
1077
|
+
return rbAry;
|
1078
|
+
#else
|
1079
|
+
return Qnil;
|
1080
|
+
#endif
|
1081
|
+
}
|
1082
|
+
|
1024
1083
|
/* call-seq:
|
1025
1084
|
* client.affected_rows
|
1026
1085
|
*
|
@@ -1347,7 +1406,11 @@ static VALUE set_init_command(VALUE self, VALUE value) {
|
|
1347
1406
|
}
|
1348
1407
|
|
1349
1408
|
static VALUE set_default_auth(VALUE self, VALUE value) {
|
1409
|
+
#ifdef HAVE_MYSQL_DEFAULT_AUTH
|
1350
1410
|
return _mysql_client_options(self, MYSQL_DEFAULT_AUTH, value);
|
1411
|
+
#else
|
1412
|
+
rb_raise(cMysql2Error, "pluggable authentication is not available, you may need a newer MySQL client library");
|
1413
|
+
#endif
|
1351
1414
|
}
|
1352
1415
|
|
1353
1416
|
static VALUE set_enable_cleartext_plugin(VALUE self, VALUE value) {
|
@@ -1411,6 +1474,7 @@ void init_mysql2_client() {
|
|
1411
1474
|
mMysql2 = rb_define_module("Mysql2"); Teach RDoc about Mysql2 constant.
|
1412
1475
|
#endif
|
1413
1476
|
cMysql2Client = rb_define_class_under(mMysql2, "Client", rb_cObject);
|
1477
|
+
rb_global_variable(&cMysql2Client);
|
1414
1478
|
|
1415
1479
|
rb_define_alloc_func(cMysql2Client, allocate);
|
1416
1480
|
|
@@ -1441,6 +1505,7 @@ void init_mysql2_client() {
|
|
1441
1505
|
rb_define_method(cMysql2Client, "query_info_string", rb_mysql_info, 0);
|
1442
1506
|
rb_define_method(cMysql2Client, "ssl_cipher", rb_mysql_get_ssl_cipher, 0);
|
1443
1507
|
rb_define_method(cMysql2Client, "encoding", rb_mysql_client_encoding, 0);
|
1508
|
+
rb_define_method(cMysql2Client, "session_track", rb_mysql_client_session_track, 1);
|
1444
1509
|
|
1445
1510
|
rb_define_private_method(cMysql2Client, "connect_timeout=", set_connect_timeout, 1);
|
1446
1511
|
rb_define_private_method(cMysql2Client, "read_timeout=", set_read_timeout, 1);
|
@@ -1613,16 +1678,32 @@ void init_mysql2_client() {
|
|
1613
1678
|
INT2NUM(0));
|
1614
1679
|
#endif
|
1615
1680
|
|
1681
|
+
#ifdef CLIENT_SESSION_TRACK
|
1682
|
+
rb_const_set(cMysql2Client, rb_intern("SESSION_TRACK"), INT2NUM(CLIENT_SESSION_TRACK));
|
1683
|
+
/* From mysql_com.h -- but stable from at least 5.7.4 through 8.0.20 */
|
1684
|
+
rb_const_set(cMysql2Client, rb_intern("SESSION_TRACK_SYSTEM_VARIABLES"), INT2NUM(SESSION_TRACK_SYSTEM_VARIABLES));
|
1685
|
+
rb_const_set(cMysql2Client, rb_intern("SESSION_TRACK_SCHEMA"), INT2NUM(SESSION_TRACK_SCHEMA));
|
1686
|
+
rb_const_set(cMysql2Client, rb_intern("SESSION_TRACK_STATE_CHANGE"), INT2NUM(SESSION_TRACK_STATE_CHANGE));
|
1687
|
+
rb_const_set(cMysql2Client, rb_intern("SESSION_TRACK_GTIDS"), INT2NUM(SESSION_TRACK_GTIDS));
|
1688
|
+
rb_const_set(cMysql2Client, rb_intern("SESSION_TRACK_TRANSACTION_CHARACTERISTICS"), INT2NUM(SESSION_TRACK_TRANSACTION_CHARACTERISTICS));
|
1689
|
+
rb_const_set(cMysql2Client, rb_intern("SESSION_TRACK_TRANSACTION_STATE"), INT2NUM(SESSION_TRACK_TRANSACTION_STATE));
|
1690
|
+
#endif
|
1691
|
+
|
1616
1692
|
#if defined(FULL_SSL_MODE_SUPPORT) // MySQL 5.7.11 and above
|
1617
1693
|
rb_const_set(cMysql2Client, rb_intern("SSL_MODE_DISABLED"), INT2NUM(SSL_MODE_DISABLED));
|
1618
1694
|
rb_const_set(cMysql2Client, rb_intern("SSL_MODE_PREFERRED"), INT2NUM(SSL_MODE_PREFERRED));
|
1619
1695
|
rb_const_set(cMysql2Client, rb_intern("SSL_MODE_REQUIRED"), INT2NUM(SSL_MODE_REQUIRED));
|
1620
1696
|
rb_const_set(cMysql2Client, rb_intern("SSL_MODE_VERIFY_CA"), INT2NUM(SSL_MODE_VERIFY_CA));
|
1621
1697
|
rb_const_set(cMysql2Client, rb_intern("SSL_MODE_VERIFY_IDENTITY"), INT2NUM(SSL_MODE_VERIFY_IDENTITY));
|
1622
|
-
#
|
1698
|
+
#else
|
1699
|
+
#ifdef HAVE_CONST_MYSQL_OPT_SSL_VERIFY_SERVER_CERT // MySQL 5.7.3 - 5.7.10 & MariaDB 10.x and later
|
1700
|
+
rb_const_set(cMysql2Client, rb_intern("SSL_MODE_VERIFY_IDENTITY"), INT2NUM(SSL_MODE_VERIFY_IDENTITY));
|
1701
|
+
#endif
|
1702
|
+
#ifdef HAVE_CONST_MYSQL_OPT_SSL_ENFORCE // MySQL 5.7.3 - 5.7.10 & MariaDB 10.x and later
|
1623
1703
|
rb_const_set(cMysql2Client, rb_intern("SSL_MODE_DISABLED"), INT2NUM(SSL_MODE_DISABLED));
|
1624
1704
|
rb_const_set(cMysql2Client, rb_intern("SSL_MODE_REQUIRED"), INT2NUM(SSL_MODE_REQUIRED));
|
1625
1705
|
#endif
|
1706
|
+
#endif
|
1626
1707
|
|
1627
1708
|
#ifndef HAVE_CONST_SSL_MODE_DISABLED
|
1628
1709
|
rb_const_set(cMysql2Client, rb_intern("SSL_MODE_DISABLED"), INT2NUM(0));
|
data/ext/mysql2/extconf.rb
CHANGED
@@ -15,10 +15,21 @@ def add_ssl_defines(header)
|
|
15
15
|
all_modes_found = %w[SSL_MODE_DISABLED SSL_MODE_PREFERRED SSL_MODE_REQUIRED SSL_MODE_VERIFY_CA SSL_MODE_VERIFY_IDENTITY].inject(true) do |m, ssl_mode|
|
16
16
|
m && have_const(ssl_mode, header)
|
17
17
|
end
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
18
|
+
if all_modes_found
|
19
|
+
$CFLAGS << ' -DFULL_SSL_MODE_SUPPORT'
|
20
|
+
else
|
21
|
+
# if we only have ssl toggle (--ssl,--disable-ssl) from 5.7.3 to 5.7.10
|
22
|
+
# and the verify server cert option. This is also the case for MariaDB.
|
23
|
+
has_verify_support = have_const('MYSQL_OPT_SSL_VERIFY_SERVER_CERT', header)
|
24
|
+
has_enforce_support = have_const('MYSQL_OPT_SSL_ENFORCE', header)
|
25
|
+
$CFLAGS << ' -DNO_SSL_MODE_SUPPORT' if !has_verify_support && !has_enforce_support
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# Homebrew openssl
|
30
|
+
if RUBY_PLATFORM =~ /darwin/ && system("command -v brew")
|
31
|
+
openssl_location = `brew --prefix openssl`.strip
|
32
|
+
$LDFLAGS << " -L#{openssl_location}/lib" if openssl_location
|
22
33
|
end
|
23
34
|
|
24
35
|
# 2.1+
|
@@ -28,6 +39,8 @@ have_func('rb_absint_singlebit_p')
|
|
28
39
|
# Missing in RBX (https://github.com/rubinius/rubinius/issues/3771)
|
29
40
|
have_func('rb_wait_for_single_fd')
|
30
41
|
|
42
|
+
have_func("rb_enc_interned_str", "ruby.h")
|
43
|
+
|
31
44
|
# borrowed from mysqlplus
|
32
45
|
# http://github.com/oldmoe/mysqlplus/blob/master/ext/extconf.rb
|
33
46
|
dirs = ENV.fetch('PATH').split(File::PATH_SEPARATOR) + %w[
|
@@ -42,6 +55,9 @@ dirs = ENV.fetch('PATH').split(File::PATH_SEPARATOR) + %w[
|
|
42
55
|
/usr/local/mysql-*
|
43
56
|
/usr/local/lib/mysql5*
|
44
57
|
/usr/local/opt/mysql5*
|
58
|
+
/usr/local/opt/mysql@*
|
59
|
+
/usr/local/opt/mysql-client
|
60
|
+
/usr/local/opt/mysql-client@*
|
45
61
|
].map { |dir| dir << '/bin' }
|
46
62
|
|
47
63
|
# For those without HOMEBREW_ROOT in PATH
|
@@ -108,6 +124,7 @@ have_struct_member('MYSQL', 'net.vio', mysql_h)
|
|
108
124
|
have_struct_member('MYSQL', 'net.pvio', mysql_h)
|
109
125
|
|
110
126
|
# These constants are actually enums, so they cannot be detected by #ifdef in C code.
|
127
|
+
have_const('MYSQL_DEFAULT_AUTH', mysql_h)
|
111
128
|
have_const('MYSQL_ENABLE_CLEARTEXT_PLUGIN', mysql_h)
|
112
129
|
have_const('SERVER_QUERY_NO_GOOD_INDEX_USED', mysql_h)
|
113
130
|
have_const('SERVER_QUERY_NO_INDEX_USED', mysql_h)
|
@@ -148,7 +165,7 @@ end
|
|
148
165
|
$CFLAGS << ' ' << usable_flags.join(' ')
|
149
166
|
|
150
167
|
enabled_sanitizers = disabled_sanitizers = []
|
151
|
-
# Specify a
|
168
|
+
# Specify a comma-separated list of sanitizers, or try them all by default
|
152
169
|
sanitizers = with_config('sanitize')
|
153
170
|
case sanitizers
|
154
171
|
when true
|
data/ext/mysql2/mysql2_ext.c
CHANGED
@@ -4,9 +4,14 @@ VALUE mMysql2, cMysql2Error, cMysql2TimeoutError;
|
|
4
4
|
|
5
5
|
/* Ruby Extension initializer */
|
6
6
|
void Init_mysql2() {
|
7
|
-
mMysql2
|
7
|
+
mMysql2 = rb_define_module("Mysql2");
|
8
|
+
rb_global_variable(&mMysql2);
|
9
|
+
|
8
10
|
cMysql2Error = rb_const_get(mMysql2, rb_intern("Error"));
|
11
|
+
rb_global_variable(&cMysql2Error);
|
12
|
+
|
9
13
|
cMysql2TimeoutError = rb_const_get(cMysql2Error, rb_intern("TimeoutError"));
|
14
|
+
rb_global_variable(&cMysql2TimeoutError);
|
10
15
|
|
11
16
|
init_mysql2_client();
|
12
17
|
init_mysql2_result();
|
data/ext/mysql2/result.c
CHANGED
@@ -17,6 +17,20 @@ static rb_encoding *binaryEncoding;
|
|
17
17
|
*/
|
18
18
|
#define MYSQL2_MIN_TIME 2678400ULL
|
19
19
|
|
20
|
+
#define MYSQL2_MAX_BYTES_PER_CHAR 3
|
21
|
+
|
22
|
+
/* From Mysql documentations:
|
23
|
+
* To distinguish between binary and nonbinary data for string data types,
|
24
|
+
* check whether the charsetnr value is 63. If so, the character set is binary,
|
25
|
+
* which indicates binary rather than nonbinary data. This enables you to distinguish BINARY
|
26
|
+
* from CHAR, VARBINARY from VARCHAR, and the BLOB types from the TEXT types.
|
27
|
+
*/
|
28
|
+
#define MYSQL2_BINARY_CHARSET 63
|
29
|
+
|
30
|
+
#ifndef MYSQL_TYPE_JSON
|
31
|
+
#define MYSQL_TYPE_JSON 245
|
32
|
+
#endif
|
33
|
+
|
20
34
|
#define GET_RESULT(self) \
|
21
35
|
mysql2_result_wrapper *wrapper; \
|
22
36
|
Data_Get_Struct(self, mysql2_result_wrapper, wrapper);
|
@@ -157,11 +171,18 @@ static VALUE rb_mysql_result_fetch_field(VALUE self, unsigned int idx, int symbo
|
|
157
171
|
rb_field = rb_intern3(field->name, field->name_length, rb_utf8_encoding());
|
158
172
|
rb_field = ID2SYM(rb_field);
|
159
173
|
} else {
|
160
|
-
|
161
|
-
|
162
|
-
if (default_internal_enc) {
|
174
|
+
#ifdef HAVE_RB_ENC_INTERNED_STR
|
175
|
+
rb_field = rb_enc_interned_str(field->name, field->name_length, conn_enc);
|
176
|
+
if (default_internal_enc && default_internal_enc != conn_enc) {
|
177
|
+
rb_field = rb_str_to_interned_str(rb_str_export_to_enc(rb_field, default_internal_enc));
|
178
|
+
}
|
179
|
+
#else
|
180
|
+
rb_field = rb_enc_str_new(field->name, field->name_length, conn_enc);
|
181
|
+
if (default_internal_enc && default_internal_enc != conn_enc) {
|
163
182
|
rb_field = rb_str_export_to_enc(rb_field, default_internal_enc);
|
164
183
|
}
|
184
|
+
rb_obj_freeze(rb_field);
|
185
|
+
#endif
|
165
186
|
}
|
166
187
|
rb_ary_store(wrapper->fields, idx, rb_field);
|
167
188
|
}
|
@@ -169,9 +190,171 @@ static VALUE rb_mysql_result_fetch_field(VALUE self, unsigned int idx, int symbo
|
|
169
190
|
return rb_field;
|
170
191
|
}
|
171
192
|
|
193
|
+
static VALUE rb_mysql_result_fetch_field_type(VALUE self, unsigned int idx) {
|
194
|
+
VALUE rb_field_type;
|
195
|
+
GET_RESULT(self);
|
196
|
+
|
197
|
+
if (wrapper->fieldTypes == Qnil) {
|
198
|
+
wrapper->numberOfFields = mysql_num_fields(wrapper->result);
|
199
|
+
wrapper->fieldTypes = rb_ary_new2(wrapper->numberOfFields);
|
200
|
+
}
|
201
|
+
|
202
|
+
rb_field_type = rb_ary_entry(wrapper->fieldTypes, idx);
|
203
|
+
if (rb_field_type == Qnil) {
|
204
|
+
MYSQL_FIELD *field = NULL;
|
205
|
+
rb_encoding *default_internal_enc = rb_default_internal_encoding();
|
206
|
+
rb_encoding *conn_enc = rb_to_encoding(wrapper->encoding);
|
207
|
+
int precision;
|
208
|
+
|
209
|
+
field = mysql_fetch_field_direct(wrapper->result, idx);
|
210
|
+
|
211
|
+
switch(field->type) {
|
212
|
+
case MYSQL_TYPE_NULL: // NULL
|
213
|
+
rb_field_type = rb_str_new_cstr("null");
|
214
|
+
break;
|
215
|
+
case MYSQL_TYPE_TINY: // signed char
|
216
|
+
rb_field_type = rb_sprintf("tinyint(%ld)", field->length);
|
217
|
+
break;
|
218
|
+
case MYSQL_TYPE_SHORT: // short int
|
219
|
+
rb_field_type = rb_sprintf("smallint(%ld)", field->length);
|
220
|
+
break;
|
221
|
+
case MYSQL_TYPE_YEAR: // short int
|
222
|
+
rb_field_type = rb_sprintf("year(%ld)", field->length);
|
223
|
+
break;
|
224
|
+
case MYSQL_TYPE_INT24: // int
|
225
|
+
rb_field_type = rb_sprintf("mediumint(%ld)", field->length);
|
226
|
+
break;
|
227
|
+
case MYSQL_TYPE_LONG: // int
|
228
|
+
rb_field_type = rb_sprintf("int(%ld)", field->length);
|
229
|
+
break;
|
230
|
+
case MYSQL_TYPE_LONGLONG: // long long int
|
231
|
+
rb_field_type = rb_sprintf("bigint(%ld)", field->length);
|
232
|
+
break;
|
233
|
+
case MYSQL_TYPE_FLOAT: // float
|
234
|
+
rb_field_type = rb_sprintf("float(%ld,%d)", field->length, field->decimals);
|
235
|
+
break;
|
236
|
+
case MYSQL_TYPE_DOUBLE: // double
|
237
|
+
rb_field_type = rb_sprintf("double(%ld,%d)", field->length, field->decimals);
|
238
|
+
break;
|
239
|
+
case MYSQL_TYPE_TIME: // MYSQL_TIME
|
240
|
+
rb_field_type = rb_str_new_cstr("time");
|
241
|
+
break;
|
242
|
+
case MYSQL_TYPE_DATE: // MYSQL_TIME
|
243
|
+
case MYSQL_TYPE_NEWDATE: // MYSQL_TIME
|
244
|
+
rb_field_type = rb_str_new_cstr("date");
|
245
|
+
break;
|
246
|
+
case MYSQL_TYPE_DATETIME: // MYSQL_TIME
|
247
|
+
rb_field_type = rb_str_new_cstr("datetime");
|
248
|
+
break;
|
249
|
+
case MYSQL_TYPE_TIMESTAMP: // MYSQL_TIME
|
250
|
+
rb_field_type = rb_str_new_cstr("timestamp");
|
251
|
+
break;
|
252
|
+
case MYSQL_TYPE_DECIMAL: // char[]
|
253
|
+
case MYSQL_TYPE_NEWDECIMAL: // char[]
|
254
|
+
/*
|
255
|
+
Handle precision similar to this line from mysql's code:
|
256
|
+
https://github.com/mysql/mysql-server/blob/ea7d2e2d16ac03afdd9cb72a972a95981107bf51/sql/field.cc#L2246
|
257
|
+
*/
|
258
|
+
precision = field->length - (field->decimals > 0 ? 2 : 1);
|
259
|
+
rb_field_type = rb_sprintf("decimal(%d,%d)", precision, field->decimals);
|
260
|
+
break;
|
261
|
+
case MYSQL_TYPE_STRING: // char[]
|
262
|
+
if (field->flags & ENUM_FLAG) {
|
263
|
+
rb_field_type = rb_str_new_cstr("enum");
|
264
|
+
} else if (field->flags & SET_FLAG) {
|
265
|
+
rb_field_type = rb_str_new_cstr("set");
|
266
|
+
} else {
|
267
|
+
if (field->charsetnr == MYSQL2_BINARY_CHARSET) {
|
268
|
+
rb_field_type = rb_sprintf("binary(%ld)", field->length);
|
269
|
+
} else {
|
270
|
+
rb_field_type = rb_sprintf("char(%ld)", field->length / MYSQL2_MAX_BYTES_PER_CHAR);
|
271
|
+
}
|
272
|
+
}
|
273
|
+
break;
|
274
|
+
case MYSQL_TYPE_VAR_STRING: // char[]
|
275
|
+
if (field->charsetnr == MYSQL2_BINARY_CHARSET) {
|
276
|
+
rb_field_type = rb_sprintf("varbinary(%ld)", field->length);
|
277
|
+
} else {
|
278
|
+
rb_field_type = rb_sprintf("varchar(%ld)", field->length / MYSQL2_MAX_BYTES_PER_CHAR);
|
279
|
+
}
|
280
|
+
break;
|
281
|
+
case MYSQL_TYPE_VARCHAR: // char[]
|
282
|
+
rb_field_type = rb_sprintf("varchar(%ld)", field->length / MYSQL2_MAX_BYTES_PER_CHAR);
|
283
|
+
break;
|
284
|
+
case MYSQL_TYPE_TINY_BLOB: // char[]
|
285
|
+
rb_field_type = rb_str_new_cstr("tinyblob");
|
286
|
+
break;
|
287
|
+
case MYSQL_TYPE_BLOB: // char[]
|
288
|
+
if (field->charsetnr == MYSQL2_BINARY_CHARSET) {
|
289
|
+
switch(field->length) {
|
290
|
+
case 255:
|
291
|
+
rb_field_type = rb_str_new_cstr("tinyblob");
|
292
|
+
break;
|
293
|
+
case 65535:
|
294
|
+
rb_field_type = rb_str_new_cstr("blob");
|
295
|
+
break;
|
296
|
+
case 16777215:
|
297
|
+
rb_field_type = rb_str_new_cstr("mediumblob");
|
298
|
+
break;
|
299
|
+
case 4294967295:
|
300
|
+
rb_field_type = rb_str_new_cstr("longblob");
|
301
|
+
default:
|
302
|
+
break;
|
303
|
+
}
|
304
|
+
} else {
|
305
|
+
if (field->length == (255 * MYSQL2_MAX_BYTES_PER_CHAR)) {
|
306
|
+
rb_field_type = rb_str_new_cstr("tinytext");
|
307
|
+
} else if (field->length == (65535 * MYSQL2_MAX_BYTES_PER_CHAR)) {
|
308
|
+
rb_field_type = rb_str_new_cstr("text");
|
309
|
+
} else if (field->length == (16777215 * MYSQL2_MAX_BYTES_PER_CHAR)) {
|
310
|
+
rb_field_type = rb_str_new_cstr("mediumtext");
|
311
|
+
} else if (field->length == 4294967295) {
|
312
|
+
rb_field_type = rb_str_new_cstr("longtext");
|
313
|
+
} else {
|
314
|
+
rb_field_type = rb_sprintf("text(%ld)", field->length);
|
315
|
+
}
|
316
|
+
}
|
317
|
+
break;
|
318
|
+
case MYSQL_TYPE_MEDIUM_BLOB: // char[]
|
319
|
+
rb_field_type = rb_str_new_cstr("mediumblob");
|
320
|
+
break;
|
321
|
+
case MYSQL_TYPE_LONG_BLOB: // char[]
|
322
|
+
rb_field_type = rb_str_new_cstr("longblob");
|
323
|
+
break;
|
324
|
+
case MYSQL_TYPE_BIT: // char[]
|
325
|
+
rb_field_type = rb_sprintf("bit(%ld)", field->length);
|
326
|
+
break;
|
327
|
+
case MYSQL_TYPE_SET: // char[]
|
328
|
+
rb_field_type = rb_str_new_cstr("set");
|
329
|
+
break;
|
330
|
+
case MYSQL_TYPE_ENUM: // char[]
|
331
|
+
rb_field_type = rb_str_new_cstr("enum");
|
332
|
+
break;
|
333
|
+
case MYSQL_TYPE_GEOMETRY: // char[]
|
334
|
+
rb_field_type = rb_str_new_cstr("geometry");
|
335
|
+
break;
|
336
|
+
case MYSQL_TYPE_JSON: // json
|
337
|
+
rb_field_type = rb_str_new_cstr("json");
|
338
|
+
break;
|
339
|
+
default:
|
340
|
+
rb_field_type = rb_str_new_cstr("unknown");
|
341
|
+
break;
|
342
|
+
}
|
343
|
+
|
344
|
+
rb_enc_associate(rb_field_type, conn_enc);
|
345
|
+
if (default_internal_enc) {
|
346
|
+
rb_field_type = rb_str_export_to_enc(rb_field_type, default_internal_enc);
|
347
|
+
}
|
348
|
+
|
349
|
+
rb_ary_store(wrapper->fieldTypes, idx, rb_field_type);
|
350
|
+
}
|
351
|
+
|
352
|
+
return rb_field_type;
|
353
|
+
}
|
354
|
+
|
172
355
|
static VALUE mysql2_set_field_string_encoding(VALUE val, MYSQL_FIELD field, rb_encoding *default_internal_enc, rb_encoding *conn_enc) {
|
173
356
|
/* if binary flag is set, respect its wishes */
|
174
|
-
if (field.flags & BINARY_FLAG && field.charsetnr ==
|
357
|
+
if (field.flags & BINARY_FLAG && field.charsetnr == MYSQL2_BINARY_CHARSET) {
|
175
358
|
rb_enc_associate(val, binaryEncoding);
|
176
359
|
} else if (!field.charsetnr) {
|
177
360
|
/* MySQL 4.x may not provide an encoding, binary will get the bytes through */
|
@@ -716,6 +899,25 @@ static VALUE rb_mysql_result_fetch_fields(VALUE self) {
|
|
716
899
|
return wrapper->fields;
|
717
900
|
}
|
718
901
|
|
902
|
+
static VALUE rb_mysql_result_fetch_field_types(VALUE self) {
|
903
|
+
unsigned int i = 0;
|
904
|
+
|
905
|
+
GET_RESULT(self);
|
906
|
+
|
907
|
+
if (wrapper->fieldTypes == Qnil) {
|
908
|
+
wrapper->numberOfFields = mysql_num_fields(wrapper->result);
|
909
|
+
wrapper->fieldTypes = rb_ary_new2(wrapper->numberOfFields);
|
910
|
+
}
|
911
|
+
|
912
|
+
if ((my_ulonglong)RARRAY_LEN(wrapper->fieldTypes) != wrapper->numberOfFields) {
|
913
|
+
for (i=0; i<wrapper->numberOfFields; i++) {
|
914
|
+
rb_mysql_result_fetch_field_type(self, i);
|
915
|
+
}
|
916
|
+
}
|
917
|
+
|
918
|
+
return wrapper->fieldTypes;
|
919
|
+
}
|
920
|
+
|
719
921
|
static VALUE rb_mysql_result_each_(VALUE self,
|
720
922
|
VALUE(*fetch_row_func)(VALUE, MYSQL_FIELD *fields, const result_each_args *args),
|
721
923
|
const result_each_args *args)
|
@@ -934,6 +1136,7 @@ VALUE rb_mysql_result_to_obj(VALUE client, VALUE encoding, VALUE options, MYSQL_
|
|
934
1136
|
wrapper->resultFreed = 0;
|
935
1137
|
wrapper->result = r;
|
936
1138
|
wrapper->fields = Qnil;
|
1139
|
+
wrapper->fieldTypes = Qnil;
|
937
1140
|
wrapper->rows = Qnil;
|
938
1141
|
wrapper->encoding = encoding;
|
939
1142
|
wrapper->streamingComplete = 0;
|
@@ -966,11 +1169,17 @@ VALUE rb_mysql_result_to_obj(VALUE client, VALUE encoding, VALUE options, MYSQL_
|
|
966
1169
|
|
967
1170
|
void init_mysql2_result() {
|
968
1171
|
cDate = rb_const_get(rb_cObject, rb_intern("Date"));
|
1172
|
+
rb_global_variable(&cDate);
|
969
1173
|
cDateTime = rb_const_get(rb_cObject, rb_intern("DateTime"));
|
1174
|
+
rb_global_variable(&cDateTime);
|
970
1175
|
|
971
1176
|
cMysql2Result = rb_define_class_under(mMysql2, "Result", rb_cObject);
|
1177
|
+
rb_undef_alloc_func(cMysql2Result);
|
1178
|
+
rb_global_variable(&cMysql2Result);
|
1179
|
+
|
972
1180
|
rb_define_method(cMysql2Result, "each", rb_mysql_result_each, -1);
|
973
1181
|
rb_define_method(cMysql2Result, "fields", rb_mysql_result_fetch_fields, 0);
|
1182
|
+
rb_define_method(cMysql2Result, "field_types", rb_mysql_result_fetch_field_types, 0);
|
974
1183
|
rb_define_method(cMysql2Result, "free", rb_mysql_result_free_, 0);
|
975
1184
|
rb_define_method(cMysql2Result, "count", rb_mysql_result_count, 0);
|
976
1185
|
rb_define_alias(cMysql2Result, "size", "count");
|
data/ext/mysql2/result.h
CHANGED
data/ext/mysql2/statement.c
CHANGED
@@ -46,7 +46,7 @@ void rb_raise_mysql2_stmt_error(mysql_stmt_wrapper *stmt_wrapper) {
|
|
46
46
|
VALUE e;
|
47
47
|
GET_CLIENT(stmt_wrapper->client);
|
48
48
|
VALUE rb_error_msg = rb_str_new2(mysql_stmt_error(stmt_wrapper->stmt));
|
49
|
-
VALUE rb_sql_state =
|
49
|
+
VALUE rb_sql_state = rb_str_new2(mysql_stmt_sqlstate(stmt_wrapper->stmt));
|
50
50
|
|
51
51
|
rb_encoding *conn_enc;
|
52
52
|
conn_enc = rb_to_encoding(wrapper->encoding);
|
@@ -456,7 +456,7 @@ static VALUE rb_mysql_stmt_execute(int argc, VALUE *argv, VALUE self) {
|
|
456
456
|
}
|
457
457
|
|
458
458
|
if (!is_streaming) {
|
459
|
-
//
|
459
|
+
// receive the whole result set from the server
|
460
460
|
if (mysql_stmt_store_result(stmt)) {
|
461
461
|
mysql_free_result(metadata);
|
462
462
|
rb_raise_mysql2_stmt_error(stmt_wrapper);
|
@@ -572,10 +572,18 @@ static VALUE rb_mysql_stmt_close(VALUE self) {
|
|
572
572
|
|
573
573
|
void init_mysql2_statement() {
|
574
574
|
cDate = rb_const_get(rb_cObject, rb_intern("Date"));
|
575
|
+
rb_global_variable(&cDate);
|
576
|
+
|
575
577
|
cDateTime = rb_const_get(rb_cObject, rb_intern("DateTime"));
|
578
|
+
rb_global_variable(&cDateTime);
|
579
|
+
|
576
580
|
cBigDecimal = rb_const_get(rb_cObject, rb_intern("BigDecimal"));
|
581
|
+
rb_global_variable(&cBigDecimal);
|
577
582
|
|
578
583
|
cMysql2Statement = rb_define_class_under(mMysql2, "Statement", rb_cObject);
|
584
|
+
rb_undef_alloc_func(cMysql2Statement);
|
585
|
+
rb_global_variable(&cMysql2Statement);
|
586
|
+
|
579
587
|
rb_define_method(cMysql2Statement, "param_count", rb_mysql_stmt_param_count, 0);
|
580
588
|
rb_define_method(cMysql2Statement, "field_count", rb_mysql_stmt_field_count, 0);
|
581
589
|
rb_define_method(cMysql2Statement, "_execute", rb_mysql_stmt_execute, -1);
|
data/lib/mysql2/client.rb
CHANGED
@@ -46,9 +46,14 @@ module Mysql2
|
|
46
46
|
# force the encoding to utf8
|
47
47
|
self.charset_name = opts[:encoding] || 'utf8'
|
48
48
|
|
49
|
+
mode = parse_ssl_mode(opts[:ssl_mode]) if opts[:ssl_mode]
|
50
|
+
if (mode == SSL_MODE_VERIFY_CA || mode == SSL_MODE_VERIFY_IDENTITY) && !opts[:sslca]
|
51
|
+
opts[:sslca] = find_default_ca_path
|
52
|
+
end
|
53
|
+
|
49
54
|
ssl_options = opts.values_at(:sslkey, :sslcert, :sslca, :sslcapath, :sslcipher)
|
50
55
|
ssl_set(*ssl_options) if ssl_options.any? || opts.key?(:sslverify)
|
51
|
-
self.ssl_mode =
|
56
|
+
self.ssl_mode = mode if mode
|
52
57
|
|
53
58
|
flags = case opts[:flags]
|
54
59
|
when Array
|
@@ -115,6 +120,18 @@ module Mysql2
|
|
115
120
|
end
|
116
121
|
end
|
117
122
|
|
123
|
+
# Find any default system CA paths to handle system roots
|
124
|
+
# by default if stricter validation is requested and no
|
125
|
+
# path is provide.
|
126
|
+
def find_default_ca_path
|
127
|
+
[
|
128
|
+
"/etc/ssl/certs/ca-certificates.crt",
|
129
|
+
"/etc/pki/tls/certs/ca-bundle.crt",
|
130
|
+
"/etc/ssl/ca-bundle.pem",
|
131
|
+
"/etc/ssl/cert.pem",
|
132
|
+
].find { |f| File.exist?(f) }
|
133
|
+
end
|
134
|
+
|
118
135
|
# Set default program_name in performance_schema.session_connect_attrs
|
119
136
|
# and performance_schema.session_account_connect_attrs
|
120
137
|
def parse_connect_attrs(conn_attrs)
|
@@ -127,7 +144,7 @@ module Mysql2
|
|
127
144
|
end
|
128
145
|
|
129
146
|
def query(sql, options = {})
|
130
|
-
Thread.handle_interrupt(::Mysql2::Util::
|
147
|
+
Thread.handle_interrupt(::Mysql2::Util::TIMEOUT_ERROR_NEVER) do
|
131
148
|
_query(sql, @query_options.merge(options))
|
132
149
|
end
|
133
150
|
end
|
data/lib/mysql2/error.rb
CHANGED
@@ -24,6 +24,7 @@ module Mysql2
|
|
24
24
|
1159 => ConnectionError, # ER_NET_READ_INTERRUPTED
|
25
25
|
1160 => ConnectionError, # ER_NET_ERROR_ON_WRITE
|
26
26
|
1161 => ConnectionError, # ER_NET_WRITE_INTERRUPTED
|
27
|
+
1927 => ConnectionError, # ER_CONNECTION_KILLED
|
27
28
|
|
28
29
|
2001 => ConnectionError, # CR_SOCKET_CREATE_ERROR
|
29
30
|
2002 => ConnectionError, # CR_CONNECTION_ERROR
|
data/lib/mysql2/statement.rb
CHANGED
@@ -1,9 +1,7 @@
|
|
1
1
|
module Mysql2
|
2
2
|
class Statement
|
3
|
-
include Enumerable
|
4
|
-
|
5
3
|
def execute(*args, **kwargs)
|
6
|
-
Thread.handle_interrupt(::Mysql2::Util::
|
4
|
+
Thread.handle_interrupt(::Mysql2::Util::TIMEOUT_ERROR_NEVER) do
|
7
5
|
_execute(*args, **kwargs)
|
8
6
|
end
|
9
7
|
end
|
data/lib/mysql2/version.rb
CHANGED
data/lib/mysql2.rb
CHANGED
@@ -0,0 +1,49 @@
|
|
1
|
+
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
2
|
+
Version: SKS 1.1.6
|
3
|
+
Comment: Hostname: pgp.mit.edu
|
4
|
+
|
5
|
+
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
|
47
|
+
sTSKHe+QnnnoFmu4gnmDU31i
|
48
|
+
=Xqbo
|
49
|
+
-----END PGP PUBLIC KEY BLOCK-----
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mysql2
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brian Lopez
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2022-05-03 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description:
|
15
15
|
email:
|
@@ -46,6 +46,7 @@ files:
|
|
46
46
|
- lib/mysql2/result.rb
|
47
47
|
- lib/mysql2/statement.rb
|
48
48
|
- lib/mysql2/version.rb
|
49
|
+
- support/3A79BD29.asc
|
49
50
|
- support/5072E1F5.asc
|
50
51
|
- support/libmysql.def
|
51
52
|
- support/mysql_enc_to_ruby.rb
|
@@ -54,6 +55,11 @@ homepage: https://github.com/brianmario/mysql2
|
|
54
55
|
licenses:
|
55
56
|
- MIT
|
56
57
|
metadata:
|
58
|
+
bug_tracker_uri: https://github.com/brianmario/mysql2/issues
|
59
|
+
changelog_uri: https://github.com/brianmario/mysql2/releases/tag/0.5.4
|
60
|
+
documentation_uri: https://www.rubydoc.info/gems/mysql2/0.5.4
|
61
|
+
homepage_uri: https://github.com/brianmario/mysql2
|
62
|
+
source_code_uri: https://github.com/brianmario/mysql2/tree/0.5.4
|
57
63
|
msys2_mingw_dependencies: libmariadbclient
|
58
64
|
post_install_message:
|
59
65
|
rdoc_options:
|
@@ -71,7 +77,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
71
77
|
- !ruby/object:Gem::Version
|
72
78
|
version: '0'
|
73
79
|
requirements: []
|
74
|
-
rubygems_version: 3.0.3
|
80
|
+
rubygems_version: 3.0.3.1
|
75
81
|
signing_key:
|
76
82
|
specification_version: 4
|
77
83
|
summary: A simple, fast Mysql library for Ruby, binding to libmysql
|