activerecord 4.1.16 → 4.2.11.3

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