activerecord 3.2.22.4 → 4.0.13

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 (173) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +2799 -617
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +23 -32
  5. data/examples/performance.rb +1 -1
  6. data/lib/active_record/aggregations.rb +40 -34
  7. data/lib/active_record/association_relation.rb +22 -0
  8. data/lib/active_record/associations/alias_tracker.rb +4 -2
  9. data/lib/active_record/associations/association.rb +60 -46
  10. data/lib/active_record/associations/association_scope.rb +46 -40
  11. data/lib/active_record/associations/belongs_to_association.rb +17 -4
  12. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +1 -1
  13. data/lib/active_record/associations/builder/association.rb +81 -28
  14. data/lib/active_record/associations/builder/belongs_to.rb +73 -56
  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 +130 -96
  21. data/lib/active_record/associations/collection_proxy.rb +916 -63
  22. data/lib/active_record/associations/has_and_belongs_to_many_association.rb +15 -13
  23. data/lib/active_record/associations/has_many_association.rb +35 -8
  24. data/lib/active_record/associations/has_many_through_association.rb +37 -17
  25. data/lib/active_record/associations/has_one_association.rb +42 -19
  26. data/lib/active_record/associations/has_one_through_association.rb +1 -1
  27. data/lib/active_record/associations/join_dependency/join_association.rb +39 -22
  28. data/lib/active_record/associations/join_dependency/join_base.rb +2 -2
  29. data/lib/active_record/associations/join_dependency/join_part.rb +21 -8
  30. data/lib/active_record/associations/join_dependency.rb +30 -9
  31. data/lib/active_record/associations/join_helper.rb +1 -11
  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 +2 -2
  35. data/lib/active_record/associations/preloader/has_many_through.rb +6 -2
  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/preloader.rb +20 -43
  39. data/lib/active_record/associations/singular_association.rb +11 -11
  40. data/lib/active_record/associations/through_association.rb +3 -3
  41. data/lib/active_record/associations.rb +223 -282
  42. data/lib/active_record/attribute_assignment.rb +134 -154
  43. data/lib/active_record/attribute_methods/before_type_cast.rb +44 -5
  44. data/lib/active_record/attribute_methods/dirty.rb +36 -29
  45. data/lib/active_record/attribute_methods/primary_key.rb +45 -31
  46. data/lib/active_record/attribute_methods/query.rb +5 -4
  47. data/lib/active_record/attribute_methods/read.rb +67 -90
  48. data/lib/active_record/attribute_methods/serialization.rb +133 -70
  49. data/lib/active_record/attribute_methods/time_zone_conversion.rb +51 -45
  50. data/lib/active_record/attribute_methods/write.rb +34 -39
  51. data/lib/active_record/attribute_methods.rb +268 -108
  52. data/lib/active_record/autosave_association.rb +80 -73
  53. data/lib/active_record/base.rb +54 -451
  54. data/lib/active_record/callbacks.rb +60 -22
  55. data/lib/active_record/coders/yaml_column.rb +18 -21
  56. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +347 -197
  57. data/lib/active_record/connection_adapters/abstract/database_limits.rb +9 -0
  58. data/lib/active_record/connection_adapters/abstract/database_statements.rb +146 -138
  59. data/lib/active_record/connection_adapters/abstract/query_cache.rb +25 -19
  60. data/lib/active_record/connection_adapters/abstract/quoting.rb +19 -3
  61. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +151 -142
  62. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +70 -0
  63. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +499 -217
  64. data/lib/active_record/connection_adapters/abstract/transaction.rb +208 -0
  65. data/lib/active_record/connection_adapters/abstract_adapter.rb +209 -44
  66. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +169 -61
  67. data/lib/active_record/connection_adapters/column.rb +67 -36
  68. data/lib/active_record/connection_adapters/connection_specification.rb +96 -0
  69. data/lib/active_record/connection_adapters/mysql2_adapter.rb +28 -29
  70. data/lib/active_record/connection_adapters/mysql_adapter.rb +200 -73
  71. data/lib/active_record/connection_adapters/postgresql/array_parser.rb +98 -0
  72. data/lib/active_record/connection_adapters/postgresql/cast.rb +160 -0
  73. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +240 -0
  74. data/lib/active_record/connection_adapters/postgresql/oid.rb +374 -0
  75. data/lib/active_record/connection_adapters/postgresql/quoting.rb +183 -0
  76. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +30 -0
  77. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +508 -0
  78. data/lib/active_record/connection_adapters/postgresql_adapter.rb +544 -899
  79. data/lib/active_record/connection_adapters/schema_cache.rb +76 -16
  80. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +595 -16
  81. data/lib/active_record/connection_handling.rb +98 -0
  82. data/lib/active_record/core.rb +472 -0
  83. data/lib/active_record/counter_cache.rb +107 -108
  84. data/lib/active_record/dynamic_matchers.rb +115 -63
  85. data/lib/active_record/errors.rb +36 -18
  86. data/lib/active_record/explain.rb +15 -63
  87. data/lib/active_record/explain_registry.rb +30 -0
  88. data/lib/active_record/explain_subscriber.rb +8 -4
  89. data/lib/active_record/fixture_set/file.rb +55 -0
  90. data/lib/active_record/fixtures.rb +159 -155
  91. data/lib/active_record/inheritance.rb +93 -59
  92. data/lib/active_record/integration.rb +8 -8
  93. data/lib/active_record/locale/en.yml +8 -1
  94. data/lib/active_record/locking/optimistic.rb +39 -43
  95. data/lib/active_record/locking/pessimistic.rb +4 -4
  96. data/lib/active_record/log_subscriber.rb +19 -9
  97. data/lib/active_record/migration/command_recorder.rb +102 -33
  98. data/lib/active_record/migration/join_table.rb +15 -0
  99. data/lib/active_record/migration.rb +411 -173
  100. data/lib/active_record/model_schema.rb +81 -94
  101. data/lib/active_record/nested_attributes.rb +173 -131
  102. data/lib/active_record/null_relation.rb +67 -0
  103. data/lib/active_record/persistence.rb +254 -106
  104. data/lib/active_record/query_cache.rb +18 -36
  105. data/lib/active_record/querying.rb +19 -15
  106. data/lib/active_record/railtie.rb +113 -38
  107. data/lib/active_record/railties/console_sandbox.rb +3 -4
  108. data/lib/active_record/railties/controller_runtime.rb +4 -3
  109. data/lib/active_record/railties/databases.rake +115 -368
  110. data/lib/active_record/railties/jdbcmysql_error.rb +1 -1
  111. data/lib/active_record/readonly_attributes.rb +7 -3
  112. data/lib/active_record/reflection.rb +110 -61
  113. data/lib/active_record/relation/batches.rb +29 -29
  114. data/lib/active_record/relation/calculations.rb +155 -125
  115. data/lib/active_record/relation/delegation.rb +94 -18
  116. data/lib/active_record/relation/finder_methods.rb +151 -203
  117. data/lib/active_record/relation/merger.rb +188 -0
  118. data/lib/active_record/relation/predicate_builder.rb +85 -42
  119. data/lib/active_record/relation/query_methods.rb +793 -146
  120. data/lib/active_record/relation/spawn_methods.rb +43 -150
  121. data/lib/active_record/relation.rb +293 -173
  122. data/lib/active_record/result.rb +48 -7
  123. data/lib/active_record/runtime_registry.rb +17 -0
  124. data/lib/active_record/sanitization.rb +41 -54
  125. data/lib/active_record/schema.rb +19 -12
  126. data/lib/active_record/schema_dumper.rb +41 -41
  127. data/lib/active_record/schema_migration.rb +46 -0
  128. data/lib/active_record/scoping/default.rb +56 -52
  129. data/lib/active_record/scoping/named.rb +78 -103
  130. data/lib/active_record/scoping.rb +54 -124
  131. data/lib/active_record/serialization.rb +6 -2
  132. data/lib/active_record/serializers/xml_serializer.rb +9 -15
  133. data/lib/active_record/statement_cache.rb +26 -0
  134. data/lib/active_record/store.rb +131 -15
  135. data/lib/active_record/tasks/database_tasks.rb +204 -0
  136. data/lib/active_record/tasks/firebird_database_tasks.rb +56 -0
  137. data/lib/active_record/tasks/mysql_database_tasks.rb +144 -0
  138. data/lib/active_record/tasks/oracle_database_tasks.rb +45 -0
  139. data/lib/active_record/tasks/postgresql_database_tasks.rb +90 -0
  140. data/lib/active_record/tasks/sqlite_database_tasks.rb +51 -0
  141. data/lib/active_record/tasks/sqlserver_database_tasks.rb +48 -0
  142. data/lib/active_record/test_case.rb +67 -38
  143. data/lib/active_record/timestamp.rb +16 -11
  144. data/lib/active_record/transactions.rb +73 -51
  145. data/lib/active_record/validations/associated.rb +19 -13
  146. data/lib/active_record/validations/presence.rb +65 -0
  147. data/lib/active_record/validations/uniqueness.rb +110 -57
  148. data/lib/active_record/validations.rb +18 -17
  149. data/lib/active_record/version.rb +7 -6
  150. data/lib/active_record.rb +63 -45
  151. data/lib/rails/generators/active_record/migration/migration_generator.rb +45 -8
  152. data/lib/rails/generators/active_record/{model/templates/migration.rb → migration/templates/create_table_migration.rb} +4 -0
  153. data/lib/rails/generators/active_record/migration/templates/migration.rb +20 -15
  154. data/lib/rails/generators/active_record/model/model_generator.rb +5 -4
  155. data/lib/rails/generators/active_record/model/templates/model.rb +4 -6
  156. data/lib/rails/generators/active_record/model/templates/module.rb +1 -1
  157. data/lib/rails/generators/active_record.rb +3 -5
  158. metadata +43 -29
  159. data/examples/associations.png +0 -0
  160. data/lib/active_record/attribute_methods/deprecated_underscore_read.rb +0 -32
  161. data/lib/active_record/connection_adapters/abstract/connection_specification.rb +0 -191
  162. data/lib/active_record/connection_adapters/sqlite_adapter.rb +0 -583
  163. data/lib/active_record/dynamic_finder_match.rb +0 -68
  164. data/lib/active_record/dynamic_scope_match.rb +0 -23
  165. data/lib/active_record/fixtures/file.rb +0 -65
  166. data/lib/active_record/identity_map.rb +0 -162
  167. data/lib/active_record/observer.rb +0 -121
  168. data/lib/active_record/session_store.rb +0 -360
  169. data/lib/rails/generators/active_record/migration.rb +0 -15
  170. data/lib/rails/generators/active_record/observer/observer_generator.rb +0 -15
  171. data/lib/rails/generators/active_record/observer/templates/observer.rb +0 -4
  172. data/lib/rails/generators/active_record/session_migration/session_migration_generator.rb +0 -25
  173. data/lib/rails/generators/active_record/session_migration/templates/migration.rb +0 -12
