activerecord 4.2.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of activerecord might be problematic. Click here for more details.

Files changed (221) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +1372 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README.rdoc +218 -0
  5. data/examples/performance.rb +184 -0
  6. data/examples/simple.rb +14 -0
  7. data/lib/active_record.rb +173 -0
  8. data/lib/active_record/aggregations.rb +266 -0
  9. data/lib/active_record/association_relation.rb +22 -0
  10. data/lib/active_record/associations.rb +1724 -0
  11. data/lib/active_record/associations/alias_tracker.rb +87 -0
  12. data/lib/active_record/associations/association.rb +253 -0
  13. data/lib/active_record/associations/association_scope.rb +194 -0
  14. data/lib/active_record/associations/belongs_to_association.rb +111 -0
  15. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +40 -0
  16. data/lib/active_record/associations/builder/association.rb +149 -0
  17. data/lib/active_record/associations/builder/belongs_to.rb +116 -0
  18. data/lib/active_record/associations/builder/collection_association.rb +91 -0
  19. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +124 -0
  20. data/lib/active_record/associations/builder/has_many.rb +15 -0
  21. data/lib/active_record/associations/builder/has_one.rb +23 -0
  22. data/lib/active_record/associations/builder/singular_association.rb +38 -0
  23. data/lib/active_record/associations/collection_association.rb +634 -0
  24. data/lib/active_record/associations/collection_proxy.rb +1027 -0
  25. data/lib/active_record/associations/has_many_association.rb +184 -0
  26. data/lib/active_record/associations/has_many_through_association.rb +238 -0
  27. data/lib/active_record/associations/has_one_association.rb +105 -0
  28. data/lib/active_record/associations/has_one_through_association.rb +36 -0
  29. data/lib/active_record/associations/join_dependency.rb +282 -0
  30. data/lib/active_record/associations/join_dependency/join_association.rb +122 -0
  31. data/lib/active_record/associations/join_dependency/join_base.rb +22 -0
  32. data/lib/active_record/associations/join_dependency/join_part.rb +71 -0
  33. data/lib/active_record/associations/preloader.rb +203 -0
  34. data/lib/active_record/associations/preloader/association.rb +162 -0
  35. data/lib/active_record/associations/preloader/belongs_to.rb +17 -0
  36. data/lib/active_record/associations/preloader/collection_association.rb +24 -0
  37. data/lib/active_record/associations/preloader/has_many.rb +17 -0
  38. data/lib/active_record/associations/preloader/has_many_through.rb +19 -0
  39. data/lib/active_record/associations/preloader/has_one.rb +23 -0
  40. data/lib/active_record/associations/preloader/has_one_through.rb +9 -0
  41. data/lib/active_record/associations/preloader/singular_association.rb +21 -0
  42. data/lib/active_record/associations/preloader/through_association.rb +96 -0
  43. data/lib/active_record/associations/singular_association.rb +86 -0
  44. data/lib/active_record/associations/through_association.rb +96 -0
  45. data/lib/active_record/attribute.rb +149 -0
  46. data/lib/active_record/attribute_assignment.rb +212 -0
  47. data/lib/active_record/attribute_decorators.rb +66 -0
  48. data/lib/active_record/attribute_methods.rb +439 -0
  49. data/lib/active_record/attribute_methods/before_type_cast.rb +71 -0
  50. data/lib/active_record/attribute_methods/dirty.rb +181 -0
  51. data/lib/active_record/attribute_methods/primary_key.rb +128 -0
  52. data/lib/active_record/attribute_methods/query.rb +40 -0
  53. data/lib/active_record/attribute_methods/read.rb +103 -0
  54. data/lib/active_record/attribute_methods/serialization.rb +70 -0
  55. data/lib/active_record/attribute_methods/time_zone_conversion.rb +65 -0
  56. data/lib/active_record/attribute_methods/write.rb +83 -0
  57. data/lib/active_record/attribute_set.rb +77 -0
  58. data/lib/active_record/attribute_set/builder.rb +86 -0
  59. data/lib/active_record/attributes.rb +139 -0
  60. data/lib/active_record/autosave_association.rb +439 -0
  61. data/lib/active_record/base.rb +317 -0
  62. data/lib/active_record/callbacks.rb +313 -0
  63. data/lib/active_record/coders/json.rb +13 -0
  64. data/lib/active_record/coders/yaml_column.rb +38 -0
  65. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +659 -0
  66. data/lib/active_record/connection_adapters/abstract/database_limits.rb +67 -0
  67. data/lib/active_record/connection_adapters/abstract/database_statements.rb +373 -0
  68. data/lib/active_record/connection_adapters/abstract/query_cache.rb +95 -0
  69. data/lib/active_record/connection_adapters/abstract/quoting.rb +133 -0
  70. data/lib/active_record/connection_adapters/abstract/savepoints.rb +21 -0
  71. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +125 -0
  72. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +574 -0
  73. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +50 -0
  74. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +991 -0
  75. data/lib/active_record/connection_adapters/abstract/transaction.rb +219 -0
  76. data/lib/active_record/connection_adapters/abstract_adapter.rb +487 -0
  77. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +883 -0
  78. data/lib/active_record/connection_adapters/column.rb +82 -0
  79. data/lib/active_record/connection_adapters/connection_specification.rb +275 -0
  80. data/lib/active_record/connection_adapters/mysql2_adapter.rb +282 -0
  81. data/lib/active_record/connection_adapters/mysql_adapter.rb +491 -0
  82. data/lib/active_record/connection_adapters/postgresql/array_parser.rb +93 -0
  83. data/lib/active_record/connection_adapters/postgresql/column.rb +20 -0
  84. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +232 -0
  85. data/lib/active_record/connection_adapters/postgresql/oid.rb +36 -0
  86. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +99 -0
  87. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +52 -0
  88. data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +13 -0
  89. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +14 -0
  90. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +46 -0
  91. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +11 -0
  92. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +27 -0
  93. data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +13 -0
  94. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +17 -0
  95. data/lib/active_record/connection_adapters/postgresql/oid/float.rb +21 -0
  96. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +59 -0
  97. data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +13 -0
  98. data/lib/active_record/connection_adapters/postgresql/oid/infinity.rb +13 -0
  99. data/lib/active_record/connection_adapters/postgresql/oid/integer.rb +11 -0
  100. data/lib/active_record/connection_adapters/postgresql/oid/json.rb +35 -0
  101. data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +23 -0
  102. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +43 -0
  103. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +43 -0
  104. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +79 -0
  105. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +15 -0
  106. data/lib/active_record/connection_adapters/postgresql/oid/time.rb +11 -0
  107. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +97 -0
  108. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +21 -0
  109. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +26 -0
  110. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +28 -0
  111. data/lib/active_record/connection_adapters/postgresql/quoting.rb +108 -0
  112. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +30 -0
  113. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +152 -0
  114. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +588 -0
  115. data/lib/active_record/connection_adapters/postgresql/utils.rb +77 -0
  116. data/lib/active_record/connection_adapters/postgresql_adapter.rb +754 -0
  117. data/lib/active_record/connection_adapters/schema_cache.rb +94 -0
  118. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +628 -0
  119. data/lib/active_record/connection_adapters/statement_pool.rb +40 -0
  120. data/lib/active_record/connection_handling.rb +132 -0
  121. data/lib/active_record/core.rb +566 -0
  122. data/lib/active_record/counter_cache.rb +175 -0
  123. data/lib/active_record/dynamic_matchers.rb +140 -0
  124. data/lib/active_record/enum.rb +198 -0
  125. data/lib/active_record/errors.rb +252 -0
  126. data/lib/active_record/explain.rb +38 -0
  127. data/lib/active_record/explain_registry.rb +30 -0
  128. data/lib/active_record/explain_subscriber.rb +29 -0
  129. data/lib/active_record/fixture_set/file.rb +56 -0
  130. data/lib/active_record/fixtures.rb +1007 -0
  131. data/lib/active_record/gem_version.rb +15 -0
  132. data/lib/active_record/inheritance.rb +247 -0
  133. data/lib/active_record/integration.rb +113 -0
  134. data/lib/active_record/locale/en.yml +47 -0
  135. data/lib/active_record/locking/optimistic.rb +204 -0
  136. data/lib/active_record/locking/pessimistic.rb +77 -0
  137. data/lib/active_record/log_subscriber.rb +75 -0
  138. data/lib/active_record/migration.rb +1051 -0
  139. data/lib/active_record/migration/command_recorder.rb +197 -0
  140. data/lib/active_record/migration/join_table.rb +15 -0
  141. data/lib/active_record/model_schema.rb +340 -0
  142. data/lib/active_record/nested_attributes.rb +548 -0
  143. data/lib/active_record/no_touching.rb +52 -0
  144. data/lib/active_record/null_relation.rb +81 -0
  145. data/lib/active_record/persistence.rb +532 -0
  146. data/lib/active_record/query_cache.rb +56 -0
  147. data/lib/active_record/querying.rb +68 -0
  148. data/lib/active_record/railtie.rb +162 -0
  149. data/lib/active_record/railties/console_sandbox.rb +5 -0
  150. data/lib/active_record/railties/controller_runtime.rb +50 -0
  151. data/lib/active_record/railties/databases.rake +391 -0
  152. data/lib/active_record/railties/jdbcmysql_error.rb +16 -0
  153. data/lib/active_record/readonly_attributes.rb +23 -0
  154. data/lib/active_record/reflection.rb +881 -0
  155. data/lib/active_record/relation.rb +681 -0
  156. data/lib/active_record/relation/batches.rb +138 -0
  157. data/lib/active_record/relation/calculations.rb +403 -0
  158. data/lib/active_record/relation/delegation.rb +140 -0
  159. data/lib/active_record/relation/finder_methods.rb +528 -0
  160. data/lib/active_record/relation/merger.rb +170 -0
  161. data/lib/active_record/relation/predicate_builder.rb +126 -0
  162. data/lib/active_record/relation/predicate_builder/array_handler.rb +47 -0
  163. data/lib/active_record/relation/predicate_builder/relation_handler.rb +13 -0
  164. data/lib/active_record/relation/query_methods.rb +1176 -0
  165. data/lib/active_record/relation/spawn_methods.rb +75 -0
  166. data/lib/active_record/result.rb +131 -0
  167. data/lib/active_record/runtime_registry.rb +22 -0
  168. data/lib/active_record/sanitization.rb +191 -0
  169. data/lib/active_record/schema.rb +64 -0
  170. data/lib/active_record/schema_dumper.rb +251 -0
  171. data/lib/active_record/schema_migration.rb +56 -0
  172. data/lib/active_record/scoping.rb +87 -0
  173. data/lib/active_record/scoping/default.rb +134 -0
  174. data/lib/active_record/scoping/named.rb +164 -0
  175. data/lib/active_record/serialization.rb +22 -0
  176. data/lib/active_record/serializers/xml_serializer.rb +193 -0
  177. data/lib/active_record/statement_cache.rb +111 -0
  178. data/lib/active_record/store.rb +205 -0
  179. data/lib/active_record/tasks/database_tasks.rb +296 -0
  180. data/lib/active_record/tasks/mysql_database_tasks.rb +145 -0
  181. data/lib/active_record/tasks/postgresql_database_tasks.rb +90 -0
  182. data/lib/active_record/tasks/sqlite_database_tasks.rb +55 -0
  183. data/lib/active_record/timestamp.rb +121 -0
  184. data/lib/active_record/transactions.rb +417 -0
  185. data/lib/active_record/translation.rb +22 -0
  186. data/lib/active_record/type.rb +23 -0
  187. data/lib/active_record/type/big_integer.rb +13 -0
  188. data/lib/active_record/type/binary.rb +50 -0
  189. data/lib/active_record/type/boolean.rb +30 -0
  190. data/lib/active_record/type/date.rb +46 -0
  191. data/lib/active_record/type/date_time.rb +43 -0
  192. data/lib/active_record/type/decimal.rb +40 -0
  193. data/lib/active_record/type/decimal_without_scale.rb +11 -0
  194. data/lib/active_record/type/decorator.rb +14 -0
  195. data/lib/active_record/type/float.rb +19 -0
  196. data/lib/active_record/type/hash_lookup_type_map.rb +17 -0
  197. data/lib/active_record/type/integer.rb +55 -0
  198. data/lib/active_record/type/mutable.rb +16 -0
  199. data/lib/active_record/type/numeric.rb +36 -0
  200. data/lib/active_record/type/serialized.rb +56 -0
  201. data/lib/active_record/type/string.rb +36 -0
  202. data/lib/active_record/type/text.rb +11 -0
  203. data/lib/active_record/type/time.rb +26 -0
  204. data/lib/active_record/type/time_value.rb +38 -0
  205. data/lib/active_record/type/type_map.rb +64 -0
  206. data/lib/active_record/type/unsigned_integer.rb +15 -0
  207. data/lib/active_record/type/value.rb +101 -0
  208. data/lib/active_record/validations.rb +90 -0
  209. data/lib/active_record/validations/associated.rb +51 -0
  210. data/lib/active_record/validations/presence.rb +67 -0
  211. data/lib/active_record/validations/uniqueness.rb +229 -0
  212. data/lib/active_record/version.rb +8 -0
  213. data/lib/rails/generators/active_record.rb +17 -0
  214. data/lib/rails/generators/active_record/migration.rb +18 -0
  215. data/lib/rails/generators/active_record/migration/migration_generator.rb +70 -0
  216. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb +22 -0
  217. data/lib/rails/generators/active_record/migration/templates/migration.rb +45 -0
  218. data/lib/rails/generators/active_record/model/model_generator.rb +52 -0
  219. data/lib/rails/generators/active_record/model/templates/model.rb +10 -0
  220. data/lib/rails/generators/active_record/model/templates/module.rb +7 -0
  221. metadata +309 -0
