activerecord 3.2.22.5 → 4.0.0.beta1

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 (162) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1024 -543
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +20 -29
  5. data/examples/performance.rb +1 -1
  6. data/lib/active_record.rb +55 -44
  7. data/lib/active_record/aggregations.rb +40 -34
  8. data/lib/active_record/associations.rb +204 -276
  9. data/lib/active_record/associations/alias_tracker.rb +1 -1
  10. data/lib/active_record/associations/association.rb +30 -35
  11. data/lib/active_record/associations/association_scope.rb +40 -40
  12. data/lib/active_record/associations/belongs_to_association.rb +15 -2
  13. data/lib/active_record/associations/builder/association.rb +81 -28
  14. data/lib/active_record/associations/builder/belongs_to.rb +35 -57
  15. data/lib/active_record/associations/builder/collection_association.rb +54 -40
  16. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +23 -41
  17. data/lib/active_record/associations/builder/has_many.rb +8 -64
  18. data/lib/active_record/associations/builder/has_one.rb +13 -50
  19. data/lib/active_record/associations/builder/singular_association.rb +13 -13
  20. data/lib/active_record/associations/collection_association.rb +92 -88
  21. data/lib/active_record/associations/collection_proxy.rb +913 -63
  22. data/lib/active_record/associations/has_and_belongs_to_many_association.rb +12 -10
  23. data/lib/active_record/associations/has_many_association.rb +35 -9
  24. data/lib/active_record/associations/has_many_through_association.rb +24 -14
  25. data/lib/active_record/associations/has_one_association.rb +33 -13
  26. data/lib/active_record/associations/has_one_through_association.rb +1 -1
  27. data/lib/active_record/associations/join_dependency.rb +2 -2
  28. data/lib/active_record/associations/join_dependency/join_association.rb +17 -22
  29. data/lib/active_record/associations/join_dependency/join_part.rb +1 -1
  30. data/lib/active_record/associations/join_helper.rb +1 -11
  31. data/lib/active_record/associations/preloader.rb +14 -17
  32. data/lib/active_record/associations/preloader/association.rb +29 -33
  33. data/lib/active_record/associations/preloader/collection_association.rb +1 -1
  34. data/lib/active_record/associations/preloader/has_and_belongs_to_many.rb +1 -1
  35. data/lib/active_record/associations/preloader/has_many_through.rb +1 -1
  36. data/lib/active_record/associations/preloader/has_one.rb +1 -1
  37. data/lib/active_record/associations/preloader/through_association.rb +13 -17
  38. data/lib/active_record/associations/singular_association.rb +11 -11
  39. data/lib/active_record/associations/through_association.rb +2 -2
  40. data/lib/active_record/attribute_assignment.rb +133 -153
  41. data/lib/active_record/attribute_methods.rb +196 -93
  42. data/lib/active_record/attribute_methods/before_type_cast.rb +44 -5
  43. data/lib/active_record/attribute_methods/dirty.rb +31 -28
  44. data/lib/active_record/attribute_methods/primary_key.rb +38 -30
  45. data/lib/active_record/attribute_methods/query.rb +5 -4
  46. data/lib/active_record/attribute_methods/read.rb +62 -91
  47. data/lib/active_record/attribute_methods/serialization.rb +97 -66
  48. data/lib/active_record/attribute_methods/time_zone_conversion.rb +39 -45
  49. data/lib/active_record/attribute_methods/write.rb +32 -39
  50. data/lib/active_record/autosave_association.rb +56 -70
  51. data/lib/active_record/base.rb +53 -450
  52. data/lib/active_record/callbacks.rb +53 -18
  53. data/lib/active_record/coders/yaml_column.rb +11 -9
  54. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +353 -197
  55. data/lib/active_record/connection_adapters/abstract/database_limits.rb +9 -0
  56. data/lib/active_record/connection_adapters/abstract/database_statements.rb +130 -131
  57. data/lib/active_record/connection_adapters/abstract/query_cache.rb +24 -19
  58. data/lib/active_record/connection_adapters/abstract/quoting.rb +23 -3
  59. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +101 -91
  60. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +59 -0
  61. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +225 -96
  62. data/lib/active_record/connection_adapters/abstract/transaction.rb +203 -0
  63. data/lib/active_record/connection_adapters/abstract_adapter.rb +99 -46
  64. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +114 -36
  65. data/lib/active_record/connection_adapters/column.rb +46 -24
  66. data/lib/active_record/connection_adapters/connection_specification.rb +96 -0
  67. data/lib/active_record/connection_adapters/mysql2_adapter.rb +16 -32
  68. data/lib/active_record/connection_adapters/mysql_adapter.rb +181 -64
  69. data/lib/active_record/connection_adapters/postgresql/array_parser.rb +97 -0
  70. data/lib/active_record/connection_adapters/postgresql/cast.rb +132 -0
  71. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +242 -0
  72. data/lib/active_record/connection_adapters/postgresql/oid.rb +347 -0
  73. data/lib/active_record/connection_adapters/postgresql/quoting.rb +158 -0
  74. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +30 -0
  75. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +448 -0
  76. data/lib/active_record/connection_adapters/postgresql_adapter.rb +454 -885
  77. data/lib/active_record/connection_adapters/schema_cache.rb +48 -16
  78. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +574 -13
  79. data/lib/active_record/connection_handling.rb +98 -0
  80. data/lib/active_record/core.rb +428 -0
  81. data/lib/active_record/counter_cache.rb +106 -108
  82. data/lib/active_record/dynamic_matchers.rb +110 -63
  83. data/lib/active_record/errors.rb +25 -8
  84. data/lib/active_record/explain.rb +8 -58
  85. data/lib/active_record/explain_subscriber.rb +6 -3
  86. data/lib/active_record/fixture_set/file.rb +56 -0
  87. data/lib/active_record/fixtures.rb +146 -148
  88. data/lib/active_record/inheritance.rb +77 -59
  89. data/lib/active_record/integration.rb +5 -5
  90. data/lib/active_record/locale/en.yml +8 -1
  91. data/lib/active_record/locking/optimistic.rb +38 -42
  92. data/lib/active_record/locking/pessimistic.rb +4 -4
  93. data/lib/active_record/log_subscriber.rb +19 -9
  94. data/lib/active_record/migration.rb +318 -153
  95. data/lib/active_record/migration/command_recorder.rb +90 -31
  96. data/lib/active_record/migration/join_table.rb +15 -0
  97. data/lib/active_record/model_schema.rb +69 -92
  98. data/lib/active_record/nested_attributes.rb +113 -148
  99. data/lib/active_record/null_relation.rb +65 -0
  100. data/lib/active_record/persistence.rb +188 -97
  101. data/lib/active_record/query_cache.rb +18 -36
  102. data/lib/active_record/querying.rb +19 -15
  103. data/lib/active_record/railtie.rb +91 -36
  104. data/lib/active_record/railties/console_sandbox.rb +0 -2
  105. data/lib/active_record/railties/controller_runtime.rb +2 -2
  106. data/lib/active_record/railties/databases.rake +90 -309
  107. data/lib/active_record/railties/jdbcmysql_error.rb +1 -1
  108. data/lib/active_record/readonly_attributes.rb +7 -3
  109. data/lib/active_record/reflection.rb +72 -56
  110. data/lib/active_record/relation.rb +241 -157
  111. data/lib/active_record/relation/batches.rb +25 -22
  112. data/lib/active_record/relation/calculations.rb +143 -121
  113. data/lib/active_record/relation/delegation.rb +96 -18
  114. data/lib/active_record/relation/finder_methods.rb +117 -183
  115. data/lib/active_record/relation/merger.rb +133 -0
  116. data/lib/active_record/relation/predicate_builder.rb +90 -42
  117. data/lib/active_record/relation/query_methods.rb +666 -136
  118. data/lib/active_record/relation/spawn_methods.rb +43 -150
  119. data/lib/active_record/result.rb +33 -6
  120. data/lib/active_record/sanitization.rb +24 -50
  121. data/lib/active_record/schema.rb +19 -12
  122. data/lib/active_record/schema_dumper.rb +31 -39
  123. data/lib/active_record/schema_migration.rb +36 -0
  124. data/lib/active_record/scoping.rb +0 -124
  125. data/lib/active_record/scoping/default.rb +48 -45
  126. data/lib/active_record/scoping/named.rb +74 -103
  127. data/lib/active_record/serialization.rb +6 -2
  128. data/lib/active_record/serializers/xml_serializer.rb +9 -15
  129. data/lib/active_record/store.rb +119 -15
  130. data/lib/active_record/tasks/database_tasks.rb +158 -0
  131. data/lib/active_record/tasks/mysql_database_tasks.rb +138 -0
  132. data/lib/active_record/tasks/postgresql_database_tasks.rb +90 -0
  133. data/lib/active_record/tasks/sqlite_database_tasks.rb +51 -0
  134. data/lib/active_record/test_case.rb +61 -38
  135. data/lib/active_record/timestamp.rb +8 -9
  136. data/lib/active_record/transactions.rb +65 -51
  137. data/lib/active_record/validations.rb +17 -15
  138. data/lib/active_record/validations/associated.rb +20 -14
  139. data/lib/active_record/validations/presence.rb +65 -0
  140. data/lib/active_record/validations/uniqueness.rb +93 -52
  141. data/lib/active_record/version.rb +4 -4
  142. data/lib/rails/generators/active_record.rb +3 -5
  143. data/lib/rails/generators/active_record/migration/migration_generator.rb +37 -7
  144. data/lib/rails/generators/active_record/migration/templates/migration.rb +20 -15
  145. data/lib/rails/generators/active_record/model/model_generator.rb +4 -3
  146. data/lib/rails/generators/active_record/model/templates/model.rb +1 -6
  147. data/lib/rails/generators/active_record/model/templates/module.rb +1 -1
  148. metadata +53 -46
  149. data/lib/active_record/attribute_methods/deprecated_underscore_read.rb +0 -32
  150. data/lib/active_record/connection_adapters/abstract/connection_specification.rb +0 -191
  151. data/lib/active_record/connection_adapters/sqlite_adapter.rb +0 -583
  152. data/lib/active_record/dynamic_finder_match.rb +0 -68
  153. data/lib/active_record/dynamic_scope_match.rb +0 -23
  154. data/lib/active_record/fixtures/file.rb +0 -65
  155. data/lib/active_record/identity_map.rb +0 -162
  156. data/lib/active_record/observer.rb +0 -121
  157. data/lib/active_record/session_store.rb +0 -360
  158. data/lib/rails/generators/active_record/migration.rb +0 -15
  159. data/lib/rails/generators/active_record/observer/observer_generator.rb +0 -15
  160. data/lib/rails/generators/active_record/observer/templates/observer.rb +0 -4
  161. data/lib/rails/generators/active_record/session_migration/session_migration_generator.rb +0 -25
  162. data/lib/rails/generators/active_record/session_migration/templates/migration.rb +0 -12