@@ -0,0 +1,208 @@
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 finalized?
27
+ @state
28
+ end
29
+
30
+ def committed?
31
+ @state == :committed
32
+ end
33
+
34
+ def rolledback?
35
+ @state == :rolledback
36
+ end
37
+
38
+ def set_state(state)
39
+ if !VALID_STATES.include?(state)
40
+ raise ArgumentError, "Invalid transaction state: #{state}"
41
+ end
42
+ @state = state
43
+ end
44
+ end
45
+
46
+ class ClosedTransaction < Transaction #:nodoc:
47
+ def number
48
+ 0
49
+ end
50
+
51
+ def begin(options = {})
52
+ RealTransaction.new(connection, self, options)
53
+ end
54
+
55
+ def closed?
56
+ true
57
+ end
58
+
59
+ def open?
60
+ false
61
+ end
62
+
63
+ def joinable?
64
+ false
65
+ end
66
+
67
+ # This is a noop when there are no open transactions
68
+ def add_record(record)
69
+ end
70
+ end
71
+
72
+ class OpenTransaction < Transaction #:nodoc:
73
+ attr_reader :parent, :records
74
+ attr_writer :joinable
75
+
76
+ def initialize(connection, parent, options = {})
77
+ super connection
78
+
79
+ @parent = parent
80
+ @records = []
81
+ @finishing = false
82
+ @joinable = options.fetch(:joinable, true)
83
+ end
84
+
85
+ # This state is necessary so that we correctly handle stuff that might
86
+ # happen in a commit/rollback. But it's kinda distasteful. Maybe we can
87
+ # find a better way to structure it in the future.
88
+ def finishing?
89
+ @finishing
90
+ end
91
+
92
+ def joinable?
93
+ @joinable && !finishing?
94
+ end
95
+
96
+ def number
97
+ if finishing?
98
+ parent.number
99
+ else
100
+ parent.number + 1
101
+ end
102
+ end
103
+
104
+ def begin(options = {})
105
+ if finishing?
106
+ parent.begin
107
+ else
108
+ SavepointTransaction.new(connection, self, options)
109
+ end
110
+ end
111
+
112
+ def rollback
113
+ @finishing = true
114
+ perform_rollback
115
+ parent
116
+ end
117
+
118
+ def commit
119
+ @finishing = true
120
+ perform_commit
121
+ parent
122
+ end
123
+
124
+ def add_record(record)
125
+ if record.has_transactional_callbacks?
126
+ records << record
127
+ else
128
+ record.set_transaction_state(@state)
129
+ end
130
+ end
131
+
132
+ def rollback_records
133
+ @state.set_state(:rolledback)
134
+ records.uniq.each do |record|
135
+ begin
136
+ record.rolledback!(parent.closed?)
137
+ rescue => e
138
+ record.logger.error(e) if record.respond_to?(:logger) && record.logger
139
+ end
140
+ end
141
+ end
142
+
143
+ def commit_records
144
+ @state.set_state(:committed)
145
+ records.uniq.each do |record|
146
+ begin
147
+ record.committed!
148
+ rescue => e
149
+ record.logger.error(e) if record.respond_to?(:logger) && record.logger
150
+ end
151
+ end
152
+ end
153
+
154
+ def closed?
155
+ false
156
+ end
157
+
158
+ def open?
159
+ true
160
+ end
161
+ end
162
+
163
+ class RealTransaction < OpenTransaction #:nodoc:
164
+ def initialize(connection, parent, options = {})
165
+ super
166
+
167
+ if options[:isolation]
168
+ connection.begin_isolated_db_transaction(options[:isolation])
169
+ else
170
+ connection.begin_db_transaction
171
+ end
172
+ end
173
+
174
+ def perform_rollback
175
+ connection.rollback_db_transaction
176
+ rollback_records
177
+ end
178
+
179
+ def perform_commit
180
+ connection.commit_db_transaction
181
+ commit_records
182
+ end
183
+ end
184
+
185
+ class SavepointTransaction < OpenTransaction #:nodoc:
186
+ def initialize(connection, parent, options = {})
187
+ if options[:isolation]
188
+ raise ActiveRecord::TransactionIsolationError, "cannot set transaction isolation in a nested transaction"
189
+ end
190
+
191
+ super
192
+ connection.create_savepoint
193
+ end
194
+
195
+ def perform_rollback
196
+ connection.rollback_to_savepoint
197
+ rollback_records
198
+ end
199
+
200
+ def perform_commit
201
+ @state.set_state(:committed)
202
+ @state.parent = parent.state
203
+ connection.release_savepoint
204
+ records.each { |r| parent.add_record(r) }
205
+ end
206
+ end
207
+ end
208
+ 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,37 @@ module ActiveRecord
11
11
  extend ActiveSupport::Autoload
