Class: Mysql2::Client

Inherits:
Object
  • Object
show all
Defined in:
lib/mysql2/client.rb,
ext/mysql2/client.c

Direct Known Subclasses

EM::Client

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(opts = {}) ⇒ Client

Returns a new instance of Client.

Raises:



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/mysql2/client.rb', line 21

def initialize(opts = {})
  raise Mysql2::Error, "Options parameter must be a Hash" unless opts.is_a? Hash

  opts = Mysql2::Util.key_hash_as_symbols(opts)
  @read_timeout = nil
  @query_options = self.class.default_query_options.dup
  @query_options.merge! opts

  initialize_ext

  # Set default connect_timeout to avoid unlimited retries from signal interruption
  opts[:connect_timeout] = 120 unless opts.key?(:connect_timeout)

  # TODO: stricter validation rather than silent massaging
  %i[reconnect connect_timeout local_infile read_timeout write_timeout default_file default_group secure_auth init_command automatic_close enable_cleartext_plugin default_auth].each do |key|
    next unless opts.key?(key)

    case key
    when :reconnect, :local_infile, :secure_auth, :automatic_close, :enable_cleartext_plugin
      send(:"#{key}=", !!opts[key]) # rubocop:disable Style/DoubleNegation
    when :connect_timeout, :read_timeout, :write_timeout
      send(:"#{key}=", Integer(opts[key])) unless opts[key].nil?
    else
      send(:"#{key}=", opts[key])
    end
  end

  # force the encoding to utf8
  self.charset_name = opts[:encoding] || 'utf8'

  mode = parse_ssl_mode(opts[:ssl_mode]) if opts[:ssl_mode]
  if (mode == SSL_MODE_VERIFY_CA || mode == SSL_MODE_VERIFY_IDENTITY) && !opts[:sslca]
    opts[:sslca] = find_default_ca_path
  end

  ssl_options = opts.values_at(:sslkey, :sslcert, :sslca, :sslcapath, :sslcipher)
  ssl_set(*ssl_options) if ssl_options.any? || opts.key?(:sslverify)
  self.ssl_mode = mode if mode

  flags = case opts[:flags]
  when Array
    parse_flags_array(opts[:flags], @query_options[:connect_flags])
  when String
    parse_flags_array(opts[:flags].split(' '), @query_options[:connect_flags])
  when Integer
    @query_options[:connect_flags] | opts[:flags]
  else
    @query_options[:connect_flags]
  end

  # SSL verify is a connection flag rather than a mysql_ssl_set option
  flags |= SSL_VERIFY_SERVER_CERT if opts[:sslverify]

  if %i[user pass hostname dbname db sock].any? { |k| @query_options.key?(k) }
    warn "============= WARNING FROM mysql2 ============="
    warn "The options :user, :pass, :hostname, :dbname, :db, and :sock are deprecated and will be removed at some point in the future."
    warn "Instead, please use :username, :password, :host, :port, :database, :socket, :flags for the options."
    warn "============= END WARNING FROM mysql2 ========="
  end

  user     = opts[:username] || opts[:user]
  pass     = opts[:password] || opts[:pass]
  host     = opts[:host] || opts[:hostname]
  port     = opts[:port]
  database = opts[:database] || opts[:dbname] || opts[:db]
  socket   = opts[:socket] || opts[:sock]

  # Correct the data types before passing these values down to the C level
  user = user.to_s unless user.nil?
  pass = pass.to_s unless pass.nil?
  host = host.to_s unless host.nil?
  port = port.to_i unless port.nil?
  database = database.to_s unless database.nil?
  socket = socket.to_s unless socket.nil?
  conn_attrs = parse_connect_attrs(opts[:connect_attrs])

  connect user, pass, host, port, database, socket, flags, conn_attrs
end

Instance Attribute Details

#query_optionsObject (readonly)

Returns the value of attribute query_options.



3
4
5
# File 'lib/mysql2/client.rb', line 3

def query_options
  @query_options
end

#read_timeoutObject (readonly)

Returns the value of attribute read_timeout.



3
4
5
# File 'lib/mysql2/client.rb', line 3

def read_timeout
  @read_timeout
end

Class Method Details

.default_query_optionsObject



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# File 'lib/mysql2/client.rb', line 5