@@ -0,0 +1,203 @@
1
+ module ActiveRecord
2
+ module ConnectionAdapters
3
+ class Transaction #:nodoc:
4
+ attr_reader :connection
5
+
6
+ def initialize(connection)
7
+ @connection = connection
8
+ @state = TransactionState.new
9
+ end
10
+
11
+ def state
12
+ @state
13
+ end
14
+ end
15
+
16
+ class TransactionState
17
+ attr_accessor :parent
18
+
19
+ VALID_STATES = Set.new([:committed, :rolledback, nil])
20
+
21
+ def initialize(state = nil)
22
+ @state = state
23
+ @parent = nil
24
+ end
25
+
26
+ def committed?
27
+ @state == :committed
28
+ end
29
+
30
+ def rolledback?
31
+ @state == :rolledback
32
+ end
33
+
34
+ def set_state(state)
35
+ if !VALID_STATES.include?(state)
36
+ raise ArgumentError, "Invalid transaction state: #{state}"
37
+ end
38
+ @state = state
39
+ end
40
+ end
41
+
42
+ class ClosedTransaction < Transaction #:nodoc:
43
+ def number
44
+ 0
45
+ end
46
+
47
+ def begin(options = {})
48
+ RealTransaction.new(connection, self, options)
49
+ end
50
+
51
+ def closed?
52
+ true
53
+ end
54
+
55
+ def open?
56
+ false
57
+ end
58
+
59
+ def joinable?
60
+ false
61
+ end
62
+
63
+ # This is a noop when there are no open transactions
64
+ def add_record(record)
65
+ end
66
+ end
67
+
68
+ class OpenTransaction < Transaction #:nodoc:
69
+ attr_reader :parent, :records
70
+ attr_writer :joinable
71
+
72
+ def initialize(connection, parent, options = {})
73
+ super connection
74
+
75
+ @parent = parent
76
+ @records = []
77
+ @finishing = false
78
+ @joinable = options.fetch(:joinable, true)
79
+ end
80
+
81
+ # This state is necesarry so that we correctly handle stuff that might
82
+ # happen in a commit/rollback. But it's kinda distasteful. Maybe we can
83
+ # find a better way to structure it in the future.
84
+ def finishing?
85
+ @finishing
86
+ end
87
+
88
+ def joinable?
89
+ @joinable && !finishing?
90
+ end
91
+
92
+ def number
93
+ if finishing?
94
+ parent.number
95
+ else
96
+ parent.number + 1
97
+ end
98
+ end
99
+
100
+ def begin(options = {})
101
+ if finishing?
102
+ parent.begin
103
+ else
104
+ SavepointTransaction.new(connection, self, options)
105
+ end
106
+ end
107
+
108
+ def rollback
109
+ @finishing = true
110
+ perform_rollback
111
+ parent
112
+ end
113
+
114
+ def commit
115
+ @finishing = true
116
+ perform_commit
117
+ parent
118
+ end
119
+
120
+ def add_record(record)
121
+ if record.has_transactional_callbacks?
122
+ records << record
123
+ else
124
+ record.set_transaction_state(@state)
125
+ end
126
+ end
127
+
128
+ def rollback_records
129
+ @state.set_state(:rolledback)
130
+ records.uniq.each do |record|
131
+ begin
132
+ record.rolledback!(parent.closed?)
133
+ rescue => e
134
+ record.logger.error(e) if record.respond_to?(:logger) && record.logger
135
+ end
136
+ end
137
+ end
138
+
139
+ def commit_records
140
+ @state.set_state(:committed)
141
+ records.uniq.each do |record|
142
+ begin
143
+ record.committed!
144
+ rescue => e
145
+ record.logger.error(e) if record.respond_to?(:logger) && record.logger
146
+ end
147
+ end
148
+ end
149
+
150
+ def closed?
151
+ false
152
+ end
153
+
154
+ def open?
155
+ true
156
+ end
157
+ end
158
+
159
+ class RealTransaction < OpenTransaction #:nodoc:
160
+ def initialize(connection, parent, options = {})
161
+ super
162
+
163
+ if options[:isolation]
164
+ connection.begin_isolated_db_transaction(options[:isolation])
165
+ else
166
+ connection.begin_db_transaction
167
+ end
168
+ end
169
+
170
+ def perform_rollback
171
+ connection.rollback_db_transaction
172
+ rollback_records
173
+ end
174
+
175
+ def perform_commit
176
+ connection.commit_db_transaction
177
+ commit_records
178
+ end
179
+ end
180
+
181
+ class SavepointTransaction < OpenTransaction #:nodoc:
182
+ def initialize(connection, parent, options = {})
183
+ if options[:isolation]
184
+ raise ActiveRecord::TransactionIsolationError, "cannot set transaction isolation in a nested transaction"
185
+ end
186
+
187
+ super
188
+ connection.create_savepoint
189
+ end
190
+
191
+ def perform_rollback
192
+ connection.rollback_to_savepoint
193
+ rollback_records
194
+ end
195
+
196
+ def perform_commit
197
+ @state.set_state(:committed)
198
+ @state.parent = parent.state
199
+ connection.release_savepoint
200
+ end
201
+ end
202
+ end
203
+ end
@@ -2,8 +2,8 @@ require 'date'
2
2
  require 'bigdecimal'
