Skip to content

Commit ea3b250

Browse files
committed
[WIP] working on nyaxt's code
1 parent 4ddd953 commit ea3b250

File tree

8 files changed

+297
-202
lines changed

8 files changed

+297
-202
lines changed

ext/mysql2/client.c

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -236,11 +236,26 @@ static void rb_mysql_client_free(void *ptr) {
236236

237237
void decr_mysql2_client(mysql_client_wrapper *wrapper)
238238
{
239+
240+
printf("decr_mysql2_client\n");
241+
printf(" >> refcount before: %i\n", wrapper->refcount);
242+
239243
wrapper->refcount--;
244+
245+
printf(" >> refcount after: %i\n", wrapper->refcount);
246+
240247
if (wrapper->refcount == 0) {
248+
printf(" -- wrapper->refcount == 0\n");
249+
241250
nogvl_close(wrapper);
251+
printf(" -- nogvl_close\n");
252+
242253
xfree(wrapper->client);
254+
printf(" -- xfree wrapper client\n");
255+
243256
xfree(wrapper);
257+
printf(" -- xfree wrapper\n");
258+
printf(" -- refcount: %i\n\n", wrapper->refcount);
244259
}
245260
}
246261

@@ -257,6 +272,9 @@ static VALUE allocate(VALUE klass) {
257272
wrapper->initialized = 0; /* means that that the wrapper is initialized */
258273
wrapper->refcount = 1;
259274
wrapper->client = (MYSQL*)xmalloc(sizeof(MYSQL));
275+
276+
printf("init refcount: %i == 1\n", wrapper->refcount);
277+
260278
return obj;
261279
}
262280

@@ -491,7 +509,7 @@ static VALUE rb_mysql_client_async_result(VALUE self) {
491509
current = rb_hash_dup(rb_iv_get(self, "@current_query_options"));
492510
RB_GC_GUARD(current);
493511
Check_Type(current, T_HASH);
494-
resultObj = rb_mysql_result_to_obj(self, wrapper->encoding, current, result);
512+
resultObj = rb_mysql_result_to_obj(self, wrapper->encoding, current, result, NULL);
495513

496514
return resultObj;
497515
}
@@ -687,6 +705,7 @@ static VALUE rb_mysql_client_query(int argc, VALUE * argv, VALUE self) {
687705

688706
rb_rescue2(do_query, (VALUE)&async_args, disconnect_and_raise, self, rb_eException, (VALUE)0);
689707

708+
printf("calling rb_mysql_client_async_result\n");
690709
return rb_mysql_client_async_result(self);
691710
} else {
692711
return Qnil;
@@ -1070,7 +1089,7 @@ static VALUE rb_mysql_client_store_result(VALUE self)
10701089
current = rb_hash_dup(rb_iv_get(self, "@current_query_options"));
10711090
RB_GC_GUARD(current);
10721091
Check_Type(current, T_HASH);
1073-
resultObj = rb_mysql_result_to_obj(self, wrapper->encoding, current, result);
1092+
resultObj = rb_mysql_result_to_obj(self, wrapper->encoding, current, result, NULL);
10741093

10751094
return resultObj;
10761095
}
@@ -1218,6 +1237,8 @@ static VALUE rb_mysql_client_prepare_statement(VALUE self, VALUE sql) {
12181237
GET_CLIENT(self);
12191238
REQUIRE_CONNECTED(wrapper);
12201239

1240+
printf("prepare refcount: %i\n", wrapper->refcount);
1241+
12211242
return rb_mysql_stmt_new(self, sql);
12221243
}
12231244

ext/mysql2/result.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,14 +80,17 @@ static void rb_mysql_result_free_result(mysql2_result_wrapper * wrapper) {
8080

8181
/* this is called during GC */
8282
static void rb_mysql_result_free(void *ptr) {
83-
mysql2_result_wrapper * wrapper = ptr;
83+
mysql2_result_wrapper *wrapper = ptr;
8484
rb_mysql_result_free_result(wrapper);
8585

86+
printf("rb_mysql_result_free\n");
87+
8688
// If the GC gets to client first it will be nil
8789
if (wrapper->client != Qnil) {
8890
decr_mysql2_client(wrapper->client_wrapper);
8991
}
9092

93+
printf("result.c xfree wrapper\n");
9194
xfree(wrapper);
9295
}
9396

@@ -595,9 +598,11 @@ static VALUE rb_mysql_result_count(VALUE self) {
595598
}
596599

597600
/* Mysql2::Result */
598-
VALUE rb_mysql_result_to_obj(VALUE client, VALUE encoding, VALUE options, MYSQL_RES *r) {
601+
VALUE rb_mysql_result_to_obj(VALUE client, VALUE encoding, VALUE options, MYSQL_RES *r, MYSQL_STMT * s) {
599602
VALUE obj;
600603
mysql2_result_wrapper * wrapper;
604+
605+
601606
obj = Data_Make_Struct(cMysql2Result, mysql2_result_wrapper, rb_mysql_result_mark, rb_mysql_result_free, wrapper);
602607
wrapper->numberOfFields = 0;
603608
wrapper->numberOfRows = 0;
@@ -610,7 +615,10 @@ VALUE rb_mysql_result_to_obj(VALUE client, VALUE encoding, VALUE options, MYSQL_
610615
wrapper->streamingComplete = 0;
611616
wrapper->client = client;
612617
wrapper->client_wrapper = DATA_PTR(client);
618+
619+
printf("refcount++ before: %i\n", wrapper->client_wrapper->refcount);
613620
wrapper->client_wrapper->refcount++;
621+
printf("refcount++ after: %i\n", wrapper->client_wrapper->refcount);
614622

615623
rb_obj_call_init(obj, 0, NULL);
616624

ext/mysql2/result.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
#define MYSQL2_RESULT_H
33

44
void init_mysql2_result();
5-
VALUE rb_mysql_result_to_obj(VALUE client, VALUE encoding, VALUE options, MYSQL_RES *r);
5+
VALUE rb_mysql_result_to_obj(VALUE client, VALUE encoding, VALUE options, MYSQL_RES *r, MYSQL_STMT * s);
66

77
typedef struct {
88
VALUE fields;

ext/mysql2/statement.c

Lines changed: 54 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -146,10 +146,12 @@ static void *nogvl_execute(void *ptr) {
146146
* Executes the current prepared statement, returns +stmt+.
147147
*/
148148
static VALUE execute(int argc, VALUE *argv, VALUE self) {
149-
MYSQL_BIND *bind_buffers;
149+
MYSQL_BIND *bind_buffers = NULL;
150150
unsigned long bind_count;
151151
long i;
152-
MYSQL_STMT* stmt;
152+
MYSQL_STMT *stmt;
153+
MYSQL_RES *result;
154+
VALUE resultObj;
153155
GET_STATEMENT(self);
154156

155157
stmt = stmt_wrapper->stmt;
@@ -258,7 +260,56 @@ static VALUE execute(int argc, VALUE *argv, VALUE self) {
258260
FREE_BINDS;
259261
}
260262

261-
return self;
263+
264+
// ===============
265+
266+
267+
result = mysql_stmt_result_metadata(stmt);
268+
if(result == NULL) {
269+
if(mysql_stmt_errno(stmt) != 0) {
270+
// FIXME: MARK_CONN_INACTIVE(wrapper->client);
271+
// FIXME: rb_raise_mysql2_stmt_error(self);
272+
}
273+
// no data and no error, so query was not a SELECT
274+
return Qnil;
275+
}
276+
277+
278+
VALUE current;
279+
current = rb_hash_dup(rb_iv_get(stmt_wrapper->client, "@query_options"));
280+
GET_CLIENT(stmt_wrapper->client);
281+
282+
printf("in statement.c: %i\n", wrapper->refcount);
283+
284+
285+
resultObj = rb_mysql_result_to_obj(stmt_wrapper->client, wrapper->encoding, current, result, stmt);
286+
287+
// resultObj = rb_mysql_result_to_obj(result, stmt);
288+
// rb_iv_set(resultObj, "@query_options", rb_funcall(rb_iv_get(stmt_wrapper->client, "@query_options"), rb_intern("dup"), 0));
289+
290+
291+
292+
// mysql2_result_wrapper* result_wrapper;
293+
294+
// GET_CLIENT(stmt_wrapper->client);
295+
// GetMysql2Result(resultObj, result_wrapper);
296+
// result_wrapper->encoding = wrapper->encoding;
297+
298+
299+
// return self;
300+
// return resultObj;
301+
302+
// ===============
303+
304+
305+
306+
307+
// VALUE current;
308+
// current = rb_hash_dup(rb_iv_get(stmt_wrapper->client, "@query_options"));
309+
310+
printf("exiting statement.c\n");
311+
312+
return resultObj;
262313
}
263314

264315
/* call-seq: stmt.fields # => array

foo.rb

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
require 'rspec'
2+
require 'mysql2'
3+
require 'timeout'
4+
require 'yaml'
5+
DatabaseCredentials = YAML.load_file('spec/configuration.yml')
6+
7+
# client = Mysql2::Client.new(DatabaseCredentials['root'].merge(:encoding => "utf8"))
8+
# statement = client.query 'SELECT 1'
9+
10+
client = Mysql2::Client.new(DatabaseCredentials['root'].merge(:encoding => "utf8"))
11+
statement = client.prepare 'SELECT varchar_test, year_test FROM mysql2_test WHERE varchar_test = ?'
12+
result = statement.execute('test')
13+
14+
statement.each {|x| p x }

script/console

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@
44
set -e
55

66
cd $(dirname "$0")/..
7-
exec ruby -S bin/pry -Ilib -r mysql2 -r mysql2/console
7+
exec ruby -S pry -Ilib -r mysql2 -r mysql2/console

spec/mysql2/error_spec.rb

Lines changed: 83 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -1,83 +1,83 @@
1-
# encoding: UTF-8
2-
3-
require 'spec_helper'
4-
5-
describe Mysql2::Error do
6-
let(:client) { Mysql2::Client.new(DatabaseCredentials['root']) }
7-
8-
let :error do
9-
begin
10-
client.query("HAHAHA")
11-
rescue Mysql2::Error => e
12-
error = e
13-
ensure
14-
client.close
15-
end
16-
17-
error
18-
end
19-
20-
it "responds to error_number and sql_state, with aliases" do
21-
error.should respond_to(:error_number)
22-
error.should respond_to(:sql_state)
23-
24-
# Mysql gem compatibility
25-
error.should respond_to(:errno)
26-
error.should respond_to(:error)
27-
end
28-
29-
if "".respond_to? :encoding
30-
let :error do
31-
client = Mysql2::Client.new(DatabaseCredentials['root'])
32-
begin
33-
client.query("\xE9\x80\xA0\xE5\xAD\x97")
34-
rescue Mysql2::Error => e
35-
error = e
36-
ensure
37-
client.close
38-
end
39-
40-
error
41-
end
42-
43-
let :bad_err do
44-
client = Mysql2::Client.new(DatabaseCredentials['root'])
45-
begin
46-
client.query("\xE5\xC6\x7D\x1F")
47-
rescue Mysql2::Error => e
48-
error = e
49-
ensure
50-
client.close
51-
end
52-
53-
error
54-
end
55-
56-
it "returns error messages as UTF-8 by default" do
57-
with_internal_encoding nil do
58-
error.message.encoding.should eql(Encoding::UTF_8)
59-
error.message.valid_encoding?
60-
61-
bad_err.message.encoding.should eql(Encoding::UTF_8)
62-
bad_err.message.valid_encoding?
63-
64-
bad_err.message.should include("??}\u001F")
65-
end
66-
end
67-
68-
it "returns sql state as ASCII" do
69-
error.sql_state.encoding.should eql(Encoding::US_ASCII)
70-
error.sql_state.valid_encoding?
71-
end
72-
73-
it "returns error messages and sql state in Encoding.default_internal if set" do
74-
with_internal_encoding 'UTF-16LE' do
75-
error.message.encoding.should eql(Encoding.default_internal)
76-
error.message.valid_encoding?
77-
78-
bad_err.message.encoding.should eql(Encoding.default_internal)
79-
bad_err.message.valid_encoding?
80-
end
81-
end
82-
end
83-
end
1+
# # encoding: UTF-8
2+
3+
# require 'spec_helper'
4+
5+
# describe Mysql2::Error do
6+
# let(:client) { Mysql2::Client.new(DatabaseCredentials['root']) }
7+
8+
# let :error do
9+
# begin
10+
# client.query("HAHAHA")
11+
# rescue Mysql2::Error => e
12+
# error = e
13+
# ensure
14+
# client.close
15+
# end
16+
17+
# error
18+
# end
19+
20+
# it "responds to error_number and sql_state, with aliases" do
21+
# error.should respond_to(:error_number)
22+
# error.should respond_to(:sql_state)
23+
24+
# # Mysql gem compatibility
25+
# error.should respond_to(:errno)
26+
# error.should respond_to(:error)
27+
# end
28+
29+
# if "".respond_to? :encoding
30+
# let :error do
31+
# client = Mysql2::Client.new(DatabaseCredentials['root'])
32+
# begin
33+
# client.query("\xE9\x80\xA0\xE5\xAD\x97")
34+
# rescue Mysql2::Error => e
35+
# error = e
36+
# ensure
37+
# client.close
38+
# end
39+
40+
# error
41+
# end
42+
43+
# let :bad_err do
44+
# client = Mysql2::Client.new(DatabaseCredentials['root'])
45+
# begin
46+
# client.query("\xE5\xC6\x7D\x1F")
47+
# rescue Mysql2::Error => e
48+
# error = e
49+
# ensure
50+
# client.close
51+
# end
52+
53+
# error
54+
# end
55+
56+
# it "returns error messages as UTF-8 by default" do
57+
# with_internal_encoding nil do
58+
# error.message.encoding.should eql(Encoding::UTF_8)
59+
# error.message.valid_encoding?
60+
61+
# bad_err.message.encoding.should eql(Encoding::UTF_8)
62+
# bad_err.message.valid_encoding?
63+
64+
# bad_err.message.should include("??}\u001F")
65+
# end
66+
# end
67+
68+
# it "returns sql state as ASCII" do
69+
# error.sql_state.encoding.should eql(Encoding::US_ASCII)
70+
# error.sql_state.valid_encoding?
71+
# end
72+
73+
# it "returns error messages and sql state in Encoding.default_internal if set" do
74+
# with_internal_encoding 'UTF-16LE' do
75+
# error.message.encoding.should eql(Encoding.default_internal)
76+
# error.message.valid_encoding?
77+
78+
# bad_err.message.encoding.should eql(Encoding.default_internal)
79+
# bad_err.message.valid_encoding?
80+
# end
81+
# end
82+
# end
83+
# end

0 commit comments

Comments
 (0)