12
12
 
13
13
  autoload :Column
14
+ autoload :ConnectionSpecification
15
+
16
+ autoload_at 'active_record/connection_adapters/abstract/schema_definitions' do
17
+ autoload :IndexDefinition
18
+ autoload :ColumnDefinition
19
+ autoload :TableDefinition
20
+ autoload :Table
21
+ autoload :AlterTable
22
+ end
14
23
 
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'
24
+ autoload_at 'active_record/connection_adapters/abstract/connection_pool' do
25
+ autoload :ConnectionHandler
26
+ autoload :ConnectionManagement
27
+ end
20
28
 
29
+ autoload_under 'abstract' do
21
30
  autoload :SchemaStatements
22
31
  autoload :DatabaseStatements
23
32
  autoload :DatabaseLimits
24
33
  autoload :Quoting
25
-
26
34
  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
35
  autoload :QueryCache
32
36
  end
33
37
 
38
+ autoload_at 'active_record/connection_adapters/abstract/transaction' do
39
+ autoload :ClosedTransaction
40
+ autoload :RealTransaction
41
+ autoload :SavepointTransaction
42
+ autoload :TransactionState
43
+ end
44
+
34
45
  # Active Record supports multiple database systems. AbstractAdapter and
35
46
  # related classes form the abstraction layer which makes this possible.
