mysql2 0.4.10 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 75b3d925930b92cf7b1a36fa196d334e245919ac
4
- data.tar.gz: 2bbe0a78b156f8c5b59643c4d57a7ce19b764bcc
3
+ metadata.gz: 658cf051d498ace207785b75cead2b0f938bba92
4
+ data.tar.gz: 7f50c5cf9a45656a5347809d4494ee0c17eb8208
5
5
  SHA512:
6
- metadata.gz: 602f336b5ed83421862b9dec36a9ddbd477dcbacc3ef16d58d5252072dba0bc7f7a955000482414eda1d104bda72ded87f3f4c795f8b4b4d36999bc6ee171e4b
7
- data.tar.gz: 20281fda66cf4595edc05ac6a933d5f641c2f9f87771e8ace1e9de00902ecea54ddbc2d1b743c3dbd97b48c795d0ad32f9ab785e5848a4f3de92c7ddebeef659
6
+ metadata.gz: '05994292d6c1de48d3fcc1af99c5c2ec85c09a6bb1111e19129d9434fcdf191d838a91fee9d61d6a67576a6ff316a39b418b9cf13e159d99cbbad2e49eb28e78'
7
+ data.tar.gz: 5d668a60aa6ed4053787b84c1cb3114604b2c22c225492b53124d7d023fd02f6c9b54f848453fedce72ac64092723b989f3cafb471605ffa5606444cf0a4d26b
data/README.md CHANGED
@@ -7,7 +7,7 @@ The Mysql2 gem is meant to serve the extremely common use-case of connecting, qu
7
7
  Some database libraries out there serve as direct 1:1 mappings of the already complex C APIs available.
8
8
  This one is not.
9
9
 
