Skip to content

Commit

Permalink
Expose the mysql_set_server_option: (#943)
Browse files Browse the repository at this point in the history
- Use case: I'd like to be able to do multiple statements query without having to reconnect to the db first. Without this feature, if I want to do a multi statement query **after** the connection is established without the `MULTI_STATEMENTS` flag, I'd have to set the flag on the connection and reconnect
- One of the main motivation for this is because Rails is now inserting fixtures inside a multi-statements query. We used the workaround I described above, but it would be great if we could use the mysql function mysql_set_server_option . For more context [Ref](rails/rails#31422 (comment))
- Ref https://dev.mysql.com/doc/refman/5.5/en/mysql-set-server-option.html
  • Loading branch information
Edouard-chin authored and sodabrew committed Mar 1, 2018
1 parent 503429c commit 9d971db
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 0 deletions.
25 changes: 25 additions & 0 deletions ext/mysql2/client.c
Original file line number Diff line number Diff line change
Expand Up @@ -1098,6 +1098,23 @@ static VALUE rb_mysql_client_ping(VALUE self) {
}
}

/* call-seq:
* client.set_server_option(value)
*
* Enables or disables an option for the connection.
* Read https://dev.mysql.com/doc/refman/5.7/en/mysql-set-server-option.html
* for more information.
*/
static VALUE rb_mysql_client_set_server_option(VALUE self, VALUE value) {
GET_CLIENT(self);

if (mysql_set_server_option(wrapper->client, NUM2INT(value)) == 0) {
return Qtrue;
} else {
return Qfalse;
}
}

/* call-seq:
* client.more_results?
*
Expand Down Expand Up @@ -1399,6 +1416,7 @@ void init_mysql2_client() {
rb_define_method(cMysql2Client, "thread_id", rb_mysql_client_thread_id, 0);
rb_define_method(cMysql2Client, "ping", rb_mysql_client_ping, 0);
rb_define_method(cMysql2Client, "select_db", rb_mysql_client_select_db, 1);
rb_define_method(cMysql2Client, "set_server_option", rb_mysql_client_set_server_option, 1);
rb_define_method(cMysql2Client, "more_results?", rb_mysql_client_more_results, 0);
rb_define_method(cMysql2Client, "next_result", rb_mysql_client_next_result, 0);
rb_define_method(cMysql2Client, "store_result", rb_mysql_client_store_result, 0);
Expand Down Expand Up @@ -1528,6 +1546,13 @@ void init_mysql2_client() {
rb_const_set(cMysql2Client, rb_intern("SECURE_CONNECTION"), LONG2NUM(0));
#endif

#if MYSQL_VERSION_ID >= 40101
rb_const_set(cMysql2Client, rb_intern("OPTION_MULTI_STATEMENTS_ON"),
LONG2NUM(MYSQL_OPTION_MULTI_STATEMENTS_ON));
rb_const_set(cMysql2Client, rb_intern("OPTION_MULTI_STATEMENTS_OFF"),
LONG2NUM(MYSQL_OPTION_MULTI_STATEMENTS_OFF));
#endif

#ifdef CLIENT_MULTI_STATEMENTS
rb_const_set(cMysql2Client, rb_intern("MULTI_STATEMENTS"),
LONG2NUM(CLIENT_MULTI_STATEMENTS));
Expand Down
34 changes: 34 additions & 0 deletions spec/mysql2/client_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,40 @@ def run_gc
# rubocop:enable Lint/AmbiguousBlockAssociation
end

context "#set_server_option" do
let(:client) do
new_client.tap do |client|
client.set_server_option(Mysql2::Client::OPTION_MULTI_STATEMENTS_ON)
end
end

it 'returns true when multi_statements is enable' do
expect(client.set_server_option(Mysql2::Client::OPTION_MULTI_STATEMENTS_ON)).to be true
end

it 'returns true when multi_statements is disable' do
expect(client.set_server_option(Mysql2::Client::OPTION_MULTI_STATEMENTS_OFF)).to be true
end

it 'returns false when multi_statements is neither OPTION_MULTI_STATEMENTS_OFF or OPTION_MULTI_STATEMENTS_ON' do
expect(client.set_server_option(344)).to be false
end

it 'enables multiple-statement' do
client.query("SELECT 1;SELECT 2;")

expect(client.next_result).to be true
expect(client.store_result.first).to eql('2' => 2)
expect(client.next_result).to be false
end

it 'disables multiple-statement' do
client.set_server_option(Mysql2::Client::OPTION_MULTI_STATEMENTS_OFF)

expect { client.query("SELECT 1;SELECT 2;") }.to raise_error(Mysql2::Error)
end
end

context "#automatic_close" do
it "is enabled by default" do
expect(new_client.automatic_close?).to be(true)
Expand Down

0 comments on commit 9d971db

Please sign in to comment.