36
47
  # An AbstractAdapter represents a connection to a database, and provides an
@@ -50,6 +61,9 @@ module ActiveRecord
50
61
  include QueryCache
51
62
  include ActiveSupport::Callbacks
52
63
  include MonitorMixin
64
+ include ColumnDumper
65
+
66
+ SIMPLE_INT = /\A\d+\z/
53
67
 
54
68
  define_callbacks :checkout, :checkin
55
69
 
@@ -57,21 +71,109 @@ module ActiveRecord
57
71
  attr_reader :schema_cache, :last_use, :in_use, :logger
58
72
  alias :in_use? :in_use
59
73
 
74
+ def self.type_cast_config_to_integer(config)
75
+ if config =~ SIMPLE_INT
76
+ config.to_i
77
+ else
78
+ config
79
+ end
80
+ end
81
+
82
+ def self.type_cast_config_to_boolean(config)
83
+ if config == "false"
84
+ false
85
+ else
86
+ config
87
+ end
88
+ end
89
+
60
90
  def initialize(connection, logger = nil, pool = nil) #:nodoc:
61
91
  super()
62
92
 
63
- @active = nil
64
93
  @connection = connection
65
94
  @in_use = false
66
95
  @instrumenter = ActiveSupport::Notifications.instrumenter
67
96
  @last_use = false