3
3
  require 'bigdecimal/util'
4
4
  require 'active_support/core_ext/benchmark'
5
- require 'active_support/deprecation'
6
5
  require 'active_record/connection_adapters/schema_cache'
6
+ require 'active_record/connection_adapters/abstract/schema_dumper'
7
7
  require 'monitor'
8
8
 
9
9
  module ActiveRecord
@@ -11,26 +11,35 @@ module ActiveRecord
11
11
  extend ActiveSupport::Autoload
12
12
 
13
13
  autoload :Column
14
+ autoload :ConnectionSpecification
14
15
 
15
- autoload_under 'abstract' do
16
- autoload :IndexDefinition, 'active_record/connection_adapters/abstract/schema_definitions'
17
- autoload :ColumnDefinition, 'active_record/connection_adapters/abstract/schema_definitions'
18
- autoload :TableDefinition, 'active_record/connection_adapters/abstract/schema_definitions'
19
- autoload :Table, 'active_record/connection_adapters/abstract/schema_definitions'
16
+ autoload_at 'active_record/connection_adapters/abstract/schema_definitions' do
17
+ autoload :IndexDefinition
18
+ autoload :ColumnDefinition
19
+ autoload :TableDefinition
20
+ autoload :Table
21
+ end
20
22
 
23
+ autoload_at 'active_record/connection_adapters/abstract/connection_pool' do
24
+ autoload :ConnectionHandler
25
+ autoload :ConnectionManagement
26
+ end
27
+
28
+ autoload_under 'abstract' do
21
29
  autoload :SchemaStatements
