activerecord 4.1.0 → 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 (185) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +776 -1330
  3. data/README.rdoc +15 -10
  4. data/lib/active_record/aggregations.rb +12 -8
  5. data/lib/active_record/association_relation.rb +4 -0
  6. data/lib/active_record/associations/alias_tracker.rb +14 -13
  7. data/lib/active_record/associations/association.rb +2 -2
  8. data/lib/active_record/associations/association_scope.rb +83 -43
  9. data/lib/active_record/associations/belongs_to_association.rb +15 -5
  10. data/lib/active_record/associations/builder/association.rb +15 -4
  11. data/lib/active_record/associations/builder/belongs_to.rb +7 -29
  12. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +9 -6
  13. data/lib/active_record/associations/builder/has_many.rb +1 -1
  14. data/lib/active_record/associations/builder/has_one.rb +2 -2
  15. data/lib/active_record/associations/builder/singular_association.rb +8 -1
  16. data/lib/active_record/associations/collection_association.rb +66 -29
  17. data/lib/active_record/associations/collection_proxy.rb +22 -26
  18. data/lib/active_record/associations/has_many_association.rb +65 -18
  19. data/lib/active_record/associations/has_many_through_association.rb +55 -27
  20. data/lib/active_record/associations/has_one_association.rb +0 -1
  21. data/lib/active_record/associations/join_dependency/join_association.rb +19 -15
  22. data/lib/active_record/associations/join_dependency/join_part.rb +0 -1
  23. data/lib/active_record/associations/join_dependency.rb +20 -12
  24. data/lib/active_record/associations/preloader/association.rb +34 -11
  25. data/lib/active_record/associations/preloader/through_association.rb +4 -3
  26. data/lib/active_record/associations/preloader.rb +49 -59
  27. data/lib/active_record/associations/singular_association.rb +25 -4
  28. data/lib/active_record/associations/through_association.rb +23 -14
  29. data/lib/active_record/associations.rb +171 -42
  30. data/lib/active_record/attribute.rb +149 -0
  31. data/lib/active_record/attribute_assignment.rb +18 -10
  32. data/lib/active_record/attribute_decorators.rb +66 -0
  33. data/lib/active_record/attribute_methods/before_type_cast.rb +2 -2
  34. data/lib/active_record/attribute_methods/dirty.rb +98 -44
  35. data/lib/active_record/attribute_methods/primary_key.rb +14 -8
  36. data/lib/active_record/attribute_methods/query.rb +1 -1
  37. data/lib/active_record/attribute_methods/read.rb +22 -59
  38. data/lib/active_record/attribute_methods/serialization.rb +37 -147
  39. data/lib/active_record/attribute_methods/time_zone_conversion.rb +34 -28
  40. data/lib/active_record/attribute_methods/write.rb +14 -21
  41. data/lib/active_record/attribute_methods.rb +67 -94
  42. data/lib/active_record/attribute_set/builder.rb +86 -0
  43. data/lib/active_record/attribute_set.rb +77 -0
  44. data/lib/active_record/attributes.rb +139 -0
  45. data/lib/active_record/autosave_association.rb +45 -38
  46. data/lib/active_record/base.rb +10 -20
  47. data/lib/active_record/callbacks.rb +7 -7
  48. data/lib/active_record/coders/json.rb +13 -0
  49. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +78 -52
  50. data/lib/active_record/connection_adapters/abstract/database_statements.rb +38 -59
  51. data/lib/active_record/connection_adapters/abstract/query_cache.rb +1 -0
  52. data/lib/active_record/connection_adapters/abstract/quoting.rb +59 -55
  53. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +46 -5
  54. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +126 -54
  55. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +14 -34
  56. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +198 -64
  57. data/lib/active_record/connection_adapters/abstract/transaction.rb +126 -114
  58. data/lib/active_record/connection_adapters/abstract_adapter.rb +154 -55
  59. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +240 -135
  60. data/lib/active_record/connection_adapters/column.rb +28 -239
  61. data/lib/active_record/connection_adapters/connection_specification.rb +16 -25
  62. data/lib/active_record/connection_adapters/mysql2_adapter.rb +20 -22
  63. data/lib/active_record/connection_adapters/mysql_adapter.rb +65 -149
  64. data/lib/active_record/connection_adapters/postgresql/array_parser.rb +15 -27
  65. data/lib/active_record/connection_adapters/postgresql/column.rb +20 -0
  66. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +39 -27
  67. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +99 -0
  68. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +52 -0
  69. data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +13 -0
  70. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +14 -0
  71. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +46 -0
  72. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +11 -0
  73. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +27 -0
  74. data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +13 -0
  75. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +17 -0
  76. data/lib/active_record/connection_adapters/postgresql/oid/float.rb +21 -0
  77. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +59 -0
  78. data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +13 -0
  79. data/lib/active_record/connection_adapters/postgresql/oid/infinity.rb +13 -0
  80. data/lib/active_record/connection_adapters/postgresql/oid/integer.rb +11 -0
  81. data/lib/active_record/connection_adapters/postgresql/oid/json.rb +35 -0
  82. data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +23 -0
  83. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +43 -0
  84. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +43 -0
  85. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +79 -0
  86. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +15 -0
  87. data/lib/active_record/connection_adapters/postgresql/oid/time.rb +11 -0
  88. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +97 -0
  89. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +21 -0
  90. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +26 -0
  91. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +28 -0
  92. data/lib/active_record/connection_adapters/postgresql/oid.rb +29 -374
  93. data/lib/active_record/connection_adapters/postgresql/quoting.rb +55 -135
  94. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +4 -4
  95. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +152 -0
  96. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +127 -38
  97. data/lib/active_record/connection_adapters/postgresql/utils.rb +77 -0
  98. data/lib/active_record/connection_adapters/postgresql_adapter.rb +220 -466
  99. data/lib/active_record/connection_adapters/schema_cache.rb +14 -28
  100. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +66 -61
  101. data/lib/active_record/connection_handling.rb +3 -3
  102. data/lib/active_record/core.rb +143 -32
  103. data/lib/active_record/counter_cache.rb +60 -7
  104. data/lib/active_record/enum.rb +10 -11
  105. data/lib/active_record/errors.rb +49 -27
  106. data/lib/active_record/explain.rb +1 -1
  107. data/lib/active_record/fixtures.rb +56 -70
  108. data/lib/active_record/gem_version.rb +2 -2
  109. data/lib/active_record/inheritance.rb +35 -10
  110. data/lib/active_record/integration.rb +4 -4
  111. data/lib/active_record/locking/optimistic.rb +35 -17
  112. data/lib/active_record/log_subscriber.rb +1 -1
  113. data/lib/active_record/migration/command_recorder.rb +19 -2
  114. data/lib/active_record/migration/join_table.rb +1 -1
  115. data/lib/active_record/migration.rb +52 -49
  116. data/lib/active_record/model_schema.rb +49 -57
  117. data/lib/active_record/nested_attributes.rb +7 -7
  118. data/lib/active_record/null_relation.rb +19 -5
  119. data/lib/active_record/persistence.rb +50 -31
  120. data/lib/active_record/query_cache.rb +3 -3
  121. data/lib/active_record/querying.rb +10 -7
  122. data/lib/active_record/railtie.rb +14 -11
  123. data/lib/active_record/railties/databases.rake +56 -54
  124. data/lib/active_record/readonly_attributes.rb +0 -1
  125. data/lib/active_record/reflection.rb +286 -102
  126. data/lib/active_record/relation/batches.rb +0 -1
  127. data/lib/active_record/relation/calculations.rb +39 -31
  128. data/lib/active_record/relation/delegation.rb +2 -2
  129. data/lib/active_record/relation/finder_methods.rb +80 -36
  130. data/lib/active_record/relation/merger.rb +25 -30
  131. data/lib/active_record/relation/predicate_builder/array_handler.rb +31 -13
  132. data/lib/active_record/relation/predicate_builder/relation_handler.rb +1 -1
  133. data/lib/active_record/relation/predicate_builder.rb +11 -10
  134. data/lib/active_record/relation/query_methods.rb +141 -55
  135. data/lib/active_record/relation/spawn_methods.rb +3 -0
  136. data/lib/active_record/relation.rb +69 -30
  137. data/lib/active_record/result.rb +18 -7
  138. data/lib/active_record/sanitization.rb +12 -2
  139. data/lib/active_record/schema.rb +0 -1
  140. data/lib/active_record/schema_dumper.rb +58 -26
  141. data/lib/active_record/schema_migration.rb +11 -0
  142. data/lib/active_record/scoping/default.rb +8 -7
  143. data/lib/active_record/scoping/named.rb +4 -0
  144. data/lib/active_record/serializers/xml_serializer.rb +3 -7
  145. data/lib/active_record/statement_cache.rb +95 -10
  146. data/lib/active_record/store.rb +19 -10
  147. data/lib/active_record/tasks/database_tasks.rb +73 -7
  148. data/lib/active_record/tasks/mysql_database_tasks.rb +3 -2
  149. data/lib/active_record/tasks/postgresql_database_tasks.rb +1 -1
  150. data/lib/active_record/tasks/sqlite_database_tasks.rb +5 -1
  151. data/lib/active_record/timestamp.rb +11 -9
  152. data/lib/active_record/transactions.rb +37 -21
  153. data/lib/active_record/type/big_integer.rb +13 -0
  154. data/lib/active_record/type/binary.rb +50 -0
  155. data/lib/active_record/type/boolean.rb +30 -0
  156. data/lib/active_record/type/date.rb +46 -0
  157. data/lib/active_record/type/date_time.rb +43 -0
  158. data/lib/active_record/type/decimal.rb +40 -0
  159. data/lib/active_record/type/decimal_without_scale.rb +11 -0
  160. data/lib/active_record/type/decorator.rb +14 -0
  161. data/lib/active_record/type/float.rb +19 -0
  162. data/lib/active_record/type/hash_lookup_type_map.rb +17 -0
  163. data/lib/active_record/type/integer.rb +55 -0
  164. data/lib/active_record/type/mutable.rb +16 -0
  165. data/lib/active_record/type/numeric.rb +36 -0
  166. data/lib/active_record/type/serialized.rb +56 -0
  167. data/lib/active_record/type/string.rb +36 -0
  168. data/lib/active_record/type/text.rb +11 -0
  169. data/lib/active_record/type/time.rb +26 -0
  170. data/lib/active_record/type/time_value.rb +38 -0
  171. data/lib/active_record/type/type_map.rb +64 -0
  172. data/lib/active_record/type/unsigned_integer.rb +15 -0
  173. data/lib/active_record/type/value.rb +101 -0
  174. data/lib/active_record/type.rb +23 -0
  175. data/lib/active_record/validations/associated.rb +5 -3
  176. data/lib/active_record/validations/presence.rb +6 -4
  177. data/lib/active_record/validations/uniqueness.rb +11 -17
  178. data/lib/active_record/validations.rb +25 -19
  179. data/lib/active_record.rb +3 -0
  180. data/lib/rails/generators/active_record/migration/migration_generator.rb +8 -4
  181. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb +4 -1
  182. data/lib/rails/generators/active_record/migration/templates/migration.rb +6 -0
  183. data/lib/rails/generators/active_record/model/templates/model.rb +1 -1
  184. metadata +65 -10
  185. data/lib/active_record/connection_adapters/postgresql/cast.rb +0 -168