68
97
  @logger = logger
69
- @open_transactions = 0
70
98
  @pool = pool
71
99
  @query_cache = Hash.new { |h,sql| h[sql] = {} }
72
100
  @query_cache_enabled = false
73
101
  @schema_cache = SchemaCache.new self
74
102
  @visitor = nil
103
+ @prepared_statements = false
104
+ end
105
+
106
+ def valid_type?(type)
107
+ true
108
+ end
109
+
110
+ class SchemaCreation
111
+ def initialize(conn)
112
+ @conn = conn
113
+ @cache = {}
114
+ end
115
+
116
+ def accept(o)
117
+ m = @cache[o.class] ||= "visit_#{o.class.name.split('::').last}"
118
+ send m, o
119
+ end
120
+
121
+ private
122
+
123
+ def visit_AlterTable(o)
124
+ sql = "ALTER TABLE #{quote_table_name(o.name)} "
125
+ sql << o.adds.map { |col| visit_AddColumn col }.join(' ')
126
+ end
127
+
128
+ def visit_AddColumn(o)
129
+ sql_type = type_to_sql(o.type.to_sym, o.limit, o.precision, o.scale)
130
+ sql = "ADD #{quote_column_name(o.name)} #{sql_type}"
131
+ add_column_options!(sql, column_options(o))
132
+ end
133
+
134
+ def visit_ColumnDefinition(o)
135
+ sql_type = type_to_sql(o.type.to_sym, o.limit, o.precision, o.scale)
136
+ column_sql = "#{quote_column_name(o.name)} #{sql_type}"
137
+ add_column_options!(column_sql, column_options(o)) unless o.primary_key?
138
+ column_sql
139
+ end
140
+
141
+ def visit_TableDefinition(o)
142
+ create_sql = "CREATE#{' TEMPORARY' if o.temporary} TABLE "
143
+ create_sql << "#{quote_table_name(o.name)} ("
144
+ create_sql << o.columns.map { |c| accept c }.join(', ')
145
+ create_sql << ") #{o.options}"
146
+ create_sql
147
+ end
148
+
149
+ def column_options(o)
150
+ column_options = {}
151
+ column_options[:null] = o.null unless o.null.nil?
152
+ column_options[:default] = o.default unless o.default.nil?
153
+ column_options[:column] = o
154
+ column_options
155
+ end
156
+
157
+ def quote_column_name(name)
158
+ @conn.quote_column_name name
159
+ end
160
+
161
+ def quote_table_name(name)
162
+ @conn.quote_table_name name
163
+ end
164
+
165
+ def type_to_sql(type, limit, precision, scale)
166
+ @conn.type_to_sql type.to_sym, limit, precision, scale
167
+ end
168
+
169
+ def add_column_options!(column_sql, column_options)
170
+ @conn.add_column_options! column_sql, column_options
171
+ column_sql
172
+ end
173
+ end
174
+
175
+ def schema_creation
176
+ SchemaCreation.new self
75
177
  end