22
30
  autoload :DatabaseStatements
23
31
  autoload :DatabaseLimits
24
32
  autoload :Quoting
25
-
26
33
  autoload :ConnectionPool
27
- autoload :ConnectionHandler, 'active_record/connection_adapters/abstract/connection_pool'
28
- autoload :ConnectionManagement, 'active_record/connection_adapters/abstract/connection_pool'
29
- autoload :ConnectionSpecification
30
-
31
34
  autoload :QueryCache
32
35
  end
33
36
 
37
+ autoload_at 'active_record/connection_adapters/abstract/transaction' do
38
+ autoload :ClosedTransaction
39
+ autoload :RealTransaction
40
+ autoload :SavepointTransaction
41
+ end
42
+
34
43
  # Active Record supports multiple database systems. AbstractAdapter and
35
44
  # related classes form the abstraction layer which makes this possible.
36
45
  # An AbstractAdapter represents a connection to a database, and provides an
@@ -50,6 +59,9 @@ module ActiveRecord
50
59
  include QueryCache
51
60
  include ActiveSupport::Callbacks
52
61
  include MonitorMixin
62
+ include ColumnDumper
63
+
64
+ SIMPLE_INT = /\A\d+\z/
53
65
 
54
66
  define_callbacks :checkout, :checkin
