diff --git a/.travis.yml b/.travis.yml index f1e95f32d..c7b315e86 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,27 +1,31 @@ +sudo: required language: ruby bundler_args: --without benchmarks +addons: + homebrew: + packages: + - mysql script: - bundle exec rake spec -# Temporary workaround for broken Rubygems on Travis before_install: - - gem update --system 2.4.8 - gem --version - | - bash -c " # Install MySQL 5.7 if DB=mysql57 - if [[ x$DB =~ mysql57 ]]; then - sudo bash .travis_mysql57.sh + bash -c " # Install MySQL if DB=mysql* + if [[ x$DB =~ xmysql ]]; then + sudo bash .travis_mysql.sh '$DB' fi " - | - bash -c " # Install MariaDB if DB=mariadb + bash -c " # Install MariaDB if DB=mariadb* if [[ x$DB =~ xmariadb ]]; then sudo bash .travis_mariadb.sh '$DB' fi " - | - bash -c " # Install MySQL is OS=darwin + bash -c " # Install MySQL if OS=darwin if [[ x$OSTYPE =~ ^xdarwin ]]; then - brew install mysql + # Disable SSL due to missing certs + echo ssl = 0 >> /usr/local/etc/my.cnf mysql.server start fi " @@ -35,29 +39,32 @@ before_install: - mysqld --version - mysql -u root -e "CREATE DATABASE IF NOT EXISTS test" - mysql -u root -e "CREATE USER '$USER'@'localhost'" || true -os: - - linux +os: linux +dist: trusty rvm: - 1.8.7 - 1.9.3 - 2.0.0 - 2.1 - 2.2 - - 2.3.1 + - 2.3 - ree matrix: + fast_finish: true allow_failures: - - env: DB=mysql57 - - rvm: rbx-2 - os: osx + - rvm: ree include: - rvm: 2.0.0 env: DB=mariadb55 - rvm: 2.0.0 env: DB=mariadb10 + - rvm: 2.0.0 + env: DB=mysql55 - rvm: 2.0.0 env: DB=mysql57 - - rvm: rbx-2 - env: RBXOPT=-Xgc.honor_start=true - rvm: 2.0.0 + dist: xenial + env: DB=mysql8 + - rvm: 2.3 os: osx diff --git a/.travis_mariadb.sh b/.travis_mariadb.sh index 652804382..172b570f6 100644 --- a/.travis_mariadb.sh +++ b/.travis_mariadb.sh @@ -1,14 +1,21 @@ #!/bin/sh +set -e + +service mysql status && service mysql stop -service mysql stop apt-get purge '^mysql*' 'libmysql*' -apt-get install python-software-properties +apt-get autoclean + +rm -rf /etc/mysql /var/lib/mysql /var/log/mysql + apt-key adv --recv-keys --keyserver hkp://keyserver.ubuntu.com:80 0xcbcb082a1bb943db +. /etc/lsb-release + if [[ x$1 = xmariadb55 ]]; then - add-apt-repository 'deb http://ftp.osuosl.org/pub/mariadb/repo/5.5/ubuntu precise main' + echo "deb http://ftp.osuosl.org/pub/mariadb/repo/5.5/ubuntu $DISTRIB_CODENAME main" >> /etc/apt/sources.list elif [[ x$1 = xmariadb10 ]]; then - add-apt-repository 'deb http://ftp.osuosl.org/pub/mariadb/repo/10.0/ubuntu precise main' + echo "deb http://ftp.osuosl.org/pub/mariadb/repo/10.3/ubuntu $DISTRIB_CODENAME main" >> /etc/apt/sources.list fi apt-get update diff --git a/.travis_mysql.sh b/.travis_mysql.sh new file mode 100644 index 000000000..aef13880f --- /dev/null +++ b/.travis_mysql.sh @@ -0,0 +1,27 @@ +#!/bin/sh +set -e + +service mysql status && service mysql stop + +apt-get purge '^mysql*' 'libmysql*' +apt-get autoclean + +rm -rf /etc/mysql /var/lib/mysql /var/log/mysql + +apt-key adv --recv-keys --keyserver hkp://keyserver.ubuntu.com:80 0x8C718D3B5072E1F5 + +. /etc/lsb-release + +if [[ x$1 = xmysql56 ]]; then + echo "deb http://repo.mysql.com/apt/ubuntu $DISTRIB_CODENAME mysql-5.6" >> /etc/apt/sources.list +elif [[ x$1 = xmysql57 ]]; then + echo "deb http://repo.mysql.com/apt/ubuntu $DISTRIB_CODENAME mysql-5.7" >> /etc/apt/sources.list +elif [[ x$1 = xmysql8 ]]; then + echo "deb http://repo.mysql.com/apt/ubuntu $DISTRIB_CODENAME mysql-8.0" >> /etc/apt/sources.list +fi + +apt-get update +apt-get -o Dpkg::Options::=--force-confdef -o Dpkg::Options::=--force-confold -y install mysql-server libmysqlclient-dev + +# disable socket auth on mysql-community-server +mysql -u root -e "USE mysql; UPDATE user SET plugin='mysql_native_password' WHERE User='root'; FLUSH PRIVILEGES;" diff --git a/.travis_mysql57.sh b/.travis_mysql57.sh deleted file mode 100644 index a9f87dda8..000000000 --- a/.travis_mysql57.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/sh - -service mysql stop - -apt-get purge '^mysql*' 'libmysql*' -apt-get autoclean - -rm -rf /var/lib/mysql -rm -rf /var/log/mysql - -apt-get install python-software-properties -apt-key adv --recv-keys --keyserver hkp://keyserver.ubuntu.com:80 0x8C718D3B5072E1F5 -add-apt-repository 'deb http://repo.mysql.com/apt/ubuntu/ precise mysql-5.7-dmr' - -apt-get update -apt-get -o Dpkg::Options::=--force-confdef -o Dpkg::Options::=--force-confold -y install mysql-server libmysqlclient-dev diff --git a/.travis_ssl.sh b/.travis_ssl.sh index 4a3f52bb2..d120b3b62 100644 --- a/.travis_ssl.sh +++ b/.travis_ssl.sh @@ -37,16 +37,16 @@ commonName_default = ca_name " >> ca.cnf echo " -commonName_default = cert_name +commonName_default = localhost " >> cert.cnf # Generate a set of certificates openssl genrsa -out ca-key.pem 2048 -openssl req -new -x509 -nodes -days 1000 -key ca-key.pem -out ca-cert.pem -batch -config ca.cnf -openssl req -newkey rsa:2048 -days 1000 -nodes -keyout pkcs8-server-key.pem -out server-req.pem -batch -config cert.cnf -openssl x509 -req -in server-req.pem -days 1000 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 -out server-cert.pem -openssl req -newkey rsa:2048 -days 1000 -nodes -keyout pkcs8-client-key.pem -out client-req.pem -batch -config cert.cnf -openssl x509 -req -in client-req.pem -days 1000 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 -out client-cert.pem +openssl req -sha1 -new -x509 -nodes -days 1000 -key ca-key.pem -out ca-cert.pem -batch -config ca.cnf +openssl req -sha1 -newkey rsa:2048 -days 1000 -nodes -keyout pkcs8-server-key.pem -out server-req.pem -batch -config cert.cnf +openssl x509 -sha1 -req -in server-req.pem -days 1000 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 -out server-cert.pem +openssl req -sha1 -newkey rsa:2048 -days 1000 -nodes -keyout pkcs8-client-key.pem -out client-req.pem -batch -config cert.cnf +openssl x509 -sha1 -req -in client-req.pem -days 1000 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 -out client-cert.pem # Convert format from PKCS#8 to PKCS#1 openssl rsa -in pkcs8-server-key.pem -out server-key.pem @@ -61,4 +61,4 @@ ssl-key=/etc/mysql/server-key.pem " >> my.cnf # Wait until the minute moves to ensure that the SSL cert is within its valid range -ruby -e 'start = Time.now.min; while Time.now.min == start; sleep 2; end' +# ruby -e 'start = Time.now.min; while Time.now.min == start; sleep 2; end' diff --git a/ext/mysql2/client.c b/ext/mysql2/client.c index 5d75304b4..9b0057e66 100644 --- a/ext/mysql2/client.c +++ b/ext/mysql2/client.c @@ -794,10 +794,12 @@ static VALUE _mysql_client_options(VALUE self, int opt, VALUE value) { retval = &boolval; break; +#if defined(MYSQL_SECURE_AUTH) case MYSQL_SECURE_AUTH: boolval = (value == Qfalse ? 0 : 1); retval = &boolval; break; +#endif case MYSQL_READ_DEFAULT_FILE: charval = (const char *)StringValueCStr(value); @@ -1182,7 +1184,12 @@ static VALUE set_ssl_options(VALUE self, VALUE key, VALUE cert, VALUE ca, VALUE } static VALUE set_secure_auth(VALUE self, VALUE value) { +/* This option was deprecated in MySQL 5.x and removed in MySQL 8.0 */ +#if defined(MYSQL_SECURE_AUTH) return _mysql_client_options(self, MYSQL_SECURE_AUTH, value); +#else + return Qfalse; +#endif } static VALUE set_read_default_file(VALUE self, VALUE value) { @@ -1297,6 +1304,10 @@ void init_mysql2_client() { #ifdef CLIENT_LONG_PASSWORD rb_const_set(cMysql2Client, rb_intern("LONG_PASSWORD"), LONG2NUM(CLIENT_LONG_PASSWORD)); +#else + /* HACK because MariaDB 10.2 no longer defines this constant, + * but we're using it in our default connection flags. */ + rb_const_set(cMysql2Client, rb_intern("LONG_PASSWORD"), INT2NUM(0)); #endif #ifdef CLIENT_FOUND_ROWS diff --git a/ext/mysql2/extconf.rb b/ext/mysql2/extconf.rb index 8590da386..dd254905c 100644 --- a/ext/mysql2/extconf.rb +++ b/ext/mysql2/extconf.rb @@ -104,6 +104,12 @@ def asplode lib asplode h unless have_header h end +mysql_h = [prefix, 'mysql.h'].compact.join('/') + +# 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) + # These gcc style flags are also supported by clang and xcode compilers, # so we'll use a does-it-work test instead of an is-it-gcc test. gcc_flags = ' -Wall -funroll-loops' diff --git a/ext/mysql2/mysql2_ext.h b/ext/mysql2/mysql2_ext.h index d6d5fd626..6350c27d9 100644 --- a/ext/mysql2/mysql2_ext.h +++ b/ext/mysql2/mysql2_ext.h @@ -1,6 +1,14 @@ #ifndef MYSQL2_EXT #define MYSQL2_EXT +/* 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 +typedef bool my_bool; +#endif + /* tell rbx not to use it's caching compat layer by doing this we're making a promise to RBX that we'll never modify the pointers we get back from RSTRING_PTR */ diff --git a/ext/mysql2/mysql_enc_name_to_ruby.h b/ext/mysql2/mysql_enc_name_to_ruby.h index dfabeef1f..b50146d36 100644 --- a/ext/mysql2/mysql_enc_name_to_ruby.h +++ b/ext/mysql2/mysql_enc_name_to_ruby.h @@ -1,4 +1,4 @@ -/* C code produced by gperf version 3.0.3 */ +/* C code produced by gperf version 3.0.4 */ /* Command-line: gperf */ /* Computed positions: -k'1,3,$' */ @@ -30,7 +30,7 @@ error "gperf generated tables don't work with this execution character set. Plea #endif struct mysql2_mysql_enc_name_to_rb_map { const char *name; const char *rb_name; }; -/* maximum key range = 66, duplicates = 0 */ +/* maximum key range = 71, duplicates = 0 */ #ifdef __GNUC__ __inline @@ -46,39 +46,39 @@ mysql2_mysql_enc_name_to_rb_hash (str, len) { static const unsigned char asso_values[] = { - 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, 40, 5, - 0, 69, 0, 40, 25, 20, 10, 55, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 35, 5, 0, - 10, 0, 20, 0, 5, 5, 69, 0, 10, 15, - 0, 0, 69, 69, 25, 5, 5, 0, 69, 30, - 69, 0, 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69 + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 15, 5, + 0, 74, 5, 25, 40, 10, 20, 50, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 40, 5, 0, + 15, 10, 0, 0, 0, 5, 74, 0, 25, 5, + 0, 5, 74, 74, 20, 5, 5, 0, 74, 45, + 74, 0, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74 }; return len + asso_values[(unsigned char)str[2]] + asso_values[(unsigned char)str[0]] + asso_values[(unsigned char)str[len - 1]]; } #ifdef __GNUC__ __inline -#ifdef __GNUC_STDC_INLINE__ +#if defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__ __attribute__ ((__gnu_inline__)) #endif #endif @@ -89,11 +89,11 @@ mysql2_mysql_enc_name_to_rb (str, len) { enum { - TOTAL_KEYWORDS = 39, + TOTAL_KEYWORDS = 41, MIN_WORD_LENGTH = 3, MAX_WORD_LENGTH = 8, MIN_HASH_VALUE = 3, - MAX_HASH_VALUE = 68 + MAX_HASH_VALUE = 73 }; static const struct mysql2_mysql_enc_name_to_rb_map wordlist[] = @@ -101,54 +101,58 @@ mysql2_mysql_enc_name_to_rb (str, len) {""}, {""}, {""}, {"gbk", "GBK"}, {""}, - {"greek", "ISO-8859-7"}, + {"utf32", "UTF-32"}, {"gb2312", "GB2312"}, {"keybcs2", NULL}, {""}, {"ucs2", "UTF-16BE"}, {"koi8u", "KOI8-R"}, {"binary", "ASCII-8BIT"}, - {"eucjpms", "eucJP-ms"}, - {""}, + {"utf8mb4", "UTF-8"}, + {"macroman", "macRoman"}, {"ujis", "eucJP-ms"}, - {"cp852", "CP852"}, + {"greek", "ISO-8859-7"}, {"cp1251", "Windows-1251"}, - {"geostd8", NULL}, + {"utf16le", "UTF-16LE"}, {""}, {"sjis", "Shift_JIS"}, {"macce", "macCentEuro"}, - {"latin2", "ISO-8859-2"}, + {"cp1257", "Windows-1257"}, + {"eucjpms", "eucJP-ms"}, + {""}, + {"utf8", "UTF-8"}, + {"cp852", "CP852"}, + {"cp1250", "Windows-1250"}, + {"gb18030", "GB18030"}, {""}, - {"macroman", "macRoman"}, - {"dec8", NULL}, - {"utf32", "UTF-32"}, - {"latin1", "ISO-8859-1"}, - {"utf8mb4", "UTF-8"}, - {"hp8", NULL}, {"swe7", NULL}, + {"koi8r", "KOI8-R"}, + {"tis620", "TIS-620"}, + {"geostd8", NULL}, + {""}, + {"big5", "Big5"}, {"euckr", "EUC-KR"}, - {"cp1257", "Windows-1257"}, + {"latin2", "ISO-8859-2"}, {""}, {""}, - {"utf8", "UTF-8"}, - {"koi8r", "KOI8-R"}, - {"cp1256", "Windows-1256"}, - {""}, {""}, {""}, - {"cp866", "IBM866"}, + {"dec8", NULL}, + {"cp850", "CP850"}, + {"latin1", "ISO-8859-1"}, + {""}, + {"hp8", NULL}, + {""}, + {"utf16", "UTF-16"}, {"latin7", "ISO-8859-13"}, {""}, {""}, {""}, {"ascii", "US-ASCII"}, - {"hebrew", "ISO-8859-8"}, - {""}, {""}, - {"big5", "Big5"}, - {"utf16", "UTF-16"}, - {"cp1250", "Windows-1250"}, - {""}, {""}, {""}, - {"cp850", "CP850"}, - {"tis620", "TIS-620"}, + {"cp1256", "Windows-1256"}, {""}, {""}, {""}, {"cp932", "Windows-31J"}, + {"hebrew", "ISO-8859-8"}, + {""}, {""}, {""}, {""}, {"latin5", "ISO-8859-9"}, - {""}, {""}, {""}, {""}, {""}, {""}, + {""}, {""}, {""}, + {"cp866", "IBM866"}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {"armscii8", NULL} }; diff --git a/ext/mysql2/mysql_enc_to_ruby.h b/ext/mysql2/mysql_enc_to_ruby.h index 37dbf6f73..f4c7673c7 100644 --- a/ext/mysql2/mysql_enc_to_ruby.h +++ b/ext/mysql2/mysql_enc_to_ruby.h @@ -54,13 +54,13 @@ const char *mysql2_mysql_enc_to_rb[] = { "macRoman", "UTF-16", "UTF-16", - NULL, + "UTF-16LE", "Windows-1256", "Windows-1257", "Windows-1257", "UTF-32", "UTF-32", - NULL, + "UTF-16LE", "ASCII-8BIT", NULL, "US-ASCII", @@ -74,7 +74,7 @@ const char *mysql2_mysql_enc_to_rb[] = { NULL, "KOI8-R", "KOI8-R", - NULL, + "UTF-8", "ISO-8859-2", "ISO-8859-9", "ISO-8859-13", @@ -119,10 +119,10 @@ const char *mysql2_mysql_enc_to_rb[] = { "UTF-16", "UTF-16", "UTF-16", - NULL, - NULL, - NULL, - NULL, + "UTF-16", + "UTF-16", + "UTF-16", + "UTF-16", NULL, NULL, NULL, @@ -146,6 +146,10 @@ const char *mysql2_mysql_enc_to_rb[] = { "UTF-16BE", "UTF-16BE", "UTF-16BE", + "UTF-16BE", + "UTF-16BE", + "UTF-16BE", + "UTF-16BE", NULL, NULL, NULL, @@ -153,11 +157,11 @@ const char *mysql2_mysql_enc_to_rb[] = { NULL, NULL, NULL, - NULL, - NULL, - NULL, - NULL, - NULL, + "UTF-16BE", + "UTF-32", + "UTF-32", + "UTF-32", + "UTF-32", "UTF-32", "UTF-32", "UTF-32", @@ -186,10 +190,6 @@ const char *mysql2_mysql_enc_to_rb[] = { NULL, NULL, NULL, - NULL, - NULL, - NULL, - NULL, "UTF-8", "UTF-8", "UTF-8", @@ -210,17 +210,70 @@ const char *mysql2_mysql_enc_to_rb[] = { "UTF-8", "UTF-8", "UTF-8", + "UTF-8", + "UTF-8", + "UTF-8", + "UTF-8", + NULL, NULL, NULL, NULL, NULL, NULL, NULL, + "UTF-8", + "UTF-8", + "UTF-8", + "UTF-8", + "UTF-8", + "UTF-8", + "UTF-8", + "UTF-8", + "UTF-8", + "UTF-8", + "UTF-8", + "UTF-8", + "UTF-8", + "UTF-8", + "UTF-8", + "UTF-8", + "UTF-8", + "UTF-8", + "UTF-8", + "UTF-8", + "UTF-8", + "UTF-8", + "UTF-8", + "UTF-8", + "UTF-8", + "GB18030", + "GB18030", + "GB18030", NULL, NULL, NULL, NULL, + "UTF-8", + "UTF-8", + "UTF-8", + "UTF-8", + "UTF-8", + "UTF-8", + "UTF-8", + "UTF-8", + "UTF-8", + "UTF-8", + "UTF-8", + "UTF-8", + "UTF-8", + "UTF-8", + "UTF-8", + "UTF-8", + "UTF-8", NULL, + "UTF-8", + "UTF-8", + "UTF-8", NULL, "UTF-8", "UTF-8", @@ -240,6 +293,18 @@ const char *mysql2_mysql_enc_to_rb[] = { "UTF-8", "UTF-8", "UTF-8", + NULL, + "UTF-8", + "UTF-8", + "UTF-8", + NULL, + "UTF-8", + NULL, + NULL, + "UTF-8", + "UTF-8", + "UTF-8", + "UTF-8", "UTF-8", "UTF-8" }; diff --git a/ext/mysql2/result.c b/ext/mysql2/result.c index dcad2f74c..519aff12d 100644 --- a/ext/mysql2/result.c +++ b/ext/mysql2/result.c @@ -3,6 +3,7 @@ #include #include "mysql_enc_to_ruby.h" +#define MYSQL2_CHARSETNR_SIZE (sizeof(mysql2_mysql_enc_to_rb)/sizeof(mysql2_mysql_enc_to_rb[0])) #ifdef HAVE_RUBY_ENCODING_H static rb_encoding *binaryEncoding; @@ -161,7 +162,7 @@ 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 < MYSQL2_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); diff --git a/spec/mysql2/client_spec.rb b/spec/mysql2/client_spec.rb index 5a443b228..303d8bbe9 100644 --- a/spec/mysql2/client_spec.rb +++ b/spec/mysql2/client_spec.rb @@ -131,10 +131,10 @@ def connect *args ssl_client = nil lambda { ssl_client = Mysql2::Client.new( + :host => '127.0.0.1', # MySQL 5.7 skips SSL over Unix Sockets w/o ssl-mode=REQUIRED :sslkey => '/etc/mysql/client-key.pem', :sslcert => '/etc/mysql/client-cert.pem', :sslca => '/etc/mysql/ca-cert.pem', - :sslcapath => '/etc/mysql/', :sslcipher => 'DHE-RSA-AES256-SHA' ) }.should_not raise_error(Mysql2::Error) @@ -232,7 +232,15 @@ def connect *args it "should > 0" do # "the statement produces extra information that can be viewed by issuing a SHOW WARNINGS" # http://dev.mysql.com/doc/refman/5.0/en/explain-extended.html - @client.query("explain extended select 1") + begin + @client.query("explain extended select 1") + rescue Mysql2::Error + # EXTENDED keyword is deprecated in MySQL 8.0 and triggers a syntax error + # https://dev.mysql.com/doc/refman/5.7/en/explain-extended.html + # "extended output is now enabled by default, so the EXTENDED keyword is superfluous and + # deprecated ... and it will be removed from EXPLAIN syntax in a future MySQL release" + @client.query("explain select 1") + end @client.warning_count.should > 0 end end diff --git a/support/mysql_enc_to_ruby.rb b/support/mysql_enc_to_ruby.rb index 4a3ef70db..00a230851 100644 --- a/support/mysql_enc_to_ruby.rb +++ b/support/mysql_enc_to_ruby.rb @@ -42,7 +42,9 @@ "binary" => "ASCII-8BIT", "geostd8" => "NULL", "cp932" => "Windows-31J", - "eucjpms" => "eucJP-ms" + "eucjpms" => "eucJP-ms", + "utf16le" => "UTF-16LE", + "gb18030" => "GB18030", } client = Mysql2::Client.new(:username => user, :password => pass, :host => host, :port => port.to_i) @@ -67,7 +69,9 @@ encodings_with_nil = encodings_with_nil.map do |encoding| name = "NULL" - if !encoding.nil? && encoding[1] != "NULL" + if !encoding.nil? && encoding[1].nil? + $stderr.puts "WARNING: Missing mapping for MySQL collation with id #{encoding[0]}, assuming NULL" + elsif !encoding.nil? && encoding[1] != "NULL" name = "\"#{encoding[1]}\"" end diff --git a/support/ruby_enc_to_mysql.rb b/support/ruby_enc_to_mysql.rb index 112016c94..482613d7a 100644 --- a/support/ruby_enc_to_mysql.rb +++ b/support/ruby_enc_to_mysql.rb @@ -37,7 +37,9 @@ "binary" => "ASCII-8BIT", "geostd8" => nil, "cp932" => "Windows-31J", - "eucjpms" => "eucJP-ms" + "eucjpms" => "eucJP-ms", + "utf16le" => "UTF-16LE", + "gb18030" => "GB18030", } puts <<-header