76
178
 
77
179
  def lease
@@ -83,10 +185,27 @@ module ActiveRecord
83
185
  end
84
186
  end
85
187
 
188
+ def schema_cache=(cache)
189
+ cache.connection = self
190
+ @schema_cache = cache
191
+ end
192
+
86
193
  def expire
87
194
  @in_use = false
88
195
  end
89
196
 
197
+ def unprepared_visitor
198
+ self.class::BindSubstitution.new self
199
+ end
200
+
201
+ def unprepared_statement
202
+ old_prepared_statements, @prepared_statements = @prepared_statements, false
203
+ old_visitor, @visitor = @visitor, unprepared_visitor
204
+ yield
205
+ ensure
206
+ @visitor, @prepared_statements = old_visitor, old_prepared_statements
207
+ end
208
+
90
209
  # Returns the human-readable name of the adapter. Use mixed case - one
91
210
  # can always use downcase if needed.
92
211
  def adapter_name
@@ -142,21 +261,52 @@ module ActiveRecord
142
261
  false
143
262
  end
144
263
 
264
+ # Does this adapter support partial indices?
265
+ def supports_partial_index?
266
+ false
267
+ end
268
+
145
269
  # Does this adapter support explain? As of this writing sqlite3,
146
270
  # mysql2, and postgresql are the only ones that do.
147
271
  def supports_explain?
148
272
  false
149
273
  end
150
274
 
151
- # QUOTING ==================================================
275
+ # Does this adapter support setting the isolation level for a transaction?
276
+ def supports_transaction_isolation?
277
+ false
278
+ end
152
279
 
153
- # Override to return the quoted table name. Defaults to column quoting.
154
- def quote_table_name(name)
155
- quote_column_name(name)
280
+ # Does this adapter support database extensions? As of this writing only
281
+ # postgresql does.
282
+ def supports_extensions?
283
+ false
284
+ end
285
+
286
+ # This is meant to be implemented by the adapters that support extensions
287
+ def disable_extension(name)
288
+ end
289
+
290
+ # This is meant to be implemented by the adapters that support extensions
291
+ def enable_extension(name)
156
292
  end
