mysql2 0.2.17 → 0.2.18
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.
- data/.travis.yml +7 -0
- data/CHANGELOG.md +7 -0
- data/ext/mysql2/client.c +30 -22
- data/lib/mysql2/version.rb +1 -1
- metadata +6 -5
data/.travis.yml
ADDED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,12 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## 0.2.18 (December 6th, 2011)
|
4
|
+
* change mysql error detection strategy from using mysql_field_count to the more explicit mysql_errno
|
5
|
+
* bugfix to avoid race condition with active connections that error out
|
6
|
+
* revert back to using xmalloc/xfree for allocations
|
7
|
+
* avoid potentially unsafe Ruby C API usage w/o GVL
|
8
|
+
* reacquire GVL before retrying on EINTR on connect
|
9
|
+
|
3
10
|
## 0.2.17 (November 9th, 2011)
|
4
11
|
|
5
12
|
## 0.2.16 (November 9th, 2011)
|
data/ext/mysql2/client.c
CHANGED
@@ -46,6 +46,8 @@ struct nogvl_connect_args {
|
|
46
46
|
struct nogvl_send_query_args {
|
47
47
|
MYSQL *mysql;
|
48
48
|
VALUE sql;
|
49
|
+
const char *sql_ptr;
|
50
|
+
long sql_len;
|
49
51
|
mysql_client_wrapper *wrapper;
|
50
52
|
};
|
51
53
|
|
@@ -112,12 +114,10 @@ static VALUE nogvl_connect(void *ptr) {
|
|
112
114
|
struct nogvl_connect_args *args = ptr;
|
113
115
|
MYSQL *client;
|
114
116
|
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
args->client_flag);
|
120
|
-
} while (! client && errno == EINTR && (errno = 0) == 0);
|
117
|
+
client = mysql_real_connect(args->mysql, args->host,
|
118
|
+
args->user, args->passwd,
|
119
|
+
args->db, args->port, args->unix_socket,
|
120
|
+
args->client_flag);
|
121
121
|
|
122
122
|
return client ? Qtrue : Qfalse;
|
123
123
|
}
|
@@ -147,7 +147,7 @@ static VALUE nogvl_close(void *ptr) {
|
|
147
147
|
#endif
|
148
148
|
|
149
149
|
mysql_close(wrapper->client);
|
150
|
-
|
150
|
+
xfree(wrapper->client);
|
151
151
|
}
|
152
152
|
|
153
153
|
return Qnil;
|
@@ -158,7 +158,7 @@ static void rb_mysql_client_free(void * ptr) {
|
|
158
158
|
|
159
159
|
nogvl_close(wrapper);
|
160
160
|
|
161
|
-
|
161
|
+
xfree(ptr);
|
162
162
|
}
|
163
163
|
|
164
164
|
static VALUE allocate(VALUE klass) {
|
@@ -169,7 +169,7 @@ static VALUE allocate(VALUE klass) {
|
|
169
169
|
wrapper->active = 0;
|
170
170
|
wrapper->reconnect_enabled = 0;
|
171
171
|
wrapper->closed = 1;
|
172
|
-
wrapper->client = (MYSQL*)
|
172
|
+
wrapper->client = (MYSQL*)xmalloc(sizeof(MYSQL));
|
173
173
|
return obj;
|
174
174
|
}
|
175
175
|
|
@@ -181,25 +181,26 @@ static VALUE rb_mysql_client_escape(RB_MYSQL_UNUSED VALUE klass, VALUE str) {
|
|
181
181
|
Check_Type(str, T_STRING);
|
182
182
|
|
183
183
|
oldLen = RSTRING_LEN(str);
|
184
|
-
newStr =
|
184
|
+
newStr = xmalloc(oldLen*2+1);
|
185
185
|
|
186
186
|
newLen = mysql_escape_string((char *)newStr, StringValuePtr(str), oldLen);
|
187
187
|
if (newLen == oldLen) {
|
188
188
|
// no need to return a new ruby string if nothing changed
|
189
|
-
|
189
|
+
xfree(newStr);
|
190
190
|
return str;
|
191
191
|
} else {
|
192
192
|
rb_str = rb_str_new((const char*)newStr, newLen);
|
193
193
|
#ifdef HAVE_RUBY_ENCODING_H
|
194
194
|
rb_enc_copy(rb_str, str);
|
195
195
|
#endif
|
196
|
-
|
196
|
+
xfree(newStr);
|
197
197
|
return rb_str;
|
198
198
|
}
|
199
199
|
}
|
200
200
|
|
201
201
|
static VALUE rb_connect(VALUE self, VALUE user, VALUE pass, VALUE host, VALUE port, VALUE database, VALUE socket, VALUE flags) {
|
202
202
|
struct nogvl_connect_args args;
|
203
|
+
VALUE rv;
|
203
204
|
GET_CLIENT(self);
|
204
205
|
|
205
206
|
args.host = NIL_P(host) ? "localhost" : StringValuePtr(host);
|
@@ -211,9 +212,14 @@ static VALUE rb_connect(VALUE self, VALUE user, VALUE pass, VALUE host, VALUE po
|
|
211
212
|
args.mysql = wrapper->client;
|
212
213
|
args.client_flag = NUM2ULONG(flags);
|
213
214
|
|
214
|
-
|
215
|
-
|
216
|
-
|
215
|
+
rv = rb_thread_blocking_region(nogvl_connect, &args, RUBY_UBF_IO, 0);
|
216
|
+
if (rv == Qfalse) {
|
217
|
+
while (rv == Qfalse && errno == EINTR) {
|
218
|
+
errno = 0;
|
219
|
+
rv = rb_thread_blocking_region(nogvl_connect, &args, RUBY_UBF_IO, 0);
|
220
|
+
}
|
221
|
+
if (rv == Qfalse)
|
222
|
+
return rb_raise_mysql2_error(wrapper);
|
217
223
|
}
|
218
224
|
|
219
225
|
return self;
|
@@ -243,10 +249,8 @@ static VALUE rb_mysql_client_close(VALUE self) {
|
|
243
249
|
static VALUE nogvl_send_query(void *ptr) {
|
244
250
|
struct nogvl_send_query_args *args = ptr;
|
245
251
|
int rv;
|
246
|
-
const char *sql = StringValuePtr(args->sql);
|
247
|
-
long sql_len = RSTRING_LEN(args->sql);
|
248
252
|
|
249
|
-
rv = mysql_send_query(args->mysql,
|
253
|
+
rv = mysql_send_query(args->mysql, args->sql_ptr, args->sql_len);
|
250
254
|
|
251
255
|
return rv == 0 ? Qtrue : Qfalse;
|
252
256
|
}
|
@@ -311,9 +315,11 @@ static VALUE rb_mysql_client_async_result(VALUE self) {
|
|
311
315
|
result = (MYSQL_RES *)rb_thread_blocking_region(nogvl_store_result, wrapper, RUBY_UBF_IO, 0);
|
312
316
|
|
313
317
|
if (result == NULL) {
|
314
|
-
if (
|
318
|
+
if (mysql_errno(wrapper->client) != 0) {
|
319
|
+
MARK_CONN_INACTIVE(self);
|
315
320
|
rb_raise_mysql2_error(wrapper);
|
316
321
|
}
|
322
|
+
// no data and no error, so query was not a SELECT
|
317
323
|
return Qnil;
|
318
324
|
}
|
319
325
|
|
@@ -450,6 +456,8 @@ static VALUE rb_mysql_client_query(int argc, VALUE * argv, VALUE self) {
|
|
450
456
|
// ensure the string is in the encoding the connection is expecting
|
451
457
|
args.sql = rb_str_export_to_enc(args.sql, conn_enc);
|
452
458
|
#endif
|
459
|
+
args.sql_ptr = StringValuePtr(args.sql);
|
460
|
+
args.sql_len = RSTRING_LEN(args.sql);
|
453
461
|
|
454
462
|
// see if this connection is still waiting on a result from a previous query
|
455
463
|
if (wrapper->active == 0) {
|
@@ -502,12 +510,12 @@ static VALUE rb_mysql_client_real_escape(VALUE self, VALUE str) {
|
|
502
510
|
#endif
|
503
511
|
|
504
512
|
oldLen = RSTRING_LEN(str);
|
505
|
-
newStr =
|
513
|
+
newStr = xmalloc(oldLen*2+1);
|
506
514
|
|
507
515
|
newLen = mysql_real_escape_string(wrapper->client, (char *)newStr, StringValuePtr(str), oldLen);
|
508
516
|
if (newLen == oldLen) {
|
509
517
|
// no need to return a new ruby string if nothing changed
|
510
|
-
|
518
|
+
xfree(newStr);
|
511
519
|
return str;
|
512
520
|
} else {
|
513
521
|
rb_str = rb_str_new((const char*)newStr, newLen);
|
@@ -517,7 +525,7 @@ static VALUE rb_mysql_client_real_escape(VALUE self, VALUE str) {
|
|
517
525
|
rb_str = rb_str_export_to_enc(rb_str, default_internal_enc);
|
518
526
|
}
|
519
527
|
#endif
|
520
|
-
|
528
|
+
xfree(newStr);
|
521
529
|
return rb_str;
|
522
530
|
}
|
523
531
|
}
|
data/lib/mysql2/version.rb
CHANGED
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mysql2
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 51
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 2
|
9
|
-
-
|
10
|
-
version: 0.2.
|
9
|
+
- 18
|
10
|
+
version: 0.2.18
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Brian Lopez
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-
|
18
|
+
date: 2011-12-06 00:00:00 -08:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -160,6 +160,7 @@ files:
|
|
160
160
|
- .gitignore
|
161
161
|
- .rspec
|
162
162
|
- .rvmrc
|
163
|
+
- .travis.yml
|
163
164
|
- CHANGELOG.md
|
164
165
|
- Gemfile
|
165
166
|
- MIT-LICENSE
|
@@ -237,7 +238,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
237
238
|
requirements: []
|
238
239
|
|
239
240
|
rubyforge_project:
|
240
|
-
rubygems_version: 1.
|
241
|
+
rubygems_version: 1.3.9.3
|
241
242
|
signing_key:
|
242
243
|
specification_version: 3
|
243
244
|
summary: A simple, fast Mysql library for Ruby, binding to libmysql
|