ar_mysql_column_charset.rb 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. require 'active_record'
  2. # Module#prepend support for Ruby 1.9
  3. require 'prepend' unless Module.method_defined?(:prepend)
  4. module ActiveRecord::ConnectionAdapters
  5. class ColumnDefinition
  6. module CharsetSupport
  7. attr_accessor :charset, :collation
  8. end
  9. prepend CharsetSupport
  10. end
  11. class TableDefinition
  12. module CharsetSupport
  13. def new_column_definition(name, type, options)
  14. column = super
  15. column.charset = options[:charset]
  16. column.collation = options[:collation]
  17. column
  18. end
  19. end
  20. prepend CharsetSupport
  21. end
  22. class AbstractMysqlAdapter
  23. module CharsetSupport
  24. def prepare_column_options(column, types)
  25. spec = super
  26. conn = ActiveRecord::Base.connection
  27. spec[:charset] = column.charset.inspect if column.charset && column.charset != conn.charset
  28. spec[:collation] = column.collation.inspect if column.collation && column.collation != conn.collation
  29. spec
  30. end
  31. def migration_keys
  32. super + [:charset, :collation]
  33. end
  34. def utf8mb4_supported?
  35. if @utf8mb4_supported.nil?
  36. @utf8mb4_supported = !select("show character set like 'utf8mb4'").empty?
  37. else
  38. @utf8mb4_supported
  39. end
  40. end
  41. def charset_collation(charset, collation)
  42. [charset, collation].map { |name|
  43. case name
  44. when nil
  45. nil
  46. when /\A(utf8mb4(_\w*)?)\z/
  47. if utf8mb4_supported?
  48. $1
  49. else
  50. "utf8#{$2}"
  51. end
  52. else
  53. name.to_s
  54. end
  55. }
  56. end
  57. def create_database(name, options = {})
  58. # utf8mb4 is used in column definitions; use utf8 for
  59. # databases.
  60. if options[:charset] == 'utf8mb4'
  61. options = options.merge(charset: 'utf8')
  62. end
  63. super(name, options)
  64. end
  65. end
  66. prepend CharsetSupport
  67. class SchemaCreation
  68. module CharsetSupport
  69. def column_options(o)
  70. column_options = super
  71. column_options[:charset] = o.charset unless o.charset.nil?
  72. column_options[:collation] = o.collation unless o.collation.nil?
  73. column_options
  74. end
  75. def add_column_options!(sql, options)
  76. charset, collation = @conn.charset_collation(options[:charset], options[:collation])
  77. if charset
  78. sql << " CHARACTER SET #{charset}"
  79. end
  80. if collation
  81. sql << " COLLATE #{collation}"
  82. end
  83. super
  84. end
  85. end
  86. prepend CharsetSupport
  87. end
  88. class Column
  89. module CharsetSupport
  90. attr_reader :charset
  91. def initialize(*args)
  92. super
  93. @charset = @collation[/\A[^_]+/] unless @collation.nil?
  94. end
  95. end
  96. prepend CharsetSupport
  97. end
  98. end
  99. end