Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Save affected_rows on the wrapper when reading results #1383

Merged
merged 1 commit into from
Dec 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions ext/mysql2/client.c
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,7 @@ static VALUE allocate(VALUE klass) {
wrapper->initialized = 0; /* will be set true after calling mysql_init */
wrapper->closed = 1; /* will be set false after calling mysql_real_connect */
wrapper->refcount = 1;
wrapper->affected_rows = -1;
wrapper->client = (MYSQL*)xmalloc(sizeof(MYSQL));

return obj;
Expand Down Expand Up @@ -669,6 +670,7 @@ static VALUE rb_mysql_client_async_result(VALUE self) {
wrapper->active_fiber = Qnil;
rb_raise_mysql2_error(wrapper);
}
wrapper->affected_rows = mysql_affected_rows(wrapper->client);

is_streaming = rb_hash_aref(rb_ivar_get(self, intern_current_query_options), sym_stream);
if (is_streaming == Qtrue) {
Expand Down Expand Up @@ -1155,12 +1157,12 @@ static VALUE rb_mysql_client_session_track(VALUE self, VALUE type) {
* if it was an UPDATE, DELETE, or INSERT.
*/
static VALUE rb_mysql_client_affected_rows(VALUE self) {
my_ulonglong retVal;
uint64_t retVal;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I see the type changed between MySQL 5.7 and 8.0:
https://dev.mysql.com/doc/c-api/8.0/en/mysql-affected-rows.html

uint64_t
mysql_affected_rows(MYSQL *mysql)

https://dev.mysql.com/doc/c-api/5.7/en/mysql-affected-rows.html

my_ulonglong
mysql_affected_rows(MYSQL *mysql)

GET_CLIENT(self);

REQUIRE_CONNECTED(wrapper);
retVal = mysql_affected_rows(wrapper->client);
if (retVal == (my_ulonglong)-1) {
retVal = wrapper->affected_rows;
if (retVal == (uint64_t)-1) {
rb_raise_mysql2_error(wrapper);
}
return ULL2NUM(retVal);
Expand Down
1 change: 1 addition & 0 deletions ext/mysql2/client.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ typedef struct {
int initialized;
int refcount;
int closed;
uint64_t affected_rows;
MYSQL *client;
} mysql_client_wrapper;

Expand Down
38 changes: 30 additions & 8 deletions spec/mysql2/client_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1033,7 +1033,7 @@ def run_gc
expect(@client).to respond_to(:last_id)
end

it "#last_id should return a Fixnum, the from the last INSERT/UPDATE" do
it "#last_id should return a Fixnum, from the last INSERT/UPDATE" do
expect(@client.last_id).to eql(0)
@client.query "INSERT INTO lastIdTest (blah) VALUES (1234)"
expect(@client.last_id).to eql(1)
Expand All @@ -1043,13 +1043,6 @@ def run_gc
expect(@client).to respond_to(:last_id)
end

it "#last_id should return a Fixnum, the from the last INSERT/UPDATE" do
@client.query "INSERT INTO lastIdTest (blah) VALUES (1234)"
expect(@client.affected_rows).to eql(1)
@client.query "UPDATE lastIdTest SET blah=4321 WHERE id=1"
expect(@client.affected_rows).to eql(1)
end

it "#last_id should handle BIGINT auto-increment ids above 32 bits" do
# The id column type must be BIGINT. Surprise: INT(x) is limited to 32-bits for all values of x.
# Insert a row with a given ID, this should raise the auto-increment state
Expand All @@ -1058,6 +1051,35 @@ def run_gc
@client.query "INSERT INTO lastIdTest (blah) VALUES (5001)"
expect(@client.last_id).to eql(5000000001)
end

it "#last_id isn't cleared by Statement#close" do
stmt = @client.prepare("INSERT INTO lastIdTest (blah) VALUES (1234)")

@client.query "INSERT INTO lastIdTest (blah) VALUES (1234)"
expect(@client.last_id).to eql(1)

stmt.close

expect(@client.last_id).to eql(1)
end

it "#affected_rows should return a Fixnum, from the last INSERT/UPDATE" do
@client.query "INSERT INTO lastIdTest (blah) VALUES (1234)"
expect(@client.affected_rows).to eql(1)
@client.query "UPDATE lastIdTest SET blah=4321 WHERE id=1"
expect(@client.affected_rows).to eql(1)
end

it "#affected_rows isn't cleared by Statement#close" do
stmt = @client.prepare("INSERT INTO lastIdTest (blah) VALUES (1234)")

@client.query "INSERT INTO lastIdTest (blah) VALUES (1234)"
expect(@client.affected_rows).to eql(1)

stmt.close

expect(@client.affected_rows).to eql(1)
end
end

it "should respond to #thread_id" do
Expand Down
Loading