55
67
 
@@ -57,16 +69,30 @@ module ActiveRecord
57
69
  attr_reader :schema_cache, :last_use, :in_use, :logger
58
70
  alias :in_use? :in_use
59
71
 
72
+ def self.type_cast_config_to_integer(config)
73
+ if config =~ SIMPLE_INT
74
+ config.to_i
75
+ else
76
+ config
77
+ end
78
+ end
79
+
80
+ def self.type_cast_config_to_boolean(config)
81
+ if config == "false"
82
+ false
83
+ else
84
+ config
85
+ end
86
+ end
87
+
60
88
  def initialize(connection, logger = nil, pool = nil) #:nodoc:
61
89
  super()
62
90
 
63
- @active = nil
64
91
  @connection = connection
65
92
  @in_use = false
66
93
  @instrumenter = ActiveSupport::Notifications.instrumenter
67
94
  @last_use = false
68
95
  @logger = logger
69
- @open_transactions = 0
70
96
  @pool = pool
71
97
  @query_cache = Hash.new { |h,sql| h[sql] = {} }
72
98
  @query_cache_enabled = false
@@ -83,6 +109,11 @@ module ActiveRecord
83
109
  end
84
110
  end
85
111
 
112
+ def schema_cache=(cache)
113
+ cache.connection = self
114
+ @schema_cache = cache
115
+ end
116
+
86
117
  def expire
87
118
  @in_use = false
88
119
  end
@@ -142,21 +173,38 @@ module ActiveRecord
142
173
  false
143
174
  end
144
175
 
176
+ # Does this adapter support partial indices?
177
+ def supports_partial_index?
178
+ false
179
+ end
180
+
145
181
  # Does this adapter support explain? As of this writing sqlite3,
146
182
  # mysql2, and postgresql are the only ones that do.
147
183
  def supports_explain?
148
184
  false
149
185
  end
150
186
 
