Skip to content

Commit

Permalink
Merge pull request #2 from skytap/merge-from-brianmario-2
Browse files Browse the repository at this point in the history
Merge remote-tracking branch 'brianmario/master'
  • Loading branch information
manlon authored Jul 12, 2018
2 parents c505ea5 + 8399968 commit 68092a2
Show file tree
Hide file tree
Showing 17 changed files with 200 additions and 66 deletions.
3 changes: 0 additions & 3 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,6 @@ Layout/CaseIndentation:
Layout/IndentHash:
EnforcedStyle: consistent

Layout/IndentHeredoc:
EnforcedStyle: powerpack

Lint/EndAlignment:
EnforcedStyleAlignWith: variable

Expand Down
11 changes: 10 additions & 1 deletion .rubocop_todo.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,23 @@
# Note that changes in the inspected code, or installation of new
# versions of RuboCop, may require this file to be generated again.

# Offense count: 3
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, SupportedStyles.
# SupportedStyles: auto_detection, squiggly, active_support, powerpack, unindent
Layout/IndentHeredoc:
Exclude:
- 'support/ruby_enc_to_mysql.rb'
- 'tasks/compile.rake'

# Offense count: 2
Metrics/AbcSize:
Max: 90

# Offense count: 31
# Configuration parameters: CountComments, ExcludedMethods.
Metrics/BlockLength:
Max: 825
Max: 850

# Offense count: 1
# Configuration parameters: CountBlocks.
Expand Down
9 changes: 8 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ bundler_args: --without benchmarks development
# Pin Rubygems to a working version. Sometimes it breaks upstream. Update now and then.
before_install:
- gem --version
- gem update --system 2.7.3
- gem update --system 2.7.6 --quiet
- gem update bundler
- gem --version
- bash .travis_setup.sh
Expand All @@ -18,6 +18,7 @@ addons:
- mysql-client-core-5.6
- mysql-client-5.6
rvm:
- 2.6
- 2.5
- 2.4
- 2.3
Expand Down Expand Up @@ -45,6 +46,12 @@ matrix:
mariadb: 10.2
hosts:
- mysql2gem.example.com
- rvm: 2.4
env: DB=mariadb10.3
addons:
mariadb: 10.3
hosts:
- mysql2gem.example.com
- rvm: 2.4
env: DB=mysql55
addons:
Expand Down
1 change: 1 addition & 0 deletions .travis_mysql55.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ set -eux
apt-get purge -qq '^mysql*' '^libmysql*'
rm -fr /etc/mysql
rm -fr /var/lib/mysql
apt-get update -qq
apt-get install -qq mysql-server-5.5 mysql-client-core-5.5 mysql-client-5.5 libmysqlclient-dev
19 changes: 12 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,11 @@ To see line numbers in backtraces, declare these environment variables

### Linux and other Unixes

You may need to install a package such as `libmysqlclient-dev` or `mysql-devel`;
refer to your distribution's package guide to find the particular package.
The most common issue we see is a user who has the library file `libmysqlclient.so` but is
missing the header file `mysql.h` -- double check that you have the _-dev_ packages installed.
You may need to install a package such as `libmysqlclient-dev`, `mysql-devel`,
or `default-libmysqlclient-dev`; refer to your distribution's package guide to
find the particular package. The most common issue we see is a user who has
the library file `libmysqlclient.so` but is missing the header file `mysql.h`
-- double check that you have the _-dev_ packages installed.

### Mac OS X

Expand Down Expand Up @@ -138,7 +139,7 @@ results.each do |row|
# conveniently, row is a hash
# the keys are the fields, as you'd expect
# the values are pre-built ruby primitives mapped from their corresponding field types in MySQL
puts row["id"] # row["id"].class == Fixnum
puts row["id"] # row["id"].is_a? Integer
if row["dne"] # non-existant hash entry is nil
puts row["dne"]
end
Expand Down Expand Up @@ -178,6 +179,9 @@ Pass your arguments to the execute method in the same number and order as the
question marks in the statement. Query options can be passed as keyword arguments
to the execute method.

Be sure to read about the known limitations of prepared statements at
https://dev.mysql.com/doc/refman/5.6/en/c-api-prepared-statement-problems.html

