mysql2 0.4.10 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +23 -6
- data/examples/eventmachine.rb +0 -2
- data/examples/threaded.rb +2 -4
- data/ext/mysql2/client.c +100 -51
- data/ext/mysql2/client.h +1 -39
- data/ext/mysql2/extconf.rb +23 -20
- data/ext/mysql2/mysql2_ext.c +2 -1
- data/ext/mysql2/mysql2_ext.h +8 -4
- data/ext/mysql2/result.c +15 -75
- data/ext/mysql2/result.h +2 -3
- data/ext/mysql2/statement.c +78 -71
- data/ext/mysql2/statement.h +0 -2
- data/ext/mysql2/wait_for_single_fd.h +2 -1
- data/lib/mysql2.rb +14 -15
- data/lib/mysql2/client.rb +33 -27
- data/lib/mysql2/em.rb +2 -4
- data/lib/mysql2/error.rb +49 -20
- data/lib/mysql2/result.rb +2 -0
- data/lib/mysql2/statement.rb +3 -9
- data/lib/mysql2/version.rb +1 -1
- data/spec/em/em_spec.rb +5 -6
- data/spec/mysql2/client_spec.rb +206 -173
- data/spec/mysql2/error_spec.rb +0 -4
- data/spec/mysql2/result_spec.rb +94 -154
- data/spec/mysql2/statement_spec.rb +105 -169
- data/spec/spec_helper.rb +6 -2
- data/support/mysql_enc_to_ruby.rb +2 -2
- data/support/ruby_enc_to_mysql.rb +5 -5
- metadata +6 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a6bf072c2ecc5ecb841ac10b4f0d7af76143e1a0
|
4
|
+
data.tar.gz: 3f92fd936bed501a93ebf7d32848b89059989310
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9efb2aa011d4e0f0fd5c6bb1a088164686cb515f78c97d20121a9810f6b4bef9f9be07f7deebf4100153a096b3e3a319f6d7ebabe1b53c1841970a0617729c0c
|
7
|
+
data.tar.gz: 3d15ed281a359a7fb8d5815769c2d6555066796cf9f3abf55ff39375a847d186ba32508820e850f09dfb34e3a3560521bc0c151355bcaa9295c3669b4c1e089f
|
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
|
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"].
|
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,11 @@ 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.
|
180
|
+
|
181
|
+
Be sure to read about the known limitations of prepared statements at
|
182
|
+
https://dev.mysql.com/doc/refman/5.6/en/c-api-prepared-statement-problems.html
|
179
183
|
|
180
184
|
``` ruby
|
181
185
|
statement = @client.prepare("SELECT * FROM users WHERE login_count = ?")
|
@@ -184,6 +188,9 @@ result2 = statement.execute(2)
|
|
184
188
|
|
185
189
|
statement = @client.prepare("SELECT * FROM users WHERE last_login >= ? AND location LIKE ?")
|
186
190
|
result = statement.execute(1, "CA")
|
191
|
+
|
192
|
+
statement = @client.prepare("SELECT * FROM users WHERE last_login >= ? AND location LIKE ?")
|
193
|
+
result = statement.execute(1, "CA", :as => :array)
|
187
194
|
```
|
188
195
|
|
189
196
|
## Connection options
|
@@ -203,6 +210,7 @@ Mysql2::Client.new(
|
|
203
210
|
:read_timeout = seconds,
|
204
211
|
:write_timeout = seconds,
|
205
212
|
:connect_timeout = seconds,
|
213
|
+
:connect_attrs = {:program_name => $PROGRAM_NAME, ...},
|
206
214
|
:reconnect = true/false,
|
207
215
|
:local_infile = true/false,
|
208
216
|
:secure_auth = true/false,
|
@@ -381,6 +389,15 @@ c = Mysql2::Client.new
|
|
381
389
|
c.query(sql, :symbolize_keys => true)
|
382
390
|
```
|
383
391
|
|
392
|
+
or
|
393
|
+
|
394
|
+
``` ruby
|
395
|
+
# this will set the options for the Mysql2::Result instance returned from the #execute method
|
396
|
+
c = Mysql2::Client.new
|
397
|
+
s = c.prepare(sql)
|
398
|
+
s.execute(arg1, args2, :symbolize_keys => true)
|
399
|
+
```
|
400
|
+
|
384
401
|
## Result types
|
385
402
|
|
386
403
|
### Array of Arrays
|
@@ -509,18 +526,18 @@ As for field values themselves, I'm workin on it - but expect that soon.
|
|
509
526
|
|
510
527
|
This gem is tested with the following Ruby versions on Linux and Mac OS X:
|
511
528
|
|
512
|
-
* Ruby MRI
|
513
|
-
* Ruby Enterprise Edition (based on MRI 1.8.7)
|
529
|
+
* Ruby MRI 2.0.0, 2.1.x, 2.2.x, 2.3.x, 2.4.x, 2.5.x, 2.6.x
|
514
530
|
* Rubinius 2.x and 3.x do work but may fail under some workloads
|
515
531
|
|
516
532
|
This gem is tested with the following MySQL and MariaDB versions:
|
517
533
|
|
518
534
|
* MySQL 5.5, 5.6, 5.7, 8.0
|
519
535
|
* MySQL Connector/C 6.0 and 6.1 (primarily on Windows)
|
520
|
-
* MariaDB 5.5, 10.0, 10.1
|
536
|
+
* MariaDB 5.5, 10.0, 10.1, 10.2, 10.3
|
521
537
|
|
522
538
|
### Ruby on Rails / Active Record
|
523
539
|
|
540
|
+
* mysql2 0.5.x works with Rails / Active Record 5.0.7, 5.1.6, and higher.
|
524
541
|
* mysql2 0.4.x works with Rails / Active Record 4.2.5 - 5.0 and higher.
|
525
542
|
* mysql2 0.3.x works with Rails / Active Record 3.1, 3.2, 4.x, 5.0.
|
526
543
|
* mysql2 0.2.x works with Rails / Active Record 2.3 - 3.0.
|
data/examples/eventmachine.rb
CHANGED
data/examples/threaded.rb
CHANGED
@@ -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
|
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(:
|
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)
|
data/ext/mysql2/client.c
CHANGED
@@ -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
|
-
|
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
|
-
|
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
|
-
|
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(
|
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
|
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
|
-
|
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",
|
1446
|
-
rb_define_private_method(cMysql2Client, "_query",
|
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
|
+
}
|