def self.default_query_options
  @default_query_options ||= {
    as: :hash,                   # the type of object you want each row back as; also supports :array (an array of values)
    async: false,                # don't wait for a result after sending the query, you'll have to monitor the socket yourself then eventually call Mysql2::Client#async_result
    cast_booleans: false,        # cast tinyint(1) fields as true/false in ruby
    symbolize_keys: false,       # return field names as symbols instead of strings
    database_timezone: :local,   # timezone Mysql2 will assume datetime objects are stored in
    application_timezone: nil,   # timezone Mysql2 will convert to before handing the object back to the caller
    cache_rows: true,            # tells Mysql2 to use its internal row cache for results
    connect_flags: REMEMBER_OPTIONS | LONG_PASSWORD | LONG_FLAG | TRANSACTIONS | PROTOCOL_41 | SECURE_CONNECTION | CONNECT_ATTRS,
    cast: true,
    default_file: nil,
    default_group: nil,
  }
end

.Mysql2::Client.escape(string) ⇒ Object

Escape string so that it may be used in a SQL statement. Note that this escape method is not connection encoding aware. If you need encoding support use Mysql2::Client#escape instead.



426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
# File 'ext/mysql2/client.c', line 426

static VALUE rb_mysql_client_escape(RB_MYSQL_UNUSED VALUE klass, VALUE str) {
  unsigned char *newStr;
  VALUE rb_str;
  unsigned long newLen, oldLen;

  Check_Type(str, T_STRING);

  oldLen = RSTRING_LEN(str);
  newStr = xmalloc(oldLen*2+1);

  newLen = mysql_escape_string((char *)newStr, RSTRING_PTR(str), oldLen);
  if (newLen == oldLen) {
    /* no need to return a new ruby string if nothing changed */
    xfree(newStr);
    return str;
  } else {
    rb_str = rb_str_new((const char*)newStr, newLen);
    rb_enc_copy(rb_str, str);
    xfree(newStr);
    return rb_str;
  }
}

.infoObject

Returns a string that represents the client library version.



1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
# File 'ext/mysql2/client.c', line 1042

static VALUE rb_mysql_client_info(RB_MYSQL_UNUSED VALUE klass) {
  VALUE version_info, version, header_version;
  version_info = rb_hash_new();

  version = rb_str_new2(mysql_get_client_info());
  header_version = rb_str_new2(MYSQL_LINK_VERSION);

  rb_enc_associate(version, rb_usascii_encoding());
  rb_enc_associate(header_version, rb_usascii_encoding());

  rb_hash_aset(version_info, sym_id, LONG2NUM(mysql_get_client_version()));
  rb_hash_aset(version_info, sym_version, version);
  rb_hash_aset(version_info, sym_header_version, header_version);

  return version_info;
}

Instance Method Details

#abandon_results!Object

When using MULTI_STATEMENTS support, calling this will throw away any unprocessed results as fast as it can in order to put the connection back into a state where queries can be issued again.



821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
# File 'ext/mysql2/client.c', line 821

static VALUE rb_mysql_client_abandon_results(VALUE self) {
  MYSQL_RES *result;
  int ret;

  GET_CLIENT(self);

  while (mysql_more_results(wrapper->client) == 1) {
    ret = mysql_next_result(wrapper->client);
    if (ret > 0) {
      rb_raise_mysql2_error(wrapper);
    }

    result = (MYSQL_RES *)rb_thread_call_without_gvl(nogvl_store_result, wrapper, RUBY_UBF_IO, 0);

    if (result != NULL) {
      mysql_free_result(result);
    }
  }

  return Qnil;
}

#affected_rowsObject

returns the number of rows changed, deleted, or inserted by the last statement if it was an UPDATE, DELETE, or INSERT.



1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
# File 'ext/mysql2/client.c', line 1150

static VALUE rb_mysql_client_affected_rows(VALUE self) {
  my_ulonglong retVal;
  GET_CLIENT(self);

  REQUIRE_CONNECTED(wrapper);
  retVal = mysql_affected_rows(wrapper->client);
  if (retVal == (my_ulonglong)-1) {
    rb_raise_mysql2_error(wrapper);
  }
  return ULL2NUM(retVal);
}

#async_resultObject

Returns the result for the last async issued query.



656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
# File 'ext/mysql2/client.c', line 656