@@ -1,11 +1,14 @@
1
1
  require 'date'
2
2
  require 'bigdecimal'
3
3
  require 'bigdecimal/util'
4
+ require 'active_record/type'
4
5
  require 'active_support/core_ext/benchmark'
5
6
  require 'active_record/connection_adapters/schema_cache'
6
7
  require 'active_record/connection_adapters/abstract/schema_dumper'
7
8
  require 'active_record/connection_adapters/abstract/schema_creation'
8
9
  require 'monitor'
10
+ require 'arel/collectors/bind'
11
+ require 'arel/collectors/sql_string'
9
12
 
10
13
  module ActiveRecord
11
14
  module ConnectionAdapters # :nodoc:
@@ -21,6 +24,7 @@ module ActiveRecord
21
24
  autoload :TableDefinition
22
25
  autoload :Table
23
26
  autoload :AlterTable
27
+ autoload :TimestampDefaultDeprecation
24
28
  end
25
29
 
26
30
  autoload_at 'active_record/connection_adapters/abstract/connection_pool' do
@@ -39,7 +43,8 @@ module ActiveRecord
39
43
  end
40
44
 
41
45
  autoload_at 'active_record/connection_adapters/abstract/transaction' do
42
- autoload :ClosedTransaction
46
+ autoload :TransactionManager
47
+ autoload :NullTransaction
43
48
  autoload :RealTransaction