``` ruby
statement = @client.prepare("SELECT * FROM users WHERE login_count = ?")
result1 = statement.execute(1)
Expand Down Expand Up @@ -523,17 +527,18 @@ As for field values themselves, I'm workin on it - but expect that soon.

This gem is tested with the following Ruby versions on Linux and Mac OS X:

* Ruby MRI 2.0.0, 2.1.x, 2.2.x, 2.3.x, 2.4.x, 2.5.x
* Ruby MRI 2.0.0, 2.1.x, 2.2.x, 2.3.x, 2.4.x, 2.5.x, 2.6.x
* Rubinius 2.x and 3.x do work but may fail under some workloads

This gem is tested with the following MySQL and MariaDB versions:

* MySQL 5.5, 5.6, 5.7, 8.0
* MySQL Connector/C 6.0 and 6.1 (primarily on Windows)
* MariaDB 5.5, 10.0, 10.1, 10.2
* MariaDB 5.5, 10.0, 10.1, 10.2, 10.3

### Ruby on Rails / Active Record

* mysql2 0.5.x works with Rails / Active Record 5.0.7, 5.1.6, and higher.
* mysql2 0.4.x works with Rails / Active Record 4.2.5 - 5.0 and higher.
* mysql2 0.3.x works with Rails / Active Record 3.1, 3.2, 4.x, 5.0.
* mysql2 0.2.x works with Rails / Active Record 2.3 - 3.0.
Expand Down
34 changes: 31 additions & 3 deletions ext/mysql2/client.c
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ static VALUE rb_set_ssl_mode_option(VALUE self, VALUE setting) {
int val = NUM2INT( setting );
if (version >= 50703 && version < 50711) {
if (val == SSL_MODE_DISABLED || val == SSL_MODE_REQUIRED) {
bool b = ( val == SSL_MODE_REQUIRED );
my_bool b = ( val == SSL_MODE_REQUIRED );
int result = mysql_options( wrapper->client, MYSQL_OPT_SSL_ENFORCE, &b );
return INT2NUM(result);
} else {
Expand Down Expand Up @@ -526,7 +526,7 @@ static VALUE do_send_query(void *args) {
*/
static void *nogvl_read_query_result(void *ptr) {
MYSQL * client = ptr;
bool res = mysql_read_query_result(client);
my_bool res = mysql_read_query_result(client);

return (void *)(res == 0 ? Qtrue : Qfalse);
}
Expand Down Expand Up @@ -846,7 +846,7 @@ static VALUE _mysql_client_options(VALUE self, int opt, VALUE value) {
const void *retval = NULL;
unsigned int intval = 0;
const char * charval = NULL;
bool boolval;
my_bool boolval;

GET_CLIENT(self);

Expand Down Expand Up @@ -1098,6 +1098,23 @@ static VALUE rb_mysql_client_ping(VALUE self) {
}
}

/* call-seq:
* client.set_server_option(value)
*
* Enables or disables an option for the connection.
* Read https://dev.mysql.com/doc/refman/5.7/en/mysql-set-server-option.html
* for more information.
*/
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;
}
}

/* call-seq:
* client.more_results?
*
Expand Down Expand Up @@ -1399,6 +1416,7 @@ void init_mysql2_client() {
rb_define_method(cMysql2Client, "thread_id", rb_mysql_client_thread_id, 0);
rb_define_method(cMysql2Client, "ping", rb_mysql_client_ping, 0);
rb_define_method(cMysql2Client, "select_db", rb_mysql_client_select_db, 1);
rb_define_method(cMysql2Client, "set_server_option", rb_mysql_client_set_server_option, 1);
rb_define_method(cMysql2Client, "more_results?", rb_mysql_client_more_results, 0);
rb_define_method(cMysql2Client, "next_result", rb_mysql_client_next_result, 0);
rb_define_method(cMysql2Client, "store_result", rb_mysql_client_store_result, 0);
Expand Down Expand Up @@ -1528,6 +1546,16 @@ void init_mysql2_client() {
rb_const_set(cMysql2Client, rb_intern("SECURE_CONNECTION"), LONG2NUM(0));
#endif

#ifdef HAVE_CONST_MYSQL_OPTION_MULTI_STATEMENTS_ON
rb_const_set(cMysql2Client, rb_intern("OPTION_MULTI_STATEMENTS_ON"),
LONG2NUM(MYSQL_OPTION_MULTI_STATEMENTS_ON));
#endif

#ifdef HAVE_CONST_MYSQL_OPTION_MULTI_STATEMENTS_OFF
rb_const_set(cMysql2Client, rb_intern("OPTION_MULTI_STATEMENTS_OFF"),
LONG2NUM(MYSQL_OPTION_MULTI_STATEMENTS_OFF));
#endif

#ifdef CLIENT_MULTI_STATEMENTS
rb_const_set(cMysql2Client, rb_intern("MULTI_STATEMENTS"),
LONG2NUM(CLIENT_MULTI_STATEMENTS));
Expand Down
8 changes: 8 additions & 0 deletions ext/mysql2/extconf.rb
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ def add_ssl_defines(header)
abort "-----\nCannot find library dir(s) #{lib}\n-----" unless lib && lib.split(File::PATH_SEPARATOR).any? { |dir| File.directory?(dir) }
warn "-----\nUsing --with-mysql-dir=#{File.dirname inc}\n-----"
rpath_dir = lib
have_library('mysqlclient')
elsif (mc = (with_config('mysql-config') || Dir[GLOB].first))
# If the user has provided a --with-mysql-config argument, we must respect it or fail.
# If the user gave --with-mysql-config with no argument means we should try to find it.
Expand Down Expand Up @@ -105,11 +106,18 @@ def add_ssl_defines(header)
add_ssl_defines(mysql_h)
have_struct_member('MYSQL', 'net.vio', mysql_h)
have_struct_member('MYSQL', 'net.pvio', mysql_h)

# These constants are actually enums, so they cannot be detected by #ifdef in C code.
have_const('MYSQL_ENABLE_CLEARTEXT_PLUGIN', mysql_h)
have_const('SERVER_QUERY_NO_GOOD_INDEX_USED', mysql_h)
have_const('SERVER_QUERY_NO_INDEX_USED', mysql_h)
have_const('SERVER_QUERY_WAS_SLOW', mysql_h)
have_const('MYSQL_OPTION_MULTI_STATEMENTS_ON', mysql_h)
have_const('MYSQL_OPTION_MULTI_STATEMENTS_OFF', mysql_h)

# my_bool is replaced by C99 bool in MySQL 8.0, but we want
# to retain compatibility with the typedef in earlier MySQLs.
have_type('my_bool', mysql_h)

# This is our wishlist. We use whichever flags work on the host.
# -Wall and -Wextra are included by default.
Expand Down
8 changes: 8 additions & 0 deletions ext/mysql2/mysql2_ext.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,14 @@ void Init_mysql2(void);
#define RB_MYSQL_UNUSED
#endif

/* MySQL 8.0 replaces my_bool with C99 bool. Earlier versions of MySQL had
* a typedef to char. Gem users reported failures on big endian systems when
* using C99 bool types with older MySQLs due to mismatched behavior. */
#ifndef HAVE_TYPE_MY_BOOL
#include <stdbool.h>
typedef bool my_bool;
#endif

#include <client.h>
#include <statement.h>
#include <result.h>
Expand Down
10 changes: 10 additions & 0 deletions ext/mysql2/mysql_enc_to_ruby.h
Original file line number Diff line number Diff line change
Expand Up @@ -245,5 +245,15 @@ static const char *mysql2_mysql_enc_to_rb[] = {
"UTF-8",
"UTF-8",
"UTF-8",
"UTF-8",
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
"UTF-8"
};

#define CHARSETNR_SIZE (sizeof(mysql2_mysql_enc_to_rb)/sizeof(mysql2_mysql_enc_to_rb[0]))
7 changes: 4 additions & 3 deletions ext/mysql2/result.c
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,8 @@ static VALUE mysql2_set_field_string_encoding(VALUE val, MYSQL_FIELD field, rb_e
const char *enc_name;
int enc_index;

enc_name = mysql2_mysql_enc_to_rb[field.charsetnr-1];
enc_name = (field.charsetnr-1 < CHARSETNR_SIZE) ? mysql2_mysql_enc_to_rb[field.charsetnr-1] : NULL;

if (enc_name != NULL) {
/* use the field encoding we were able to match */
enc_index = rb_enc_find_index(enc_name);
Expand Down Expand Up @@ -218,8 +219,8 @@ static void rb_mysql_result_alloc_result_buffers(VALUE self, MYSQL_FIELD *fields
if (wrapper->result_buffers != NULL) return;

wrapper->result_buffers = xcalloc(wrapper->numberOfFields, sizeof(MYSQL_BIND));
wrapper->is_null = xcalloc(wrapper->numberOfFields, sizeof(bool));
wrapper->error = xcalloc(wrapper->numberOfFields, sizeof(bool));
wrapper->is_null = xcalloc(wrapper->numberOfFields, sizeof(my_bool));
wrapper->error = xcalloc(wrapper->numberOfFields, sizeof(my_bool));
wrapper->length = xcalloc(wrapper->numberOfFields, sizeof(unsigned long));

for (i = 0; i < wrapper->numberOfFields; i++) {
Expand Down
5 changes: 2 additions & 3 deletions ext/mysql2/result.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#ifndef MYSQL2_RESULT_H
#define MYSQL2_RESULT_H
#include <stdbool.h>

void init_mysql2_result(void);
VALUE rb_mysql_result_to_obj(VALUE client, VALUE encoding, VALUE options, MYSQL_RES *r, VALUE statement);
Expand All @@ -22,8 +21,8 @@ typedef struct {
mysql_client_wrapper *client_wrapper;
/* statement result bind buffers */
MYSQL_BIND *result_buffers;
bool *is_null;
bool *error;
my_bool *is_null;
my_bool *error;
unsigned long *length;
} mysql2_result_wrapper;

Expand Down
Loading

0 comments on commit 68092a2

Please sign in to comment.