static VALUE rb_mysql_client_async_result(VALUE self) {
  MYSQL_RES * result;
  VALUE resultObj;
  VALUE current, is_streaming;
  GET_CLIENT(self);

  /* if we're not waiting on a result, do nothing */
  if (NIL_P(wrapper->active_fiber))
    return Qnil;

  REQUIRE_CONNECTED(wrapper);
  if ((VALUE)rb_thread_call_without_gvl(nogvl_read_query_result, wrapper->client, RUBY_UBF_IO, 0) == Qfalse) {
    /* an error occurred, mark this connection inactive */
    wrapper->active_fiber = Qnil;
    rb_raise_mysql2_error(wrapper);
  }

  is_streaming = rb_hash_aref(rb_ivar_get(self, intern_current_query_options), sym_stream);
  if (is_streaming == Qtrue) {
    result = (MYSQL_RES *)rb_thread_call_without_gvl(nogvl_use_result, wrapper, RUBY_UBF_IO, 0);
  } else {
    result = (MYSQL_RES *)rb_thread_call_without_gvl(nogvl_store_result, wrapper, RUBY_UBF_IO, 0);
  }

  if (result == NULL) {
    if (mysql_errno(wrapper->client) != 0) {
      wrapper->active_fiber = Qnil;
      rb_raise_mysql2_error(wrapper);
    }
    /* no data and no error, so query was not a SELECT */
    return Qnil;
  }

  // Duplicate the options hash and put the copy in the Result object
  current = rb_hash_dup(rb_ivar_get(self, intern_current_query_options));
  (void)RB_GC_GUARD(current);
  Check_Type(current, T_HASH);
  resultObj = rb_mysql_result_to_obj(self, wrapper->encoding, current, result, Qnil);

  rb_mysql_set_server_query_flags(wrapper->client, resultObj);

  return resultObj;
}

#automatic_close=(false) ⇒ Object

Set this to false to leave the connection open after it is garbage collected. To avoid “Aborted connection” errors on the server, explicitly call close when the connection is no longer needed.



1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
# File 'ext/mysql2/client.c', line 1344

static VALUE set_automatic_close(VALUE self, VALUE value) {
  GET_CLIENT(self);
  if (RTEST(value)) {
    wrapper->automatic_close = 1;
  } else {
#ifndef _WIN32
    wrapper->automatic_close = 0;
#else
    rb_warn("Connections are always closed by garbage collector on Windows");
#endif
  }
  return value;
}

#automatic_close?Boolean

Returns:

  • (Boolean)


1330
1331
1332
1333
# File 'ext/mysql2/client.c', line 1330

static VALUE get_automatic_close(VALUE self) {
  GET_CLIENT(self);
  return wrapper->automatic_close ? Qtrue : Qfalse;
}

#closenil

Immediately disconnect from the server; normally the garbage collector will disconnect automatically when a connection is no longer needed. Explicitly closing this will free up server resources sooner than waiting for the garbage collector.

Returns:

  • (nil)


568
569
570
571
572
573
574
575
576
# File 'ext/mysql2/client.c', line 568

static VALUE rb_mysql_client_close(VALUE self) {
  GET_CLIENT(self);

  if (wrapper->client) {
    rb_thread_call_without_gvl(nogvl_close, wrapper, RUBY_UBF_IO, 0);
  }

  return Qnil;
}

#closed?Boolean

Returns:

  • (Boolean)


583
584
585
586
# File 'ext/mysql2/client.c', line 583

static VALUE rb_mysql_client_closed(VALUE self) {
  GET_CLIENT(self);
  return CONNECTED(wrapper) ? Qfalse : Qtrue;
}

#encodingObject

Returns the encoding set on the client.



1320
1321
1322
1323
# File 'ext/mysql2/client.c', line 1320

static VALUE rb_mysql_client_encoding(VALUE self) {
  GET_CLIENT(self);
  return wrapper->encoding;
}

#escape(string) ⇒ Object

Escape string so that it may be used in a SQL statement.



900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
# File 'ext/mysql2/client.c', line 900