44
49
  autoload :SavepointTransaction
45
50
  autoload :TransactionState
@@ -59,6 +64,7 @@ module ActiveRecord
59
64
  # Most of the methods in the adapter are useful during migrations. Most
60
65
  # notably, the instance methods provided by SchemaStatement are very useful.
61
66
  class AbstractAdapter
67
+ ADAPTER_NAME = 'Abstract'.freeze
62
68
  include Quoting, DatabaseStatements, SchemaStatements
63
69
  include DatabaseLimits
64
70
  include QueryCache
@@ -71,8 +77,8 @@ module ActiveRecord
71
77
  define_callbacks :checkout, :checkin
72
78
 
73
79
  attr_accessor :visitor, :pool
74
- attr_reader :schema_cache, :last_use, :in_use, :logger
75
- alias :in_use? :in_use
80
+ attr_reader :schema_cache, :owner, :logger
81
+ alias :in_use? :owner
76
82
 
77
83
  def self.type_cast_config_to_integer(config)
78
84
  if config =~ SIMPLE_INT
@@ -90,13 +96,14 @@ module ActiveRecord
90
96
  end
91
97
  end
92
98
 
99
+ attr_reader :prepared_statements
100
+
93
101
  def initialize(connection, logger = nil, pool = nil) #:nodoc:
94
102
  super()
95
103
 
96
104
  @connection = connection
97
- @in_use = false
105
+ @owner = nil
98
106
  @instrumenter = ActiveSupport::Notifications.instrumenter
99
- @last_use = false
100
107
  @logger = logger
101
108
  @pool = pool
102
109
  @schema_cache = SchemaCache.new self
@@ -104,6 +111,26 @@ module ActiveRecord
104
111
  @prepared_statements = false
105
112
  end
106
113
 
114
+ class BindCollector < Arel::Collectors::Bind
115
+ def compile(bvs, conn)
116
+ super(bvs.map { |bv| conn.quote(*bv.reverse) })
117
+ end
118
+ end
119
+
120
+ class SQLString < Arel::Collectors::SQLString
121
+ def compile(bvs, conn)
122
+ super(bvs)
123
+ end
124
+ end
125
+
126
+ def collector
127
+ if prepared_statements
128
+ SQLString.new
129
+ else
130
+ BindCollector.new
131
+ end
132
+ end
133
+
107
134
  def valid_type?(type)
108
135
  true
109
136
  end
@@ -114,9 +141,8 @@ module ActiveRecord
114
141
 
115
142
  def lease
116
143
  synchronize do
117
- unless in_use
118
- @in_use = true
119
- @last_use = Time.now
144
+ unless in_use?
145
+ @owner = Thread.current
120
146
  end
121
147
  end
122
148
  end
@@ -127,49 +153,35 @@ module ActiveRecord
127
153
  end
128
154
 
129
155
  def expire
130
- @in_use = false
131
- end
132
-
133
- def unprepared_visitor
134
- self.class::BindSubstitution.new self
156
+ @owner = nil
135
157
  end
136
158
 
137
159
  def unprepared_statement
138
160
  old_prepared_statements, @prepared_statements = @prepared_statements, false
139
- old_visitor, @visitor = @visitor, unprepared_visitor
140
161
  yield
141
162
  ensure
142
- @visitor, @prepared_statements = old_visitor, old_prepared_statements
163
+ @prepared_statements = old_prepared_statements
143
164
  end
144
165
 
145
166
  # Returns the human-readable name of the adapter. Use mixed case - one
146
167
  # can always use downcase if needed.
147
168
  def adapter_name
148
- 'Abstract'
169
+ self.class::ADAPTER_NAME
149
170
  end
150
171
 
151
- # Does this adapter support migrations? Backend specific, as the
152
- # abstract adapter always returns +false+.
172
+ # Does this adapter support migrations?
153
173
  def supports_migrations?
154
174
  false
155
175
  end
156
176
 
157
177
  # Can this adapter determine the primary key for tables not attached
158
- # to an Active Record class, such as join tables? Backend specific, as
159
- # the abstract adapter always returns +false+.
178
+ # to an Active Record class, such as join tables?
160
179
  def supports_primary_key?
161
180
  false
162
181
  end
163
182
 
164
- # Does this adapter support using DISTINCT within COUNT? This is +true+
165
- # for all adapters except sqlite.
166
- def supports_count_distinct?
167
- true
168
- end
169
-
170
183
  # Does this adapter support DDL rollbacks in transactions? That is, would
171
- # CREATE TABLE or ALTER TABLE get rolled back by a transaction? PostgreSQL,
172
- # SQL Server, and others support this. MySQL and others do not.
184
+ # CREATE TABLE or ALTER TABLE get rolled back by a transaction?
173
185
  def supports_ddl_transactions?
174
186
  false
175
187
  end
@@ -178,8 +190,7 @@ module ActiveRecord
178
190
  false
179
191
  end
180
192
 
