activerecord 7.0.8.7 → 7.1.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (237) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1795 -1424
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +16 -16
  5. data/lib/active_record/aggregations.rb +16 -13
  6. data/lib/active_record/association_relation.rb +1 -1
  7. data/lib/active_record/associations/association.rb +20 -4
  8. data/lib/active_record/associations/association_scope.rb +16 -9
  9. data/lib/active_record/associations/belongs_to_association.rb +14 -6
  10. data/lib/active_record/associations/builder/association.rb +3 -3
  11. data/lib/active_record/associations/builder/belongs_to.rb +21 -8
  12. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +1 -5
  13. data/lib/active_record/associations/builder/singular_association.rb +4 -0
  14. data/lib/active_record/associations/collection_association.rb +19 -13
  15. data/lib/active_record/associations/collection_proxy.rb +15 -10
  16. data/lib/active_record/associations/foreign_association.rb +10 -3
  17. data/lib/active_record/associations/has_many_association.rb +20 -13
  18. data/lib/active_record/associations/has_many_through_association.rb +10 -6
  19. data/lib/active_record/associations/has_one_association.rb +10 -3
  20. data/lib/active_record/associations/join_dependency/join_association.rb +3 -2
  21. data/lib/active_record/associations/join_dependency.rb +10 -10
  22. data/lib/active_record/associations/preloader/association.rb +31 -7
  23. data/lib/active_record/associations/preloader.rb +13 -10
  24. data/lib/active_record/associations/singular_association.rb +1 -1
  25. data/lib/active_record/associations/through_association.rb +22 -11
  26. data/lib/active_record/associations.rb +319 -217
  27. data/lib/active_record/attribute_assignment.rb +0 -2
  28. data/lib/active_record/attribute_methods/before_type_cast.rb +17 -0
  29. data/lib/active_record/attribute_methods/dirty.rb +53 -35
  30. data/lib/active_record/attribute_methods/primary_key.rb +76 -24
  31. data/lib/active_record/attribute_methods/query.rb +28 -16
  32. data/lib/active_record/attribute_methods/read.rb +21 -8
  33. data/lib/active_record/attribute_methods/serialization.rb +150 -31
  34. data/lib/active_record/attribute_methods/time_zone_conversion.rb +4 -0
  35. data/lib/active_record/attribute_methods/write.rb +6 -6
  36. data/lib/active_record/attribute_methods.rb +145 -21
  37. data/lib/active_record/attributes.rb +3 -3
  38. data/lib/active_record/autosave_association.rb +59 -10
  39. data/lib/active_record/base.rb +7 -2
  40. data/lib/active_record/callbacks.rb +10 -24
  41. data/lib/active_record/coders/column_serializer.rb +61 -0
  42. data/lib/active_record/coders/json.rb +1 -1
  43. data/lib/active_record/coders/yaml_column.rb +70 -42
  44. data/lib/active_record/connection_adapters/abstract/connection_handler.rb +163 -88
  45. data/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb +2 -0
  46. data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +3 -1
  47. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +80 -50
  48. data/lib/active_record/connection_adapters/abstract/database_limits.rb +5 -0
  49. data/lib/active_record/connection_adapters/abstract/database_statements.rb +129 -31
  50. data/lib/active_record/connection_adapters/abstract/query_cache.rb +62 -23
  51. data/lib/active_record/connection_adapters/abstract/quoting.rb +41 -6
  52. data/lib/active_record/connection_adapters/abstract/savepoints.rb +4 -3
  53. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +18 -4
  54. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +137 -11
  55. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +296 -127
  56. data/lib/active_record/connection_adapters/abstract/transaction.rb +287 -58
  57. data/lib/active_record/connection_adapters/abstract_adapter.rb +511 -92
  58. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +244 -121
  59. data/lib/active_record/connection_adapters/column.rb +9 -0
  60. data/lib/active_record/connection_adapters/mysql/column.rb +1 -0
  61. data/lib/active_record/connection_adapters/mysql/database_statements.rb +22 -143
  62. data/lib/active_record/connection_adapters/mysql/quoting.rb +16 -12
  63. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +9 -0
  64. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +6 -0
  65. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +1 -1
  66. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +19 -13
  67. data/lib/active_record/connection_adapters/mysql2/database_statements.rb +151 -0
  68. data/lib/active_record/connection_adapters/mysql2_adapter.rb +106 -55
  69. data/lib/active_record/connection_adapters/pool_config.rb +14 -5
  70. data/lib/active_record/connection_adapters/pool_manager.rb +19 -9
  71. data/lib/active_record/connection_adapters/postgresql/column.rb +14 -3
  72. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +74 -40
  73. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +6 -0
  74. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +3 -2
  75. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +11 -2
  76. data/lib/active_record/connection_adapters/postgresql/oid/timestamp_with_time_zone.rb +1 -1
  77. data/lib/active_record/connection_adapters/postgresql/quoting.rb +10 -6
  78. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +3 -9
  79. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +76 -6
  80. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +131 -2
  81. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +53 -0
  82. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +364 -61
  83. data/lib/active_record/connection_adapters/postgresql_adapter.rb +353 -192
  84. data/lib/active_record/connection_adapters/schema_cache.rb +287 -59
  85. data/lib/active_record/connection_adapters/sqlite3/column.rb +49 -0
  86. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +52 -39
  87. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +4 -3
  88. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +1 -0
  89. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +26 -7
  90. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +211 -81
  91. data/lib/active_record/connection_adapters/statement_pool.rb +7 -0
  92. data/lib/active_record/connection_adapters/trilogy/database_statements.rb +99 -0
  93. data/lib/active_record/connection_adapters/trilogy_adapter.rb +258 -0
  94. data/lib/active_record/connection_adapters.rb +3 -1
  95. data/lib/active_record/connection_handling.rb +72 -95
  96. data/lib/active_record/core.rb +181 -154
  97. data/lib/active_record/counter_cache.rb +52 -27
  98. data/lib/active_record/database_configurations/connection_url_resolver.rb +1 -1
  99. data/lib/active_record/database_configurations/database_config.rb +9 -3
  100. data/lib/active_record/database_configurations/hash_config.rb +28 -14
  101. data/lib/active_record/database_configurations/url_config.rb +17 -11
  102. data/lib/active_record/database_configurations.rb +86 -33
  103. data/lib/active_record/delegated_type.rb +15 -10
  104. data/lib/active_record/deprecator.rb +7 -0
  105. data/lib/active_record/destroy_association_async_job.rb +3 -1
  106. data/lib/active_record/encryption/auto_filtered_parameters.rb +66 -0
  107. data/lib/active_record/encryption/cipher/aes256_gcm.rb +4 -1
  108. data/lib/active_record/encryption/config.rb +25 -1
  109. data/lib/active_record/encryption/configurable.rb +12 -19
  110. data/lib/active_record/encryption/context.rb +10 -3
  111. data/lib/active_record/encryption/contexts.rb +5 -1
  112. data/lib/active_record/encryption/derived_secret_key_provider.rb +8 -2
  113. data/lib/active_record/encryption/encryptable_record.rb +42 -18
  114. data/lib/active_record/encryption/encrypted_attribute_type.rb +23 -8
  115. data/lib/active_record/encryption/extended_deterministic_queries.rb +66 -69
  116. data/lib/active_record/encryption/extended_deterministic_uniqueness_validator.rb +3 -3
  117. data/lib/active_record/encryption/key_generator.rb +12 -1
  118. data/lib/active_record/encryption/message_serializer.rb +2 -0
  119. data/lib/active_record/encryption/properties.rb +3 -3
  120. data/lib/active_record/encryption/scheme.rb +22 -21
  121. data/lib/active_record/encryption.rb +3 -0
  122. data/lib/active_record/enum.rb +112 -28
  123. data/lib/active_record/errors.rb +112 -18
  124. data/lib/active_record/explain.rb +23 -3
  125. data/lib/active_record/fixture_set/model_metadata.rb +14 -4
  126. data/lib/active_record/fixture_set/render_context.rb +2 -0
  127. data/lib/active_record/fixture_set/table_row.rb +29 -8
  128. data/lib/active_record/fixtures.rb +135 -71
  129. data/lib/active_record/future_result.rb +40 -5
  130. data/lib/active_record/gem_version.rb +4 -4
  131. data/lib/active_record/inheritance.rb +30 -16
  132. data/lib/active_record/insert_all.rb +57 -10
  133. data/lib/active_record/integration.rb +8 -8
  134. data/lib/active_record/internal_metadata.rb +120 -30
  135. data/lib/active_record/locking/optimistic.rb +1 -1
  136. data/lib/active_record/locking/pessimistic.rb +5 -2
  137. data/lib/active_record/log_subscriber.rb +29 -12
  138. data/lib/active_record/marshalling.rb +59 -0
  139. data/lib/active_record/message_pack.rb +124 -0
  140. data/lib/active_record/middleware/database_selector/resolver.rb +4 -0
  141. data/lib/active_record/middleware/database_selector.rb +6 -8
  142. data/lib/active_record/middleware/shard_selector.rb +3 -1
  143. data/lib/active_record/migration/command_recorder.rb +104 -5
  144. data/lib/active_record/migration/compatibility.rb +145 -5
  145. data/lib/active_record/migration/default_strategy.rb +23 -0
  146. data/lib/active_record/migration/execution_strategy.rb +19 -0
  147. data/lib/active_record/migration/pending_migration_connection.rb +21 -0
  148. data/lib/active_record/migration.rb +219 -111
  149. data/lib/active_record/model_schema.rb +69 -44
  150. data/lib/active_record/nested_attributes.rb +37 -8
  151. data/lib/active_record/normalization.rb +167 -0
  152. data/lib/active_record/persistence.rb +188 -37
  153. data/lib/active_record/promise.rb +84 -0
  154. data/lib/active_record/query_cache.rb +4 -22
  155. data/lib/active_record/query_logs.rb +77 -52
  156. data/lib/active_record/query_logs_formatter.rb +41 -0
  157. data/lib/active_record/querying.rb +15 -2
  158. data/lib/active_record/railtie.rb +107 -45
  159. data/lib/active_record/railties/controller_runtime.rb +12 -6
  160. data/lib/active_record/railties/databases.rake +144 -150
  161. data/lib/active_record/railties/job_runtime.rb +23 -0
  162. data/lib/active_record/readonly_attributes.rb +32 -5
  163. data/lib/active_record/reflection.rb +181 -45
  164. data/lib/active_record/relation/batches/batch_enumerator.rb +5 -3
  165. data/lib/active_record/relation/batches.rb +190 -61
  166. data/lib/active_record/relation/calculations.rb +187 -63
  167. data/lib/active_record/relation/delegation.rb +23 -9
  168. data/lib/active_record/relation/finder_methods.rb +77 -16
  169. data/lib/active_record/relation/merger.rb +2 -0
  170. data/lib/active_record/relation/predicate_builder/association_query_value.rb +11 -2
  171. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +10 -7
  172. data/lib/active_record/relation/predicate_builder/relation_handler.rb +5 -1
  173. data/lib/active_record/relation/predicate_builder.rb +26 -14
  174. data/lib/active_record/relation/query_attribute.rb +2 -1
  175. data/lib/active_record/relation/query_methods.rb +371 -68
  176. data/lib/active_record/relation/spawn_methods.rb +18 -1
  177. data/lib/active_record/relation.rb +103 -37
  178. data/lib/active_record/result.rb +19 -5
  179. data/lib/active_record/runtime_registry.rb +24 -1
  180. data/lib/active_record/sanitization.rb +51 -11
  181. data/lib/active_record/schema.rb +2 -3
  182. data/lib/active_record/schema_dumper.rb +46 -7
  183. data/lib/active_record/schema_migration.rb +68 -33
  184. data/lib/active_record/scoping/default.rb +15 -5
  185. data/lib/active_record/scoping/named.rb +2 -2
  186. data/lib/active_record/scoping.rb +2 -1
  187. data/lib/active_record/secure_password.rb +60 -0
  188. data/lib/active_record/secure_token.rb +21 -3
  189. data/lib/active_record/signed_id.rb +7 -5
  190. data/lib/active_record/store.rb +8 -8
  191. data/lib/active_record/suppressor.rb +3 -1
  192. data/lib/active_record/table_metadata.rb +10 -1
  193. data/lib/active_record/tasks/database_tasks.rb +152 -108
  194. data/lib/active_record/tasks/mysql_database_tasks.rb +15 -6
  195. data/lib/active_record/tasks/postgresql_database_tasks.rb +16 -13
  196. data/lib/active_record/tasks/sqlite_database_tasks.rb +15 -7
  197. data/lib/active_record/test_fixtures.rb +114 -96
  198. data/lib/active_record/timestamp.rb +30 -16
  199. data/lib/active_record/token_for.rb +113 -0
  200. data/lib/active_record/touch_later.rb +11 -6
  201. data/lib/active_record/transactions.rb +36 -10
  202. data/lib/active_record/type/adapter_specific_registry.rb +1 -8
  203. data/lib/active_record/type/internal/timezone.rb +7 -2
  204. data/lib/active_record/type/time.rb +4 -0
  205. data/lib/active_record/validations/absence.rb +1 -1
  206. data/lib/active_record/validations/numericality.rb +5 -4
  207. data/lib/active_record/validations/presence.rb +5 -28
  208. data/lib/active_record/validations/uniqueness.rb +47 -2
  209. data/lib/active_record/validations.rb +8 -4
  210. data/lib/active_record/version.rb +1 -1
  211. data/lib/active_record.rb +122 -17
  212. data/lib/arel/errors.rb +10 -0
  213. data/lib/arel/factory_methods.rb +4 -0
  214. data/lib/arel/nodes/binary.rb +6 -1
  215. data/lib/arel/nodes/bound_sql_literal.rb +61 -0
  216. data/lib/arel/nodes/cte.rb +36 -0
  217. data/lib/arel/nodes/fragments.rb +35 -0
  218. data/lib/arel/nodes/homogeneous_in.rb +1 -9
  219. data/lib/arel/nodes/leading_join.rb +8 -0
  220. data/lib/arel/nodes/node.rb +111 -2
  221. data/lib/arel/nodes/sql_literal.rb +6 -0
  222. data/lib/arel/nodes/table_alias.rb +4 -0
  223. data/lib/arel/nodes.rb +4 -0
  224. data/lib/arel/predications.rb +2 -0
  225. data/lib/arel/table.rb +9 -5
  226. data/lib/arel/tree_manager.rb +5 -1
  227. data/lib/arel/visitors/mysql.rb +8 -1
  228. data/lib/arel/visitors/to_sql.rb +83 -18
  229. data/lib/arel/visitors/visitor.rb +2 -2
  230. data/lib/arel.rb +16 -2
  231. data/lib/rails/generators/active_record/application_record/USAGE +8 -0
  232. data/lib/rails/generators/active_record/migration.rb +3 -1
  233. data/lib/rails/generators/active_record/model/USAGE +113 -0
  234. data/lib/rails/generators/active_record/model/model_generator.rb +15 -6
  235. metadata +46 -10
  236. data/lib/active_record/connection_adapters/legacy_pool_manager.rb +0 -35
  237. data/lib/active_record/null_relation.rb +0 -63