static VALUE rb_mysql_client_real_escape(VALUE self, VALUE str) {
  unsigned char *newStr;
  VALUE rb_str;
  unsigned long newLen, oldLen;
  rb_encoding *default_internal_enc;
  rb_encoding *conn_enc;
  GET_CLIENT(self);

  REQUIRE_CONNECTED(wrapper);
  Check_Type(str, T_STRING);
  default_internal_enc = rb_default_internal_encoding();
  conn_enc = rb_to_encoding(wrapper->encoding);
  /* ensure the string is in the encoding the connection is expecting */
  str = rb_str_export_to_enc(str, conn_enc);

  oldLen = RSTRING_LEN(str);
  newStr = xmalloc(oldLen*2+1);

  newLen = mysql_real_escape_string(wrapper->client, (char *)newStr, RSTRING_PTR(str), oldLen);
  if (newLen == oldLen) {
    /* no need to return a new ruby string if nothing changed */
    if (default_internal_enc) {
      str = rb_str_export_to_enc(str, default_internal_enc);
    }
    xfree(newStr);
    return str;
  } else {
    rb_str = rb_str_new((const char*)newStr, newLen);
    rb_enc_associate(rb_str, conn_enc);
    if (default_internal_enc) {
      rb_str = rb_str_export_to_enc(rb_str, default_internal_enc);
    }
    xfree(newStr);
    return rb_str;
  }
}

#find_default_ca_pathObject

Find any default system CA paths to handle system roots by default if stricter validation is requested and no path is provide.



128
129
130
131
132
133
134
135
# File 'lib/mysql2/client.rb', line 128

def find_default_ca_path
  [
    "/etc/ssl/certs/ca-certificates.crt",
    "/etc/pki/tls/certs/ca-bundle.crt",
    "/etc/ssl/ca-bundle.pem",
    "/etc/ssl/cert.pem",
  ].find { |f| File.exist?(f) }
end

#infoObject



164
165
166
# File 'lib/mysql2/client.rb', line 164

def info
  self.class.info
end

#last_idObject

Returns the value generated for an AUTO_INCREMENT column by the previous INSERT or UPDATE statement.



1108
1109
1110
1111
1112
# File 'ext/mysql2/client.c', line 1108

static VALUE rb_mysql_client_last_id(VALUE self) {
  GET_CLIENT(self);
  REQUIRE_CONNECTED(wrapper);
  return ULL2NUM(mysql_insert_id(wrapper->client));
}

#more_results?Boolean

Returns true or false if there are more results to process.

Returns:

  • (Boolean)


1253
1254
1255
1256
1257
1258
1259
1260
# File 'ext/mysql2/client.c', line 1253

static VALUE rb_mysql_client_more_results(VALUE self)
{
  GET_CLIENT(self);
  if (mysql_more_results(wrapper->client) == 0)
    return Qfalse;
  else
    return Qtrue;
}

#next_resultObject

Fetch the next result set from the server. Returns nothing.



1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
# File 'ext/mysql2/client.c', line 1268

static VALUE rb_mysql_client_next_result(VALUE self)
{
    int ret;
    GET_CLIENT(self);
    ret = mysql_next_result(wrapper->client);
    if (ret > 0) {
      rb_raise_mysql2_error(wrapper);
      return Qfalse;
    } else if (ret == 0) {
      return Qtrue;
    } else {
      return Qfalse;
    }
}

#parse_connect_attrs(conn_attrs) ⇒ Object

Set default program_name in performance_schema.session_connect_attrs and performance_schema.session_account_connect_attrs



139
140
141
142
143
144
145
146
147
# File 'lib/mysql2/client.rb', line 139

def parse_connect_attrs(conn_attrs)
  return {} if Mysql2::Client::CONNECT_ATTRS.zero?

  conn_attrs ||= {}
  conn_attrs[:program_name] ||= $PROGRAM_NAME
  conn_attrs.each_with_object({}) do |(key, value), hash|
    hash[key.to_s] = value.to_s
  end
end

#parse_flags_array(flags, initial = 0) ⇒ Object



111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/mysql2/client.rb', line 111

def parse_flags_array(flags, initial = 0)
  flags.reduce(initial) do |memo, f|
    fneg = f.start_with?('-') ? f[1..-1] : nil
    if fneg && fneg =~ /^\w+$/ && Mysql2::Client.const_defined?(fneg)
      memo & ~ Mysql2::Client.const_get(fneg)
    elsif f && f =~ /^\w+$/ && Mysql2::Client.const_defined?(f)
      memo | Mysql2::Client.const_get(f)
    else
      warn "Unknown MySQL connection flag: '#{f}'"
      memo
    end
  end
end

#parse_ssl_mode(mode) ⇒ Object



