mysql2 0.4.1-x86-mingw32 → 0.4.2-x86-mingw32
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +35 -6
- data/ext/mysql2/client.c +7 -11
- data/ext/mysql2/extconf.rb +39 -15
- data/ext/mysql2/result.c +20 -17
- data/ext/mysql2/statement.c +8 -5
- data/ext/mysql2/statement.h +1 -0
- 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 +26 -4
- data/lib/mysql2/version.rb +1 -1
- data/spec/mysql2/client_spec.rb +22 -16
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3bb560fb34faab47b795f3c40199d99f709cfd90
|
4
|
+
data.tar.gz: 3c37d37dde6f570334ac52ce98c96fccb403a162
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f14f96988d2e98d7939bb1f816c473381baf76e97a1c3ffd702015be4cdedfbdb7efb215840656b5e087df8ee2dedbd2d583013ea30b7200e8b1d5976709161b
|
7
|
+
data.tar.gz: 9d6d0f4255a060f88512696ec3a4885f5ab454a4750cf53199070b1c99f074cc4416551d2b7a8ba0cc0a239573bdba90a6f134c9340bd426d98dbca0cdde5a11
|
data/README.md
CHANGED
@@ -58,6 +58,20 @@ This may be needed if you deploy to a system where these libraries
|
|
58
58
|
are located somewhere different than on your build system.
|
59
59
|
This overrides any rpath calculated by default or by the options above.
|
60
60
|
|
61
|
+
* `--with-sanitize[=address,cfi,integer,memory,thread,undefined]` -
|
62
|
+
Enable sanitizers for Clang / GCC. If no argument is given, try to enable
|
63
|
+
all sanitizers or fail if none are available. If a command-separated list of
|
64
|
+
specific sanitizers is given, configure will fail unless they all are available.
|
65
|
+
Note that the some sanitizers may incur a performance penalty, and the Address
|
66
|
+
Sanitizer may require a runtime library.
|
67
|
+
To see line numbers in backtraces, declare these environment variables
|
68
|
+
(adjust the llvm-symbolizer path as needed for your system):
|
69
|
+
|
70
|
+
``` sh
|
71
|
+
export ASAN_SYMBOLIZER_PATH=/usr/bin/llvm-symbolizer-3.4
|
72
|
+
export ASAN_OPTIONS=symbolize=1
|
73
|
+
```
|
74
|
+
|
61
75
|
### Linux and other Unixes
|
62
76
|
|
63
77
|
You may need to install a package such as `libmysqlclient-dev` or `mysql-devel`;
|
@@ -258,15 +272,26 @@ Yields:
|
|
258
272
|
next_result: Unknown column 'A' in 'field list' (Mysql2::Error)
|
259
273
|
```
|
260
274
|
|
261
|
-
See https://gist.github.com/1367987 for using MULTI_STATEMENTS with Active Record.
|
262
|
-
|
263
275
|
### Secure auth
|
264
276
|
|
265
277
|
Starting wih MySQL 5.6.5, secure_auth is enabled by default on servers (it was disabled by default prior to this).
|
266
278
|
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
279
|
The MySQL 5.6.5 client library may also refuse to attempt a connection if provided an older format password.
|
268
|
-
To bypass this restriction in the client, pass the option
|
269
|
-
|
280
|
+
To bypass this restriction in the client, pass the option `:secure_auth => false` to Mysql2::Client.new().
|
281
|
+
|
282
|
+
### Flags option parsing
|
283
|
+
|
284
|
+
The `:flags` parameter accepts an integer, a string, or an array. The integer
|
285
|
+
form allows the client to assemble flags from constants defined under
|
286
|
+
`Mysql2::Client` such as `Mysql2::Client::FOUND_ROWS`. Use a bitwise `|` (OR)
|
287
|
+
to specify several flags.
|
288
|
+
|
289
|
+
The string form will be split on whitespace and parsed as with the array form:
|
290
|
+
Plain flags are added to the default flags, while flags prefixed with `-`
|
291
|
+
(minus) are removed from the default flags.
|
292
|
+
|
293
|
+
This allows easier use with ActiveRecord's database.yml, avoiding the need for magic flag numbers.
|
294
|
+
For example, to disable protocol compression, and enable multiple statements and result sets:
|
270
295
|
|
271
296
|
``` yaml
|
272
297
|
development:
|
@@ -277,13 +302,17 @@ development:
|
|
277
302
|
password: my_password
|
278
303
|
host: 127.0.0.1
|
279
304
|
port: 3306
|
305
|
+
flags:
|
306
|
+
- -COMPRESS
|
307
|
+
- FOUND_ROWS
|
308
|
+
- MULTI_STATEMENTS
|
280
309
|
secure_auth: false
|
281
310
|
```
|
282
311
|
|
283
312
|
### Reading a MySQL config file
|
284
313
|
|
285
314
|
You may read configuration options from a MySQL configuration file by passing
|
286
|
-
the `:default_file` and `:default_group`
|
315
|
+
the `:default_file` and `:default_group` parameters. For example:
|
287
316
|
|
288
317
|
``` ruby
|
289
318
|
Mysql2::Client.new(:default_file => '/user/.my.cnf', :default_group => 'client')
|
@@ -291,7 +320,7 @@ Mysql2::Client.new(:default_file => '/user/.my.cnf', :default_group => 'client')
|
|
291
320
|
|
292
321
|
### Initial command on connect and reconnect
|
293
322
|
|
294
|
-
If you specify the init_command option, the SQL string you provide will be executed after the connection is established.
|
323
|
+
If you specify the `:init_command` option, the SQL string you provide will be executed after the connection is established.
|
295
324
|
If `:reconnect` is set to `true`, init_command will also be executed after a successful reconnect.
|
296
325
|
It is useful if you want to provide session options which survive reconnection.
|
297
326
|
|
data/ext/mysql2/client.c
CHANGED
@@ -133,7 +133,7 @@ static VALUE rb_raise_mysql2_error(mysql_client_wrapper *wrapper) {
|
|
133
133
|
|
134
134
|
static void *nogvl_init(void *ptr) {
|
135
135
|
MYSQL *client;
|
136
|
-
mysql_client_wrapper *wrapper =
|
136
|
+
mysql_client_wrapper *wrapper = ptr;
|
137
137
|
|
138
138
|
/* may initialize embedded server and read /etc/services off disk */
|
139
139
|
client = mysql_init(wrapper->client);
|
@@ -213,6 +213,7 @@ static void *nogvl_close(void *ptr) {
|
|
213
213
|
|
214
214
|
if (wrapper->client) {
|
215
215
|
mysql_close(wrapper->client);
|
216
|
+
xfree(wrapper->client);
|
216
217
|
wrapper->client = NULL;
|
217
218
|
wrapper->connected = 0;
|
218
219
|
wrapper->active_thread = Qnil;
|
@@ -223,7 +224,7 @@ static void *nogvl_close(void *ptr) {
|
|
223
224
|
|
224
225
|
/* this is called during GC */
|
225
226
|
static void rb_mysql_client_free(void *ptr) {
|
226
|
-
mysql_client_wrapper *wrapper =
|
227
|
+
mysql_client_wrapper *wrapper = ptr;
|
227
228
|
decr_mysql2_client(wrapper);
|
228
229
|
}
|
229
230
|
|
@@ -249,7 +250,6 @@ void decr_mysql2_client(mysql_client_wrapper *wrapper)
|
|
249
250
|
#endif
|
250
251
|
|
251
252
|
nogvl_close(wrapper);
|
252
|
-
xfree(wrapper->client);
|
253
253
|
xfree(wrapper);
|
254
254
|
}
|
255
255
|
}
|
@@ -437,10 +437,9 @@ static void *nogvl_read_query_result(void *ptr) {
|
|
437
437
|
}
|
438
438
|
|
439
439
|
static void *nogvl_do_result(void *ptr, char use_result) {
|
440
|
-
mysql_client_wrapper *wrapper;
|
440
|
+
mysql_client_wrapper *wrapper = ptr;
|
441
441
|
MYSQL_RES *result;
|
442
442
|
|
443
|
-
wrapper = (mysql_client_wrapper *)ptr;
|
444
443
|
if (use_result) {
|
445
444
|
result = mysql_use_result(wrapper->client);
|
446
445
|
} else {
|
@@ -533,14 +532,13 @@ static VALUE disconnect_and_raise(VALUE self, VALUE error) {
|
|
533
532
|
}
|
534
533
|
|
535
534
|
static VALUE do_query(void *args) {
|
536
|
-
struct async_query_args *async_args;
|
535
|
+
struct async_query_args *async_args = args;
|
537
536
|
struct timeval tv;
|
538
|
-
struct timeval*
|
537
|
+
struct timeval *tvp;
|
539
538
|
long int sec;
|
540
539
|
int retval;
|
541
540
|
VALUE read_timeout;
|
542
541
|
|
543
|
-
async_args = (struct async_query_args *)args;
|
544
542
|
read_timeout = rb_iv_get(async_args->self, "@read_timeout");
|
545
543
|
|
546
544
|
tvp = NULL;
|
@@ -578,11 +576,9 @@ static VALUE do_query(void *args) {
|
|
578
576
|
}
|
579
577
|
#else
|
580
578
|
static VALUE finish_and_mark_inactive(void *args) {
|
581
|
-
VALUE self;
|
579
|
+
VALUE self = args;
|
582
580
|
MYSQL_RES *result;
|
583
581
|
|
584
|
-
self = (VALUE)args;
|
585
|
-
|
586
582
|
GET_CLIENT(self);
|
587
583
|
|
588
584
|
if (!NIL_P(wrapper->active_thread)) {
|
data/ext/mysql2/extconf.rb
CHANGED
@@ -105,31 +105,55 @@ wishlist = [
|
|
105
105
|
'-Wno-missing-field-initializers', # gperf generates bad code
|
106
106
|
'-Wno-missing-variable-declarations', # missing symbols due to ruby native ext initialization
|
107
107
|
'-Wno-padded', # mysql :(
|
108
|
+
'-Wno-reserved-id-macro', # rubby :(
|
108
109
|
'-Wno-sign-conversion', # gperf generates bad code
|
109
110
|
'-Wno-static-in-inline', # gperf generates bad code
|
110
111
|
'-Wno-switch-enum', # result.c -- enum_field_types (when not fully covered, e.g. mysql 5.6+)
|
111
112
|
'-Wno-undef', # rubinius :(
|
113
|
+
'-Wno-unreachable-code', # rubby :(
|
112
114
|
'-Wno-used-but-marked-unused', # rubby :(
|
113
115
|
]
|
114
116
|
|
115
|
-
if ENV['CI']
|
116
|
-
wishlist += [
|
117
|
-
'-Werror',
|
118
|
-
'-fsanitize=address',
|
119
|
-
'-fsanitize=cfi',
|
120
|
-
'-fsanitize=integer',
|
121
|
-
'-fsanitize=memory',
|
122
|
-
'-fsanitize=thread',
|
123
|
-
'-fsanitize=undefined',
|
124
|
-
]
|
125
|
-
end
|
126
|
-
|
127
117
|
usable_flags = wishlist.select do |flag|
|
128
|
-
try_link('int main() {return 0;}', flag)
|
118
|
+
try_link('int main() {return 0;}', "-Werror #{flag}")
|
129
119
|
end
|
130
120
|
|
131
121
|
$CFLAGS << ' ' << usable_flags.join(' ')
|
132
122
|
|
123
|
+
enabled_sanitizers = disabled_sanitizers = []
|
124
|
+
# Specify a commna-separated list of sanitizers, or try them all by default
|
125
|
+
sanitizers = with_config('sanitize')
|
126
|
+
case sanitizers
|
127
|
+
when true
|
128
|
+
# Try them all, turn on whatever we can
|
129
|
+
enabled_sanitizers = %w(address cfi integer memory thread undefined).select do |s|
|
130
|
+
try_link('int main() {return 0;}', "-Werror -fsanitize=#{s}")
|
131
|
+
end
|
132
|
+
abort "-----\nCould not enable any sanitizers!\n-----" if enabled_sanitizers.empty?
|
133
|
+
when String
|
134
|
+
# Figure out which sanitizers are supported
|
135
|
+
enabled_sanitizers, disabled_sanitizers = sanitizers.split(',').partition do |s|
|
136
|
+
try_link('int main() {return 0;}', "-Werror -fsanitize=#{s}")
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
unless disabled_sanitizers.empty?
|
141
|
+
abort "-----\nCould not enable requested sanitizers: #{disabled_sanitizers.join(',')}\n-----"
|
142
|
+
end
|
143
|
+
|
144
|
+
unless enabled_sanitizers.empty?
|
145
|
+
warn "-----\nEnabling sanitizers: #{enabled_sanitizers.join(',')}\n-----"
|
146
|
+
enabled_sanitizers.each do |s|
|
147
|
+
# address sanitizer requires runtime support
|
148
|
+
if s == 'address' # rubocop:disable Style/IfUnlessModifier
|
149
|
+
have_library('asan') || $LDFLAGS << ' -fsanitize=address'
|
150
|
+
end
|
151
|
+
$CFLAGS << " -fsanitize=#{s}"
|
152
|
+
end
|
153
|
+
# Options for line numbers in backtraces
|
154
|
+
$CFLAGS << ' -g -fno-omit-frame-pointer'
|
155
|
+
end
|
156
|
+
|
133
157
|
if RUBY_PLATFORM =~ /mswin|mingw/
|
134
158
|
# Build libmysql.a interface link library
|
135
159
|
require 'rake'
|
@@ -155,8 +179,8 @@ if RUBY_PLATFORM =~ /mswin|mingw/
|
|
155
179
|
|
156
180
|
# Make sure the generated interface library works (if cross-compiling, trust without verifying)
|
157
181
|
unless RbConfig::CONFIG['host_os'] =~ /mswin|mingw/
|
158
|
-
abort "-----\nCannot find libmysql.a\n
|
159
|
-
abort "-----\nCannot link to libmysql.a (my_init)\n
|
182
|
+
abort "-----\nCannot find libmysql.a\n-----" unless have_library('libmysql')
|
183
|
+
abort "-----\nCannot link to libmysql.a (my_init)\n-----" unless have_func('my_init')
|
160
184
|
end
|
161
185
|
|
162
186
|
# Vendor libmysql.dll
|
data/ext/mysql2/result.c
CHANGED
@@ -48,7 +48,7 @@ static rb_encoding *binaryEncoding;
|
|
48
48
|
#define MYSQL2_MIN_TIME 62171150401ULL
|
49
49
|
#endif
|
50
50
|
|
51
|
-
#define GET_RESULT(
|
51
|
+
#define GET_RESULT(self) \
|
52
52
|
mysql2_result_wrapper *wrapper; \
|
53
53
|
Data_Get_Struct(self, mysql2_result_wrapper, wrapper);
|
54
54
|
|
@@ -91,16 +91,18 @@ static void rb_mysql_result_free_result(mysql2_result_wrapper * wrapper) {
|
|
91
91
|
|
92
92
|
if (wrapper->resultFreed != 1) {
|
93
93
|
if (wrapper->stmt_wrapper) {
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
94
|
+
if (!wrapper->stmt_wrapper->closed) {
|
95
|
+
mysql_stmt_free_result(wrapper->stmt_wrapper->stmt);
|
96
|
+
|
97
|
+
/* MySQL BUG? If the statement handle was previously used, and so
|
98
|
+
* mysql_stmt_bind_result was called, and if that result set and bind buffers were freed,
|
99
|
+
* MySQL still thinks the result set buffer is available and will prefetch the
|
100
|
+
* first result in mysql_stmt_execute. This will corrupt or crash the program.
|
101
|
+
* By setting bind_result_done back to 0, we make MySQL think that a result set
|
102
|
+
* has never been bound to this statement handle before to prevent the prefetch.
|
103
|
+
*/
|
104
|
+
wrapper->stmt_wrapper->stmt->bind_result_done = 0;
|
105
|
+
}
|
104
106
|
|
105
107
|
if (wrapper->result_buffers) {
|
106
108
|
unsigned int i;
|
@@ -203,7 +205,7 @@ static VALUE rb_mysql_result_fetch_field(VALUE self, unsigned int idx, int symbo
|
|
203
205
|
|
204
206
|
#ifdef HAVE_RUBY_ENCODING_H
|
205
207
|
static VALUE mysql2_set_field_string_encoding(VALUE val, MYSQL_FIELD field, rb_encoding *default_internal_enc, rb_encoding *conn_enc) {
|
206
|
-
/* if binary flag is set, respect
|
208
|
+
/* if binary flag is set, respect its wishes */
|
207
209
|
if (field.flags & BINARY_FLAG && field.charsetnr == 63) {
|
208
210
|
rb_enc_associate(val, binaryEncoding);
|
209
211
|
} else if (!field.charsetnr) {
|
@@ -309,11 +311,10 @@ static void rb_mysql_result_alloc_result_buffers(VALUE self, MYSQL_FIELD *fields
|
|
309
311
|
case MYSQL_TYPE_SET: // char[]
|
310
312
|
case MYSQL_TYPE_ENUM: // char[]
|
311
313
|
case MYSQL_TYPE_GEOMETRY: // char[]
|
314
|
+
default:
|
312
315
|
wrapper->result_buffers[i].buffer = xmalloc(fields[i].max_length);
|
313
316
|
wrapper->result_buffers[i].buffer_length = fields[i].max_length;
|
314
317
|
break;
|
315
|
-
default:
|
316
|
-
rb_raise(cMysql2Error, "unhandled mysql type: %d", fields[i].type);
|
317
318
|
}
|
318
319
|
|
319
320
|
wrapper->result_buffers[i].is_null = &wrapper->is_null[i];
|
@@ -491,14 +492,12 @@ static VALUE rb_mysql_result_fetch_row_stmt(VALUE self, MYSQL_FIELD * fields, co
|
|
491
492
|
case MYSQL_TYPE_SET: // char[]
|
492
493
|
case MYSQL_TYPE_ENUM: // char[]
|
493
494
|
case MYSQL_TYPE_GEOMETRY: // char[]
|
495
|
+
default:
|
494
496
|
val = rb_str_new(result_buffer->buffer, *(result_buffer->length));
|
495
497
|
#ifdef HAVE_RUBY_ENCODING_H
|
496
498
|
val = mysql2_set_field_string_encoding(val, fields[i], default_internal_enc, conn_enc);
|
497
499
|
#endif
|
498
500
|
break;
|
499
|
-
default:
|
500
|
-
rb_raise(cMysql2Error, "unhandled buffer type: %d",
|
501
|
-
result_buffer->buffer_type);
|
502
501
|
}
|
503
502
|
}
|
504
503
|
|
@@ -858,6 +857,10 @@ static VALUE rb_mysql_result_each(int argc, VALUE * argv, VALUE self) {
|
|
858
857
|
|
859
858
|
GET_RESULT(self);
|
860
859
|
|
860
|
+
if (wrapper->stmt_wrapper && wrapper->stmt_wrapper->closed) {
|
861
|
+
rb_raise(cMysql2Error, "Statement handle already closed");
|
862
|
+
}
|
863
|
+
|
861
864
|
defaults = rb_iv_get(self, "@query_options");
|
862
865
|
Check_Type(defaults, T_HASH);
|
863
866
|
if (rb_scan_args(argc, argv, "01&", &opts, &block) == 1) {
|
data/ext/mysql2/statement.c
CHANGED
@@ -8,18 +8,19 @@ static VALUE intern_usec, intern_sec, intern_min, intern_hour, intern_day, inter
|
|
8
8
|
#define GET_STATEMENT(self) \
|
9
9
|
mysql_stmt_wrapper *stmt_wrapper; \
|
10
10
|
Data_Get_Struct(self, mysql_stmt_wrapper, stmt_wrapper); \
|
11
|
-
if (!stmt_wrapper->stmt) { rb_raise(cMysql2Error, "Invalid statement handle"); }
|
11
|
+
if (!stmt_wrapper->stmt) { rb_raise(cMysql2Error, "Invalid statement handle"); } \
|
12
|
+
if (stmt_wrapper->closed) { rb_raise(cMysql2Error, "Statement handle already closed"); }
|
12
13
|
|
13
14
|
|
14
15
|
static void rb_mysql_stmt_mark(void * ptr) {
|
15
|
-
mysql_stmt_wrapper*
|
16
|
+
mysql_stmt_wrapper *stmt_wrapper = ptr;
|
16
17
|
if (!stmt_wrapper) return;
|
17
18
|
|
18
19
|
rb_gc_mark(stmt_wrapper->client);
|
19
20
|
}
|
20
21
|
|
21
22
|
static void *nogvl_stmt_close(void * ptr) {
|
22
|
-
mysql_stmt_wrapper *stmt_wrapper =
|
23
|
+
mysql_stmt_wrapper *stmt_wrapper = ptr;
|
23
24
|
if (stmt_wrapper->stmt) {
|
24
25
|
mysql_stmt_close(stmt_wrapper->stmt);
|
25
26
|
stmt_wrapper->stmt = NULL;
|
@@ -28,7 +29,7 @@ static void *nogvl_stmt_close(void * ptr) {
|
|
28
29
|
}
|
29
30
|
|
30
31
|
static void rb_mysql_stmt_free(void * ptr) {
|
31
|
-
mysql_stmt_wrapper*
|
32
|
+
mysql_stmt_wrapper *stmt_wrapper = ptr;
|
32
33
|
decr_mysql2_stmt(stmt_wrapper);
|
33
34
|
}
|
34
35
|
|
@@ -93,7 +94,7 @@ static void *nogvl_prepare_statement(void *ptr) {
|
|
93
94
|
}
|
94
95
|
|
95
96
|
VALUE rb_mysql_stmt_new(VALUE rb_client, VALUE sql) {
|
96
|
-
mysql_stmt_wrapper*
|
97
|
+
mysql_stmt_wrapper *stmt_wrapper;
|
97
98
|
VALUE rb_stmt;
|
98
99
|
#ifdef HAVE_RUBY_ENCODING_H
|
99
100
|
rb_encoding *conn_enc;
|
@@ -105,6 +106,7 @@ VALUE rb_mysql_stmt_new(VALUE rb_client, VALUE sql) {
|
|
105
106
|
{
|
106
107
|
stmt_wrapper->client = rb_client;
|
107
108
|
stmt_wrapper->refcount = 1;
|
109
|
+
stmt_wrapper->closed = 0;
|
108
110
|
stmt_wrapper->stmt = NULL;
|
109
111
|
}
|
110
112
|
|
@@ -461,6 +463,7 @@ static VALUE rb_mysql_stmt_affected_rows(VALUE self) {
|
|
461
463
|
*/
|
462
464
|
static VALUE rb_mysql_stmt_close(VALUE self) {
|
463
465
|
GET_STATEMENT(self);
|
466
|
+
stmt_wrapper->closed = 1;
|
464
467
|
rb_thread_call_without_gvl(nogvl_stmt_close, stmt_wrapper, RUBY_UBF_IO, 0);
|
465
468
|
return Qnil;
|
466
469
|
}
|
data/ext/mysql2/statement.h
CHANGED
data/lib/mysql2/1.8/mysql2.so
CHANGED
Binary file
|
data/lib/mysql2/1.9/mysql2.so
CHANGED
Binary file
|
data/lib/mysql2/2.0/mysql2.so
CHANGED
Binary file
|
data/lib/mysql2/2.1/mysql2.so
CHANGED
Binary file
|
data/lib/mysql2/2.2/mysql2.so
CHANGED
Binary file
|
data/lib/mysql2/client.rb
CHANGED
@@ -10,7 +10,7 @@ module Mysql2
|
|
10
10
|
:symbolize_keys => false, # return field names as symbols instead of strings
|
11
11
|
:database_timezone => :local, # timezone Mysql2 will assume datetime objects are stored in
|
12
12
|
:application_timezone => nil, # timezone Mysql2 will convert to before handing the object back to the caller
|
13
|
-
:cache_rows => true, # tells Mysql2 to use
|
13
|
+
:cache_rows => true, # tells Mysql2 to use its internal row cache for results
|
14
14
|
:connect_flags => REMEMBER_OPTIONS | LONG_PASSWORD | LONG_FLAG | TRANSACTIONS | PROTOCOL_41 | SECURE_CONNECTION,
|
15
15
|
:cast => true,
|
16
16
|
:default_file => nil,
|
@@ -48,10 +48,18 @@ module Mysql2
|
|
48
48
|
ssl_options = opts.values_at(:sslkey, :sslcert, :sslca, :sslcapath, :sslcipher)
|
49
49
|
ssl_set(*ssl_options) if ssl_options.any?
|
50
50
|
|
51
|
+
case opts[:flags]
|
52
|
+
when Array
|
53
|
+
flags = parse_flags_array(opts[:flags], @query_options[:connect_flags])
|
54
|
+
when String
|
55
|
+
flags = parse_flags_array(opts[:flags].split(' '), @query_options[:connect_flags])
|
56
|
+
when Integer
|
57
|
+
flags = @query_options[:connect_flags] | opts[:flags]
|
58
|
+
else
|
59
|
+
flags = @query_options[:connect_flags]
|
60
|
+
end
|
61
|
+
|
51
62
|
# SSL verify is a connection flag rather than a mysql_ssl_set option
|
52
|
-
flags = 0
|
53
|
-
flags |= @query_options[:connect_flags]
|
54
|
-
flags |= opts[:flags] if opts[:flags]
|
55
63
|
flags |= SSL_VERIFY_SERVER_CERT if opts[:sslverify] && ssl_options.any?
|
56
64
|
|
57
65
|
if [:user, :pass, :hostname, :dbname, :db, :sock].any? { |k| @query_options.key?(k) }
|
@@ -79,6 +87,20 @@ module Mysql2
|
|
79
87
|
connect user, pass, host, port, database, socket, flags
|
80
88
|
end
|
81
89
|
|
90
|
+
def parse_flags_array(flags, initial = 0)
|
91
|
+
flags.reduce(initial) do |memo, f|
|
92
|
+
fneg = f.start_with?('-') ? f[1..-1] : nil
|
93
|
+
if fneg && fneg =~ /^\w+$/ && Mysql2::Client.const_defined?(fneg)
|
94
|
+
memo & ~ Mysql2::Client.const_get(fneg)
|
95
|
+
elsif f && f =~ /^\w+$/ && Mysql2::Client.const_defined?(f)
|
96
|
+
memo | Mysql2::Client.const_get(f)
|
97
|
+
else
|
98
|
+
warn "Unknown MySQL connection flag: '#{f}'"
|
99
|
+
memo
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
82
104
|
if Thread.respond_to?(:handle_interrupt)
|
83
105
|
def query(sql, options = {})
|
84
106
|
Thread.handle_interrupt(::Mysql2::Util::TimeoutError => :never) do
|
data/lib/mysql2/version.rb
CHANGED
data/spec/mysql2/client_spec.rb
CHANGED
@@ -43,27 +43,33 @@ RSpec.describe Mysql2::Client do
|
|
43
43
|
}.not_to raise_error
|
44
44
|
end
|
45
45
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
@connect_args << args
|
52
|
-
end
|
46
|
+
Klient = Class.new(Mysql2::Client) do
|
47
|
+
attr_reader :connect_args
|
48
|
+
def connect(*args)
|
49
|
+
@connect_args ||= []
|
50
|
+
@connect_args << args
|
53
51
|
end
|
54
|
-
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should accept connect flags and pass them to #connect" do
|
55
|
+
client = Klient.new :flags => Mysql2::Client::FOUND_ROWS
|
55
56
|
expect(client.connect_args.last[6] & Mysql2::Client::FOUND_ROWS).to be > 0
|
56
57
|
end
|
57
58
|
|
59
|
+
it "should parse flags array" do
|
60
|
+
client = Klient.new :flags => %w( FOUND_ROWS -PROTOCOL_41 )
|
61
|
+
expect(client.connect_args.last[6] & Mysql2::Client::FOUND_ROWS).to eql(Mysql2::Client::FOUND_ROWS)
|
62
|
+
expect(client.connect_args.last[6] & Mysql2::Client::PROTOCOL_41).to eql(0)
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should parse flags string" do
|
66
|
+
client = Klient.new :flags => "FOUND_ROWS -PROTOCOL_41"
|
67
|
+
expect(client.connect_args.last[6] & Mysql2::Client::FOUND_ROWS).to eql(Mysql2::Client::FOUND_ROWS)
|
68
|
+
expect(client.connect_args.last[6] & Mysql2::Client::PROTOCOL_41).to eql(0)
|
69
|
+
end
|
70
|
+
|
58
71
|
it "should default flags to (REMEMBER_OPTIONS, LONG_PASSWORD, LONG_FLAG, TRANSACTIONS, PROTOCOL_41, SECURE_CONNECTION)" do
|
59
|
-
|
60
|
-
attr_reader :connect_args
|
61
|
-
def connect(*args)
|
62
|
-
@connect_args ||= []
|
63
|
-
@connect_args << args
|
64
|
-
end
|
65
|
-
end
|
66
|
-
client = klient.new
|
72
|
+
client = Klient.new
|
67
73
|
client_flags = Mysql2::Client::REMEMBER_OPTIONS |
|
68
74
|
Mysql2::Client::LONG_PASSWORD |
|
69
75
|
Mysql2::Client::LONG_FLAG |
|
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.4.
|
4
|
+
version: 0.4.2
|
5
5
|
platform: x86-mingw32
|
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: 2015-
|
12
|
+
date: 2015-11-25 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description:
|
15
15
|
email:
|