157
293
 
294
+ # A list of extensions, to be filled in by adapters that support them. At
295
+ # the moment only postgresql does.
296
+ def extensions
297
+ []
298
+ end
299
+
300
+ # A list of index algorithms, to be filled by adapters that support them.
301
+ # MySQL and PostgreSQL have support for them right now.
302
+ def index_algorithms
303
+ {}
304
+ end
305
+
306
+ # QUOTING ==================================================
307
+
158
308
  # Returns a bind substitution value given a +column+ and list of current
159
- # +binds+
309
+ # +binds+.
160
310
  def substitute_at(column, index)
161
311
  Arel::Nodes::BindParam.new '?'
162
312
  end
@@ -174,19 +324,27 @@ module ActiveRecord
174
324
  # checking whether the database is actually capable of responding, i.e. whether
175
325
  # the connection isn't stale.
176
326
  def active?
177
- @active != false
327
+ end
328
+
329
+ # Adapter should redefine this if it needs a threadsafe way to approximate
330
+ # if the connection is active
331
+ def active_threadsafe?
332
+ active?
178
333
  end
179
334
 
180
335
  # Disconnects from the database if already connected, and establishes a
181
- # new connection with the database.
336
+ # new connection with the database. Implementors should call super if they
337
+ # override the default implementation.
182
338
  def reconnect!
183
- @active = true
339
+ clear_cache!
340
+ reset_transaction
184
341
  end
185
342
 
186
343
  # Disconnects from the database if already connected. Otherwise, this
187
344
  # method does nothing.
188
345
  def disconnect!
189
- @active = false
346
+ clear_cache!
347
+ reset_transaction
190
348
  end
191
349
 
192
350
  # Reset the state of this connection, directing the DBMS to clear
@@ -229,18 +387,22 @@ module ActiveRecord
229
387
  @connection
230
388
  end
231
389
 
232
- attr_reader :open_transactions
390
+ def open_transactions
391
+ @transaction.number
392
+ end
233
393
 
234
394
  def increment_open_transactions
235
- @open_transactions += 1
395
+ ActiveSupport::Deprecation.warn "#increment_open_transactions is deprecated and has no effect"
236
396
  end
237
397
 
238
398
  def decrement_open_transactions
239
- @open_transactions -= 1
399
+ ActiveSupport::Deprecation.warn "#decrement_open_transactions is deprecated and has no effect"
240
400
  end
241
401
 
242
402
  def transaction_joinable=(joinable)
243
- @transaction_joinable = joinable
403
+ message = "#transaction_joinable= is deprecated. Please pass the :joinable option to #begin_transaction instead."
404
+ ActiveSupport::Deprecation.warn message
405
+ @transaction.joinable = joinable
244
406
  end
245
407
 
246
408
  def create_savepoint
@@ -271,26 +433,29 @@ module ActiveRecord
271
433
 
272
434
  protected
273
435
 
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
436
+ def log(sql, name = "SQL", binds = [])
437
+ @instrumenter.instrument(
438
+ "sql.active_record",
439
+ :sql => sql,
440
+ :name => name,
441
+ :connection_id => object_id,
442
+ :binds => binds) { yield }
443
+ rescue => e
444
+ message = "#{e.class.name}: #{e.message}: #{sql}"
445
+ @logger.error message if @logger
446
+ exception = translate_exception(e, message)
447
+ exception.set_backtrace e.backtrace
448
+ raise exception
449
+ end
288
450
 
289
- def translate_exception(e, message)
290
- # override in derived class
291
- ActiveRecord::StatementInvalid.new(message)
292
- end
451
+ def translate_exception(exception, message)
452
+ # override in derived class
453
+ ActiveRecord::StatementInvalid.new(message, exception)
454
+ end
293
455
 
456
+ def without_prepared_statement?(binds)
457
+ !@prepared_statements || binds.empty?
458
+ end
294
459
  end
295
460
  end
296
461
  end