100
101
102
103
104
105
106
107
108
109
# File 'lib/mysql2/client.rb', line 100

def parse_ssl_mode(mode)
  m = mode.to_s.upcase
  if m.start_with?('SSL_MODE_')
    return Mysql2::Client.const_get(m) if Mysql2::Client.const_defined?(m)
  else
    x = 'SSL_MODE_' + m
    return Mysql2::Client.const_get(x) if Mysql2::Client.const_defined?(x)
  end
  warn "Unknown MySQL ssl_mode flag: #{mode}"
end

#pingObject

Checks whether the connection to the server is working. If the connection has gone down and auto-reconnect is enabled an attempt to reconnect is made. If the connection is down and auto-reconnect is disabled, ping returns an error.



1221
1222
1223
1224
1225
1226
1227
1228
1229
# File 'ext/mysql2/client.c', line 1221

static VALUE rb_mysql_client_ping(VALUE self) {
  GET_CLIENT(self);

  if (!CONNECTED(wrapper)) {
    return Qfalse;
  } else {
    return (VALUE)rb_thread_call_without_gvl(nogvl_ping, wrapper->client, RUBY_UBF_IO, 0);
  }
}

#prepare(sql) ⇒ Object

Create a new prepared statement.



1520
1521
1522
1523
1524
1525
# File 'ext/mysql2/client.c', line 1520

static VALUE rb_mysql_client_prepare_statement(VALUE self, VALUE sql) {
  GET_CLIENT(self);
  REQUIRE_CONNECTED(wrapper);

  return rb_mysql_stmt_new(self, sql);
}

#query(sql, options = {}) ⇒ Object



149
150
151
152
153
# File 'lib/mysql2/client.rb', line 149

def query(sql, options = {})
  Thread.handle_interrupt(::Mysql2::Util::TIMEOUT_ERROR_NEVER) do
    _query(sql, @query_options.merge(options))
  end
end

#query_infoObject



155
156
157
158
159
160
161
162
# File 'lib/mysql2/client.rb', line 155

def query_info
  info = query_info_string
  return {} unless info

  info_hash = {}
  info.split.each_slice(2) { |s| info_hash[s[0].downcase.delete(':').to_sym] = s[1].to_i }
  info_hash
end

#query_info_stringObject



458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
# File 'ext/mysql2/client.c', line 458

static VALUE rb_mysql_info(VALUE self) {
  const char *info;
  VALUE rb_str;
  GET_CLIENT(self);

  info = mysql_info(wrapper->client);

  if (info == NULL) {
    return Qnil;
  }

  rb_str = rb_str_new2(info);
  rb_enc_associate(rb_str, rb_utf8_encoding());

  return rb_str;
}

#reconnect=(true) ⇒ Object

Enable or disable the automatic reconnect behavior of libmysql. Read dev.mysql.com/doc/refman/5.5/en/auto-reconnect.html for more information.



1365
1366
1367
# File 'ext/mysql2/client.c', line 1365

static VALUE set_reconnect(VALUE self, VALUE value) {
  return _mysql_client_options(self, MYSQL_OPT_RECONNECT, value);
}

#select_db(name) ⇒ Object

Causes the database specified by name to become the default (current) database on the connection specified by mysql.



1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
# File 'ext/mysql2/client.c', line 1191

static VALUE rb_mysql_client_select_db(VALUE self, VALUE db)
{
  struct nogvl_select_db_args args;

  GET_CLIENT(self);
  REQUIRE_CONNECTED(wrapper);

  args.mysql = wrapper->client;
  args.db = StringValueCStr(db);

  if (rb_thread_call_without_gvl(nogvl_select_db, &args, RUBY_UBF_IO, 0) == Qfalse)
    rb_raise_mysql2_error(wrapper);

  return db;
}

#server_infoObject

Returns a string that represents the server version number



1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
# File 'ext/mysql2/client.c', line 1064

static VALUE rb_mysql_client_server_info(VALUE self) {
  VALUE version, server_info;
  rb_encoding *default_internal_enc;
  rb_encoding *conn_enc;
  GET_CLIENT(self);

  REQUIRE_CONNECTED(wrapper);
  default_internal_enc = rb_default_internal_encoding();
  conn_enc = rb_to_encoding(wrapper->encoding);

  version = rb_hash_new();
  rb_hash_aset(version, sym_id, LONG2FIX(mysql_get_server_version(wrapper->client)));
  server_info = rb_str_new2(mysql_get_server_info(wrapper->client));
  rb_enc_associate(server_info, conn_enc);
  if (default_internal_enc) {
    server_info = rb_str_export_to_enc(server_info, default_internal_enc);
  }
  rb_hash_aset(version, sym_version, server_info);
  return version;
}