181
- # Does this adapter support savepoints? PostgreSQL and MySQL do,
182
- # SQLite < 3.6.8 does not.
193
+ # Does this adapter support savepoints?
183
194
  def supports_savepoints?
184
195
  false
185
196
  end
@@ -187,7 +198,6 @@ module ActiveRecord
187
198
  # Should primary key values be selected from their corresponding
188
199
  # sequence before the insert statement? If true, next_sequence_value
189
200
  # is called before each insert to set the record's primary key.
190
- # This is false for all adapters but Firebird.
191
201
  def prefetch_primary_key?(table_name = nil)
192
202
  false
193
203
  end
@@ -202,8 +212,7 @@ module ActiveRecord
202
212
  false
203
213
  end
204
214
 
205
- # Does this adapter support explain? As of this writing sqlite3,
206
- # mysql2, and postgresql are the only ones that do.
215
+ # Does this adapter support explain?
207
216
  def supports_explain?
208
217
  false
209
218
  end
@@ -213,12 +222,27 @@ module ActiveRecord
213
222
  false
214
223
  end
215
224
 
216
- # Does this adapter support database extensions? As of this writing only
217
- # postgresql does.
225
+ # Does this adapter support database extensions?
218
226
  def supports_extensions?
219
227
  false
220
228
  end
221
229
 
230
+ # Does this adapter support creating indexes in the same statement as
231
+ # creating the table?
232
+ def supports_indexes_in_create?
233
+ false
234
+ end
235
+
236
+ # Does this adapter support creating foreign key constraints?
237
+ def supports_foreign_keys?
238
+ false
239
+ end
240
+
241
+ # Does this adapter support views?
242
+ def supports_views?
243
+ false
244
+ end
245
+
222
246
  # This is meant to be implemented by the adapters that support extensions
223
247
  def disable_extension(name)
224
248
  end
@@ -227,24 +251,22 @@ module ActiveRecord
227
251
  def enable_extension(name)
228
252
  end
229
253
 
230
- # A list of extensions, to be filled in by adapters that support them. At
231
- # the moment only postgresql does.
254
+ # A list of extensions, to be filled in by adapters that support them.
232
255
  def extensions
233
256
  []
234
257
  end
235
258
 
236
259
  # A list of index algorithms, to be filled by adapters that support them.
237
- # MySQL and PostgreSQL have support for them right now.
238
260
  def index_algorithms
239
261
  {}
240
262
  end
241
263
 
242
264
  # QUOTING ==================================================
243
265
 
244
- # Returns a bind substitution value given a bind +index+ and +column+
266
+ # Returns a bind substitution value given a bind +column+
245
267
  # NOTE: The column param is currently being used by the sqlserver-adapter
246
- def substitute_at(column, index)
247
- Arel::Nodes::BindParam.new '?'
268
+ def substitute_at(column, _unused = 0)
269
+ Arel::Nodes::BindParam.new
248
270
  end
249
271
 
250
272
  # REFERENTIAL INTEGRITY ====================================
@@ -262,12 +284,6 @@ module ActiveRecord
262
284
  def active?
263
285
  end
264
286
 
265
- # Adapter should redefine this if it needs a threadsafe way to approximate
266
- # if the connection is active
267
- def active_threadsafe?
268
- active?
269
- end
270
-
271
287
  # Disconnects from the database if already connected, and establishes a
272
288
  # new connection with the database. Implementors should call super if they
273
289
  # override the default implementation.
@@ -301,7 +317,6 @@ module ActiveRecord
301
317
  end
302
318
 
303
319
  # Returns true if its required to reload the connection between requests for development mode.
304
- # This is not the case for Ruby/MySQL and it's not necessary for any adapters except SQLite.
305
320
  def requires_reloading?
306
321
  false
307
322
  end
@@ -323,10 +338,6 @@ module ActiveRecord
323
338
  @connection
324
339
  end
325
340
 
326
- def open_transactions
327
- @transaction.number
328
- end
329
-
330
341
  def create_savepoint(name = nil)
331
342
  end
332
343
 
@@ -336,16 +347,22 @@ module ActiveRecord
336
347
  def release_savepoint(name = nil)
337
348
  end
338
349
 
339
- def case_sensitive_modifier(node)
350
+ def case_sensitive_modifier(node, table_attribute)
340
351
  node
341
352
  end
342
353
 
354
+ def case_sensitive_comparison(table, attribute, column, value)
355
+ table_attr = table[attribute]
356
+ value = case_sensitive_modifier(value, table_attr) unless value.nil?
357
+ table_attr.eq(value)
358
+ end
359
+
343
360
  def case_insensitive_comparison(table, attribute, column, value)
