Skip to content

Commit d759e8b

Browse files
author
Marcin Bunsch
committed
Allow setting the init command on the connection.
When reconnect is enabled, it is handled within libmysqlclient. In such case, if a connection sets any session variables after connecting, they will be lost after the reconnection.
1 parent 53249ab commit d759e8b

File tree

3 files changed

+57
-5
lines changed

3 files changed

+57
-5
lines changed

ext/mysql2/client.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ struct nogvl_connect_args {
6767
const char *user;
6868
const char *passwd;
6969
const char *db;
70+
const char *init_command;
7071
unsigned int port;
7172
const char *unix_socket;
7273
unsigned long client_flag;
@@ -156,6 +157,10 @@ static void *nogvl_connect(void *ptr) {
156157
struct nogvl_connect_args *args = ptr;
157158
MYSQL *client;
158159

160+
if (args->init_command != NULL) {
161+
mysql_options(args->mysql, MYSQL_INIT_COMMAND, args->init_command);
162+
}
163+
159164
client = mysql_real_connect(args->mysql, args->host,
160165
args->user, args->passwd,
161166
args->db, args->port, args->unix_socket,
@@ -322,7 +327,7 @@ static VALUE rb_mysql_info(VALUE self) {
322327
return rb_str;
323328
}
324329

325-
static VALUE rb_connect(VALUE self, VALUE user, VALUE pass, VALUE host, VALUE port, VALUE database, VALUE socket, VALUE flags) {
330+
static VALUE rb_connect(VALUE self, VALUE user, VALUE pass, VALUE host, VALUE port, VALUE database, VALUE socket, VALUE flags, VALUE init_command) {
326331
struct nogvl_connect_args args;
327332
VALUE rv;
328333
GET_CLIENT(self);
@@ -335,6 +340,7 @@ static VALUE rb_connect(VALUE self, VALUE user, VALUE pass, VALUE host, VALUE po
335340
args.db = NIL_P(database) ? NULL : StringValuePtr(database);
336341
args.mysql = wrapper->client;
337342
args.client_flag = NUM2ULONG(flags);
343+
args.init_command = NIL_P(init_command) ? NULL : StringValuePtr(init_command);
338344

339345
rv = (VALUE) rb_thread_call_without_gvl(nogvl_connect, &args, RUBY_UBF_IO, 0);
340346
if (rv == Qfalse) {
@@ -1237,7 +1243,7 @@ void init_mysql2_client() {
12371243
rb_define_private_method(cMysql2Client, "default_group=", set_read_default_group, 1);
12381244
rb_define_private_method(cMysql2Client, "ssl_set", set_ssl_options, 5);
12391245
rb_define_private_method(cMysql2Client, "initialize_ext", initialize_ext, 0);
1240-
rb_define_private_method(cMysql2Client, "connect", rb_connect, 7);
1246+
rb_define_private_method(cMysql2Client, "connect", rb_connect, 8);
12411247

12421248
sym_id = ID2SYM(rb_intern("id"));
12431249
sym_version = ID2SYM(rb_intern("version"));

lib/mysql2/client.rb

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ def initialize(opts = {})
5555
database = opts[:database] || opts[:dbname] || opts[:db]
5656
socket = opts[:socket] || opts[:sock]
5757
flags = opts[:flags] ? opts[:flags] | @query_options[:connect_flags] : @query_options[:connect_flags]
58+
init_command = opts[:init_command]
5859

5960
# Correct the data types before passing these values down to the C level
6061
user = user.to_s unless user.nil?
@@ -63,8 +64,9 @@ def initialize(opts = {})
6364
port = port.to_i unless port.nil?
6465
database = database.to_s unless database.nil?
6566
socket = socket.to_s unless socket.nil?
67+
init_command = init_command.to_s unless init_command.nil?
6668

67-
connect user, pass, host, port, database, socket, flags
69+
connect user, pass, host, port, database, socket, flags, init_command
6870
end
6971

7072
def self.default_query_options

spec/mysql2/client_spec.rb

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ def connect *args
5454
end
5555
end
5656
client = klient.new :flags => Mysql2::Client::FOUND_ROWS
57-
(client.connect_args.last.last & Mysql2::Client::FOUND_ROWS).should be_true
57+
(client.connect_args.last[6] & Mysql2::Client::FOUND_ROWS).should be_true
5858
end
5959

6060
it "should default flags to (REMEMBER_OPTIONS, LONG_PASSWORD, LONG_FLAG, TRANSACTIONS, PROTOCOL_41, SECURE_CONNECTION)" do
@@ -66,14 +66,58 @@ def connect *args
6666
end
6767
end
6868
client = klient.new
69-
(client.connect_args.last.last & (Mysql2::Client::REMEMBER_OPTIONS |
69+
(client.connect_args.last[6] & (Mysql2::Client::REMEMBER_OPTIONS |
7070
Mysql2::Client::LONG_PASSWORD |
7171
Mysql2::Client::LONG_FLAG |
7272
Mysql2::Client::TRANSACTIONS |
7373
Mysql2::Client::PROTOCOL_41 |
7474
Mysql2::Client::SECURE_CONNECTION)).should be_true
7575
end
7676

77+
it "should accept init_command" do
78+
klient = Class.new(Mysql2::Client) do
79+
attr_reader :connect_args
80+
def connect *args
81+
@connect_args ||= []
82+
@connect_args << args
83+
end
84+
end
85+
command = "SET @@session.something = 1"
86+
client = klient.new :init_command => command
87+
client.connect_args.last[7].should eq(command)
88+
end
89+
90+
it "should execute init command" do
91+
options = DatabaseCredentials['root'].dup
92+
options[:init_command] = "SET @something = 'setting_value';"
93+
client = Mysql2::Client.new(options)
94+
result = client.query("SELECT @something;")
95+
result.first['@something'].should eq('setting_value')
96+
end
97+
98+
it "should send init_command after reconnect" do
99+
pending "Ruby 2.1 has changed Timeout behavior." if RUBY_VERSION =~ /2.1/
100+
options = DatabaseCredentials['root'].dup
101+
options[:init_command] = "SET @something = 'setting_value';"
102+
options[:reconnect] = true
103+
client = Mysql2::Client.new(options)
104+
105+
result = client.query("SELECT @something;")
106+
result.first['@something'].should eq('setting_value')
107+
108+
# simulate a broken connection
109+
begin
110+
Timeout.timeout(1) do
111+
client.query("SELECT sleep(2)")
112+
end
113+
rescue Timeout::Error
114+
end
115+
client.ping.should be_false
116+
117+
result = client.query("SELECT @something;")
118+
result.first['@something'].should eq('setting_value')
119+
end
120+
77121
it "should have a global default_query_options hash" do
78122
Mysql2::Client.should respond_to(:default_query_options)
79123
end

0 commit comments

Comments
 (0)