10
- It also forces the use of UTF-8 [or binary] for the connection [and all strings in 1.9, unless Encoding.default_internal is set then it'll convert from UTF-8 to that encoding] and uses encoding-aware MySQL API calls where it can.
10
+ It also forces the use of UTF-8 [or binary] for the connection and uses encoding-aware MySQL API calls where it can.
11
11
 
12
12
  The API consists of three classes:
13
13
 
@@ -138,7 +138,7 @@ results.each do |row|
138
138
  # conveniently, row is a hash
139
139
  # the keys are the fields, as you'd expect
140
140
  # the values are pre-built ruby primitives mapped from their corresponding field types in MySQL
141
- puts row["id"] # row["id"].class == Fixnum
141
+ puts row["id"] # row["id"].is_a? Integer
142
142
  if row["dne"] # non-existant hash entry is nil
143
143
  puts row["dne"]
144
144
  end
@@ -175,7 +175,8 @@ end
175
175
  Prepared statements are supported, as well. In a prepared statement, use a `?`
176
176
  in place of each value and then execute the statement to retrieve a result set.
177
177
  Pass your arguments to the execute method in the same number and order as the
178
- question marks in the statement.
178
+ question marks in the statement. Query options can be passed as keyword arguments
179
+ to the execute method.
179
180
 
180
181
  ``` ruby
181
182
  statement = @client.prepare("SELECT * FROM users WHERE login_count = ?")
@@ -184,6 +185,9 @@ result2 = statement.execute(2)
184
185
 
185
186
  statement = @client.prepare("SELECT * FROM users WHERE last_login >= ? AND location LIKE ?")
186
187
  result = statement.execute(1, "CA")
188
+
189
+ statement = @client.prepare("SELECT * FROM users WHERE last_login >= ? AND location LIKE ?")
190
+ result = statement.execute(1, "CA", :as => :array)
187
191
  ```
188
192
 
189
193
  ## Connection options
@@ -203,6 +207,7 @@ Mysql2::Client.new(
203
207
  :read_timeout = seconds,
204
208
  :write_timeout = seconds,
205
209
  :connect_timeout = seconds,
210
+ :connect_attrs = {:program_name => $PROGRAM_NAME, ...},
206
211
  :reconnect = true/false,
207
212
  :local_infile = true/false,
208
213
  :secure_auth = true/false,
@@ -381,6 +386,15 @@ c = Mysql2::Client.new
381
386
  c.query(sql, :symbolize_keys => true)
382
387
  ```
383
388
 
389
+ or
390
+
391
+ ``` ruby
392
+ # this will set the options for the Mysql2::Result instance returned from the #execute method
393
+ c = Mysql2::Client.new
394
+ s = c.prepare(sql)
395
+ s.execute(arg1, args2, :symbolize_keys => true)
396
+ ```
397
+
384
398
  ## Result types
385
399
 
386
400
  ### Array of Arrays
@@ -509,15 +523,14 @@ As for field values themselves, I'm workin on it - but expect that soon.
509
523
 
510
524
  This gem is tested with the following Ruby versions on Linux and Mac OS X:
511
525
 
512
- * Ruby MRI 1.8.7, 1.9.3, 2.0.0, 2.1.x, 2.2.x, 2.3.x, 2.4.x
513
- * Ruby Enterprise Edition (based on MRI 1.8.7)
526
+ * Ruby MRI 2.0.0, 2.1.x, 2.2.x, 2.3.x, 2.4.x, 2.5.x, 2.6.x
514
527
  * Rubinius 2.x and 3.x do work but may fail under some workloads
515
528
 
516
529
  This gem is tested with the following MySQL and MariaDB versions:
517
530
 
518
531
  * MySQL 5.5, 5.6, 5.7, 8.0
519
532
  * MySQL Connector/C 6.0 and 6.1 (primarily on Windows)
520
- * MariaDB 5.5, 10.0, 10.1
533
+ * MariaDB 5.5, 10.0, 10.1, 10.2, 10.3
521
534
 
522
535
  ### Ruby on Rails / Active Record
523
536
 
@@ -1,5 +1,3 @@
1
- # encoding: utf-8
2
-
3
1
  $LOAD_PATH.unshift 'lib'
4
2
 
5
3
  require 'rubygems'
@@ -1,17 +1,15 @@
1
- # encoding: utf-8
2
-
3
1
  $LOAD_PATH.unshift 'lib'
4
2
  require 'mysql2'
5
3
  require 'timeout'
6
4
 
7
5
  # Should never exceed worst case 3.5 secs across all 20 threads
8
6
  Timeout.timeout(3.5) do
9
- 20.times.map do
7
+ Array.new(20) do
10
8
  Thread.new do
11
9
  overhead = rand(3)
12
10
  puts ">> thread #{Thread.current.object_id} query, #{overhead} sec overhead"
13
11
  # 3 second overhead per query
14
- Mysql2::Client.new(:host => "localhost", :username => "root").query("SELECT sleep(#{overhead}) as result")
12
+ Mysql2::Client.new(host: "localhost", username: "root").query("SELECT sleep(#{overhead}) as result")
15
13
  puts "<< thread #{Thread.current.object_id} result, #{overhead} sec overhead"
16
14
  end
17
15
  end.each(&:join)
@@ -15,16 +15,11 @@
15
15
  #include "mysql_enc_name_to_ruby.h"
16
16
 
17
17
  VALUE cMysql2Client;
18
- extern VALUE mMysql2, cMysql2Error;
18
+ extern VALUE mMysql2, cMysql2Error, cMysql2TimeoutError;
19
19
  static VALUE sym_id, sym_version, sym_header_version, sym_async, sym_symbolize_keys, sym_as, sym_array, sym_stream;
20
+ static VALUE sym_no_good_index_used, sym_no_index_used, sym_query_was_slow;
20
21
  static ID intern_brackets, intern_merge, intern_merge_bang, intern_new_with_args;
21
22
 
22
- #ifndef HAVE_RB_HASH_DUP
23
- VALUE rb_hash_dup(VALUE other) {
24
- return rb_funcall(rb_cHash, intern_brackets, 1, other);
25
- }
26
- #endif
27
-
28
23
  #define REQUIRE_INITIALIZED(wrapper) \
29
24
  if (!wrapper->initialized) { \
30
25
  rb_raise(cMysql2Error, "MySQL client is not initialized"); \
@@ -119,7 +114,7 @@ static VALUE rb_set_ssl_mode_option(VALUE self, VALUE setting) {
119
114
  int val = NUM2INT( setting );
120
115
  if (version >= 50703 && version < 50711) {
121
116
  if (val == SSL_MODE_DISABLED || val == SSL_MODE_REQUIRED) {
122
- bool b = ( val == SSL_MODE_REQUIRED );
117
+ my_bool b = ( val == SSL_MODE_REQUIRED );
123
118
  int result = mysql_options( wrapper->client, MYSQL_OPT_SSL_ENFORCE, &b );
124
119
  return INT2NUM(result);
125
120
  } else {
@@ -178,10 +173,8 @@ static VALUE rb_raise_mysql2_error(mysql_client_wrapper *wrapper) {
178
173
  VALUE rb_sql_state = rb_tainted_str_new2(mysql_sqlstate(wrapper->client));
179
174
  VALUE e;
180
175
 
181
- #ifdef HAVE_RUBY_ENCODING_H
182
176
  rb_enc_associate(rb_error_msg, rb_utf8_encoding());
183
177
  rb_enc_associate(rb_sql_state, rb_usascii_encoding());
184
- #endif
185
178
 
186
179
  e = rb_funcall(cMysql2Error, intern_new_with_args, 4,
187
180
  rb_error_msg,
@@ -357,9 +350,7 @@ static VALUE rb_mysql_client_escape(RB_MYSQL_UNUSED VALUE klass, VALUE str) {
357
350
  return str;
358
351
  } else {
359
352
  rb_str = rb_str_new((const char*)newStr, newLen);
360
- #ifdef HAVE_RUBY_ENCODING_H
361
353
  rb_enc_copy(rb_str, str);
362
- #endif
363
354
  xfree(newStr);
364
355
  return rb_str;
365
356
  }
@@ -386,9 +377,7 @@ static VALUE rb_mysql_info(VALUE self) {
386
377
  }
387
378
 
388
379
  rb_str = rb_str_new2(info);
389
- #ifdef HAVE_RUBY_ENCODING_H
390
380
  rb_enc_associate(rb_str, rb_utf8_encoding());
391
- #endif
392
381
 
393
382
  return rb_str;
394
383
  }
@@ -406,14 +395,25 @@ static VALUE rb_mysql_get_ssl_cipher(VALUE self)
406
395
  }
407
396
 
408
397
  rb_str = rb_str_new2(cipher);
409
- #ifdef HAVE_RUBY_ENCODING_H
410
398
  rb_enc_associate(rb_str, rb_utf8_encoding());
411
- #endif
412
399
 
413
400
  return rb_str;
414
401
  }
415
402
 
416
- static VALUE rb_connect(VALUE self, VALUE user, VALUE pass, VALUE host, VALUE port, VALUE database, VALUE socket, VALUE flags) {
403
+ #ifdef CLIENT_CONNECT_ATTRS
404
+ static int opt_connect_attr_add_i(VALUE key, VALUE value, VALUE arg)
405
+ {
406
+ mysql_client_wrapper *wrapper = (mysql_client_wrapper *)arg;
407
+ rb_encoding *enc = rb_to_encoding(wrapper->encoding);
408
+ key = rb_str_export_to_enc(key, enc);
409
+ value = rb_str_export_to_enc(value, enc);
410
+
411
+ mysql_options4(wrapper->client, MYSQL_OPT_CONNECT_ATTR_ADD, StringValueCStr(key), StringValueCStr(value));
412
+ return ST_CONTINUE;
413
+ }
414
+ #endif
415
+
416
+ static VALUE rb_mysql_connect(VALUE self, VALUE user, VALUE pass, VALUE host, VALUE port, VALUE database, VALUE socket, VALUE flags, VALUE conn_attrs) {
417
417
  struct nogvl_connect_args args;
418
418
  time_t start_time, end_time, elapsed_time, connect_timeout;
419
419
  VALUE rv;
@@ -428,6 +428,11 @@ static VALUE rb_connect(VALUE self, VALUE user, VALUE pass, VALUE host, VALUE po
428
428
  args.mysql = wrapper->client;
429
429
  args.client_flag = NUM2ULONG(flags);
430
430
 
431
+ #ifdef CLIENT_CONNECT_ATTRS
432
+ mysql_options(wrapper->client, MYSQL_OPT_CONNECT_ATTR_RESET, 0);
433
+ rb_hash_foreach(conn_attrs, opt_connect_attr_add_i, (VALUE)wrapper);
434
+ #endif
435
+
431
436
  if (wrapper->connect_timeout)
432
437
  time(&start_time);
433
438
  rv = (VALUE) rb_thread_call_without_gvl(nogvl_connect, &args, RUBY_UBF_IO, 0);
@@ -521,7 +526,7 @@ static VALUE do_send_query(void *args) {
521
526
  */
522
527
  static void *nogvl_read_query_result(void *ptr) {
523
528
  MYSQL * client = ptr;
524
- bool res = mysql_read_query_result(client);
529
+ my_bool res = mysql_read_query_result(client);
525
530
 
526
531
  return (void *)(res == 0 ? Qtrue : Qfalse);
527
532
  }
@@ -590,11 +595,14 @@ static VALUE rb_mysql_client_async_result(VALUE self) {
590
595
  return Qnil;
591
596
  }
592
597
 
598
+ // Duplicate the options hash and put the copy in the Result object
593
599
  current = rb_hash_dup(rb_iv_get(self, "@current_query_options"));
594
600
  (void)RB_GC_GUARD(current);
595
601
  Check_Type(current, T_HASH);
596
602
  resultObj = rb_mysql_result_to_obj(self, wrapper->encoding, current, result, Qnil);
597
603
 
604
+ rb_mysql_set_server_query_flags(wrapper->client, resultObj);
605
+
598
606
  return resultObj;
599
607
  }
600
608
 
@@ -652,7 +660,7 @@ static VALUE do_query(void *args) {
652
660
  retval = rb_wait_for_single_fd(async_args->fd, RB_WAITFD_IN, tvp);
653
661
 
654
662
  if (retval == 0) {
655
- rb_raise(cMysql2Error, "Timeout waiting for a response from the last query. (waited %d seconds)", FIX2INT(read_timeout));
663
+ rb_raise(cMysql2TimeoutError, "Timeout waiting for a response from the last query. (waited %d seconds)", FIX2INT(read_timeout));
656
664
  }
657
665
 
658
666
  if (retval < 0) {
@@ -747,7 +755,7 @@ static VALUE rb_mysql_client_abandon_results(VALUE self) {
747
755
  * Query the database with +sql+, with optional +options+. For the possible
748
756
  * options, see default_query_options on the Mysql2::Client class.
749
757
  */
750
- static VALUE rb_query(VALUE self, VALUE sql, VALUE current) {
758
+ static VALUE rb_mysql_query(VALUE self, VALUE sql, VALUE current) {
751
759
  #ifndef _WIN32
752
760
  struct async_query_args async_args;
753
761
  #endif
@@ -762,12 +770,8 @@ static VALUE rb_query(VALUE self, VALUE sql, VALUE current) {
762
770
  rb_iv_set(self, "@current_query_options", current);
763
771
 
764
772
  Check_Type(sql, T_STRING);
765
- #ifdef HAVE_RUBY_ENCODING_H
766
773
  /* ensure the string is in the encoding the connection is expecting */
767
774
  args.sql = rb_str_export_to_enc(sql, rb_to_encoding(wrapper->encoding));
768
- #else
769
- args.sql = sql;
770
- #endif
771
775
  args.sql_ptr = RSTRING_PTR(args.sql);
772
776
  args.sql_len = RSTRING_LEN(args.sql);
773
777
  args.wrapper = wrapper;
@@ -804,20 +808,16 @@ static VALUE rb_mysql_client_real_escape(VALUE self, VALUE str) {
804
808
  unsigned char *newStr;
805
809
  VALUE rb_str;
806
810
  unsigned long newLen, oldLen;
807
- #ifdef HAVE_RUBY_ENCODING_H
808
811
  rb_encoding *default_internal_enc;
809
812
  rb_encoding *conn_enc;
810
- #endif
811
813
  GET_CLIENT(self);
812
814
 
813
815
  REQUIRE_CONNECTED(wrapper);
814
816
  Check_Type(str, T_STRING);
815
- #ifdef HAVE_RUBY_ENCODING_H
816
817
  default_internal_enc = rb_default_internal_encoding();
817
818
  conn_enc = rb_to_encoding(wrapper->encoding);
818
819
  /* ensure the string is in the encoding the connection is expecting */
819
820
  str = rb_str_export_to_enc(str, conn_enc);
820
- #endif
821
821
 
822
822
  oldLen = RSTRING_LEN(str);
823
823
  newStr = xmalloc(oldLen*2+1);
@@ -825,21 +825,17 @@ static VALUE rb_mysql_client_real_escape(VALUE self, VALUE str) {
825
825
  newLen = mysql_real_escape_string(wrapper->client, (char *)newStr, RSTRING_PTR(str), oldLen);
826
826
  if (newLen == oldLen) {
827
827
  /* no need to return a new ruby string if nothing changed */
828
- #ifdef HAVE_RUBY_ENCODING_H
829
828
  if (default_internal_enc) {
830
829
  str = rb_str_export_to_enc(str, default_internal_enc);
831
830
  }
832
- #endif
833
831
  xfree(newStr);
834
832
  return str;
835
833
  } else {
836
834
  rb_str = rb_str_new((const char*)newStr, newLen);
837
- #ifdef HAVE_RUBY_ENCODING_H
838
835
  rb_enc_associate(rb_str, conn_enc);
839
836
  if (default_internal_enc) {
840
837
  rb_str = rb_str_export_to_enc(rb_str, default_internal_enc);
841
838
  }
842
- #endif
843
839
  xfree(newStr);
844
840
  return rb_str;
845
841
  }
@@ -850,7 +846,7 @@ static VALUE _mysql_client_options(VALUE self, int opt, VALUE value) {
850
846
  const void *retval = NULL;
851
847
  unsigned int intval = 0;
852
848
  const char * charval = NULL;
853
- bool boolval;
849
+ my_bool boolval;
854
850
 
855
851
  GET_CLIENT(self);
856
852
 
@@ -950,10 +946,8 @@ static VALUE rb_mysql_client_info(RB_MYSQL_UNUSED VALUE klass) {
950
946
  version = rb_str_new2(mysql_get_client_info());
951
947
  header_version = rb_str_new2(MYSQL_LINK_VERSION);
952
948
 
953
- #ifdef HAVE_RUBY_ENCODING_H
954
949
  rb_enc_associate(version, rb_usascii_encoding());
955
950
  rb_enc_associate(header_version, rb_usascii_encoding());
956
- #endif
957
951
 
958
952
  rb_hash_aset(version_info, sym_id, LONG2NUM(mysql_get_client_version()));
959
953
  rb_hash_aset(version_info, sym_version, version);
@@ -969,27 +963,21 @@ static VALUE rb_mysql_client_info(RB_MYSQL_UNUSED VALUE klass) {
969
963
  */
970
964
  static VALUE rb_mysql_client_server_info(VALUE self) {
971
965
  VALUE version, server_info;
972
- #ifdef HAVE_RUBY_ENCODING_H
973
966
  rb_encoding *default_internal_enc;
974
967
  rb_encoding *conn_enc;
975
- #endif
976
968
  GET_CLIENT(self);
977
969
 
978
970
  REQUIRE_CONNECTED(wrapper);
979
- #ifdef HAVE_RUBY_ENCODING_H
980
971
  default_internal_enc = rb_default_internal_encoding();
981
972
  conn_enc = rb_to_encoding(wrapper->encoding);
982
- #endif
983
973
 
984
974
  version = rb_hash_new();
985
975
  rb_hash_aset(version, sym_id, LONG2FIX(mysql_get_server_version(wrapper->client)));
986
976
  server_info = rb_str_new2(mysql_get_server_info(wrapper->client));
987
- #ifdef HAVE_RUBY_ENCODING_H
988
977
  rb_enc_associate(server_info, conn_enc);
989
978
  if (default_internal_enc) {
990
979
  server_info = rb_str_export_to_enc(server_info, default_internal_enc);
991
980
  }
992
- #endif
993
981
  rb_hash_aset(version, sym_version, server_info);
994
982
  return version;
995
983
  }
@@ -1110,6 +1098,23 @@ static VALUE rb_mysql_client_ping(VALUE self) {
1110
1098
  }
1111
1099
  }
1112
1100
 
1101
+ /* call-seq:
1102
+ * client.set_server_option(value)
1103
+ *
1104
+ * Enables or disables an option for the connection.
1105
+ * Read https://dev.mysql.com/doc/refman/5.7/en/mysql-set-server-option.html
1106
+ * for more information.
1107
+ */
1108
+ static VALUE rb_mysql_client_set_server_option(VALUE self, VALUE value) {
1109
+ GET_CLIENT(self);
1110
+
1111
+ if (mysql_set_server_option(wrapper->client, NUM2INT(value)) == 0) {
1112
+ return Qtrue;
1113
+ } else {
1114
+ return Qfalse;
1115
+ }
1116
+ }
1117
+
1113
1118
  /* call-seq:
1114
1119
  * client.more_results?
1115
1120
  *
@@ -1168,6 +1173,7 @@ static VALUE rb_mysql_client_store_result(VALUE self)
1168
1173
  return Qnil;
1169
1174
  }
1170
1175
 
1176
+ // Duplicate the options hash and put the copy in the Result object
1171
1177
  current = rb_hash_dup(rb_iv_get(self, "@current_query_options"));
1172
1178
  (void)RB_GC_GUARD(current);
1173
1179
  Check_Type(current, T_HASH);
@@ -1176,7 +1182,6 @@ static VALUE rb_mysql_client_store_result(VALUE self)
1176
1182
  return resultObj;
1177
1183
  }
1178
1184
 
1179
- #ifdef HAVE_RUBY_ENCODING_H
1180
1185
  /* call-seq:
1181
1186
  * client.encoding
1182
1187
  *
@@ -1186,7 +1191,6 @@ static VALUE rb_mysql_client_encoding(VALUE self) {
1186
1191
  GET_CLIENT(self);
1187
1192
  return wrapper->encoding;
1188
1193
  }
1189
- #endif
1190
1194
 
1191
1195
  /* call-seq:
1192
1196
  * client.automatic_close?
@@ -1272,17 +1276,14 @@ static VALUE set_write_timeout(VALUE self, VALUE value) {
1272
1276
 
1273
1277
  static VALUE set_charset_name(VALUE self, VALUE value) {
1274
1278
  char *charset_name;
1275
- #ifdef HAVE_RUBY_ENCODING_H
1276
1279
  const struct mysql2_mysql_enc_name_to_rb_map *mysql2rb;
1277
1280
  rb_encoding *enc;
1278
1281
  VALUE rb_enc;
1279
- #endif
1280
1282
  GET_CLIENT(self);
1281
1283
 
1282
1284
  Check_Type(value, T_STRING);
1283
1285
  charset_name = RSTRING_PTR(value);
1284
1286
 
1285
- #ifdef HAVE_RUBY_ENCODING_H
1286
1287
  mysql2rb = mysql2_mysql_enc_name_to_rb(charset_name, (unsigned int)RSTRING_LEN(value));
1287
1288
  if (mysql2rb == NULL || mysql2rb->rb_name == NULL) {
1288
1289
  VALUE inspect = rb_inspect(value);
@@ -1292,7 +1293,6 @@ static VALUE set_charset_name(VALUE self, VALUE value) {
1292
1293
  rb_enc = rb_enc_from_encoding(enc);
1293
1294
  wrapper->encoding = rb_enc;
1294
1295
  }
1295
- #endif
1296
1296
 
1297
1297
  if (mysql_options(wrapper->client, MYSQL_SET_CHARSET_NAME, charset_name)) {
1298
1298
  /* TODO: warning - unable to set charset */
@@ -1416,6 +1416,7 @@ void init_mysql2_client() {
1416
1416
  rb_define_method(cMysql2Client, "thread_id", rb_mysql_client_thread_id, 0);
1417
1417
  rb_define_method(cMysql2Client, "ping", rb_mysql_client_ping, 0);
1418
1418
  rb_define_method(cMysql2Client, "select_db", rb_mysql_client_select_db, 1);
1419
+ rb_define_method(cMysql2Client, "set_server_option", rb_mysql_client_set_server_option, 1);
1419
1420
  rb_define_method(cMysql2Client, "more_results?", rb_mysql_client_more_results, 0);
1420
1421
  rb_define_method(cMysql2Client, "next_result", rb_mysql_client_next_result, 0);
1421
1422
  rb_define_method(cMysql2Client, "store_result", rb_mysql_client_store_result, 0);
@@ -1425,9 +1426,7 @@ void init_mysql2_client() {
1425
1426
  rb_define_method(cMysql2Client, "warning_count", rb_mysql_client_warning_count, 0);
1426
1427
  rb_define_method(cMysql2Client, "query_info_string", rb_mysql_info, 0);
1427
1428
  rb_define_method(cMysql2Client, "ssl_cipher", rb_mysql_get_ssl_cipher, 0);
1428
- #ifdef HAVE_RUBY_ENCODING_H
1429
1429
  rb_define_method(cMysql2Client, "encoding", rb_mysql_client_encoding, 0);
1430
- #endif
1431
1430
 
1432
1431
  rb_define_private_method(cMysql2Client, "connect_timeout=", set_connect_timeout, 1);
1433
1432
  rb_define_private_method(cMysql2Client, "read_timeout=", set_read_timeout, 1);
@@ -1442,8 +1441,8 @@ void init_mysql2_client() {
1442
1441
  rb_define_private_method(cMysql2Client, "ssl_mode=", rb_set_ssl_mode_option, 1);
1443
1442
  rb_define_private_method(cMysql2Client, "enable_cleartext_plugin=", set_enable_cleartext_plugin, 1);
1444
1443
  rb_define_private_method(cMysql2Client, "initialize_ext", initialize_ext, 0);
1445
- rb_define_private_method(cMysql2Client, "connect", rb_connect, 7);
1446
- rb_define_private_method(cMysql2Client, "_query", rb_query, 2);
1444
+ rb_define_private_method(cMysql2Client, "connect", rb_mysql_connect, 8);
1445
+ rb_define_private_method(cMysql2Client, "_query", rb_mysql_query, 2);
1447
1446
 
1448
1447
  sym_id = ID2SYM(rb_intern("id"));
1449
1448
  sym_version = ID2SYM(rb_intern("version"));
@@ -1454,6 +1453,10 @@ void init_mysql2_client() {
1454
1453
  sym_array = ID2SYM(rb_intern("array"));
1455
1454
  sym_stream = ID2SYM(rb_intern("stream"));
1456
1455
 
1456
+ sym_no_good_index_used = ID2SYM(rb_intern("no_good_index_used"));
1457
+ sym_no_index_used = ID2SYM(rb_intern("no_index_used"));
1458
+ sym_query_was_slow = ID2SYM(rb_intern("query_was_slow"));
1459
+
1457
1460
  intern_brackets = rb_intern("[]");
1458
1461
  intern_merge = rb_intern("merge");
1459
1462
  intern_merge_bang = rb_intern("merge!");
@@ -1543,6 +1546,16 @@ void init_mysql2_client() {
1543
1546
  rb_const_set(cMysql2Client, rb_intern("SECURE_CONNECTION"), LONG2NUM(0));
1544
1547
  #endif
1545
1548
 
1549
+ #ifdef HAVE_CONST_MYSQL_OPTION_MULTI_STATEMENTS_ON
1550
+ rb_const_set(cMysql2Client, rb_intern("OPTION_MULTI_STATEMENTS_ON"),
1551
+ LONG2NUM(MYSQL_OPTION_MULTI_STATEMENTS_ON));
1552
+ #endif
1553
+
1554
+ #ifdef HAVE_CONST_MYSQL_OPTION_MULTI_STATEMENTS_OFF
1555
+ rb_const_set(cMysql2Client, rb_intern("OPTION_MULTI_STATEMENTS_OFF"),
1556
+ LONG2NUM(MYSQL_OPTION_MULTI_STATEMENTS_OFF));
1557
+ #endif
1558
+
1546
1559
  #ifdef CLIENT_MULTI_STATEMENTS
1547
1560
  rb_const_set(cMysql2Client, rb_intern("MULTI_STATEMENTS"),
1548
1561
  LONG2NUM(CLIENT_MULTI_STATEMENTS));
@@ -1573,6 +1586,16 @@ void init_mysql2_client() {
1573
1586
  LONG2NUM(CLIENT_BASIC_FLAGS));
1574
1587
  #endif
1575
1588
 
1589
+ #ifdef CLIENT_CONNECT_ATTRS
1590
+ rb_const_set(cMysql2Client, rb_intern("CONNECT_ATTRS"),
1591
+ LONG2NUM(CLIENT_CONNECT_ATTRS));
1592
+ #else
1593
+ /* HACK because MySQL 5.5 and earlier don't define this constant,
1594
+ * but we're using it in our default connection flags. */
1595
+ rb_const_set(cMysql2Client, rb_intern("CONNECT_ATTRS"),
1596
+ INT2NUM(0));
1597
+ #endif
1598
+
1576
1599
  #if defined(FULL_SSL_MODE_SUPPORT) // MySQL 5.7.11 and above
1577
1600
  rb_const_set(cMysql2Client, rb_intern("SSL_MODE_DISABLED"), INT2NUM(SSL_MODE_DISABLED));
1578
1601
  rb_const_set(cMysql2Client, rb_intern("SSL_MODE_PREFERRED"), INT2NUM(SSL_MODE_PREFERRED));
@@ -1600,3 +1623,29 @@ void init_mysql2_client() {
1600
1623
  rb_const_set(cMysql2Client, rb_intern("SSL_MODE_VERIFY_IDENTITY"), INT2NUM(0));
1601
1624
  #endif
1602
1625
  }
1626
+
1627
+ #define flag_to_bool(f) ((client->server_status & f) ? Qtrue : Qfalse)
1628
+
1629
+ void rb_mysql_set_server_query_flags(MYSQL *client, VALUE result) {
1630
+ VALUE server_flags = rb_hash_new();
1631
+
1632
+ #ifdef HAVE_CONST_SERVER_QUERY_NO_GOOD_INDEX_USED
1633
+ rb_hash_aset(server_flags, sym_no_good_index_used, flag_to_bool(SERVER_QUERY_NO_GOOD_INDEX_USED));
1634
+ #else
1635
+ rb_hash_aset(server_flags, sym_no_good_index_used, Qnil);
1636
+ #endif
1637
+
1638
+ #ifdef HAVE_CONST_SERVER_QUERY_NO_INDEX_USED
1639
+ rb_hash_aset(server_flags, sym_no_index_used, flag_to_bool(SERVER_QUERY_NO_INDEX_USED));
1640
+ #else
1641
+ rb_hash_aset(server_flags, sym_no_index_used, Qnil);
1642
+ #endif
1643
+
1644
+ #ifdef HAVE_CONST_SERVER_QUERY_WAS_SLOW
1645
+ rb_hash_aset(server_flags, sym_query_was_slow, flag_to_bool(SERVER_QUERY_WAS_SLOW));
1646
+ #else
1647
+ rb_hash_aset(server_flags, sym_query_was_slow, Qnil);
1648
+ #endif
1649
+
1650
+ rb_iv_set(result, "@server_flags", server_flags);
1651
+ }