Apply monkey patching only after loading a MySQL adapter.

Akinori MUSHA 10 年 前
コミット
a621a19f2f
共有3 個のファイルを変更した127 個の追加116 個の削除を含む
  1. 1 3
      config/initializers/ar_mysql_column_charset.rb
  2. 8 113
      lib/ar_mysql_column_charset.rb
  3. 118 0
      lib/ar_mysql_column_charset/main.rb

+ 1 - 3
config/initializers/ar_mysql_column_charset.rb

@@ -1,3 +1 @@
1
-ActiveSupport.on_load :active_record do
2
-  require 'ar_mysql_column_charset'
3
-end
1
+require 'ar_mysql_column_charset'

+ 8 - 113
lib/ar_mysql_column_charset.rb

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

+ 118 - 0
lib/ar_mysql_column_charset/main.rb

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