Class: Mysql2::Client
- Inherits:
-
Object
- Object
- Mysql2::Client
- Defined in:
- lib/mysql2/client.rb,
ext/mysql2/client.c
Direct Known Subclasses
Constant Summary collapse
- @@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 it's internal row cache for results :connect_flags => REMEMBER_OPTIONS | LONG_PASSWORD | LONG_FLAG | TRANSACTIONS | PROTOCOL_41 | SECURE_CONNECTION, :cast => true, :default_file => nil, :default_group => nil }
Instance Attribute Summary collapse
-
#query_options ⇒ Object
readonly
Returns the value of attribute query_options.
-
#read_timeout ⇒ Object
readonly
Returns the value of attribute read_timeout.
Class Method Summary collapse
- .default_query_options ⇒ Object
-
.Mysql2::Client.escape(string) ⇒ Object
Escape
string
so that it may be used in a SQL statement.
Instance Method Summary collapse
-
#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.
-
#affected_rows ⇒ Object
returns the number of rows changed, deleted, or inserted by the last statement if it was an UPDATE, DELETE, or INSERT.
-
#async_result ⇒ Object
Returns the result for the last async issued query.
-
#close ⇒ Object
Immediately disconnect from the server, normally the garbage collector will disconnect automatically when a connection is no longer needed.
-
#encoding ⇒ Object
Returns the encoding set on the client.
-
#escape(string) ⇒ Object
Escape
string
so that it may be used in a SQL statement. -
#info ⇒ Object
Returns a string that represents the client library version.
-
#initialize(opts = {}) ⇒ Client
constructor
A new instance of Client.
-
#last_id ⇒ Object
Returns the value generated for an AUTO_INCREMENT column by the previous INSERT or UPDATE statement.
-
#more_results? ⇒ Boolean
Returns true or false if there are more results to process.
-
#next_result ⇒ Object
Fetch the next result set from the server.
-
#ping ⇒ Object
Checks whether the connection to the server is working.
-
#query(sql, options = {}) ⇒ Object
Query the database with
sql
, with optionaloptions
. - #query_info ⇒ Object
- #query_info_string ⇒ Object
-
#reconnect=(true) ⇒ Object
Enable or disable the automatic reconnect behavior of libmysql.
-
#select_db(name) ⇒ Object
Causes the database specified by
name
to become the default (current) database on the connection specified by mysql. -
#server_info ⇒ Object
Returns a string that represents the server version number.
-
#socket ⇒ Object
Return the file descriptor number for this client.
-
#store_result ⇒ Object
Return the next result object from a query which yielded multiple result sets.
-
#thread_id ⇒ Object
Returns the thread ID of the current connection.
- #warning_count ⇒ Object
Constructor Details
#initialize(opts = {}) ⇒ Client
Returns a new instance of Client.
18 19 20 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 |
# File 'lib/mysql2/client.rb', line 18 def initialize(opts = {}) opts = Mysql2::Util.key_hash_as_symbols( opts ) @read_timeout = nil @query_options = @@default_query_options.dup @query_options.merge! opts initialize_ext [:reconnect, :connect_timeout, :local_infile, :read_timeout, :write_timeout, :default_file, :default_group, :secure_auth].each do |key| next unless opts.key?(key) case key when :reconnect, :local_infile, :secure_auth send(:"#{key}=", !!opts[key]) when :connect_timeout, :read_timeout, :write_timeout send(:"#{key}=", opts[key].to_i) else send(:"#{key}=", opts[key]) end end # force the encoding to utf8 self.charset_name = opts[:encoding] || 'utf8' = opts.values_at(:sslkey, :sslcert, :sslca, :sslcapath, :sslcipher) ssl_set(*) if .any? if [:user,:pass,:hostname,:dbname,:db,:sock].any?{|k| @query_options.has_key?(k) } warn "============= WARNING FROM mysql2 =============" warn "The options :user, :pass, :hostname, :dbname, :db, and :sock will be deprecated 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] flags = opts[:flags] ? opts[:flags] | @query_options[:connect_flags] : @query_options[:connect_flags] # 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? connect user, pass, host, port, database, socket, flags end |
Instance Attribute Details
#query_options ⇒ Object (readonly)
Returns the value of attribute query_options.
3 4 5 |
# File 'lib/mysql2/client.rb', line 3 def @query_options end |
#read_timeout ⇒ Object (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_options ⇒ Object
70 71 72 |
# File 'lib/mysql2/client.rb', line 70 def self. @@default_query_options 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.
232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 |
# File 'ext/mysql2/client.c', line 232
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, StringValuePtr(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);
#ifdef HAVE_RUBY_ENCODING_H
rb_enc_copy(rb_str, str);
#endif
xfree(newStr);
return rb_str;
}
}
|
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.
537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 |
# File 'ext/mysql2/client.c', line 537
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_rows ⇒ Object
returns the number of rows changed, deleted, or inserted by the last statement if it was an UPDATE, DELETE, or INSERT.
858 859 860 861 862 863 864 865 866 867 868 |
# File 'ext/mysql2/client.c', line 858
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_result ⇒ Object
Returns the result for the last async issued query.
399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 |
# File 'ext/mysql2/client.c', line 399
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_thread))
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 */
MARK_CONN_INACTIVE(self);
return rb_raise_mysql2_error(wrapper);
}
is_streaming = rb_hash_aref(rb_iv_get(self, "@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) {
MARK_CONN_INACTIVE(self);
rb_raise_mysql2_error(wrapper);
}
/* no data and no error, so query was not a SELECT */
return Qnil;
}
current = rb_hash_dup(rb_iv_get(self, "@current_query_options"));
RB_GC_GUARD(current);
Check_Type(current, T_HASH);
resultObj = rb_mysql_result_to_obj(self, wrapper->encoding, current, result);
return resultObj;
}
|
#close ⇒ Object
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.
320 321 322 323 324 325 326 327 328 |
# File 'ext/mysql2/client.c', line 320
static VALUE rb_mysql_client_close(VALUE self) {
GET_CLIENT(self);
if (wrapper->connected) {
rb_thread_call_without_gvl(nogvl_close, wrapper, RUBY_UBF_IO, 0);
}
return Qnil;
}
|
#encoding ⇒ Object
Returns the encoding set on the client.
1011 1012 1013 1014 |
# File 'ext/mysql2/client.c', line 1011
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.
645 646 647 648 649 650 651 652 653 654 655 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 |
# File 'ext/mysql2/client.c', line 645
static VALUE rb_mysql_client_real_escape(VALUE self, VALUE str) {
unsigned char *newStr;
VALUE rb_str;
unsigned long newLen, oldLen;
#ifdef HAVE_RUBY_ENCODING_H
rb_encoding *default_internal_enc;
rb_encoding *conn_enc;
#endif
GET_CLIENT(self);
REQUIRE_CONNECTED(wrapper);
Check_Type(str, T_STRING);
#ifdef HAVE_RUBY_ENCODING_H
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);
#endif
oldLen = RSTRING_LEN(str);
newStr = xmalloc(oldLen*2+1);
newLen = mysql_real_escape_string(wrapper->client, (char *)newStr, StringValuePtr(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);
#ifdef HAVE_RUBY_ENCODING_H
rb_enc_associate(rb_str, conn_enc);
if (default_internal_enc) {
rb_str = rb_str_export_to_enc(rb_str, default_internal_enc);
}
#endif
xfree(newStr);
return rb_str;
}
}
|
#info ⇒ Object
Returns a string that represents the client library version.
763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 |
# File 'ext/mysql2/client.c', line 763
static VALUE rb_mysql_client_info(VALUE self) {
VALUE version, client_info;
#ifdef HAVE_RUBY_ENCODING_H
rb_encoding *default_internal_enc;
rb_encoding *conn_enc;
GET_CLIENT(self);
#endif
version = rb_hash_new();
#ifdef HAVE_RUBY_ENCODING_H
default_internal_enc = rb_default_internal_encoding();
conn_enc = rb_to_encoding(wrapper->encoding);
#endif
rb_hash_aset(version, sym_id, LONG2NUM(mysql_get_client_version()));
client_info = rb_str_new2(mysql_get_client_info());
#ifdef HAVE_RUBY_ENCODING_H
rb_enc_associate(client_info, conn_enc);
if (default_internal_enc) {
client_info = rb_str_export_to_enc(client_info, default_internal_enc);
}
#endif
rb_hash_aset(version, sym_version, client_info);
return version;
}
|
#last_id ⇒ Object
Returns the value generated for an AUTO_INCREMENT column by the previous INSERT or UPDATE statement.
846 847 848 849 850 |
# File 'ext/mysql2/client.c', line 846
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.
944 945 946 947 948 949 950 951 |
# File 'ext/mysql2/client.c', line 944
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_result ⇒ Object
Fetch the next result set from the server. Returns nothing.
959 960 961 962 963 964 965 966 967 968 969 970 971 972 |
# File 'ext/mysql2/client.c', line 959
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;
}
}
|
#ping ⇒ Object
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.
929 930 931 932 933 934 935 936 937 |
# File 'ext/mysql2/client.c', line 929
static VALUE rb_mysql_client_ping(VALUE self) {
GET_CLIENT(self);
if (!wrapper->connected) {
return Qfalse;
} else {
return (VALUE)rb_thread_call_without_gvl(nogvl_ping, wrapper->client, RUBY_UBF_IO, 0);
}
}
|
#query(sql, options = {}) ⇒ Object
Query the database with sql
, with optional options
. For the possible options, see @@default_query_options on the Mysql2::Client class.
565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 |
# File 'ext/mysql2/client.c', line 565
static VALUE rb_mysql_client_query(int argc, VALUE * argv, VALUE self) {
#ifndef _WIN32
struct async_query_args async_args;
#endif
struct nogvl_send_query_args args;
int async = 0;
VALUE opts, current;
VALUE thread_current = rb_thread_current();
#ifdef HAVE_RUBY_ENCODING_H
rb_encoding *conn_enc;
#endif
GET_CLIENT(self);
REQUIRE_CONNECTED(wrapper);
args.mysql = wrapper->client;
current = rb_hash_dup(rb_iv_get(self, "@query_options"));
RB_GC_GUARD(current);
Check_Type(current, T_HASH);
rb_iv_set(self, "@current_query_options", current);
if (rb_scan_args(argc, argv, "11", &args.sql, &opts) == 2) {
rb_funcall(current, intern_merge_bang, 1, opts);
if (rb_hash_aref(current, sym_async) == Qtrue) {
async = 1;
}
}
Check_Type(args.sql, T_STRING);
#ifdef HAVE_RUBY_ENCODING_H
conn_enc = rb_to_encoding(wrapper->encoding);
/* ensure the string is in the encoding the connection is expecting */
args.sql = rb_str_export_to_enc(args.sql, conn_enc);
#endif
args.sql_ptr = StringValuePtr(args.sql);
args.sql_len = RSTRING_LEN(args.sql);
/* see if this connection is still waiting on a result from a previous query */
if (NIL_P(wrapper->active_thread)) {
/* mark this connection active */
wrapper->active_thread = thread_current;
} else if (wrapper->active_thread == thread_current) {
rb_raise(cMysql2Error, "This connection is still waiting for a result, try again once you have the result");
} else {
VALUE inspect = rb_inspect(wrapper->active_thread);
const char *thr = StringValueCStr(inspect);
rb_raise(cMysql2Error, "This connection is in use by: %s", thr);
RB_GC_GUARD(inspect);
}
args.wrapper = wrapper;
#ifndef _WIN32
rb_rescue2(do_send_query, (VALUE)&args, disconnect_and_raise, self, rb_eException, (VALUE)0);
if (!async) {
async_args.fd = wrapper->client->net.fd;
async_args.self = self;
rb_rescue2(do_query, (VALUE)&async_args, disconnect_and_raise, self, rb_eException, (VALUE)0);
return rb_mysql_client_async_result(self);
} else {
return Qnil;
}
#else
do_send_query(&args);
/* this will just block until the result is ready */
return rb_ensure(rb_mysql_client_async_result, self, finish_and_mark_inactive, self);
#endif
}
|
#query_info ⇒ Object
74 75 76 77 78 79 80 |
# File 'lib/mysql2/client.rb', line 74 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_string ⇒ Object
266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 |
# File 'ext/mysql2/client.c', line 266
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);
#ifdef HAVE_RUBY_ENCODING_H
rb_enc_associate(rb_str, rb_utf8_encoding());
#endif
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.
1024 1025 1026 |
# File 'ext/mysql2/client.c', line 1024
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.
899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 |
# File 'ext/mysql2/client.c', line 899
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 = StringValuePtr(db);
if (rb_thread_call_without_gvl(nogvl_select_db, &args, RUBY_UBF_IO, 0) == Qfalse)
rb_raise_mysql2_error(wrapper);
return db;
}
|
#server_info ⇒ Object
Returns a string that represents the server version number
794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 |
# File 'ext/mysql2/client.c', line 794
static VALUE rb_mysql_client_server_info(VALUE self) {
VALUE version, server_info;
#ifdef HAVE_RUBY_ENCODING_H
rb_encoding *default_internal_enc;
rb_encoding *conn_enc;
#endif
GET_CLIENT(self);
REQUIRE_CONNECTED(wrapper);
#ifdef HAVE_RUBY_ENCODING_H
default_internal_enc = rb_default_internal_encoding();
conn_enc = rb_to_encoding(wrapper->encoding);
#endif
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));
#ifdef HAVE_RUBY_ENCODING_H
rb_enc_associate(server_info, conn_enc);
if (default_internal_enc) {
server_info = rb_str_export_to_enc(server_info, default_internal_enc);
}
#endif
rb_hash_aset(version, sym_version, server_info);
return version;
}
|
#socket ⇒ Object
Return the file descriptor number for this client.
826 827 828 829 830 831 832 833 834 835 836 837 838 |
# File 'ext/mysql2/client.c', line 826
static VALUE rb_mysql_client_socket(VALUE self) {
GET_CLIENT(self);
#ifndef _WIN32
{
int fd_set_fd;
REQUIRE_CONNECTED(wrapper);
fd_set_fd = wrapper->client->net.fd;
return INT2NUM(fd_set_fd);
}
#else
rb_raise(cMysql2Error, "Raw access to the mysql file descriptor isn't supported on Windows");
#endif
}
|
#store_result ⇒ Object
Return the next result object from a query which yielded multiple result sets.
980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 |
# File 'ext/mysql2/client.c', line 980
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;
}
current = rb_hash_dup(rb_iv_get(self, "@current_query_options"));
RB_GC_GUARD(current);
Check_Type(current, T_HASH);
resultObj = rb_mysql_result_to_obj(self, wrapper->encoding, current, result);
return resultObj;
}
|
#thread_id ⇒ Object
Returns the thread ID of the current connection.
875 876 877 878 879 880 881 882 |
# File 'ext/mysql2/client.c', line 875
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_count ⇒ Object
257 258 259 260 261 262 263 264 |
# File 'ext/mysql2/client.c', line 257
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);
}
|