@@ -4,6 +4,7 @@ require "set"
4
4
  require "active_record/connection_adapters/sql_type_metadata"
5
5
  require "active_record/connection_adapters/abstract/schema_dumper"
6
6
  require "active_record/connection_adapters/abstract/schema_creation"
7
+ require "active_support/concurrency/null_lock"
7
8
  require "active_support/concurrency/load_interlock_aware_monitor"
8
9
  require "arel/collectors/bind"
9
10
  require "arel/collectors/composite"
@@ -12,6 +13,8 @@ require "arel/collectors/substitute_binds"
12
13
 
13
14
  module ActiveRecord
14
15
  module ConnectionAdapters # :nodoc:
16
+ # = Active Record Abstract Adapter
17
+ #
15
18
  # Active Record supports multiple database systems. AbstractAdapter and
16
19
  # related classes form the abstraction layer which makes this possible.
17
20
  # An AbstractAdapter represents a connection to a database, and provides an
@@ -36,12 +39,20 @@ module ActiveRecord
36
39
  include Savepoints
37
40
 
38
41
  SIMPLE_INT = /\A\d+\z/
39
- COMMENT_REGEX = %r{(?:--.*\n)|/\*(?:[^*]|\*[^/])*\*/}m
42
+ COMMENT_REGEX = %r{(?:--.*\n)|/\*(?:[^*]|\*[^/])*\*/}
40
43
 
