cosine-active_record_encoding 0.9.3 → 0.9.4

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.
Files changed (2) hide show
  1. data/lib/active_record_encoding.rb +85 -59
  2. metadata +1 -1
@@ -7,64 +7,49 @@
7
7
  #
8
8
  # ActiveRecordEncoding — Module to make ActiveRecord aware of Unicode
9
9
  # encoding issues on Ruby 1.9. This software is not supported on Ruby
10
- # 1.8 at all, and never will be. It should be used only if the
11
- # underlying database does not or cannot properly handle the encoding of
12
- # data that is returned as "ASCII-8BIT" encoded data. Most databases
13
- # can properly encode data, so your first assumption should be that you
14
- # do not need this software unless you really know you need it.
10
+ # 1.8 at all, and probably never will be. It should be used only if the
11
+ # underlying database and its driver does not or cannot properly handle
12
+ # the encoding of the data it returns (usually as "ASCII-8BIT"). Most
13
+ # databases can properly encode data, however, so your first assumption
14
+ # should be that you do not need this software unless you really know
15
+ # you need it.
15
16
  #
16
- # ActiveRecordEncoding keeps two variables on the default encoding to
17
- # use when accessing the database.
17
+ # ActiveRecordEncoding keeps two variables for each column and table
18
+ # where encoding is requested: a required external_encoding value and
19
+ # an optional internal_encoding value.
18
20
  #
19
- # ActiveRecordEncoding.external_encoding = 'ISO-8859-1'
20
- # ActiveRecordEncoding.internal_encoding = 'UTF-8'
21
+ # External encodings must be defined for each column or table where
22
+ # a translation is to occur, and this is done in the model definition:
21
23
  #
22
- # Deprecation Notice: ActiveRecordEncoding.external_encoding will be
23
- # discontinued in favor of explicitly setting encodings for particular
24
- # tables and columns in a future version.
24
+ # class User < ActiveRecord::Base
25
+ # external_encoding 'ISO-8859-1', :for => :comment
26
+ # external_encoding 'ISO-8859-1', :for => [:first_name, :last_name]
27
+ # end
25
28
  #
26
- # If the external_encoding is not explicitly set then no conversions
27
- # will be done. The internal_encoding value defaults to
28
- # Encoding.default_internal if not explicitly set.
29
+ # A similar internal_encoding method exists and specifies what encoding
30
+ # to use internally for each column or table, but this may also be set
31
+ # systemwide in the Rails environment files:
29
32
  #
30
- # The internal_encoding value is the encoding of the Strings that are
31
- # returned by ActiveRecord from String-based columns. The
32
- # external_encoding value tells ActiveRecord how the database is
33
- # actually encoding the data that is being returned as "ASCII-8BIT".
34
- # A conversion is done if necessary.
33
+ # ActiveRecordEncoding.internal_encoding = 'UTF-8'
35
34
  #
36
35
  # When data is being saved back to the database, the internal_encoding
37
36
  # value is ignored and the encoding of the input is used to determine
38
- # how to encode the data in the external_encoding.
39
- #
40
- # Encodings may also be defined on a table-by-table basis or
41
- # a column-by-column basis in the model definition.
37
+ # how to convert data to the external_encoding.
42
38
  #
43
39
  module ActiveRecordEncoding
44
-
45
40
  class << self
46
- attr_accessor :external_encoding, :internal_encoding
47
- end
48
-
49
- #
50
- # Set both ActiveRecordEncoding.external_encoding and
51
- # ActiveRecordEncoding.internal_encoding in a single method.
52
- #
53
- # ActiveRecordEncoding.encoding = 'UTF-8'
54
- #
55
- def encoding= (new_encoding)
56
- @internal_encoding = @external_encoding = new_encoding
41
+ attr_accessor :internal_encoding
42
+ alias :encoding= :internal_encoding=
57
43
  end
58
- module_function :encoding=
59
44
  end
60
45
 
61
46
 
62
-
63
- module ActiveRecordEncoding::ActiveRecordExtensionClassMethods
64
-
65
- def active_record_encodings
66
- @active_record_encodings ||= Hash.new { |h, k| h[k] = Hash.new }
67
- end
47
+ #
48
+ # StandardClassMethods defines class methods for inclusion in
49
+ # ActiveRecord::Base in order to provide the user interface for
50
+ # ActiveRecordEncoding.
51
+ #
52
+ module ActiveRecordEncoding::StandardClassMethods
68
53
 
69
54
  #
70
55
  # Set the external_encoding value for this model class.
@@ -85,6 +70,9 @@ module ActiveRecordEncoding::ActiveRecordExtensionClassMethods
85
70
  # end
86
71
  #
87
72
  def external_encoding (new_encoding, options = {})
73
+ extend ActiveRecordEncoding::ExtendedClassMethods
74
+ include ActiveRecordEncoding::IncludedInstanceMethods
75
+
88
76
  if attr_names = options[:for]
89
77
  [*attr_names].each do |attr_name|
90
78
  active_record_encodings[attr_name.to_s][:ext] = new_encoding
@@ -113,6 +101,9 @@ module ActiveRecordEncoding::ActiveRecordExtensionClassMethods
113
101
  # end
114
102
  #
115
103
  def internal_encoding (new_encoding, options = {})
104
+ extend ActiveRecordEncoding::ExtendedClassMethods
105
+ include ActiveRecordEncoding::IncludedInstanceMethods
106
+
116
107
  if attr_names = options[:for]
117
108
  [*attr_names].each do |attr_name|
