2014-07-25 17:32:53 +09:00
|
|
|
require 'active_record'
|
|
|
|
|
2014-08-13 21:55:14 +09:00
|
|
|
# Module#prepend support for Ruby 1.9
|
|
|
|
require 'prepend' unless Module.method_defined?(:prepend)
|
|
|
|
|
2014-07-25 17:32:53 +09:00
|
|
|
module ActiveRecord::ConnectionAdapters
|
|
|
|
class ColumnDefinition
|
|
|
|
module CharsetSupport
|
|
|
|
attr_accessor :charset, :collation
|
|
|
|
end
|
|
|
|
|
|
|
|
prepend CharsetSupport
|
|
|
|
end
|
|
|
|
|
|
|
|
class TableDefinition
|
|
|
|
module CharsetSupport
|
|
|
|
def new_column_definition(name, type, options)
|
|
|
|
column = super
|
|
|
|
column.charset = options[:charset]
|
|
|
|
column.collation = options[:collation]
|
|
|
|
column
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
prepend CharsetSupport
|
|
|
|
end
|
|
|
|
|
|
|
|
class AbstractMysqlAdapter
|
|
|
|
module CharsetSupport
|
|
|
|
def prepare_column_options(column, types)
|
|
|
|
spec = super
|
2014-12-01 21:59:12 +09:00
|
|
|
spec[:charset] = column.charset.inspect if column.charset && column.charset != charset
|
|
|
|
spec[:collation] = column.collation.inspect if column.collation && column.collation != collation
|
2014-07-25 17:32:53 +09:00
|
|
|
spec
|
|
|
|
end
|
|
|
|
|
|
|
|
def migration_keys
|
|
|
|
super + [:charset, :collation]
|
|
|
|
end
|
2014-08-21 19:43:04 +09:00
|
|
|
|
|
|
|
def utf8mb4_supported?
|
|
|
|
if @utf8mb4_supported.nil?
|
|
|
|
@utf8mb4_supported = !select("show character set like 'utf8mb4'").empty?
|
|
|
|
else
|
|
|
|
@utf8mb4_supported
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def charset_collation(charset, collation)
|
|
|
|
[charset, collation].map { |name|
|
|
|
|
case name
|
|
|
|
when nil
|
|
|
|
nil
|
|
|
|
when /\A(utf8mb4(_\w*)?)\z/
|
|
|
|
if utf8mb4_supported?
|
|
|
|
$1
|
|
|
|
else
|
|
|
|
"utf8#{$2}"
|
|
|
|
end
|
|
|
|
else
|
|
|
|
name.to_s
|
|
|
|
end
|
|
|
|
}
|
|
|
|
end
|
2014-10-01 21:20:39 +09:00
|
|
|
|
|
|
|
def create_database(name, options = {})
|
|
|
|
# utf8mb4 is used in column definitions; use utf8 for
|
|
|
|
# databases.
|
2014-12-01 21:59:12 +09:00
|
|
|
[:charset, :collation].each { |key|
|
|
|
|
case options[key]
|
|
|
|
when /\A(utf8mb4(_\w*)?)\z/
|
|
|
|
options = options.merge(key => "utf8#{$2}")
|
|
|
|
end
|
|
|
|
}
|
2014-10-01 21:20:39 +09:00
|
|
|
super(name, options)
|
|
|
|
end
|
2014-07-25 17:32:53 +09:00
|
|
|
end
|
|
|
|
|
|
|
|
prepend CharsetSupport
|
|
|
|
|
|
|
|
class SchemaCreation
|
|
|
|
module CharsetSupport
|
|
|
|
def column_options(o)
|
|
|
|
column_options = super
|
|
|
|
column_options[:charset] = o.charset unless o.charset.nil?
|
|
|
|
column_options[:collation] = o.collation unless o.collation.nil?
|
|
|
|
column_options
|
|
|
|
end
|
|
|
|
|
|
|
|
def add_column_options!(sql, options)
|
2014-08-21 19:43:04 +09:00
|
|
|
charset, collation = @conn.charset_collation(options[:charset], options[:collation])
|
|
|
|
|
|
|
|
if charset
|
|
|
|
sql << " CHARACTER SET #{charset}"
|
2014-07-25 17:32:53 +09:00
|
|
|
end
|
|
|
|
|
2014-08-21 19:43:04 +09:00
|
|
|
if collation
|
|
|
|
sql << " COLLATE #{collation}"
|
2014-07-25 17:32:53 +09:00
|
|
|
end
|
|
|
|
|
|
|
|
super
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
prepend CharsetSupport
|
|
|
|
end
|
|
|
|
|
|
|
|
class Column
|
|
|
|
module CharsetSupport
|
|
|
|
attr_reader :charset
|
|
|
|
|
|
|
|
def initialize(*args)
|
|
|
|
super
|
|
|
|
@charset = @collation[/\A[^_]+/] unless @collation.nil?
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
prepend CharsetSupport
|
|
|
|
end
|
|
|
|
end
|
2014-08-13 21:55:14 +09:00
|
|
|
end
|