41
- attr_accessor :pool
44
+ attr_reader :pool
42
45
  attr_reader :visitor, :owner, :logger, :lock
43
46
  alias :in_use? :owner
44
47
 
48
+ def pool=(value)
49
+ return if value.eql?(@pool)
50
+ @schema_cache = nil
51
+ @pool = value
52
+
53
+ @pool.schema_reflection.load!(self) if ActiveRecord.lazily_load_schema_cache
54
+ end
55
+
45
56
  set_callback :checkin, :after, :enable_lazy_transactions!
46
57
 
47
58
  def self.type_cast_config_to_integer(config)
@@ -62,6 +73,16 @@ module ActiveRecord
62
73
  end
63
74
  end
64
75
 
76
+ def self.validate_default_timezone(config)
77
+ case config
78
+ when nil
79
+ when "utc", "local"
80
+ config.to_sym
81
+ else
82
+ raise ArgumentError, "default_timezone must be either 'utc' or 'local'"
83
+ end
84
+ end
85
+
65
86
  DEFAULT_READ_QUERY = [:begin, :commit, :explain, :release, :rollback, :savepoint, :select, :with] # :nodoc:
66
87
  private_constant :DEFAULT_READ_QUERY
67
88
 
@@ -71,27 +92,104 @@ module ActiveRecord
71
92
  /\A(?:[(\s]|#{COMMENT_REGEX})*#{Regexp.union(*parts)}/
72
93
  end
73
94
 
74
- def initialize(connection, logger = nil, config = {}) # :nodoc:
95
+ def self.find_cmd_and_exec(commands, *args) # :doc:
96
+ commands = Array(commands)
97
+
98
+ dirs_on_path = ENV["PATH"].to_s.split(File::PATH_SEPARATOR)
99
+ unless (ext = RbConfig::CONFIG["EXEEXT"]).empty?
100
+ commands = commands.map { |cmd| "#{cmd}#{ext}" }
101
+ end
102
+
103
+ full_path_command = nil
104
+ found = commands.detect do |cmd|
105
+ dirs_on_path.detect do |path|
106
+ full_path_command = File.join(path, cmd)
107
+ begin
108
+ stat = File.stat(full_path_command)
109
+ rescue SystemCallError
110
+ else
111
+ stat.file? && stat.executable?
112
+ end
113
+ end
114
+ end
115
+
116
+ if found
117
+ exec full_path_command, *args
118
+ else
119
+ abort("Couldn't find database client: #{commands.join(', ')}. Check your $PATH and try again.")
120
+ end
121
+ end
122
+
123
+ # Opens a database console session.
124
+ def self.dbconsole(config, options = {})
125
+ raise NotImplementedError
126
+ end
127
+
128
+ def initialize(config_or_deprecated_connection, deprecated_logger = nil, deprecated_connection_options = nil, deprecated_config = nil) # :nodoc:
75
129
  super()
76
130
 
77
- @connection = connection
78
- @owner = nil
79
- @instrumenter = ActiveSupport::Notifications.instrumenter
80
- @logger = logger
81
- @config = config
82
- @pool = ActiveRecord::ConnectionAdapters::NullPool.new
83
- @idle_since = Process.clock_gettime(Process::CLOCK_MONOTONIC)
131
+ @raw_connection = nil
132
+ @unconfigured_connection = nil
133
+
134
+ if config_or_deprecated_connection.is_a?(Hash)
135
+ @config = config_or_deprecated_connection.symbolize_keys
136
+ @logger = ActiveRecord::Base.logger
137
+
138
+ if deprecated_logger || deprecated_connection_options || deprecated_config
139
+ raise ArgumentError, "when initializing an ActiveRecord adapter with a config hash, that should be the only argument"
140
+ end
141
+ else
142
+ # Soft-deprecated for now; we'll probably warn in future.
143
+
144
+ @unconfigured_connection = config_or_deprecated_connection
145
+ @logger = deprecated_logger || ActiveRecord::Base.logger
146
+ if deprecated_config
147
+ @config = (deprecated_config || {}).symbolize_keys
148
+ @connection_parameters = deprecated_connection_options
149
+ else
150
+ @config = (deprecated_connection_options || {}).symbolize_keys
151
+ @connection_parameters = nil
152
+ end
153
+ end
154
+
155
+ @owner = nil
156
+ @instrumenter = ActiveSupport::Notifications.instrumenter
157
+ @pool = ActiveRecord::ConnectionAdapters::NullPool.new
158
+ @idle_since = Process.clock_gettime(Process::CLOCK_MONOTONIC)
84
159
  @visitor = arel_visitor
85
160
  @statements = build_statement_pool
86
- @lock = ActiveSupport::Concurrency::LoadInterlockAwareMonitor.new
161
+ self.lock_thread = nil
87
162
 
88
- @prepared_statements = self.class.type_cast_config_to_boolean(
89
- config.fetch(:prepared_statements, true)
163
+ @prepared_statements = !ActiveRecord.disable_prepared_statements && self.class.type_cast_config_to_boolean(
164
+ @config.fetch(:prepared_statements) { default_prepared_statements }
90
165
  )
91
166
 
92
167
  @advisory_locks_enabled = self.class.type_cast_config_to_boolean(
93
- config.fetch(:advisory_locks, true)
168
+ @config.fetch(:advisory_locks, true)
94
169
  )
170
+
171
+ @default_timezone = self.class.validate_default_timezone(@config[:default_timezone])
172
+
173
+ @raw_connection_dirty = false
174
+ @verified = false
175
+ end
176
+
177
+ THREAD_LOCK = ActiveSupport::Concurrency::ThreadLoadInterlockAwareMonitor.new
178
+ private_constant :THREAD_LOCK
179
+
180
+ FIBER_LOCK = ActiveSupport::Concurrency::LoadInterlockAwareMonitor.new
181
+ private_constant :FIBER_LOCK
182
+
183
+ def lock_thread=(lock_thread) # :nodoc:
184
+ @lock =
185
+ case lock_thread
186
+ when Thread
187
+ THREAD_LOCK
188
+ when Fiber
189
+ FIBER_LOCK
190
+ else
191
+ ActiveSupport::Concurrency::NullLock
192
+ end
95
193
  end
96
194
 
97
195
  EXCEPTION_NEVER = { Exception => :never }.freeze # :nodoc:
@@ -121,18 +219,28 @@ module ActiveRecord
121
219
  @config.fetch(:use_metadata_table, true)
122
220
  end
123
221
 
222
+ def connection_retries
223
+ (@config[:connection_retries] || 1).to_i
224
+ end
225
+
226
+ def retry_deadline
227
+ if @config[:retry_deadline]
228
+ @config[:retry_deadline].to_f
229
+ else
230
+ nil
231
+ end
232
+ end
233
+
234
+ def default_timezone
235
+ @default_timezone || ActiveRecord.default_timezone
236
+ end
237
+
124
238
  # Determines whether writes are currently being prevented.
125
239
  #
126
- # Returns true if the connection is a replica.
127
- #
128
- # If the application is using legacy handling, returns
129
- # true if +connection_handler.prevent_writes+ is set.
130
- #
131
- # If the application is using the new connection handling
132
- # will return true based on +current_preventing_writes+.
240
+ # Returns true if the connection is a replica or returns
241
+ # the value of +current_preventing_writes+.
133
242
  def preventing_writes?
134
243
  return true if replica?
135
- return ActiveRecord::Base.connection_handler.prevent_writes if ActiveRecord.legacy_connection_handling
136
244
  return false if connection_class.nil?
137
245
 
138
246
  connection_class.current_preventing_writes
@@ -143,25 +251,15 @@ module ActiveRecord
143
251
  end
144
252
 
145
253
  def migration_context # :nodoc:
146
- MigrationContext.new(migrations_paths, schema_migration)
254
+ MigrationContext.new(migrations_paths, schema_migration, internal_metadata)
147
255
  end
148
256
 
149
257
  def schema_migration # :nodoc:
150
- @schema_migration ||= begin
151
- conn = self
152
- spec_name = conn.pool.pool_config.connection_specification_name
153
-
154
- return ActiveRecord::SchemaMigration if spec_name == "ActiveRecord::Base"
155
-
156
- schema_migration_name = "#{spec_name}::SchemaMigration"
157
-
158
- Class.new(ActiveRecord::SchemaMigration) do
159
- define_singleton_method(:name) { schema_migration_name }
160
- define_singleton_method(:to_s) { schema_migration_name }
258
+ SchemaMigration.new(self)
259
+ end
161
260
 
162
- self.connection_specification_name = spec_name
163
- end
164
- end
261
+ def internal_metadata # :nodoc:
262
+ InternalMetadata.new(self)
165
263
  end
166
264
 
167
265
  def prepared_statements?
@@ -200,16 +298,16 @@ module ActiveRecord
200
298
  def lease
201
299
  if in_use?
202
300
  msg = +"Cannot lease connection, "
203
- if @owner == Thread.current
301
+ if @owner == ActiveSupport::IsolatedExecutionState.context
204
302
  msg << "it is already leased by the current thread."
205
303
  else
206
304
  msg << "it is already in use by a different thread: #{@owner}. " \
207
- "Current thread: #{Thread.current}."
305
+ "Current thread: #{ActiveSupport::IsolatedExecutionState.context}."
208
306
  end
209
307
  raise ActiveRecordError, msg
210
308
  end
211
309
 
212
- @owner = Thread.current
310
+ @owner = ActiveSupport::IsolatedExecutionState.context
213
311
  end
214
312
 
215
313
  def connection_class # :nodoc:
@@ -229,21 +327,16 @@ module ActiveRecord
229
327
  end
230
328
 
231
329
  def schema_cache
232
- @pool.get_schema_cache(self)
233
- end
234
-
235
- def schema_cache=(cache)
236
- cache.connection = self
237
- @pool.set_schema_cache(cache)
330
+ @schema_cache ||= BoundSchemaReflection.new(@pool.schema_reflection, self)
238
331
  end
239
332
 
240
333
  # this method must only be called while holding connection pool's mutex
241
334
  def expire
242
335
  if in_use?
243
- if @owner != Thread.current
336
+ if @owner != ActiveSupport::IsolatedExecutionState.context
244
337
  raise ActiveRecordError, "Cannot expire connection, " \
245
338
  "it is owned by a different thread: #{@owner}. " \
246
- "Current thread: #{Thread.current}."
339
+ "Current thread: #{ActiveSupport::IsolatedExecutionState.context}."
247
340
  end
248
341
 
249
342
  @idle_since = Process.clock_gettime(Process::CLOCK_MONOTONIC)
@@ -256,10 +349,10 @@ module ActiveRecord
256
349
  # this method must only be called while holding connection pool's mutex (and a desire for segfaults)
257
350
  def steal! # :nodoc:
258
351
  if in_use?
259
- if @owner != Thread.current
352
+ if @owner != ActiveSupport::IsolatedExecutionState.context
260
353
  pool.send :remove_connection_from_thread_cache, self, @owner
261
354
 
262
- @owner = Thread.current
355
+ @owner = ActiveSupport::IsolatedExecutionState.context
263
356
  end
264
357
  else
265
358
  raise ActiveRecordError, "Cannot steal connection, it is not currently leased."
@@ -287,7 +380,14 @@ module ActiveRecord
287
380
 
288
381
  # Does the database for this adapter exist?
289
382
  def self.database_exists?(config)
290
- raise NotImplementedError
383
+ new(config).database_exists?
384
+ end
385
+
386
+ def database_exists?
387
+ connect!
388
+ true
389
+ rescue ActiveRecord::NoDatabaseError
390
+ false
291
391
  end
292
392
 
293
393
  # Does this adapter support DDL rollbacks in transactions? That is, would
@@ -305,6 +405,16 @@ module ActiveRecord
305
405
  false
306
406
  end
307
407
 
408
+ # Do TransactionRollbackErrors on savepoints affect the parent
409
+ # transaction?
410
+ def savepoint_errors_invalidate_transactions?
411
+ false
412
+ end
413
+
414
+ def supports_restart_db_transaction?
415
+ false
416
+ end
417
+
308
418
  # Does this adapter support application-enforced advisory locking?
309
419
  def supports_advisory_locks?
310
420
  false
@@ -331,6 +441,11 @@ module ActiveRecord
331
441
  false
332
442
  end
333
443
 
444
+ # Does this adapter support including non-key columns?
445
+ def supports_index_include?
446
+ false
447
+ end
448
+
334
449
  # Does this adapter support expression indices?
335
450
  def supports_expression_index?
336
451
  false
@@ -377,6 +492,16 @@ module ActiveRecord
377
492
  false
378
493
  end
379
494
 
495
+ # Does this adapter support creating exclusion constraints?
496
+ def supports_exclusion_constraints?
497
+ false
498
+ end
499
+
500
+ # Does this adapter support creating unique constraints?
501
+ def supports_unique_constraints?
502
+ false
503
+ end
504
+
380
505
  # Does this adapter support views?
381
506
  def supports_views?
382
507
  false
@@ -392,7 +517,7 @@ module ActiveRecord
392
517
  false
393
518
  end
394
519
 
395
- # Does this adapter support json data type?
520
+ # Does this adapter support JSON data type?
396
521
  def supports_json?
397
522
  false
398
523
  end
@@ -450,23 +575,47 @@ module ActiveRecord
450
575
  true
451
576
  end
452
577
 
578
+ def supports_nulls_not_distinct?
579
+ false
580
+ end
581
+
582
+ def return_value_after_insert?(column) # :nodoc:
583
+ column.auto_incremented_by_db?
584
+ end
585
+
453
586
  def async_enabled? # :nodoc:
454
587
  supports_concurrent_connections? &&
455
588
  !ActiveRecord.async_query_executor.nil? && !pool.async_executor.nil?
456
589
  end
457
590
 
458
591
  # This is meant to be implemented by the adapters that support extensions
459
- def disable_extension(name)
592
+ def disable_extension(name, **)
460
593
  end
461
594
 
462
595
  # This is meant to be implemented by the adapters that support extensions
463
- def enable_extension(name)
596
+ def enable_extension(name, **)
464
597
  end
465
598
 
466
599
  # This is meant to be implemented by the adapters that support custom enum types
467
600
  def create_enum(*) # :nodoc:
468
601
  end
469
602
 
603
+ # This is meant to be implemented by the adapters that support custom enum types
604
+ def drop_enum(*) # :nodoc:
605
+ end
606
+
607
+ # This is meant to be implemented by the adapters that support custom enum types
608
+ def rename_enum(*) # :nodoc:
609
+ end
610
+
611
+ # This is meant to be implemented by the adapters that support custom enum types
612
+ def add_enum_value(*) # :nodoc:
613
+ end
614
+
615
+ # This is meant to be implemented by the adapters that support custom enum types
616
+ def rename_enum_value(*) # :nodoc:
617
+ end
618
+
470
619
  def advisory_locks_enabled? # :nodoc:
471
620
  supports_advisory_locks? && @advisory_locks_enabled
472
621
  end
@@ -504,7 +653,17 @@ module ActiveRecord
504
653
 
505
654
  # Override to check all foreign key constraints in a database.
506
655
  def all_foreign_keys_valid?
656
+ check_all_foreign_keys_valid!
507
657
  true
658
+ rescue ActiveRecord::StatementInvalid
659
+ false
660
+ end
661
+ deprecate :all_foreign_keys_valid?, deprecator: ActiveRecord.deprecator
662
+
663
+ # Override to check all foreign key constraints in a database.
664
+ # The adapter should raise a +ActiveRecord::StatementInvalid+ if foreign key
665
+ # constraints are not met.
666
+ def check_all_foreign_keys_valid!
508
667
  end
509
668
 
510
669
  # CONNECTION MANAGEMENT ====================================
@@ -515,19 +674,51 @@ module ActiveRecord
515
674
  def active?
516
675
  end
517
676
 
518
- # Disconnects from the database if already connected, and establishes a
519
- # new connection with the database. Implementors should call super if they
520
- # override the default implementation.
521
- def reconnect!
522
- clear_cache!
523
- reset_transaction
677
+ # Disconnects from the database if already connected, and establishes a new
678
+ # connection with the database. Implementors should define private #reconnect
679
+ # instead.
680
+ def reconnect!(restore_transactions: false)
681
+ retries_available = connection_retries
682
+ deadline = retry_deadline && Process.clock_gettime(Process::CLOCK_MONOTONIC) + retry_deadline
683
+
684
+ @lock.synchronize do
685
+ reconnect
686
+
687
+ enable_lazy_transactions!
688
+ @raw_connection_dirty = false
689
+ @verified = true
690
+
691
+ reset_transaction(restore: restore_transactions) do
692
+ clear_cache!(new_connection: true)
693
+ configure_connection
694
+ end
695
+ rescue => original_exception
696
+ translated_exception = translate_exception_class(original_exception, nil, nil)
697
+ retry_deadline_exceeded = deadline && deadline < Process.clock_gettime(Process::CLOCK_MONOTONIC)
698
+
699
+ if !retry_deadline_exceeded && retries_available > 0
700
+ retries_available -= 1
701
+
702
+ if retryable_connection_error?(translated_exception)
703
+ backoff(connection_retries - retries_available)
704
+ retry
705
+ end
706
+ end
707
+
708
+ @verified = false
709
+
710
+ raise translated_exception
711
+ end
524
712
  end
525
713
 
526
714
  # Disconnects from the database if already connected. Otherwise, this
527
715
  # method does nothing.
528
716
  def disconnect!
529
- clear_cache!
530
- reset_transaction
717
+ @lock.synchronize do
718
+ clear_cache!(new_connection: true)
719
+ reset_transaction
720
+ @raw_connection_dirty = false
721
+ end
531
722
  end
532
723
 
533
724
  # Immediately forget this connection ever existed. Unlike disconnect!,
@@ -538,22 +729,20 @@ module ActiveRecord
538
729
  # rid of a connection that belonged to its parent.
539
730
  def discard!
540
731
  # This should be overridden by concrete adapters.
541
- #
542
- # Prevent @connection's finalizer from touching the socket, or
543
- # otherwise communicating with its server, when it is collected.
544
- if schema_cache.connection == self
545
- schema_cache.connection = nil
546
- end
547
732
  end
548
733
 
549
734
  # Reset the state of this connection, directing the DBMS to clear
550
735
  # transactions and other connection-related server-side state. Usually a
551
736
  # database-dependent operation.
552
737
  #
553
- # The default implementation does nothing; the implementation should be
554
- # overridden by concrete adapters.
738
+ # If a database driver or protocol does not support such a feature,
739
+ # implementors may alias this to #reconnect!. Otherwise, implementors
740
+ # should call super immediately after resetting the connection (and while
741
+ # still holding @lock).
555
742
  def reset!
556
- # this should be overridden by concrete adapters
743
+ clear_cache!(new_connection: true)
744
+ reset_transaction
745
+ configure_connection
557
746
  end
558
747
 
559
748
  # Removes the connection from the pool and disconnect it.
@@ -563,8 +752,16 @@ module ActiveRecord
563
752
  end
564
753
 
565
754
  # Clear any caching the database adapter may be doing.
566
- def clear_cache!
567
- @lock.synchronize { @statements.clear } if @statements
755
+ def clear_cache!(new_connection: false)
756
+ if @statements
757
+ @lock.synchronize do
758
+ if new_connection
759
+ @statements.reset
760
+ else
761
+ @statements.clear
762
+ end
763
+ end
764
+ end
568
765
  end
569
766
 
570
767
  # Returns true if its required to reload the connection between requests for development mode.
@@ -576,7 +773,31 @@ module ActiveRecord
576
773
  # This is done under the hood by calling #active?. If the connection
577
774
  # is no longer active, then this method will reconnect to the database.
578
775
  def verify!
579
- reconnect! unless active?
776
+ unless active?
777
+ @lock.synchronize do
778
+ if @unconfigured_connection
779
+ @raw_connection = @unconfigured_connection
780
+ @unconfigured_connection = nil
781
+ configure_connection
782
+ @verified = true
783
+ return
784
+ end
785
+
786
+ reconnect!(restore_transactions: true)
787
+ end
788
+ end
789
+
790
+ @verified = true
791
+ end
792
+
793
+ def connect!
794
+ verify!
795
+ self
796
+ end
797
+
798
+ def clean! # :nodoc:
799
+ @raw_connection_dirty = false
800
+ @verified = nil
580
801
  end
581
802
 
582
803
  # Provides access to the underlying database driver for this adapter. For
@@ -590,8 +811,11 @@ module ActiveRecord
590
811
  # this client. If that is the case, generally you'll want to invalidate
591
812
  # the query cache using +ActiveRecord::Base.clear_query_cache+.
592
813
  def raw_connection
593
- disable_lazy_transactions!
594
- @connection
814
+ with_raw_connection do |conn|
815
+ disable_lazy_transactions!
816
+ @raw_connection_dirty = true
817
+ conn
818
+ end
595
819
  end
596
820
 
597
821
  def default_uniqueness_comparison(attribute, value) # :nodoc:
@@ -658,6 +882,21 @@ module ActiveRecord
658
882
  end
659
883
 
660
884
  class << self
885
+ def register_class_with_precision(mapping, key, klass, **kwargs) # :nodoc:
886
+ mapping.register_type(key) do |*args|
887
+ precision = extract_precision(args.last)
888
+ klass.new(precision: precision, **kwargs)
889
+ end
890
+ end
891
+
892
+ def extended_type_map(default_timezone:) # :nodoc:
893
+ Type::TypeMap.new(self::TYPE_MAP).tap do |m|
894
+ register_class_with_precision m, %r(\A[^\(]*time)i, Type::Time, timezone: default_timezone
895
+ register_class_with_precision m, %r(\A[^\(]*datetime)i, Type::DateTime, timezone: default_timezone
896
+ m.alias_type %r(\A[^\(]*timestamp)i, "datetime"
897
+ end
898
+ end
899
+
661
900
  private
662
901
  def initialize_type_map(m)
663
902
  register_class_with_limit m, %r(boolean)i, Type::Boolean
@@ -699,13 +938,6 @@ module ActiveRecord
699
938
  end
700
939
  end
701
940
 
702
- def register_class_with_precision(mapping, key, klass)
703
- mapping.register_type(key) do |*args|
704
- precision = extract_precision(args.last)
705
- klass.new(precision: precision)
706
- end
707
- end
708
-
709
941
  def extract_scale(sql_type)
710
942
  case sql_type
711
943
  when /\((\d+)\)/ then 0
@@ -723,10 +955,177 @@ module ActiveRecord
723
955
  end
724
956
 
725
957
  TYPE_MAP = Type::TypeMap.new.tap { |m| initialize_type_map(m) }
958
+ EXTENDED_TYPE_MAPS = Concurrent::Map.new
726
959
 
727
960
  private
961
+ def reconnect_can_restore_state?
962
+ transaction_manager.restorable? && !@raw_connection_dirty
963
+ end
964
+
965
+ # Lock the monitor, ensure we're properly connected and
966
+ # transactions are materialized, and then yield the underlying
967
+ # raw connection object.
968
+ #
969
+ # If +allow_retry+ is true, a connection-related exception will
970
+ # cause an automatic reconnect and re-run of the block, up to
971
+ # the connection's configured +connection_retries+ setting
972
+ # and the configured +retry_deadline+ limit. (Note that when
973
+ # +allow_retry+ is true, it's possible to return without having marked
974
+ # the connection as verified. If the block is guaranteed to exercise the
975
+ # connection, consider calling `verified!` to avoid needless
976
+ # verification queries in subsequent calls.)
977
+ #
978
+ # If +materialize_transactions+ is false, the block will be run without
979
+ # ensuring virtual transactions have been materialized in the DB
980
+ # server's state. The active transaction will also remain clean
981
+ # (if it is not already dirty), meaning it's able to be restored
982
+ # by reconnecting and opening an equivalent-depth set of new
983
+ # transactions. This should only be used by transaction control
984
+ # methods, and internal transaction-agnostic queries.
985
+ #
986
+ ###
987
+ #
988
+ # It's not the primary use case, so not something to optimize
989
+ # for, but note that this method does need to be re-entrant:
990
+ # +materialize_transactions+ will re-enter if it has work to do,
991
+ # and the yield block can also do so under some circumstances.
992
+ #
993
+ # In the latter case, we really ought to guarantee the inner
994
+ # call will not reconnect (which would interfere with the
995
+ # still-yielded connection in the outer block), but we currently
996
+ # provide no special enforcement there.
997
+ #
998
+ def with_raw_connection(allow_retry: false, materialize_transactions: true)
999
+ @lock.synchronize do
1000
+ connect! if @raw_connection.nil? && reconnect_can_restore_state?
1001
+
1002
+ self.materialize_transactions if materialize_transactions
1003
+
1004
+ retries_available = allow_retry ? connection_retries : 0
1005
+ deadline = retry_deadline && Process.clock_gettime(Process::CLOCK_MONOTONIC) + retry_deadline
1006
+ reconnectable = reconnect_can_restore_state?
1007
+
1008
+ if @verified
1009
+ # Cool, we're confident the connection's ready to use. (Note this might have
1010
+ # become true during the above #materialize_transactions.)
1011
+ elsif reconnectable
1012
+ if allow_retry
1013
+ # Not sure about the connection yet, but if anything goes wrong we can
1014
+ # just reconnect and re-run our query
1015
+ else
1016
+ # We can reconnect if needed, but we don't trust the upcoming query to be
1017
+ # safely re-runnable: let's verify the connection to be sure
1018
+ verify!
1019
+ end
1020
+ else
1021
+ # We don't know whether the connection is okay, but it also doesn't matter:
1022
+ # we wouldn't be able to reconnect anyway. We're just going to run our query
1023
+ # and hope for the best.
1024
+ end
1025
+
1026
+ begin
1027
+ yield @raw_connection
1028
+ rescue => original_exception
1029
+ translated_exception = translate_exception_class(original_exception, nil, nil)
1030
+ invalidate_transaction(translated_exception)
1031
+ retry_deadline_exceeded = deadline && deadline < Process.clock_gettime(Process::CLOCK_MONOTONIC)
1032
+
1033
+ if !retry_deadline_exceeded && retries_available > 0
1034
+ retries_available -= 1
1035
+
1036
+ if retryable_query_error?(translated_exception)
1037
+ backoff(connection_retries - retries_available)
1038
+ retry
1039
+ elsif reconnectable && retryable_connection_error?(translated_exception)
1040
+ reconnect!(restore_transactions: true)
1041
+ # Only allowed to reconnect once, because reconnect! has its own retry
1042
+ # loop
1043
+ reconnectable = false
1044
+ retry
1045
+ end
1046
+ end
1047
+
1048
+ unless retryable_query_error?(translated_exception)
1049
+ # Barring a known-retryable error inside the query (regardless of
1050
+ # whether we were in a _position_ to retry it), we should infer that
1051
+ # there's likely a real problem with the connection.
1052
+ @verified = false
1053
+ end
1054
+
1055
+ raise translated_exception
1056
+ ensure
1057
+ dirty_current_transaction if materialize_transactions
1058
+ end
1059
+ end
1060
+ end
1061
+
1062
+ # Mark the connection as verified. Call this inside a
1063
+ # `with_raw_connection` block only when the block is guaranteed to
1064
+ # exercise the raw connection.
1065
+ def verified!
1066
+ @verified = true
1067
+ end
1068
+
1069
+ def retryable_connection_error?(exception)
1070
+ exception.is_a?(ConnectionNotEstablished) || exception.is_a?(ConnectionFailed)
1071
+ end
1072
+
1073
+ def invalidate_transaction(exception)
1074
+ return unless exception.is_a?(TransactionRollbackError)
1075
+ return unless savepoint_errors_invalidate_transactions?
1076
+
1077
+ current_transaction.invalidate!
1078
+ end
1079
+
1080
+ def retryable_query_error?(exception)
1081
+ # We definitely can't retry if we were inside an invalidated transaction.
1082
+ return false if current_transaction.invalidated?
1083
+
1084
+ exception.is_a?(Deadlocked) || exception.is_a?(LockWaitTimeout)
1085
+ end
1086
+
1087
+ def backoff(counter)
1088
+ sleep 0.1 * counter
1089
+ end
1090
+
1091
+ def reconnect
1092
+ raise NotImplementedError
1093
+ end
1094
+
1095
+ # Returns a raw connection for internal use with methods that are known
1096
+ # to both be thread-safe and not rely upon actual server communication.
1097
+ # This is useful for e.g. string escaping methods.
1098
+ def any_raw_connection
1099
+ @raw_connection || valid_raw_connection
1100
+ end
1101
+
1102
+ # Similar to any_raw_connection, but ensures it is validated and
1103
+ # connected. Any method called on this result still needs to be
1104
+ # independently thread-safe, so it probably shouldn't talk to the
1105
+ # server... but some drivers fail if they know the connection has gone
1106
+ # away.
1107
+ def valid_raw_connection
1108
+ (@verified && @raw_connection) ||
1109
+ # `allow_retry: false`, to force verification: the block won't
1110
+ # raise, so a retry wouldn't help us get the valid connection we
1111
+ # need.
1112
+ with_raw_connection(allow_retry: false, materialize_transactions: false) { |conn| conn }
1113
+ end
1114
+
1115
+ def extended_type_map_key
1116
+ if @default_timezone
1117
+ { default_timezone: @default_timezone }
1118
+ end
1119
+ end
1120
+
728
1121
  def type_map
729
- TYPE_MAP
1122
+ if key = extended_type_map_key
1123
+ self.class::EXTENDED_TYPE_MAPS.compute_if_absent(key) do
1124
+ self.class.extended_type_map(**key)
1125
+ end
1126
+ else
1127
+ self.class::TYPE_MAP
1128
+ end
730
1129
  end
731
1130
 
732
1131
  def translate_exception_class(e, sql, binds)
@@ -748,16 +1147,16 @@ module ActiveRecord
748
1147
  type_casted_binds: type_casted_binds,
749
1148
  statement_name: statement_name,
750
1149
  async: async,
751
- connection: self) do
752
- @lock.synchronize(&block)
753
- rescue => e
754
- raise translate_exception_class(e, sql, binds)
755
- end
1150
+ connection: self,
1151
+ &block
1152
+ )
1153
+ rescue ActiveRecord::StatementInvalid => ex
1154
+ raise ex.set_query(sql, binds)
756
1155
  end
757
1156
 
758
1157
  def transform_query(sql)
759
1158
  ActiveRecord.query_transformers.each do |transformer|
760
- sql = transformer.call(sql)
1159
+ sql = transformer.call(sql, self)
761
1160
  end
762
1161
  sql
763
1162
  end
@@ -765,10 +1164,10 @@ module ActiveRecord
765
1164
  def translate_exception(exception, message:, sql:, binds:)
766
1165
  # override in derived class
767
1166
  case exception
768
- when RuntimeError
1167
+ when RuntimeError, ActiveRecord::ActiveRecordError
769
1168
  exception
770
1169
  else
771
- ActiveRecord::StatementInvalid.new(message, sql: sql, binds: binds)
1170
+ ActiveRecord::StatementInvalid.new(message, sql: sql, binds: binds, connection_pool: @pool)
772
1171
  end
773
1172
  end
774
1173
 
@@ -815,6 +1214,26 @@ module ActiveRecord
815
1214
  def build_result(columns:, rows:, column_types: {})
816
1215
  ActiveRecord::Result.new(columns, rows, column_types)
817
1216
  end
1217
+
1218
+ # Perform any necessary initialization upon the newly-established
1219
+ # @raw_connection -- this is the place to modify the adapter's
1220
+ # connection settings, run queries to configure any application-global
1221
+ # "session" variables, etc.
1222
+ #
1223
+ # Implementations may assume this method will only be called while
1224
+ # holding @lock (or from #initialize).
1225
+ def configure_connection
1226
+ end
1227
+
1228
+ def default_prepared_statements
1229
+ true
1230
+ end
1231
+
1232
+ def warning_ignored?(warning)
1233
+ ActiveRecord.db_warnings_ignore.any? do |warning_matcher|
1234
+ warning.message.match?(warning_matcher) || warning.code.to_s.match?(warning_matcher)
1235
+ end
1236
+ end
818
1237
  end
819
1238
  end
820
1239
  end