mysql2 0.2.18 → 0.2.19b1
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.
- data/.gitignore +2 -0
- data/.rbenv-version +1 -0
- data/Gemfile.lock +61 -0
- data/README.md +70 -4
- data/ext/mysql2/client.c +320 -61
- data/ext/mysql2/client.h +5 -3
- data/ext/mysql2/extconf.rb +6 -5
- data/ext/mysql2/result.c +91 -40
- data/ext/mysql2/result.h +1 -0
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +42 -13
- data/lib/mysql2.rb +18 -3
- data/lib/mysql2/client.rb +39 -12
- data/lib/mysql2/em.rb +13 -3
- data/lib/mysql2/version.rb +1 -1
- data/spec/configuration.yml.example +11 -0
- data/spec/em/em_fiber_spec.rb +2 -2
- data/spec/em/em_spec.rb +68 -7
- data/spec/mysql2/client_spec.rb +114 -12
- data/spec/mysql2/error_spec.rb +2 -2
- data/spec/mysql2/result_spec.rb +57 -5
- data/spec/spec_helper.rb +3 -1
- data/tasks/rspec.rake +11 -1
- metadata +149 -149
data/ext/mysql2/client.h
CHANGED
@@ -33,10 +33,12 @@ void init_mysql2_client();
|
|
33
33
|
|
34
34
|
typedef struct {
|
35
35
|
VALUE encoding;
|
36
|
-
|
36
|
+
VALUE active_thread; /* rb_thread_current() or Qnil */
|
37
37
|
int reconnect_enabled;
|
38
|
-
int
|
38
|
+
int active;
|
39
|
+
int connected;
|
40
|
+
int initialized;
|
39
41
|
MYSQL *client;
|
40
42
|
} mysql_client_wrapper;
|
41
43
|
|
42
|
-
#endif
|
44
|
+
#endif
|
data/ext/mysql2/extconf.rb
CHANGED
@@ -17,6 +17,7 @@ dirs = ENV['PATH'].split(File::PATH_SEPARATOR) + %w[
|
|
17
17
|
/opt/local/mysql
|
18
18
|
/opt/local/lib/mysql5
|
19
19
|
/usr
|
20
|
+
/usr/mysql
|
20
21
|
/usr/local
|
21
22
|
/usr/local/mysql
|
22
23
|
/usr/local/mysql-*
|
@@ -61,13 +62,13 @@ end
|
|
61
62
|
asplode h unless have_header h
|
62
63
|
end
|
63
64
|
|
64
|
-
|
65
|
+
# GCC specific flags
|
66
|
+
if RbConfig::MAKEFILE_CONFIG['CC'] =~ /gcc/
|
65
67
|
$CFLAGS << ' -Wall -funroll-loops'
|
66
|
-
end
|
67
|
-
# $CFLAGS << ' -O0 -ggdb3 -Wextra'
|
68
68
|
|
69
|
-
if hard_mysql_path = $libs[%r{-L(/[^ ]+)}, 1]
|
70
|
-
|
69
|
+
if hard_mysql_path = $libs[%r{-L(/[^ ]+)}, 1]
|
70
|
+
$LDFLAGS << " -Wl,-rpath,#{hard_mysql_path}"
|
71
|
+
end
|
71
72
|
end
|
72
73
|
|
73
74
|
create_makefile('mysql2/mysql2')
|
data/ext/mysql2/result.c
CHANGED
@@ -55,7 +55,7 @@ static VALUE intern_encoding_from_charset;
|
|
55
55
|
static ID intern_new, intern_utc, intern_local, intern_encoding_from_charset_code,
|
56
56
|
intern_localtime, intern_local_offset, intern_civil, intern_new_offset;
|
57
57
|
static VALUE sym_symbolize_keys, sym_as, sym_array, sym_database_timezone, sym_application_timezone,
|
58
|
-
sym_local, sym_utc, sym_cast_booleans, sym_cache_rows, sym_cast;
|
58
|
+
sym_local, sym_utc, sym_cast_booleans, sym_cache_rows, sym_cast, sym_stream;
|
59
59
|
static ID intern_merge;
|
60
60
|
|
61
61
|
static void rb_mysql_result_mark(void * wrapper) {
|
@@ -163,11 +163,10 @@ static VALUE mysql2_set_field_string_encoding(VALUE val, MYSQL_FIELD field, rb_e
|
|
163
163
|
#endif
|
164
164
|
|
165
165
|
|
166
|
-
static VALUE rb_mysql_result_fetch_row(VALUE self, ID db_timezone, ID app_timezone, int symbolizeKeys, int asArray, int castBool, int cast) {
|
166
|
+
static VALUE rb_mysql_result_fetch_row(VALUE self, ID db_timezone, ID app_timezone, int symbolizeKeys, int asArray, int castBool, int cast, MYSQL_FIELD * fields) {
|
167
167
|
VALUE rowVal;
|
168
168
|
mysql2_result_wrapper * wrapper;
|
169
169
|
MYSQL_ROW row;
|
170
|
-
MYSQL_FIELD * fields = NULL;
|
171
170
|
unsigned int i = 0;
|
172
171
|
unsigned long * fieldLengths;
|
173
172
|
void * ptr;
|
@@ -193,7 +192,6 @@ static VALUE rb_mysql_result_fetch_row(VALUE self, ID db_timezone, ID app_timezo
|
|
193
192
|
} else {
|
194
193
|
rowVal = rb_hash_new();
|
195
194
|
}
|
196
|
-
fields = mysql_fetch_fields(wrapper->result);
|
197
195
|
fieldLengths = mysql_fetch_lengths(wrapper->result);
|
198
196
|
if (wrapper->fields == Qnil) {
|
199
197
|
wrapper->numberOfFields = mysql_num_fields(wrapper->result);
|
@@ -225,7 +223,7 @@ static VALUE rb_mysql_result_fetch_row(VALUE self, ID db_timezone, ID app_timezo
|
|
225
223
|
break;
|
226
224
|
case MYSQL_TYPE_TINY: // TINYINT field
|
227
225
|
if (castBool && fields[i].length == 1) {
|
228
|
-
val = *row[i]
|
226
|
+
val = *row[i] != '0' ? Qtrue : Qfalse;
|
229
227
|
break;
|
230
228
|
}
|
231
229
|
case MYSQL_TYPE_SHORT: // SMALLINT field
|
@@ -237,7 +235,9 @@ static VALUE rb_mysql_result_fetch_row(VALUE self, ID db_timezone, ID app_timezo
|
|
237
235
|
break;
|
238
236
|
case MYSQL_TYPE_DECIMAL: // DECIMAL or NUMERIC field
|
239
237
|
case MYSQL_TYPE_NEWDECIMAL: // Precision math DECIMAL or NUMERIC field (MySQL 5.0.3 and up)
|
240
|
-
if (
|
238
|
+
if (fields[i].decimals == 0) {
|
239
|
+
val = rb_cstr2inum(row[i], 10);
|
240
|
+
} else if (strtod(row[i], NULL) == 0.000000){
|
241
241
|
val = rb_funcall(cBigDecimal, intern_new, 1, opt_decimal_zero);
|
242
242
|
}else{
|
243
243
|
val = rb_funcall(cBigDecimal, intern_new, 1, rb_str_new(row[i], fieldLengths[i]));
|
@@ -392,7 +392,8 @@ static VALUE rb_mysql_result_each(int argc, VALUE * argv, VALUE self) {
|
|
392
392
|
ID db_timezone, app_timezone, dbTz, appTz;
|
393
393
|
mysql2_result_wrapper * wrapper;
|
394
394
|
unsigned long i;
|
395
|
-
int symbolizeKeys = 0, asArray = 0, castBool = 0, cacheRows = 1, cast = 1;
|
395
|
+
int symbolizeKeys = 0, asArray = 0, castBool = 0, cacheRows = 1, cast = 1, streaming = 0;
|
396
|
+
MYSQL_FIELD * fields = NULL;
|
396
397
|
|
397
398
|
GetMysql2Result(self, wrapper);
|
398
399
|
|
@@ -423,6 +424,14 @@ static VALUE rb_mysql_result_each(int argc, VALUE * argv, VALUE self) {
|
|
423
424
|
cast = 0;
|
424
425
|
}
|
425
426
|
|
427
|
+
if(rb_hash_aref(opts, sym_stream) == Qtrue) {
|
428
|
+
streaming = 1;
|
429
|
+
}
|
430
|
+
|
431
|
+
if(streaming && cacheRows) {
|
432
|
+
rb_warn("cacheRows is ignored if streaming is true");
|
433
|
+
}
|
434
|
+
|
426
435
|
dbTz = rb_hash_aref(opts, sym_database_timezone);
|
427
436
|
if (dbTz == sym_local) {
|
428
437
|
db_timezone = intern_local;
|
@@ -445,49 +454,82 @@ static VALUE rb_mysql_result_each(int argc, VALUE * argv, VALUE self) {
|
|
445
454
|
}
|
446
455
|
|
447
456
|
if (wrapper->lastRowProcessed == 0) {
|
448
|
-
|
449
|
-
|
457
|
+
if(streaming) {
|
458
|
+
// We can't get number of rows if we're streaming,
|
459
|
+
// until we've finished fetching all rows
|
460
|
+
wrapper->numberOfRows = 0;
|
450
461
|
wrapper->rows = rb_ary_new();
|
451
|
-
|
462
|
+
} else {
|
463
|
+
wrapper->numberOfRows = mysql_num_rows(wrapper->result);
|
464
|
+
if (wrapper->numberOfRows == 0) {
|
465
|
+
wrapper->rows = rb_ary_new();
|
466
|
+
return wrapper->rows;
|
467
|
+
}
|
468
|
+
wrapper->rows = rb_ary_new2(wrapper->numberOfRows);
|
452
469
|
}
|
453
|
-
wrapper->rows = rb_ary_new2(wrapper->numberOfRows);
|
454
470
|
}
|
455
471
|
|
456
|
-
if (
|
457
|
-
|
458
|
-
// internal array. Lets hand that over to the user since it's ready to go
|
459
|
-
for (i = 0; i < wrapper->numberOfRows; i++) {
|
460
|
-
rb_yield(rb_ary_entry(wrapper->rows, i));
|
461
|
-
}
|
462
|
-
} else {
|
463
|
-
unsigned long rowsProcessed = 0;
|
464
|
-
rowsProcessed = RARRAY_LEN(wrapper->rows);
|
465
|
-
for (i = 0; i < wrapper->numberOfRows; i++) {
|
472
|
+
if (streaming) {
|
473
|
+
if(!wrapper->streamingComplete) {
|
466
474
|
VALUE row;
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
475
|
+
|
476
|
+
fields = mysql_fetch_fields(wrapper->result);
|
477
|
+
|
478
|
+
do {
|
479
|
+
row = rb_mysql_result_fetch_row(self, db_timezone, app_timezone, symbolizeKeys, asArray, castBool, cast, fields);
|
480
|
+
|
481
|
+
if (block != Qnil && row != Qnil) {
|
482
|
+
rb_yield(row);
|
483
|
+
wrapper->lastRowProcessed++;
|
473
484
|
}
|
474
|
-
|
485
|
+
} while(row != Qnil);
|
486
|
+
|
487
|
+
rb_mysql_result_free_result(wrapper);
|
488
|
+
|
489
|
+
wrapper->numberOfRows = wrapper->lastRowProcessed;
|
490
|
+
wrapper->streamingComplete = 1;
|
491
|
+
} else {
|
492
|
+
rb_raise(cMysql2Error, "You have already fetched all the rows for this query and streaming is true. (to reiterate you must requery).");
|
493
|
+
}
|
494
|
+
} else {
|
495
|
+
if (cacheRows && wrapper->lastRowProcessed == wrapper->numberOfRows) {
|
496
|
+
// we've already read the entire dataset from the C result into our
|
497
|
+
// internal array. Lets hand that over to the user since it's ready to go
|
498
|
+
for (i = 0; i < wrapper->numberOfRows; i++) {
|
499
|
+
rb_yield(rb_ary_entry(wrapper->rows, i));
|
475
500
|
}
|
501
|
+
} else {
|
502
|
+
unsigned long rowsProcessed = 0;
|
503
|
+
rowsProcessed = RARRAY_LEN(wrapper->rows);
|
504
|
+
fields = mysql_fetch_fields(wrapper->result);
|
505
|
+
|
506
|
+
for (i = 0; i < wrapper->numberOfRows; i++) {
|
507
|
+
VALUE row;
|
508
|
+
if (cacheRows && i < rowsProcessed) {
|
509
|
+
row = rb_ary_entry(wrapper->rows, i);
|
510
|
+
} else {
|
511
|
+
row = rb_mysql_result_fetch_row(self, db_timezone, app_timezone, symbolizeKeys, asArray, castBool, cast, fields);
|
512
|
+
if (cacheRows) {
|
513
|
+
rb_ary_store(wrapper->rows, i, row);
|
514
|
+
}
|
515
|
+
wrapper->lastRowProcessed++;
|
516
|
+
}
|
476
517
|
|
477
|
-
|
518
|
+
if (row == Qnil) {
|
519
|
+
// we don't need the mysql C dataset around anymore, peace it
|
520
|
+
rb_mysql_result_free_result(wrapper);
|
521
|
+
return Qnil;
|
522
|
+
}
|
523
|
+
|
524
|
+
if (block != Qnil) {
|
525
|
+
rb_yield(row);
|
526
|
+
}
|
527
|
+
}
|
528
|
+
if (wrapper->lastRowProcessed == wrapper->numberOfRows) {
|
478
529
|
// we don't need the mysql C dataset around anymore, peace it
|
479
530
|
rb_mysql_result_free_result(wrapper);
|
480
|
-
return Qnil;
|
481
|
-
}
|
482
|
-
|
483
|
-
if (block != Qnil) {
|
484
|
-
rb_yield(row);
|
485
531
|
}
|
486
532
|
}
|
487
|
-
if (wrapper->lastRowProcessed == wrapper->numberOfRows) {
|
488
|
-
// we don't need the mysql C dataset around anymore, peace it
|
489
|
-
rb_mysql_result_free_result(wrapper);
|
490
|
-
}
|
491
533
|
}
|
492
534
|
|
493
535
|
return wrapper->rows;
|
@@ -497,8 +539,15 @@ static VALUE rb_mysql_result_count(VALUE self) {
|
|
497
539
|
mysql2_result_wrapper *wrapper;
|
498
540
|
|
499
541
|
GetMysql2Result(self, wrapper);
|
500
|
-
|
501
|
-
|
542
|
+
if(wrapper->resultFreed) {
|
543
|
+
if (wrapper->streamingComplete){
|
544
|
+
return LONG2NUM(wrapper->numberOfRows);
|
545
|
+
} else {
|
546
|
+
return LONG2NUM(RARRAY_LEN(wrapper->rows));
|
547
|
+
}
|
548
|
+
} else {
|
549
|
+
return INT2FIX(mysql_num_rows(wrapper->result));
|
550
|
+
}
|
502
551
|
}
|
503
552
|
|
504
553
|
/* Mysql2::Result */
|
@@ -514,6 +563,7 @@ VALUE rb_mysql_result_to_obj(MYSQL_RES * r) {
|
|
514
563
|
wrapper->fields = Qnil;
|
515
564
|
wrapper->rows = Qnil;
|
516
565
|
wrapper->encoding = Qnil;
|
566
|
+
wrapper->streamingComplete = 0;
|
517
567
|
rb_obj_call_init(obj, 0, NULL);
|
518
568
|
return obj;
|
519
569
|
}
|
@@ -551,6 +601,7 @@ void init_mysql2_result() {
|
|
551
601
|
sym_application_timezone = ID2SYM(rb_intern("application_timezone"));
|
552
602
|
sym_cache_rows = ID2SYM(rb_intern("cache_rows"));
|
553
603
|
sym_cast = ID2SYM(rb_intern("cast"));
|
604
|
+
sym_stream = ID2SYM(rb_intern("stream"));
|
554
605
|
|
555
606
|
opt_decimal_zero = rb_str_new2("0.0");
|
556
607
|
rb_global_variable(&opt_decimal_zero); //never GC
|
data/ext/mysql2/result.h
CHANGED
@@ -314,13 +314,13 @@ module ActiveRecord
|
|
314
314
|
end
|
315
315
|
|
316
316
|
def add_limit_offset!(sql, options)
|
317
|
-
limit, offset = options
|
317
|
+
limit, offset = options.fetch(:limit, 18446744073709551615), options[:offset]
|
318
318
|
if limit && offset
|
319
319
|
sql << " LIMIT #{offset.to_i}, #{sanitize_limit(limit)}"
|
320
320
|
elsif limit
|
321
321
|
sql << " LIMIT #{sanitize_limit(limit)}"
|
322
322
|
elsif offset
|
323
|
-
sql << " OFFSET #{offset.to_i}"
|
323
|
+
sql << " LIMIT #{sanitize_limit(limit)} OFFSET #{offset.to_i}"
|
324
324
|
end
|
325
325
|
sql
|
326
326
|
end
|
@@ -378,14 +378,32 @@ module ActiveRecord
|
|
378
378
|
show_variable 'collation_database'
|
379
379
|
end
|
380
380
|
|
381
|
-
def tables(name = nil)
|
381
|
+
def tables(name = nil, database = nil)
|
382
382
|
tables = []
|
383
|
-
|
383
|
+
|
384
|
+
sql = "SHOW TABLES "
|
385
|
+
sql << "IN #{quote_table_name(database)} " if database
|
386
|
+
|
387
|
+
execute(sql, 'SCHEMA').each do |field|
|
384
388
|
tables << field.first
|
385
389
|
end
|
386
390
|
tables
|
387
391
|
end
|
388
392
|
|
393
|
+
def table_exists?(name)
|
394
|
+
return true if super
|
395
|
+
|
396
|
+
name = name.to_s
|
397
|
+
schema, table = name.split('.', 2)
|
398
|
+
|
399
|
+
unless table # A table was provided without a schema
|
400
|
+
table = schema
|
401
|
+
schema = nil
|
402
|
+
end
|
403
|
+
|
404
|
+
tables(nil, schema).include? table
|
405
|
+
end
|
406
|
+
|
389
407
|
def drop_table(table_name, options = {})
|
390
408
|
super(table_name, options)
|
391
409
|
end
|
@@ -480,15 +498,26 @@ module ActiveRecord
|
|
480
498
|
|
481
499
|
# Maps logical Rails types to MySQL-specific data types.
|
482
500
|
def type_to_sql(type, limit = nil, precision = nil, scale = nil)
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
501
|
+
case type.to_s
|
502
|
+
when 'integer'
|
503
|
+
case limit
|
504
|
+
when 1; 'tinyint'
|
505
|
+
when 2; 'smallint'
|
506
|
+
when 3; 'mediumint'
|
507
|
+
when nil, 4, 11; 'int(11)' # compatibility with MySQL default
|
508
|
+
when 5..8; 'bigint'
|
509
|
+
else raise(ActiveRecordError, "No integer type has byte size #{limit}")
|
510
|
+
end
|
511
|
+
when 'text'
|
512
|
+
case limit
|
513
|
+
when 0..0xff; 'tinytext'
|
514
|
+
when nil, 0x100..0xffff; 'text'
|
515
|
+
when 0x10000..0xffffff; 'mediumtext'
|
516
|
+
when 0x1000000..0xffffffff; 'longtext'
|
517
|
+
else raise(ActiveRecordError, "No text type has character length #{limit}")
|
518
|
+
end
|
519
|
+
else
|
520
|
+
super
|
492
521
|
end
|
493
522
|
end
|
494
523
|
|
data/lib/mysql2.rb
CHANGED
@@ -16,6 +16,21 @@ module Mysql2
|
|
16
16
|
end
|
17
17
|
|
18
18
|
if defined?(ActiveRecord::VERSION::STRING) && ActiveRecord::VERSION::STRING >= "3.1"
|
19
|
-
|
20
|
-
|
21
|
-
|
19
|
+
warn "============= WARNING FROM mysql2 ============="
|
20
|
+
warn "This version of mysql2 (#{Mysql2::VERSION}) isn't compatible with Rails 3.1 as the ActiveRecord adapter was pulled into Rails itself."
|
21
|
+
warn "Please use the 0.3.x (or greater) releases if you plan on using it in Rails >= 3.1.x"
|
22
|
+
warn "============= END WARNING FROM mysql2 ============="
|
23
|
+
end
|
24
|
+
|
25
|
+
# For holding utility methods
|
26
|
+
module Mysql2::Util
|
27
|
+
|
28
|
+
#
|
29
|
+
# Rekey a string-keyed hash with equivalent symbols.
|
30
|
+
#
|
31
|
+
def self.key_hash_as_symbols(hash)
|
32
|
+
return nil unless hash
|
33
|
+
Hash[hash.map { |k,v| [k.to_sym, v] }]
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
data/lib/mysql2/client.rb
CHANGED
@@ -14,31 +14,36 @@ module Mysql2
|
|
14
14
|
}
|
15
15
|
|
16
16
|
def initialize(opts = {})
|
17
|
+
opts = Mysql2::Util.key_hash_as_symbols( opts )
|
17
18
|
@query_options = @@default_query_options.dup
|
18
19
|
@query_options.merge! opts
|
19
20
|
|
20
|
-
|
21
|
+
initialize_ext
|
21
22
|
|
22
|
-
|
23
|
+
# Set MySQL connection options (each one is a call to mysql_options())
|
24
|
+
[:reconnect, :connect_timeout, :local_infile, :read_timeout].each do |key|
|
23
25
|
next unless opts.key?(key)
|
24
26
|
send(:"#{key}=", opts[key])
|
25
27
|
end
|
28
|
+
|
26
29
|
# force the encoding to utf8
|
27
30
|
self.charset_name = opts[:encoding] || 'utf8'
|
28
31
|
|
29
|
-
@read_timeout = opts[:read_timeout]
|
30
|
-
if @read_timeout and @read_timeout < 0
|
31
|
-
raise Mysql2::Error, "read_timeout must be a positive integer, you passed #{@read_timeout}"
|
32
|
-
end
|
33
|
-
|
34
32
|
ssl_set(*opts.values_at(:sslkey, :sslcert, :sslca, :sslcapath, :sslcipher))
|
33
|
+
|
34
|
+
if [:user,:pass,:hostname,:dbname,:db,:sock].any?{|k| @query_options.has_key?(k) }
|
35
|
+
warn "============= WARNING FROM mysql2 ============="
|
36
|
+
warn "The options :user, :pass, :hostname, :dbname, :db, and :sock will be deprecated at some point in the future."
|
37
|
+
warn "Instead, please use :username, :password, :host, 'localhost', :port, :database, :socket, :flags for the options."
|
38
|
+
warn "============= END WARNING FROM mysql2 ========="
|
39
|
+
end
|
35
40
|
|
36
|
-
user = opts[:username]
|
37
|
-
pass = opts[:password]
|
38
|
-
host = opts[:host] || 'localhost'
|
41
|
+
user = opts[:username] || opts[:user]
|
42
|
+
pass = opts[:password] || opts[:pass]
|
43
|
+
host = opts[:host] || opts[:hostname] || 'localhost'
|
39
44
|
port = opts[:port] || 3306
|
40
|
-
database = opts[:database]
|
41
|
-
socket = opts[:socket]
|
45
|
+
database = opts[:database] || opts[:dbname] || opts[:db]
|
46
|
+
socket = opts[:socket] || opts[:sock]
|
42
47
|
flags = opts[:flags] ? opts[:flags] | @query_options[:connect_flags] : @query_options[:connect_flags]
|
43
48
|
|
44
49
|
connect user, pass, host, port, database, socket, flags
|
@@ -87,6 +92,7 @@ module Mysql2
|
|
87
92
|
"ucs2" => Encoding::UTF_16BE,
|
88
93
|
"ujis" => Encoding::EucJP_ms,
|
89
94
|
"utf8" => Encoding::UTF_8,
|
95
|
+
"utf8mb4" => Encoding::UTF_8,
|
90
96
|
}
|
91
97
|
|
92
98
|
MYSQL_CHARSET_MAP = {
|
@@ -134,6 +140,8 @@ module Mysql2
|
|
134
140
|
42 => {:name => "latin7", :collation => "latin7_general_cs"},
|
135
141
|
43 => {:name => "macce", :collation => "macce_bin"},
|
136
142
|
44 => {:name => "cp1250", :collation => "cp1250_croatian_ci"},
|
143
|
+
45 => {:name => "utf8mb4", :collation => "utf8mb4_general_ci"},
|
144
|
+
46 => {:name => "utf8mb4", :collation => "utf8mb4_bin"},
|
137
145
|
47 => {:name => "latin1", :collation => "latin1_bin"},
|
138
146
|
48 => {:name => "latin1", :collation => "latin1_general_ci"},
|
139
147
|
49 => {:name => "latin1", :collation => "latin1_general_cs"},
|
@@ -218,6 +226,25 @@ module Mysql2
|
|
218
226
|
208 => {:name => "utf8", :collation => "utf8_persian_ci"},
|
219
227
|
209 => {:name => "utf8", :collation => "utf8_esperanto_ci"},
|
220
228
|
210 => {:name => "utf8", :collation => "utf8_hungarian_ci"},
|
229
|
+
224 => {:name => "utf8mb4", :collation => "utf8mb4_unicode_ci"},
|
230
|
+
225 => {:name => "utf8mb4", :collation => "utf8mb4_icelandic_ci"},
|
231
|
+
226 => {:name => "utf8mb4", :collation => "utf8mb4_latvian_ci"},
|
232
|
+
227 => {:name => "utf8mb4", :collation => "utf8mb4_romanian_ci"},
|
233
|
+
228 => {:name => "utf8mb4", :collation => "utf8mb4_slovenian_ci"},
|
234
|
+
229 => {:name => "utf8mb4", :collation => "utf8mb4_polish_ci"},
|
235
|
+
230 => {:name => "utf8mb4", :collation => "utf8mb4_estonian_ci"},
|
236
|
+
231 => {:name => "utf8mb4", :collation => "utf8mb4_spanish_ci"},
|
237
|
+
232 => {:name => "utf8mb4", :collation => "utf8mb4_swedish_ci"},
|
238
|
+
233 => {:name => "utf8mb4", :collation => "utf8mb4_turkish_ci"},
|
239
|
+
234 => {:name => "utf8mb4", :collation => "utf8mb4_czech_ci"},
|
240
|
+
235 => {:name => "utf8mb4", :collation => "utf8mb4_danish_ci"},
|
241
|
+
236 => {:name => "utf8mb4", :collation => "utf8mb4_lithuanian_ci"},
|
242
|
+
237 => {:name => "utf8mb4", :collation => "utf8mb4_slovak_ci"},
|
243
|
+
238 => {:name => "utf8mb4", :collation => "utf8mb4_spanish2_ci"},
|
244
|
+
239 => {:name => "utf8mb4", :collation => "utf8mb4_roman_ci"},
|
245
|
+
240 => {:name => "utf8mb4", :collation => "utf8mb4_persian_ci"},
|
246
|
+
241 => {:name => "utf8mb4", :collation => "utf8mb4_esperanto_ci"},
|
247
|
+
242 => {:name => "utf8mb4", :collation => "utf8mb4_hungarian_ci"},
|
221
248
|
254 => {:name => "utf8", :collation => "utf8_general_cs"}
|
222
249
|
}
|
223
250
|
|