344
361
  table[attribute].lower.eq(table.lower(value))
345
362
  end
346
363
 
347
364
  def current_savepoint_name
348
- "active_record_#{open_transactions}"
365
+ current_transaction.savepoint_name
349
366
  end
350
367
 
351
368
  # Check the connection back in to the connection pool
@@ -353,8 +370,84 @@ module ActiveRecord
353
370
  pool.checkin self
354
371
  end
355
372
 
373
+ def type_map # :nodoc:
374
+ @type_map ||= Type::TypeMap.new.tap do |mapping|
375
+ initialize_type_map(mapping)
376
+ end
377
+ end
378
+
379
+ def new_column(name, default, cast_type, sql_type = nil, null = true)
380
+ Column.new(name, default, cast_type, sql_type, null)
381
+ end
382
+
383
+ def lookup_cast_type(sql_type) # :nodoc:
384
+ type_map.lookup(sql_type)
385
+ end
386
+
387
+ def column_name_for_operation(operation, node) # :nodoc:
388
+ node.to_sql
389
+ end
390
+
356
391
  protected
357
392
 
393
+ def initialize_type_map(m) # :nodoc:
394
+ register_class_with_limit m, %r(boolean)i, Type::Boolean
395
+ register_class_with_limit m, %r(char)i, Type::String
396
+ register_class_with_limit m, %r(binary)i, Type::Binary
397
+ register_class_with_limit m, %r(text)i, Type::Text
398
+ register_class_with_limit m, %r(date)i, Type::Date
399
+ register_class_with_limit m, %r(time)i, Type::Time
400
+ register_class_with_limit m, %r(datetime)i, Type::DateTime
401
+ register_class_with_limit m, %r(float)i, Type::Float
402
+ register_class_with_limit m, %r(int)i, Type::Integer
403
+
404
+ m.alias_type %r(blob)i, 'binary'
405
+ m.alias_type %r(clob)i, 'text'
406
+ m.alias_type %r(timestamp)i, 'datetime'
407
+ m.alias_type %r(numeric)i, 'decimal'
408
+ m.alias_type %r(number)i, 'decimal'
409
+ m.alias_type %r(double)i, 'float'
410
+
411
+ m.register_type(%r(decimal)i) do |sql_type|
412
+ scale = extract_scale(sql_type)
413
+ precision = extract_precision(sql_type)
414
+
415
+ if scale == 0
416
+ # FIXME: Remove this class as well
417
+ Type::DecimalWithoutScale.new(precision: precision)
418
+ else
419
+ Type::Decimal.new(precision: precision, scale: scale)
420
+ end
421
+ end
422
+ end
423
+
424
+ def reload_type_map # :nodoc:
425
+ type_map.clear
426
+ initialize_type_map(type_map)
427
+ end
428
+
429
+ def register_class_with_limit(mapping, key, klass) # :nodoc:
430
+ mapping.register_type(key) do |*args|
431
+ limit = extract_limit(args.last)
432
+ klass.new(limit: limit)
433
+ end
434
+ end
435
+
436
+ def extract_scale(sql_type) # :nodoc:
437
+ case sql_type
438
+ when /\((\d+)\)/ then 0
439
+ when /\((\d+)(,(\d+))\)/ then $3.to_i
440
+ end
441
+ end
442
+
443
+ def extract_precision(sql_type) # :nodoc:
444
+ $1.to_i if sql_type =~ /\((\d+)(,\d+)?\)/
445
+ end
446
+
447
+ def extract_limit(sql_type) # :nodoc:
448
+ $1.to_i if sql_type =~ /\((.*)\)/
449
+ end
450
+
358
451
  def translate_exception_class(e, sql)
359
452
  message = "#{e.class.name}: #{e.message}: #{sql}"
360
453
  @logger.error message if @logger
@@ -381,7 +474,13 @@ module ActiveRecord
381
474
  end
382
475
 
383
476
  def without_prepared_statement?(binds)
384
- !@prepared_statements || binds.empty?
477
+ !prepared_statements || binds.empty?
478
+ end
479
+
480
+ def column_for(table_name, column_name) # :nodoc:
481
+ column_name = column_name.to_s
482
+ columns(table_name).detect { |c| c.name == column_name } ||
483
+ raise(ActiveRecordError, "No such column: #{table_name}.#{column_name}")
385
484
  end
386
485
  end
387
486
  end