151
- # QUOTING ==================================================
187
+ # Does this adapter support setting the isolation level for a transaction?
188
+ def supports_transaction_isolation?
189
+ false
190
+ end
191
+
192
+ # Does this adapter support database extensions? As of this writing only
193
+ # postgresql does.
194
+ def supports_extensions?
195
+ false
196
+ end
152
197
 
153
- # Override to return the quoted table name. Defaults to column quoting.
154
- def quote_table_name(name)
155
- quote_column_name(name)
198
+ # A list of extensions, to be filled in by adapters that support them. At
199
+ # the moment only postgresql does.
200
+ def extensions
201
+ []
156
202
  end
157
203
 
204
+ # QUOTING ==================================================
205
+
158
206
  # Returns a bind substitution value given a +column+ and list of current
159
- # +binds+
207
+ # +binds+.
160
208
  def substitute_at(column, index)
161
209
  Arel::Nodes::BindParam.new '?'
162
210
  end
@@ -174,19 +222,21 @@ module ActiveRecord
174
222
  # checking whether the database is actually capable of responding, i.e. whether
175
223
  # the connection isn't stale.
176
224
  def active?
177
- @active != false
178
225
  end
179
226
 
180
227
  # Disconnects from the database if already connected, and establishes a
181
- # new connection with the database.
228
+ # new connection with the database. Implementors should call super if they
229
+ # override the default implementation.
182
230
  def reconnect!
183
- @active = true
231
+ clear_cache!
232
+ reset_transaction
184
233
  end
185
234
 
186
235
  # Disconnects from the database if already connected. Otherwise, this
187
236
  # method does nothing.
188
237
  def disconnect!
189
- @active = false
238
+ clear_cache!
239
+ reset_transaction
190
240
  end
191
241
 
192
242
  # Reset the state of this connection, directing the DBMS to clear
@@ -229,18 +279,22 @@ module ActiveRecord
229
279
  @connection
230
280
  end
231
281
 
232
- attr_reader :open_transactions
282
+ def open_transactions
283
+ @transaction.number
284
+ end
233
285
 
234
286
  def increment_open_transactions
235
- @open_transactions += 1
287
+ ActiveSupport::Deprecation.warn "#increment_open_transactions is deprecated and has no effect"
236
288
  end
237
289
 
238
290
  def decrement_open_transactions
239
- @open_transactions -= 1
291
+ ActiveSupport::Deprecation.warn "#decrement_open_transactions is deprecated and has no effect"
240
292
  end
241
293
 
242
294
  def transaction_joinable=(joinable)
243
- @transaction_joinable = joinable
295
+ message = "#transaction_joinable= is deprecated. Please pass the :joinable option to #begin_transaction instead."
296
+ ActiveSupport::Deprecation.warn message
297
+ @transaction.joinable = joinable
244
298
  end
245
299
 
246
300
  def create_savepoint
@@ -271,26 +325,25 @@ module ActiveRecord
271
325
 
272
326
  protected
273
327
 
274
- def log(sql, name = "SQL", binds = [])
275
- @instrumenter.instrument(
276
- "sql.active_record",
277
- :sql => sql,
278
- :name => name,
279
- :connection_id => object_id,
280
- :binds => binds) { yield }
281
- rescue Exception => e
282
- message = "#{e.class.name}: #{e.message}: #{sql}"
283
- @logger.debug message if @logger
284
- exception = translate_exception(e, message)
285
- exception.set_backtrace e.backtrace
286
- raise exception
287
- end
288
-
289
- def translate_exception(e, message)
290
- # override in derived class
291
- ActiveRecord::StatementInvalid.new(message)
292
- end
293
-
328
+ def log(sql, name = "SQL", binds = [])
329
+ @instrumenter.instrument(
330
+ "sql.active_record",
331
+ :sql => sql,
332
+ :name => name,
333
+ :connection_id => object_id,
334
+ :binds => binds) { yield }
335
+ rescue => e
336
+ message = "#{e.class.name}: #{e.message}: #{sql}"
337
+ @logger.error message if @logger
338
+ exception = translate_exception(e, message)
339
+ exception.set_backtrace e.backtrace
340
+ raise exception
341
+ end
342
+
343
+ def translate_exception(exception, message)
344
+ # override in derived class
345
+ ActiveRecord::StatementInvalid.new(message)
346
+ end
294
347
  end
295
348
  end
296
349
  end