mysql2 0.4.1-x86-mingw32 → 0.4.2-x86-mingw32
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/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:
|