@@ -0,0 +1,22 @@
1
+ module ActiveRecord
2
+ module Translation
3
+ include ActiveModel::Translation
4
+
5
+ # Set the lookup ancestors for ActiveModel.
6
+ def lookup_ancestors #:nodoc:
7
+ klass = self
8
+ classes = [klass]
9
+ return classes if klass == ActiveRecord::Base
10
+
11
+ while klass != klass.base_class
12
+ classes << klass = klass.superclass
13
+ end
14
+ classes
15
+ end
16
+
17
+ # Set the i18n scope to overwrite ActiveModel.
18
+ def i18n_scope #:nodoc:
19
+ :activerecord
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,23 @@
1
+ require 'active_record/type/decorator'
2
+ require 'active_record/type/mutable'
3
+ require 'active_record/type/numeric'
4
+ require 'active_record/type/time_value'
5
+ require 'active_record/type/value'
6
+
7
+ require 'active_record/type/big_integer'
8
+ require 'active_record/type/binary'
9
+ require 'active_record/type/boolean'
10
+ require 'active_record/type/date'
11
+ require 'active_record/type/date_time'
12
+ require 'active_record/type/decimal'
13
+ require 'active_record/type/decimal_without_scale'
14
+ require 'active_record/type/float'
15
+ require 'active_record/type/integer'
16
+ require 'active_record/type/serialized'
17
+ require 'active_record/type/string'
18
+ require 'active_record/type/text'
19
+ require 'active_record/type/time'
20
+ require 'active_record/type/unsigned_integer'
21
+
22
+ require 'active_record/type/type_map'
23
+ require 'active_record/type/hash_lookup_type_map'
@@ -0,0 +1,13 @@
1
+ require 'active_record/type/integer'
2
+
3
+ module ActiveRecord
4
+ module Type
5
+ class BigInteger < Integer # :nodoc:
6
+ private
7
+
8
+ def max_value
9
+ ::Float::INFINITY
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,50 @@
1
+ module ActiveRecord
2
+ module Type
3
+ class Binary < Value # :nodoc:
4
+ def type
5
+ :binary
6
+ end
7
+
8
+ def binary?
9
+ true
10
+ end
11
+
12
+ def type_cast(value)
13
+ if value.is_a?(Data)
14
+ value.to_s
15
+ else
16
+ super
17
+ end
18
+ end
19
+
20
+ def type_cast_for_database(value)
21
+ return if value.nil?
22
+ Data.new(super)
23
+ end
24
+
25
+ def changed_in_place?(raw_old_value, value)
26
+ old_value = type_cast_from_database(raw_old_value)
27
+ old_value != value
28
+ end
29
+
30
+ class Data # :nodoc:
31
+ def initialize(value)
32
+ @value = value.to_s
33
+ end
34
+
35
+ def to_s
36
+ @value
37
+ end
38
+ alias_method :to_str, :to_s
39
+
40
+ def hex
41
+ @value.unpack('H*')[0]
42
+ end
43
+
44
+ def ==(other)
45
+ other == to_s || super
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,30 @@
1
+ module ActiveRecord
2
+ module Type
3
+ class Boolean < Value # :nodoc:
4
+ def type
5
+ :boolean
6
+ end
7
+
8
+ private
9
+
10
+ def cast_value(value)
11
+ if value == ''
12
+ nil
13
+ elsif ConnectionAdapters::Column::TRUE_VALUES.include?(value)
14
+ true
15
+ else
16
+ if !ConnectionAdapters::Column::FALSE_VALUES.include?(value)
17
+ ActiveSupport::Deprecation.warn(<<-MSG.squish)
18
+ You attempted to assign a value which is not explicitly `true` or `false`
19
+ to a boolean column. Currently this value casts to `false`. This will
20
+ change to match Ruby's semantics, and will cast to `true` in Rails 5.
21
+ If you would like to maintain the current behavior, you should
22
+ explicitly handle the values you would like cast to `false`.
23
+ MSG
24
+ end
25
+ false
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,46 @@
1
+ module ActiveRecord
2
+ module Type
3
+ class Date < Value # :nodoc:
4
+ def type
5
+ :date
6
+ end
7
+
8
+ def klass
9
+ ::Date
10
+ end
11
+
12
+ def type_cast_for_schema(value)
13
+ "'#{value.to_s(:db)}'"
14
+ end
15
+
16
+ private
17
+
18
+ def cast_value(value)
19
+ if value.is_a?(::String)
20
+ return if value.empty?
21
+ fast_string_to_date(value) || fallback_string_to_date(value)
22
+ elsif value.respond_to?(:to_date)
23
+ value.to_date
24
+ else
25
+ value
26
+ end
27
+ end
28
+
29
+ def fast_string_to_date(string)
30
+ if string =~ ConnectionAdapters::Column::Format::ISO_DATE
31
+ new_date $1.to_i, $2.to_i, $3.to_i
32
+ end
33
+ end
34
+
35
+ def fallback_string_to_date(string)
36
+ new_date(*::Date._parse(string, false).values_at(:year, :mon, :mday))
37
+ end
38
+
39
+ def new_date(year, mon, mday)
40
+ if year && year != 0
41
+ ::Date.new(year, mon, mday) rescue nil
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,43 @@
1
+ module ActiveRecord
2
+ module Type
3
+ class DateTime < Value # :nodoc:
4
+ include TimeValue
5
+
6
+ def type
7
+ :datetime
8
+ end
9
+
10
+ def type_cast_for_database(value)
11
+ zone_conversion_method = ActiveRecord::Base.default_timezone == :utc ? :getutc : :getlocal
12
+
13
+ if value.acts_like?(:time)
14
+ value.send(zone_conversion_method)
15
+ else
16
+ super
17
+ end
18
+ end
19
+
20
+ private
21
+
22
+ def cast_value(string)
23
+ return string unless string.is_a?(::String)
24
+ return if string.empty?
25
+
26
+ fast_string_to_time(string) || fallback_string_to_time(string)
27
+ end
28
+
29
+ # '0.123456' -> 123456
30
+ # '1.123456' -> 123456
31
+ def microseconds(time)
32
+ time[:sec_fraction] ? (time[:sec_fraction] * 1_000_000).to_i : 0
33
+ end
34
+
35
+ def fallback_string_to_time(string)
36
+ time_hash = ::Date._parse(string)
37
+ time_hash[:sec_fraction] = microseconds(time_hash)
38
+
39
+ new_time(*time_hash.values_at(:year, :mon, :mday, :hour, :min, :sec, :sec_fraction, :offset))
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,40 @@
1
+ module ActiveRecord
2
+ module Type
3
+ class Decimal < Value # :nodoc:
4
+ include Numeric
5
+
6
+ def type
7
+ :decimal
8
+ end
9
+
10
+ def type_cast_for_schema(value)
11
+ value.to_s
12
+ end
13
+
14
+ private
15
+
16
+ def cast_value(value)
17
+ case value
18
+ when ::Float
19
+ BigDecimal(value, float_precision)
20
+ when ::Numeric, ::String
21
+ BigDecimal(value, precision.to_i)
22
+ else
23
+ if value.respond_to?(:to_d)
24
+ value.to_d
25
+ else
26
+ cast_value(value.to_s)
27
+ end
28
+ end
29
+ end
30
+
31
+ def float_precision
32
+ if precision.to_i > ::Float::DIG + 1
33
+ ::Float::DIG + 1
34
+ else
35
+ precision.to_i
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,11 @@
1
+ require 'active_record/type/big_integer'
2
+
3
+ module ActiveRecord
4
+ module Type
5
+ class DecimalWithoutScale < BigInteger # :nodoc:
6
+ def type
7
+ :decimal
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,14 @@
1
+ module ActiveRecord
2
+ module Type
3
+ module Decorator # :nodoc:
4
+ def init_with(coder)
5
+ @subtype = coder['subtype']
6
+ __setobj__(@subtype)
7
+ end
8
+
9
+ def encode_with(coder)
10
+ coder['subtype'] = __getobj__
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,19 @@
1
+ module ActiveRecord
2
+ module Type
3
+ class Float < Value # :nodoc:
4
+ include Numeric
5
+
6
+ def type
7
+ :float
8
+ end
9
+
10
+ alias type_cast_for_database type_cast
11
+
12
+ private
13
+
14
+ def cast_value(value)
15
+ value.to_f
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,17 @@
1
+ module ActiveRecord
2
+ module Type
3
+ class HashLookupTypeMap < TypeMap # :nodoc:
4
+ delegate :key?, to: :@mapping
5
+
6
+ def alias_type(type, alias_type)
7
+ register_type(type) { |_, *args| lookup(alias_type, *args) }
8
+ end
9
+
10
+ private
11
+
12
+ def perform_fetch(type, *args, &block)
13
+ @mapping.fetch(type, block).call(type, *args)
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,55 @@
1
+ module ActiveRecord
2
+ module Type
3
+ class Integer < Value # :nodoc:
4
+ include Numeric
5
+
6
+ def initialize(*)
7
+ super
8
+ @range = min_value...max_value
9
+ end
10
+
11
+ def type
12
+ :integer
13
+ end
14
+
15
+ alias type_cast_for_database type_cast
16
+
17
+ def type_cast_from_database(value)
18
+ return if value.nil?
19
+ value.to_i
20
+ end
21
+
22
+ protected
23
+
24
+ attr_reader :range
25
+
26
+ private
27
+
28
+ def cast_value(value)
29
+ case value
30
+ when true then 1
31
+ when false then 0
32
+ else
33
+ result = value.to_i rescue nil
34
+ ensure_in_range(result) if result
35
+ result
36
+ end
37
+ end
38
+
39
+ def ensure_in_range(value)
40
+ unless range.cover?(value)
41
+ raise RangeError, "#{value} is out of range for #{self.class} with limit #{limit || 4}"
42
+ end
43
+ end
44
+
45
+ def max_value
46
+ limit = self.limit || 4
47
+ 1 << (limit * 8 - 1) # 8 bits per byte with one bit for sign
48
+ end
49
+
50
+ def min_value
51
+ -max_value
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,16 @@
1
+ module ActiveRecord
2
+ module Type
3
+ module Mutable # :nodoc:
4
+ def type_cast_from_user(value)
5
+ type_cast_from_database(type_cast_for_database(value))
6
+ end
7
+
8
+ # +raw_old_value+ will be the `_before_type_cast` version of the
9
+ # value (likely a string). +new_value+ will be the current, type
10
+ # cast value.
11
+ def changed_in_place?(raw_old_value, new_value)
12
+ raw_old_value != type_cast_for_database(new_value)
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,36 @@
1
+ module ActiveRecord
2
+ module Type
3
+ module Numeric # :nodoc:
4
+ def number?
5
+ true
6
+ end
7
+
8
+ def type_cast(value)
9
+ value = case value
10
+ when true then 1
11
+ when false then 0
12
+ when ::String then value.presence
13
+ else value
14
+ end
15
+ super(value)
16
+ end
17
+
18
+ def changed?(old_value, _new_value, new_value_before_type_cast) # :nodoc:
19
+ super || number_to_non_number?(old_value, new_value_before_type_cast)
20
+ end
21
+
22
+ private
23
+
24
+ def number_to_non_number?(old_value, new_value_before_type_cast)
25
+ old_value != nil && non_numeric_string?(new_value_before_type_cast)
26
+ end
27
+
28
+ def non_numeric_string?(value)
29
+ # 'wibble'.to_i will give zero, we want to make sure
30
+ # that we aren't marking int zero to string zero as
31
+ # changed.
32
+ value.to_s !~ /\A\d+\.?\d*\z/
33
+ end
34
+ end
35
+ end
36
+ end