#session_trackObject

Returns information about changes to the session state on the server.



1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
# File 'ext/mysql2/client.c', line 1119

static VALUE rb_mysql_client_session_track(VALUE self, VALUE type) {
#ifdef CLIENT_SESSION_TRACK
  const char *data;
  size_t length;
  my_ulonglong retVal;
  GET_CLIENT(self);

  REQUIRE_CONNECTED(wrapper);
  retVal = mysql_session_track_get_first(wrapper->client, NUM2INT(type), &data, &length);
  if (retVal != 0) {
    return Qnil;
  }
  VALUE rbAry = rb_ary_new();
  VALUE rbFirst = rb_str_new(data, length);
  rb_ary_push(rbAry, rbFirst);
  while(mysql_session_track_get_next(wrapper->client, NUM2INT(type), &data, &length) == 0) {
    VALUE rbNext = rb_str_new(data, length);
    rb_ary_push(rbAry, rbNext);
  }
  return rbAry;
#else
  return Qnil;
#endif
}

#set_server_option(value) ⇒ Object

Enables or disables an option for the connection. Read dev.mysql.com/doc/refman/5.7/en/mysql-set-server-option.html for more information.



1238
1239
1240
1241
1242
1243
1244
1245
1246
# File 'ext/mysql2/client.c', line 1238

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;
  }
}

#socketObject



1097
1098
1099
# File 'ext/mysql2/client.c', line 1097

static VALUE rb_mysql_client_socket(RB_MYSQL_UNUSED VALUE self) {
  rb_raise(cMysql2Error, "Raw access to the mysql file descriptor isn't supported on Windows");
}

#ssl_cipherObject



475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
# File 'ext/mysql2/client.c', line 475

static VALUE rb_mysql_get_ssl_cipher(VALUE self)
{
  const char *cipher;
  VALUE rb_str;
  GET_CLIENT(self);

  cipher = mysql_get_ssl_cipher(wrapper->client);

  if (cipher == NULL) {
    return Qnil;
  }

  rb_str = rb_str_new2(cipher);
  rb_enc_associate(rb_str, rb_utf8_encoding());

  return rb_str;
}

#store_resultObject

Return the next result object from a query which yielded multiple result sets.



1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
# File 'ext/mysql2/client.c', line 1289

static VALUE rb_mysql_client_store_result(VALUE self)
{
  MYSQL_RES * result;
  VALUE resultObj;
  VALUE current;
  GET_CLIENT(self);

  result = (MYSQL_RES *)rb_thread_call_without_gvl(nogvl_store_result, wrapper, RUBY_UBF_IO, 0);

  if (result == NULL) {
    if (mysql_errno(wrapper->client) != 0) {
      rb_raise_mysql2_error(wrapper);
    }
    /* no data and no error, so query was not a SELECT */
    return Qnil;
  }

  // Duplicate the options hash and put the copy in the Result object
  current = rb_hash_dup(rb_ivar_get(self, intern_current_query_options));
  (void)RB_GC_GUARD(current);
  Check_Type(current, T_HASH);
  resultObj = rb_mysql_result_to_obj(self, wrapper->encoding, current, result, Qnil);

  return resultObj;
}

#thread_idObject

Returns the thread ID of the current connection.



1167
1168
1169
1170
1171
1172
1173
1174
# File 'ext/mysql2/client.c', line 1167

static VALUE rb_mysql_client_thread_id(VALUE self) {
  unsigned long retVal;
  GET_CLIENT(self);

  REQUIRE_CONNECTED(wrapper);
  retVal = mysql_thread_id(wrapper->client);
  return ULL2NUM(retVal);
}

#warning_countObject



449
450
451
452
453
454
455
456
# File 'ext/mysql2/client.c', line 449

static VALUE rb_mysql_client_warning_count(VALUE self) {
  unsigned int warning_count;
  GET_CLIENT(self);

  warning_count = mysql_warning_count(wrapper->client);

  return UINT2NUM(warning_count);
}