118
109
  active_record_encodings[attr_name.to_s][:int] = new_encoding
@@ -142,6 +133,9 @@ module ActiveRecordEncoding::ActiveRecordExtensionClassMethods
142
133
  # end
143
134
  #
144
135
  def encoding (new_encoding, options = {})
136
+ extend ActiveRecordEncoding::ExtendedClassMethods
137
+ include ActiveRecordEncoding::IncludedInstanceMethods
138
+
145
139
  if attr_names = options[:for]
146
140
  [*attr_names].each do |attr_name|
147
141
  active_record_encodings[attr_name.to_s] =
@@ -153,10 +147,23 @@ module ActiveRecordEncoding::ActiveRecordExtensionClassMethods
153
147
  end
154
148
  end
155
149
 
150
+ end # ActiveRecordEncoding::StandardClassMethods
151
+
152
+
153
+ #
154
+ # ExtendedClassMethods defines class methods for inclusion in
155
+ # models sub-classed from ActiveRecord::Base to do the dirty work. It
156
+ # is only included in models that use ActiveRecordEncoding.
157
+ #
158
+ module ActiveRecordEncoding::ExtendedClassMethods
159
+
160
+ def active_record_encodings #:nodoc:
161
+ @active_record_encodings ||= Hash.new { |h, k| h[k] = Hash.new }
162
+ end
163
+
156
164
  def active_record_external_encoding (attr_name = nil) #:nodoc:
157
165
  active_record_encodings[attr_name][:ext] ||
158
- @active_record_external_encoding ||
159
- ActiveRecordEncoding.external_encoding
166
+ @active_record_external_encoding
160
167
  end
161
168
 
162
169
  def active_record_internal_encoding (attr_name = nil) #:nodoc:
@@ -172,6 +179,7 @@ module ActiveRecordEncoding::ActiveRecordExtensionClassMethods
172
179
  # Redefine the attribute read method to do the conversion.
173
180
  def encoding_aware_define_read_method (symbol, attr_name, column) #:nodoc:
174
181
  pre_encoding_aware_define_read_method(symbol, attr_name, column)
182
+ return if active_record_external_encoding(attr_name).nil?
175
183
  method_name = "encoding_aware_attr_#{symbol}".to_sym
176
184
  old_method_name = "pre_#{method_name}".to_sym
177
185
  code = <<-__EOM__
@@ -181,25 +189,42 @@ module ActiveRecordEncoding::ActiveRecordExtensionClassMethods
181
189
  alias_method "pre_#{method_name}".to_sym, symbol
182
190
  alias_method symbol, method_name
183
191
  end
184
- end
185
192
 
193
+ end # ActiveRecordEncoding::ExtendedClassMethods
186
194
 
187
- class ActiveRecord::Base #:nodoc:
188
- extend ActiveRecordEncoding::ActiveRecordExtensionClassMethods
189
195
 
190
- class << self
191
- alias_method :pre_encoding_aware_define_read_method, :define_read_method
192
- alias_method :define_read_method, :encoding_aware_define_read_method
196
+ #
197
+ # IncludedInstanceMethods defines instance methods for inclusion in
198
+ # models sub-classed from ActiveRecord::Base to do the dirty work. It
199
+ # is only included in models that use ActiveRecordEncoding.
200
+ #
201
+ module ActiveRecordEncoding::IncludedInstanceMethods
202
+
203
+ def self.included (model_class) #:nodoc:
204
+ class << model_class
205
+ alias_method :pre_encoding_aware_define_read_method, :define_read_method
206
+ alias_method :define_read_method, :encoding_aware_define_read_method
207
+ end
208
+
209
+ model_class.class_eval do
210
+ alias_method :pre_encoding_aware_read_attribute, :read_attribute
211
+ alias_method :read_attribute, :encoding_aware_read_attribute
212
+ end
193
213
  end
194
214
 
195
215
  # Method that casts the Binary data into Unicode, if necessary.
196
216
  def encoding_aware_attribute_cast! (attr_name, value) #:nodoc:
197
- if value.respond_to? :encoding and
198
- value.encoding.to_s.eql?('ASCII-8BIT') and
199
- ext_encoding = self.class.active_record_external_encoding(attr_name) \
217
+ if not value.frozen? and
218
+ not value.instance_variable_get(:@active_record_encoded) \
200
219
  then
201
- int_encoding = self.class.active_record_internal_encoding(attr_name)
202
- value.force_encoding(ext_encoding).encode!(int_encoding)
220
+ if value.respond_to? :encoding and
221
+ ext_encoding = self.class.active_record_external_encoding(attr_name) \
222
+ then
223
+ int_encoding = self.class.active_record_internal_encoding(attr_name)
224
+ value.force_encoding(ext_encoding).encode!(int_encoding)
225
+ end
226
+
227
+ value.instance_variable_set(:@active_record_encoded, true)
203
228
  end
204
229
 
205
230
  value
@@ -239,6 +264,7 @@ class ActiveRecord::Base #:nodoc:
239
264
  end
240
265
  end
241
266
 
242
- alias_method :pre_encoding_aware_read_attribute, :read_attribute
243
- alias_method :read_attribute, :encoding_aware_read_attribute
244
- end
267
+ end # ActiveRecordEncoding::IncludedInstanceMethods
268
+
269
+
270
+ ActiveRecord::Base.extend ActiveRecordEncoding::StandardClassMethods
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cosine-active_record_encoding
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.3
4
+ version: 0.9.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael H. Buselli