Skip to content

Commit 0aef65e

Browse files
committed
Merge pull request brianmario#501 from marcinbunsch/init-command
Allow setting the init command on the connection.
2 parents 53249ab + 95bf8a2 commit 0aef65e

File tree

4 files changed

+69
-6
lines changed

4 files changed

+69
-6
lines changed

README.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,10 +156,12 @@ Mysql2::Client.new(
156156
:local_infile = true/false,
157157
:secure_auth = true/false,
158158
:default_file = '/path/to/my.cfg',
159-
:default_group = 'my.cfg section'
159+
:default_group = 'my.cfg section',
160+
:init_command => sql
160161
)
161162
```
162163

164+
163165
### SSL options
164166

165167
Setting any of the following options will enable an SSL connection, but only if
@@ -251,6 +253,15 @@ the `:default_file` and `:default_group` paramters. For example:
251253
Mysql2::Client.new(:default_file => '/user/.my.cnf', :default_group => 'client')
252254
```
253255

256+
### init_command
257+
258+
If you specify the init_command option, the SQL string you provide will be executed after the connection is established.
259+
If `:reconnect` is set to `true`, init_command will also be executed after a successful reconnect.
260+
It is useful if you want to provide session options which survive reconnection.
261+
262+
``` ruby
263+
Mysql2::Client.new(:init_command => "SET @@SESSION.sql_mode = 'STRICT_ALL_TABLES'")
264+
```
254265

255266
## Cascading config
256267

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)