mysql2 0.3.10 → 0.3.11
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +14 -0
- data/README.md +9 -0
- data/ext/mysql2/client.c +30 -22
- data/ext/mysql2/result.c +1 -1
- data/lib/mysql2/version.rb +1 -1
- metadata +5 -5
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,12 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## 0.3.11 (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.3.10 (November 9th, 2011)
|
4
11
|
|
5
12
|
## 0.3.9 (November 9th, 2011)
|
@@ -48,6 +55,13 @@
|
|
48
55
|
* BREAKING CHANGE: the ActiveRecord adapter has been pulled into Rails 3.1 and is no longer part of the gem
|
49
56
|
* added Mysql2::Client.escape (class-level) for raw one-off non-encoding-aware escaping
|
50
57
|
|
58
|
+
## 0.2.18 (December 6th, 2011)
|
59
|
+
* change mysql error detection strategy from using mysql_field_count to the more explicit mysql_errno
|
60
|
+
* bugfix to avoid race condition with active connections that error out
|
61
|
+
* revert back to using xmalloc/xfree for allocations
|
62
|
+
* avoid potentially unsafe Ruby C API usage w/o GVL
|
63
|
+
* reacquire GVL before retrying on EINTR on connect
|
64
|
+
|
51
65
|
## 0.2.17 (November 9th, 2011)
|
52
66
|
|
53
67
|
## 0.2.16 (November 9th, 2011)
|
data/README.md
CHANGED
@@ -317,6 +317,15 @@ bundle install
|
|
317
317
|
rake
|
318
318
|
```
|
319
319
|
|
320
|
+
The tests require the "test" database to exist, and expect to connect
|
321
|
+
both as root and the running user, both with a blank password:
|
322
|
+
|
323
|
+
``` sql
|
324
|
+
CREATE DATABASE test;
|
325
|
+
CREATE USER '<user>'@'localhost' IDENTIFIED BY '';
|
326
|
+
GRANT ALL PRIVILEGES ON test.* TO '<user>'@'localhost';
|
327
|
+
```
|
328
|
+
|
320
329
|
## Special Thanks
|
321
330
|
|
322
331
|
* Eric Wong - for the contribution (and the informative explanations) of some thread-safety, non-blocking I/O and cleanup patches. You rock dude
|
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/ext/mysql2/result.c
CHANGED
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: 5
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 3
|
9
|
-
-
|
10
|
-
version: 0.3.
|
9
|
+
- 11
|
10
|
+
version: 0.3.11
|
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
|
@@ -232,7 +232,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
232
232
|
requirements: []
|
233
233
|
|
234
234
|
rubyforge_project:
|
235
|
-
rubygems_version: 1.
|
235
|
+
rubygems_version: 1.3.9.3
|
236
236
|
signing_key:
|
237
237
|
specification_version: 3
|
238
238
|
summary: A simple, fast Mysql library for Ruby, binding to libmysql
|