aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord')
-rw-r--r--activerecord/CHANGELOG.md8
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb1
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb3
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb2
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract_adapter.rb14
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb27
-rw-r--r--activerecord/lib/active_record/connection_adapters/mysql/database_statements.rb7
-rw-r--r--activerecord/lib/active_record/connection_adapters/mysql/schema_dumper.rb2
-rw-r--r--activerecord/lib/active_record/connection_adapters/mysql/schema_statements.rb4
-rw-r--r--activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb2
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb2
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb17
-rw-r--r--activerecord/lib/active_record/connection_adapters/schema_cache.rb35
-rw-r--r--activerecord/lib/active_record/connection_adapters/sqlite3/database_statements.rb2
-rw-r--r--activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb26
-rw-r--r--activerecord/lib/active_record/integration.rb2
-rw-r--r--activerecord/lib/active_record/internal_metadata.rb6
-rw-r--r--activerecord/lib/active_record/persistence.rb25
-rw-r--r--activerecord/lib/active_record/schema_migration.rb2
-rw-r--r--activerecord/lib/active_record/tasks/database_tasks.rb4
-rw-r--r--activerecord/test/cases/adapter_test.rb44
-rw-r--r--activerecord/test/cases/adapters/mysql2/datetime_precision_quoting_test.rb3
-rw-r--r--activerecord/test/cases/adapters/mysql2/schema_test.rb2
-rw-r--r--activerecord/test/cases/adapters/mysql2/sp_test.rb2
-rw-r--r--activerecord/test/cases/adapters/postgresql/extension_migration_test.rb13
-rw-r--r--activerecord/test/cases/adapters/postgresql/geometric_test.rb2
-rw-r--r--activerecord/test/cases/adapters/postgresql/partitions_test.rb2
-rw-r--r--activerecord/test/cases/ar_schema_test.rb9
-rw-r--r--activerecord/test/cases/connection_adapters/schema_cache_test.rb30
-rw-r--r--activerecord/test/cases/defaults_test.rb2
-rw-r--r--activerecord/test/cases/helper.rb2
-rw-r--r--activerecord/test/cases/migration/columns_test.rb2
-rw-r--r--activerecord/test/cases/migration/foreign_key_test.rb2
-rw-r--r--activerecord/test/cases/migration_test.rb2
-rw-r--r--activerecord/test/cases/tasks/database_tasks_test.rb50
35 files changed, 244 insertions, 114 deletions
diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md
index a191f50da7..f0396c3d53 100644
--- a/activerecord/CHANGELOG.md
+++ b/activerecord/CHANGELOG.md
@@ -1,3 +1,9 @@
+* Add `rails db:prepare` to migrate or setup a database.
+
+ Runs `db:migrate` if the database exists or `db:setup` if it doesn't.
+
+ *Roberto Miranda*
+
* Add `after_save_commit` callback as shortcut for `after_commit :hook, on: [ :create, :update ]`.
*DHH*
@@ -79,7 +85,7 @@
bulk deletes by `delete_all`.
Supports skipping or upserting duplicates through the `ON CONFLICT` syntax
- for Postgres (9.5+) and Sqlite (3.24+) and `ON DUPLICATE KEY UPDATE` syntax
+ for PostgreSQL (9.5+) and SQLite (3.24+) and `ON DUPLICATE KEY UPDATE` syntax
for MySQL.
*Bob Lail*
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb b/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb
index 0ded1a5318..68498b5dc5 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb
@@ -810,6 +810,7 @@ module ActiveRecord
def new_connection
Base.send(spec.adapter_method, spec.config).tap do |conn|
conn.schema_cache = schema_cache.dup if schema_cache
+ conn.check_version
end
end
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb b/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb
index 93b1c4e632..a7753e3e9c 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb
@@ -7,7 +7,8 @@ module ActiveRecord
module QueryCache
class << self
def included(base) #:nodoc:
- dirties_query_cache base, :insert, :update, :delete, :rollback_to_savepoint, :rollback_db_transaction
+ dirties_query_cache base, :insert, :update, :delete, :truncate, :truncate_tables,
+ :rollback_to_savepoint, :rollback_db_transaction
base.set_callback :checkout, :after, :configure_query_cache!
base.set_callback :checkin, :after, :disable_query_cache!
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
index 6981ea6ecd..9f0335b31d 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
@@ -966,7 +966,7 @@ module ActiveRecord
# [<tt>:on_update</tt>]
# Action that happens <tt>ON UPDATE</tt>. Valid values are +:nullify+, +:cascade+ and +:restrict+
# [<tt>:validate</tt>]
- # (Postgres only) Specify whether or not the constraint should be validated. Defaults to +true+.
+ # (PostgreSQL only) Specify whether or not the constraint should be validated. Defaults to +true+.
def add_foreign_key(from_table, to_table, options = {})
return unless supports_foreign_keys?
diff --git a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
index 7aad306d50..200184c2f9 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
@@ -133,8 +133,6 @@ module ActiveRecord
@advisory_locks_enabled = self.class.type_cast_config_to_boolean(
config.fetch(:advisory_locks, true)
)
-
- check_version
end
def replica?
@@ -575,9 +573,17 @@ module ActiveRecord
"INSERT #{insert.into} #{insert.values_list}"
end
+ def get_database_version # :nodoc:
+ end
+
+ def database_version # :nodoc:
+ schema_cache.database_version
+ end
+
+ def check_version # :nodoc:
+ end
+
private
- def check_version
- end
def type_map
@type_map ||= Type::TypeMap.new.tap do |mapping|
diff --git a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
index 8ca2cfa9ed..f5da19f0f6 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
@@ -55,8 +55,8 @@ module ActiveRecord
super(connection, logger, config)
end
- def version #:nodoc:
- @version ||= Version.new(version_string)
+ def get_database_version #:nodoc:
+ Version.new(version_string)
end
def mariadb? # :nodoc:
@@ -68,11 +68,11 @@ module ActiveRecord
end
def supports_index_sort_order?
- !mariadb? && version >= "8.0.1"
+ !mariadb? && database_version >= "8.0.1"
end
def supports_expression_index?
- !mariadb? && version >= "8.0.13"
+ !mariadb? && database_version >= "8.0.13"
end
def supports_transaction_isolation?
@@ -96,16 +96,16 @@ module ActiveRecord
end
def supports_datetime_with_precision?
- mariadb? || version >= "5.6.4"
+ mariadb? || database_version >= "5.6.4"
end
def supports_virtual_columns?
- mariadb? || version >= "5.7.5"
+ mariadb? || database_version >= "5.7.5"
end
# See https://dev.mysql.com/doc/refman/8.0/en/optimizer-hints.html for more details.
def supports_optimizer_hints?
- !mariadb? && version >= "5.7.7"
+ !mariadb? && database_version >= "5.7.7"
end
def supports_advisory_locks?
@@ -526,12 +526,13 @@ module ActiveRecord
sql
end
- private
- def check_version
- if version < "5.5.8"
- raise "Your version of MySQL (#{version_string}) is too old. Active Record supports MySQL >= 5.5.8."
- end
+ def check_version # :nodoc:
+ if database_version < "5.5.8"
+ raise "Your version of MySQL (#{database_version}) is too old. Active Record supports MySQL >= 5.5.8."
end
+ end
+
+ private
def initialize_type_map(m = type_map)
super
@@ -702,7 +703,7 @@ module ActiveRecord
end
def supports_rename_index?
- mariadb? ? false : version >= "5.7.6"
+ mariadb? ? false : database_version >= "5.7.6"
end
def configure_connection
diff --git a/activerecord/lib/active_record/connection_adapters/mysql/database_statements.rb b/activerecord/lib/active_record/connection_adapters/mysql/database_statements.rb
index 1199c0ad1b..a14394fe04 100644
--- a/activerecord/lib/active_record/connection_adapters/mysql/database_statements.rb
+++ b/activerecord/lib/active_record/connection_adapters/mysql/database_statements.rb
@@ -145,15 +145,12 @@ module ActiveRecord
elsif previous_packet.nil?
true
else
- (current_packet.bytesize + previous_packet.bytesize) > max_allowed_packet
+ (current_packet.bytesize + previous_packet.bytesize + 2) > max_allowed_packet
end
end
def max_allowed_packet
- @max_allowed_packet ||= begin
- bytes_margin = 2
- show_variable("max_allowed_packet") - bytes_margin
- end
+ @max_allowed_packet ||= show_variable("max_allowed_packet")
end
def exec_stmt_and_free(sql, name, binds, cache_stmt: false)
diff --git a/activerecord/lib/active_record/connection_adapters/mysql/schema_dumper.rb b/activerecord/lib/active_record/connection_adapters/mysql/schema_dumper.rb
index 57518b02fa..a37557361a 100644
--- a/activerecord/lib/active_record/connection_adapters/mysql/schema_dumper.rb
+++ b/activerecord/lib/active_record/connection_adapters/mysql/schema_dumper.rb
@@ -64,7 +64,7 @@ module ActiveRecord
end
def extract_expression_for_virtual_column(column)
- if @connection.mariadb? && @connection.version < "10.2.5"
+ if @connection.mariadb? && @connection.database_version < "10.2.5"
create_table_info = @connection.send(:create_table_info, column.table_name)
column_name = @connection.quote_column_name(column.name)
if %r/#{column_name} #{Regexp.quote(column.sql_type)}(?: COLLATE \w+)? AS \((?<expression>.+?)\) #{column.extra}/ =~ create_table_info
diff --git a/activerecord/lib/active_record/connection_adapters/mysql/schema_statements.rb b/activerecord/lib/active_record/connection_adapters/mysql/schema_statements.rb
index 4018f0815c..a1f90a0642 100644
--- a/activerecord/lib/active_record/connection_adapters/mysql/schema_statements.rb
+++ b/activerecord/lib/active_record/connection_adapters/mysql/schema_statements.rb
@@ -126,9 +126,9 @@ module ActiveRecord
def row_format_dynamic_by_default?
if mariadb?
- version >= "10.2.2"
+ database_version >= "10.2.2"
else
- version >= "5.7.9"
+ database_version >= "5.7.9"
end
end
diff --git a/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb b/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb
index 9bdaa00336..0dc880c731 100644
--- a/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb
@@ -43,7 +43,7 @@ module ActiveRecord
end
def supports_json?
- !mariadb? && version >= "5.7.8"
+ !mariadb? && database_version >= "5.7.8"
end
def supports_comments?
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb b/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb
index a38c1325c0..41d1a8e4ab 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb
@@ -287,7 +287,7 @@ module ActiveRecord
quoted_sequence = quote_table_name(sequence)
max_pk = query_value("SELECT MAX(#{quote_column_name pk}) FROM #{quote_table_name(table)}", "SCHEMA")
if max_pk.nil?
- if postgresql_version >= 100000
+ if database_version >= 100000
minvalue = query_value("SELECT seqmin FROM pg_sequence WHERE seqrelid = #{quote(quoted_sequence)}::regclass", "SCHEMA")
else
minvalue = query_value("SELECT min_value FROM #{quoted_sequence}", "SCHEMA")
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
index 29f764e8f4..0ed4e61d18 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
@@ -201,7 +201,7 @@ module ActiveRecord
end
def supports_insert_on_conflict?
- postgresql_version >= 90500
+ database_version >= 90500
end
alias supports_insert_on_duplicate_skip? supports_insert_on_conflict?
alias supports_insert_on_duplicate_update? supports_insert_on_conflict?
@@ -344,7 +344,7 @@ module ActiveRecord
end
def supports_pgcrypto_uuid?
- postgresql_version >= 90400
+ database_version >= 90400
end
def supports_optimizer_hints?
@@ -424,7 +424,7 @@ module ActiveRecord
}
# Returns the version of the connected PostgreSQL server.
- def postgresql_version
+ def get_database_version
@connection.server_version
end
@@ -446,12 +446,13 @@ module ActiveRecord
sql
end
- private
- def check_version
- if postgresql_version < 90300
- raise "Your version of PostgreSQL (#{postgresql_version}) is too old. Active Record supports PostgreSQL >= 9.3."
- end
+ def check_version # :nodoc:
+ if database_version < 90300
+ raise "Your version of PostgreSQL (#{database_version}) is too old. Active Record supports PostgreSQL >= 9.3."
end
+ end
+
+ private
# See https://www.postgresql.org/docs/current/static/errcodes-appendix.html
VALUE_LIMIT_VIOLATION = "22001"
diff --git a/activerecord/lib/active_record/connection_adapters/schema_cache.rb b/activerecord/lib/active_record/connection_adapters/schema_cache.rb
index 07453b4403..dbfe1e4a34 100644
--- a/activerecord/lib/active_record/connection_adapters/schema_cache.rb
+++ b/activerecord/lib/active_record/connection_adapters/schema_cache.rb
@@ -26,21 +26,23 @@ module ActiveRecord
end
def encode_with(coder)
- coder["columns"] = @columns
- coder["columns_hash"] = @columns_hash
- coder["primary_keys"] = @primary_keys
- coder["data_sources"] = @data_sources
- coder["indexes"] = @indexes
- coder["version"] = connection.migration_context.current_version
+ coder["columns"] = @columns
+ coder["columns_hash"] = @columns_hash
+ coder["primary_keys"] = @primary_keys
+ coder["data_sources"] = @data_sources
+ coder["indexes"] = @indexes
+ coder["version"] = connection.migration_context.current_version
+ coder["database_version"] = database_version
end
def init_with(coder)
- @columns = coder["columns"]
- @columns_hash = coder["columns_hash"]
- @primary_keys = coder["primary_keys"]
- @data_sources = coder["data_sources"]
- @indexes = coder["indexes"] || {}
- @version = coder["version"]
+ @columns = coder["columns"]
+ @columns_hash = coder["columns_hash"]
+ @primary_keys = coder["primary_keys"]
+ @data_sources = coder["data_sources"]
+ @indexes = coder["indexes"] || {}
+ @version = coder["version"]
+ @database_version = coder["database_version"]
end
def primary_keys(table_name)
@@ -91,6 +93,10 @@ module ActiveRecord
@indexes[table_name] ||= connection.indexes(table_name)
end
+ def database_version # :nodoc:
+ @database_version ||= connection.get_database_version
+ end
+
# Clears out internal caches
def clear!
@columns.clear
@@ -99,6 +105,7 @@ module ActiveRecord
@data_sources.clear
@indexes.clear
@version = nil
+ @database_version = nil
end
def size
@@ -117,11 +124,11 @@ module ActiveRecord
def marshal_dump
# if we get current version during initialization, it happens stack over flow.
@version = connection.migration_context.current_version
- [@version, @columns, @columns_hash, @primary_keys, @data_sources, @indexes]
+ [@version, @columns, @columns_hash, @primary_keys, @data_sources, @indexes, database_version]
end
def marshal_load(array)
- @version, @columns, @columns_hash, @primary_keys, @data_sources, @indexes = array
+ @version, @columns, @columns_hash, @primary_keys, @data_sources, @indexes, @database_version = array
@indexes = @indexes || {}
end
diff --git a/activerecord/lib/active_record/connection_adapters/sqlite3/database_statements.rb b/activerecord/lib/active_record/connection_adapters/sqlite3/database_statements.rb
index 84dcae49b9..ffa75172b5 100644
--- a/activerecord/lib/active_record/connection_adapters/sqlite3/database_statements.rb
+++ b/activerecord/lib/active_record/connection_adapters/sqlite3/database_statements.rb
@@ -14,7 +14,7 @@ module ActiveRecord
log(sql, name) do
ActiveSupport::Dependencies.interlock.permit_concurrent_loads do
- @connection.execute_batch(sql)
+ @connection.execute_batch2(sql)
end
end
end
diff --git a/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb b/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb
index ff23a525b9..1801924c09 100644
--- a/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb
@@ -10,7 +10,7 @@ require "active_record/connection_adapters/sqlite3/schema_definitions"
require "active_record/connection_adapters/sqlite3/schema_dumper"
require "active_record/connection_adapters/sqlite3/schema_statements"
-gem "sqlite3", "~> 1.3", ">= 1.3.6"
+gem "sqlite3", "~> 1.4"
require "sqlite3"
module ActiveRecord
@@ -111,7 +111,7 @@ module ActiveRecord
end
def supports_expression_index?
- sqlite_version >= "3.9.0"
+ database_version >= "3.9.0"
end
def requires_reloading?
@@ -135,7 +135,7 @@ module ActiveRecord
end
def supports_insert_on_conflict?
- sqlite_version >= "3.24.0"
+ database_version >= "3.24.0"
end
alias supports_insert_on_duplicate_skip? supports_insert_on_conflict?
alias supports_insert_on_duplicate_update? supports_insert_on_conflict?
@@ -397,6 +397,16 @@ module ActiveRecord
sql
end
+ def get_database_version # :nodoc:
+ SQLite3Adapter::Version.new(query_value("SELECT sqlite_version(*)"))
+ end
+
+ def check_version # :nodoc:
+ if database_version < "3.8.0"
+ raise "Your version of SQLite (#{database_version}) is too old. Active Record supports SQLite >= 3.8."
+ end
+ end
+
private
# See https://www.sqlite.org/limits.html,
# the default value is 999 when not configured.
@@ -404,12 +414,6 @@ module ActiveRecord
999
end
- def check_version
- if sqlite_version < "3.8.0"
- raise "Your version of SQLite (#{sqlite_version}) is too old. Active Record supports SQLite >= 3.8."
- end
- end
-
def initialize_type_map(m = type_map)
super
register_class_with_limit m, %r(int)i, SQLite3Integer
@@ -527,10 +531,6 @@ module ActiveRecord
SELECT #{quoted_from_columns} FROM #{quote_table_name(from)}")
end
- def sqlite_version
- @sqlite_version ||= SQLite3Adapter::Version.new(query_value("SELECT sqlite_version(*)"))
- end
-
def translate_exception(exception, message:, sql:, binds:)
case exception.message
# SQLite 3.8.2 returns a newly formatted error message:
diff --git a/activerecord/lib/active_record/integration.rb b/activerecord/lib/active_record/integration.rb
index fa6f0d36ec..67a63cd2d1 100644
--- a/activerecord/lib/active_record/integration.rb
+++ b/activerecord/lib/active_record/integration.rb
@@ -180,7 +180,7 @@ module ActiveRecord
# raw_timestamp_to_cache_version(timestamp)
# # => "20181015200215266505"
#
- # Postgres truncates trailing zeros,
+ # PostgreSQL truncates trailing zeros,
# https://github.com/postgres/postgres/commit/3e1beda2cde3495f41290e1ece5d544525810214
# to account for this we pad the output with zeros
def raw_timestamp_to_cache_version(timestamp)
diff --git a/activerecord/lib/active_record/internal_metadata.rb b/activerecord/lib/active_record/internal_metadata.rb
index 88b0c828ae..e6166581f1 100644
--- a/activerecord/lib/active_record/internal_metadata.rb
+++ b/activerecord/lib/active_record/internal_metadata.rb
@@ -17,7 +17,7 @@ module ActiveRecord
end
def table_name
- "#{table_name_prefix}#{ActiveRecord::Base.internal_metadata_table_name}#{table_name_suffix}"
+ "#{table_name_prefix}#{internal_metadata_table_name}#{table_name_suffix}"
end
def []=(key, value)
@@ -44,6 +44,10 @@ module ActiveRecord
end
end
end
+
+ def drop_table
+ connection.drop_table table_name, if_exists: true
+ end
end
end
end
diff --git a/activerecord/lib/active_record/persistence.rb b/activerecord/lib/active_record/persistence.rb
index 7705cefa59..bf2f61737b 100644
--- a/activerecord/lib/active_record/persistence.rb
+++ b/activerecord/lib/active_record/persistence.rb
@@ -85,14 +85,14 @@ module ActiveRecord
# ==== Options
#
# [:returning]
- # (Postgres-only) An array of attributes to return for all successfully
+ # (PostgreSQL only) An array of attributes to return for all successfully
# inserted records, which by default is the primary key.
# Pass <tt>returning: %w[ id name ]</tt> for both id and name
# or <tt>returning: false</tt> to omit the underlying <tt>RETURNING</tt> SQL
# clause entirely.
#
# [:unique_by]
- # (Postgres and SQLite only) By default rows are considered to be unique
+ # (PostgreSQL and SQLite only) By default rows are considered to be unique
# by every unique index on the table. Any duplicate rows are skipped.
#
# To skip rows according to just one unique index pass <tt>:unique_by</tt>.
@@ -107,9 +107,9 @@ module ActiveRecord
# unique_by: %i[ author_id name ]
# unique_by: :index_books_on_isbn
#
- # Because it relies on the index information from the database
- # <tt>:unique_by</tt> is recommended to be paired with
- # Active Record's schema_cache.
+ # Because it relies on the index information from the database
+ # <tt>:unique_by</tt> is recommended to be paired with
+ # Active Record's schema_cache.
#
# ==== Example
#
@@ -154,7 +154,7 @@ module ActiveRecord
# ==== Options
#
# [:returning]
- # (Postgres-only) An array of attributes to return for all successfully
+ # (PostgreSQL only) An array of attributes to return for all successfully
# inserted records, which by default is the primary key.
# Pass <tt>returning: %w[ id name ]</tt> for both id and name
# or <tt>returning: false</tt> to omit the underlying <tt>RETURNING</tt> SQL
@@ -202,14 +202,14 @@ module ActiveRecord
# ==== Options
#
# [:returning]
- # (Postgres-only) An array of attributes to return for all successfully
+ # (PostgreSQL only) An array of attributes to return for all successfully
# inserted records, which by default is the primary key.
# Pass <tt>returning: %w[ id name ]</tt> for both id and name
# or <tt>returning: false</tt> to omit the underlying <tt>RETURNING</tt> SQL
# clause entirely.
#
# [:unique_by]
- # (Postgres and SQLite only) By default rows are considered to be unique
+ # (PostgreSQL and SQLite only) By default rows are considered to be unique
# by every unique index on the table. Any duplicate rows are skipped.
#
# To skip rows according to just one unique index pass <tt>:unique_by</tt>.
@@ -224,9 +224,9 @@ module ActiveRecord
# unique_by: %i[ author_id name ]
# unique_by: :index_books_on_isbn
#
- # Because it relies on the index information from the database
- # <tt>:unique_by</tt> is recommended to be paired with
- # Active Record's schema_cache.
+ # Because it relies on the index information from the database
+ # <tt>:unique_by</tt> is recommended to be paired with
+ # Active Record's schema_cache.
#
# ==== Examples
#
@@ -238,7 +238,7 @@ module ActiveRecord
# { title: "Eloquent Ruby", author: "Russ", isbn: "1" }
# ], unique_by: :isbn)
#
- # Book.find_by(isbn: "1").title # => "Eloquent Ruby"
+ # Book.find_by(isbn: "1").title # => "Eloquent Ruby"
def upsert_all(attributes, returning: nil, unique_by: nil)
InsertAll.new(self, attributes, on_duplicate: :update, returning: returning, unique_by: unique_by).execute
end
@@ -568,7 +568,6 @@ module ActiveRecord
became.send(:initialize)
became.instance_variable_set("@attributes", @attributes)
became.instance_variable_set("@mutations_from_database", @mutations_from_database ||= nil)
- became.instance_variable_set("@changed_attributes", attributes_changed_by_setter)
became.instance_variable_set("@new_record", new_record?)
became.instance_variable_set("@destroyed", destroyed?)
became.errors.copy!(errors)
diff --git a/activerecord/lib/active_record/schema_migration.rb b/activerecord/lib/active_record/schema_migration.rb
index 1fca1a18f6..74547de862 100644
--- a/activerecord/lib/active_record/schema_migration.rb
+++ b/activerecord/lib/active_record/schema_migration.rb
@@ -19,7 +19,7 @@ module ActiveRecord
end
def table_name
- "#{table_name_prefix}#{ActiveRecord::Base.schema_migrations_table_name}#{table_name_suffix}"
+ "#{table_name_prefix}#{schema_migrations_table_name}#{table_name_suffix}"
end
def table_exists?
diff --git a/activerecord/lib/active_record/tasks/database_tasks.rb b/activerecord/lib/active_record/tasks/database_tasks.rb
index 155d2b0b98..7285c15477 100644
--- a/activerecord/lib/active_record/tasks/database_tasks.rb
+++ b/activerecord/lib/active_record/tasks/database_tasks.rb
@@ -186,8 +186,8 @@ module ActiveRecord
ActiveRecord::Base.connected_to(database: { truncation: configuration }) do
table_names = ActiveRecord::Base.connection.tables
table_names -= [
- ActiveRecord::Base.schema_migrations_table_name,
- ActiveRecord::Base.internal_metadata_table_name
+ SchemaMigration.table_name,
+ InternalMetadata.table_name
]
ActiveRecord::Base.connection.truncate_tables(*table_names)
diff --git a/activerecord/test/cases/adapter_test.rb b/activerecord/test/cases/adapter_test.rb
index 2b20d842e8..ba04859bf0 100644
--- a/activerecord/test/cases/adapter_test.rb
+++ b/activerecord/test/cases/adapter_test.rb
@@ -485,23 +485,51 @@ module ActiveRecord
end
def test_truncate
- assert_operator @connection.query_value("SELECT COUNT(*) FROM posts"), :>, 0
+ assert_operator Post.count, :>, 0
@connection.truncate("posts")
- assert_equal 0, @connection.query_value("SELECT COUNT(*) FROM posts")
+ assert_equal 0, Post.count
+ end
+
+ def test_truncate_with_query_cache
+ @connection.enable_query_cache!
+
+ assert_operator Post.count, :>, 0
+
+ @connection.truncate("posts")
+
+ assert_equal 0, Post.count
+ ensure
+ @connection.disable_query_cache!
end
def test_truncate_tables
- assert_operator @connection.query_value("SELECT COUNT(*) FROM posts"), :>, 0
- assert_operator @connection.query_value("SELECT COUNT(*) FROM authors"), :>, 0
- assert_operator @connection.query_value("SELECT COUNT(*) FROM author_addresses"), :>, 0
+ assert_operator Post.count, :>, 0
+ assert_operator Author.count, :>, 0
+ assert_operator AuthorAddress.count, :>, 0
@connection.truncate_tables("author_addresses", "authors", "posts")
- assert_equal 0, @connection.query_value("SELECT COUNT(*) FROM posts")
- assert_equal 0, @connection.query_value("SELECT COUNT(*) FROM authors")
- assert_equal 0, @connection.query_value("SELECT COUNT(*) FROM author_addresses")
+ assert_equal 0, Post.count
+ assert_equal 0, Author.count
+ assert_equal 0, AuthorAddress.count
+ end
+
+ def test_truncate_tables_with_query_cache
+ @connection.enable_query_cache!
+
+ assert_operator Post.count, :>, 0
+ assert_operator Author.count, :>, 0
+ assert_operator AuthorAddress.count, :>, 0
+
+ @connection.truncate_tables("author_addresses", "authors", "posts")
+
+ assert_equal 0, Post.count
+ assert_equal 0, Author.count
+ assert_equal 0, AuthorAddress.count
+ ensure
+ @connection.disable_query_cache!
end
# test resetting sequences in odd tables in PostgreSQL
diff --git a/activerecord/test/cases/adapters/mysql2/datetime_precision_quoting_test.rb b/activerecord/test/cases/adapters/mysql2/datetime_precision_quoting_test.rb
index 00a075e063..cbe55f1d53 100644
--- a/activerecord/test/cases/adapters/mysql2/datetime_precision_quoting_test.rb
+++ b/activerecord/test/cases/adapters/mysql2/datetime_precision_quoting_test.rb
@@ -46,10 +46,7 @@ class Mysql2DatetimePrecisionQuotingTest < ActiveRecord::Mysql2TestCase
def stub_version(full_version_string)
@connection.stub(:full_version, full_version_string) do
- @connection.remove_instance_variable(:@version) if @connection.instance_variable_defined?(:@version)
yield
end
- ensure
- @connection.remove_instance_variable(:@version) if @connection.instance_variable_defined?(:@version)
end
end
diff --git a/activerecord/test/cases/adapters/mysql2/schema_test.rb b/activerecord/test/cases/adapters/mysql2/schema_test.rb
index 1283b0642c..b8f51acba0 100644
--- a/activerecord/test/cases/adapters/mysql2/schema_test.rb
+++ b/activerecord/test/cases/adapters/mysql2/schema_test.rb
@@ -41,7 +41,7 @@ module ActiveRecord
column_24 = @connection.columns(:mysql_doubles).find { |c| c.name == "float_24" }
column_25 = @connection.columns(:mysql_doubles).find { |c| c.name == "float_25" }
- # Mysql floats are precision 0..24, Mysql doubles are precision 25..53
+ # MySQL floats are precision 0..24, MySQL doubles are precision 25..53
assert_equal 24, column_no_limit.limit
assert_equal 24, column_short.limit
assert_equal 53, column_long.limit
diff --git a/activerecord/test/cases/adapters/mysql2/sp_test.rb b/activerecord/test/cases/adapters/mysql2/sp_test.rb
index 7b6dce71e9..626ef59570 100644
--- a/activerecord/test/cases/adapters/mysql2/sp_test.rb
+++ b/activerecord/test/cases/adapters/mysql2/sp_test.rb
@@ -9,7 +9,7 @@ class Mysql2StoredProcedureTest < ActiveRecord::Mysql2TestCase
def setup
@connection = ActiveRecord::Base.connection
- unless ActiveRecord::Base.connection.version >= "5.6.0"
+ unless ActiveRecord::Base.connection.database_version >= "5.6.0"
skip("no stored procedure support")
end
end
diff --git a/activerecord/test/cases/adapters/postgresql/extension_migration_test.rb b/activerecord/test/cases/adapters/postgresql/extension_migration_test.rb
index df97ab11e7..0fd7b2c6ed 100644
--- a/activerecord/test/cases/adapters/postgresql/extension_migration_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/extension_migration_test.rb
@@ -22,23 +22,26 @@ class PostgresqlExtensionMigrationTest < ActiveRecord::PostgreSQLTestCase
@connection = ActiveRecord::Base.connection
- @old_schema_migration_table_name = ActiveRecord::SchemaMigration.table_name
@old_table_name_prefix = ActiveRecord::Base.table_name_prefix
@old_table_name_suffix = ActiveRecord::Base.table_name_suffix
ActiveRecord::Base.table_name_prefix = "p_"
ActiveRecord::Base.table_name_suffix = "_s"
+ ActiveRecord::SchemaMigration.reset_table_name
+ ActiveRecord::InternalMetadata.reset_table_name
+
ActiveRecord::SchemaMigration.delete_all rescue nil
- ActiveRecord::SchemaMigration.table_name = "p_schema_migrations_s"
ActiveRecord::Migration.verbose = false
end
def teardown
- ActiveRecord::Base.table_name_prefix = @old_table_name_prefix
- ActiveRecord::Base.table_name_suffix = @old_table_name_suffix
ActiveRecord::SchemaMigration.delete_all rescue nil
ActiveRecord::Migration.verbose = true
- ActiveRecord::SchemaMigration.table_name = @old_schema_migration_table_name
+
+ ActiveRecord::Base.table_name_prefix = @old_table_name_prefix
+ ActiveRecord::Base.table_name_suffix = @old_table_name_suffix
+ ActiveRecord::SchemaMigration.reset_table_name
+ ActiveRecord::InternalMetadata.reset_table_name
super
end
diff --git a/activerecord/test/cases/adapters/postgresql/geometric_test.rb b/activerecord/test/cases/adapters/postgresql/geometric_test.rb
index 8c6f046553..14c262f4ce 100644
--- a/activerecord/test/cases/adapters/postgresql/geometric_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/geometric_test.rb
@@ -247,7 +247,7 @@ class PostgreSQLGeometricLineTest < ActiveRecord::PostgreSQLTestCase
class PostgresqlLine < ActiveRecord::Base; end
setup do
- unless ActiveRecord::Base.connection.send(:postgresql_version) >= 90400
+ unless ActiveRecord::Base.connection.database_version >= 90400
skip("line type is not fully implemented")
end
@connection = ActiveRecord::Base.connection
diff --git a/activerecord/test/cases/adapters/postgresql/partitions_test.rb b/activerecord/test/cases/adapters/postgresql/partitions_test.rb
index 0ac9ca1200..4015bc94f9 100644
--- a/activerecord/test/cases/adapters/postgresql/partitions_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/partitions_test.rb
@@ -12,7 +12,7 @@ class PostgreSQLPartitionsTest < ActiveRecord::PostgreSQLTestCase
end
def test_partitions_table_exists
- skip unless ActiveRecord::Base.connection.postgresql_version >= 100000
+ skip unless ActiveRecord::Base.connection.database_version >= 100000
@connection.create_table :partitioned_events, force: true, id: false,
options: "partition by range (issued_at)" do |t|
t.timestamp :issued_at
diff --git a/activerecord/test/cases/ar_schema_test.rb b/activerecord/test/cases/ar_schema_test.rb
index 9d88b14dab..9027cc582a 100644
--- a/activerecord/test/cases/ar_schema_test.rb
+++ b/activerecord/test/cases/ar_schema_test.rb
@@ -51,11 +51,11 @@ class ActiveRecordSchemaTest < ActiveRecord::TestCase
assert_equal 7, @connection.migration_context.current_version
end
- def test_schema_define_w_table_name_prefix
- table_name = ActiveRecord::SchemaMigration.table_name
+ def test_schema_define_with_table_name_prefix
old_table_name_prefix = ActiveRecord::Base.table_name_prefix
ActiveRecord::Base.table_name_prefix = "nep_"
- ActiveRecord::SchemaMigration.table_name = "nep_#{table_name}"
+ ActiveRecord::SchemaMigration.reset_table_name
+ ActiveRecord::InternalMetadata.reset_table_name
ActiveRecord::Schema.define(version: 7) do
create_table :fruits do |t|
t.column :color, :string
@@ -67,7 +67,8 @@ class ActiveRecordSchemaTest < ActiveRecord::TestCase
assert_equal 7, @connection.migration_context.current_version
ensure
ActiveRecord::Base.table_name_prefix = old_table_name_prefix
- ActiveRecord::SchemaMigration.table_name = table_name
+ ActiveRecord::SchemaMigration.reset_table_name
+ ActiveRecord::InternalMetadata.reset_table_name
end
def test_schema_raises_an_error_for_invalid_column_type
diff --git a/activerecord/test/cases/connection_adapters/schema_cache_test.rb b/activerecord/test/cases/connection_adapters/schema_cache_test.rb
index 5113548091..89a9c30f9b 100644
--- a/activerecord/test/cases/connection_adapters/schema_cache_test.rb
+++ b/activerecord/test/cases/connection_adapters/schema_cache_test.rb
@@ -6,8 +6,9 @@ module ActiveRecord
module ConnectionAdapters
class SchemaCacheTest < ActiveRecord::TestCase
def setup
- @connection = ActiveRecord::Base.connection
- @cache = SchemaCache.new @connection
+ @connection = ActiveRecord::Base.connection
+ @cache = SchemaCache.new @connection
+ @database_version = @connection.get_database_version
end
def test_primary_key
@@ -28,6 +29,7 @@ module ActiveRecord
assert new_cache.data_sources("posts")
assert_equal "id", new_cache.primary_keys("posts")
assert_equal 1, new_cache.indexes("posts").size
+ assert_equal @database_version.to_s, new_cache.database_version.to_s
end
end
@@ -55,6 +57,20 @@ module ActiveRecord
@connection.schema_cache = old_cache
end
+ def test_yaml_loads_5_1_dump_without_database_version_still_queries_for_database_version
+ @cache = YAML.load(File.read(schema_dump_path))
+
+ # Simulate assignment in railtie after loading the cache.
+ old_cache, @connection.schema_cache = @connection.schema_cache, @cache
+
+ # We can't verify queries get executed because the database version gets
+ # cached in both MySQL and PostgreSQL outside of the schema cache.
+ assert_nil @cache.instance_variable_get(:@database_version)
+ assert_equal @database_version.to_s, @cache.database_version.to_s
+ ensure
+ @connection.schema_cache = old_cache
+ end
+
def test_primary_key_for_non_existent_table
assert_nil @cache.primary_keys("omgponies")
end
@@ -74,6 +90,14 @@ module ActiveRecord
assert_equal indexes, @cache.indexes("posts")
end
+ def test_caches_database_version
+ @cache.database_version # cache database_version
+
+ assert_no_queries do
+ assert_equal @database_version.to_s, @cache.database_version.to_s
+ end
+ end
+
def test_clearing
@cache.columns("posts")
@cache.columns_hash("posts")
@@ -84,6 +108,7 @@ module ActiveRecord
@cache.clear!
assert_equal 0, @cache.size
+ assert_nil @cache.instance_variable_get(:@database_version)
end
def test_dump_and_load
@@ -101,6 +126,7 @@ module ActiveRecord
assert @cache.data_sources("posts")
assert_equal "id", @cache.primary_keys("posts")
assert_equal 1, @cache.indexes("posts").size
+ assert_equal @database_version.to_s, @cache.database_version.to_s
end
end
diff --git a/activerecord/test/cases/defaults_test.rb b/activerecord/test/cases/defaults_test.rb
index 5d02e59ef6..50a86b0a19 100644
--- a/activerecord/test/cases/defaults_test.rb
+++ b/activerecord/test/cases/defaults_test.rb
@@ -89,7 +89,7 @@ if current_adapter?(:PostgreSQLAdapter)
test "schema dump includes default expression" do
output = dump_table_schema("defaults")
- if ActiveRecord::Base.connection.postgresql_version >= 100000
+ if ActiveRecord::Base.connection.database_version >= 100000
assert_match %r/t\.date\s+"modified_date",\s+default: -> { "CURRENT_DATE" }/, output
assert_match %r/t\.datetime\s+"modified_time",\s+default: -> { "CURRENT_TIMESTAMP" }/, output
else
diff --git a/activerecord/test/cases/helper.rb b/activerecord/test/cases/helper.rb
index f95d082907..298ee40df1 100644
--- a/activerecord/test/cases/helper.rb
+++ b/activerecord/test/cases/helper.rb
@@ -53,7 +53,7 @@ def supports_default_expression?
true
elsif current_adapter?(:Mysql2Adapter)
conn = ActiveRecord::Base.connection
- !conn.mariadb? && conn.version >= "8.0.13"
+ !conn.mariadb? && conn.database_version >= "8.0.13"
end
end
diff --git a/activerecord/test/cases/migration/columns_test.rb b/activerecord/test/cases/migration/columns_test.rb
index dbbba9c5fa..cce3461e18 100644
--- a/activerecord/test/cases/migration/columns_test.rb
+++ b/activerecord/test/cases/migration/columns_test.rb
@@ -136,7 +136,7 @@ module ActiveRecord
def test_remove_column_with_multi_column_index
# MariaDB starting with 10.2.8
# Dropping a column that is part of a multi-column UNIQUE constraint is not permitted.
- skip if current_adapter?(:Mysql2Adapter) && connection.mariadb? && connection.version >= "10.2.8"
+ skip if current_adapter?(:Mysql2Adapter) && connection.mariadb? && connection.database_version >= "10.2.8"
add_column "test_models", :hat_size, :integer
add_column "test_models", :hat_style, :string, limit: 100
diff --git a/activerecord/test/cases/migration/foreign_key_test.rb b/activerecord/test/cases/migration/foreign_key_test.rb
index ba21923d79..5f1057f093 100644
--- a/activerecord/test/cases/migration/foreign_key_test.rb
+++ b/activerecord/test/cases/migration/foreign_key_test.rb
@@ -155,7 +155,7 @@ if ActiveRecord::Base.connection.supports_foreign_keys?
class ForeignKeyChangeColumnWithSuffixTest < ForeignKeyChangeColumnTest
setup do
- ActiveRecord::Base.table_name_suffix = "_p"
+ ActiveRecord::Base.table_name_suffix = "_s"
end
teardown do
diff --git a/activerecord/test/cases/migration_test.rb b/activerecord/test/cases/migration_test.rb
index 788c8c36b8..f10c26c308 100644
--- a/activerecord/test/cases/migration_test.rb
+++ b/activerecord/test/cases/migration_test.rb
@@ -385,6 +385,7 @@ class MigrationTest < ActiveRecord::TestCase
assert_equal "changed", ActiveRecord::SchemaMigration.table_name
ensure
ActiveRecord::Base.schema_migrations_table_name = original_schema_migrations_table_name
+ ActiveRecord::SchemaMigration.reset_table_name
Reminder.reset_table_name
end
@@ -405,6 +406,7 @@ class MigrationTest < ActiveRecord::TestCase
assert_equal "changed", ActiveRecord::InternalMetadata.table_name
ensure
ActiveRecord::Base.internal_metadata_table_name = original_internal_metadata_table_name
+ ActiveRecord::InternalMetadata.reset_table_name
Reminder.reset_table_name
end
diff --git a/activerecord/test/cases/tasks/database_tasks_test.rb b/activerecord/test/cases/tasks/database_tasks_test.rb
index 06f11108f9..dd4a0b0455 100644
--- a/activerecord/test/cases/tasks/database_tasks_test.rb
+++ b/activerecord/test/cases/tasks/database_tasks_test.rb
@@ -50,6 +50,8 @@ module ActiveRecord
protected_environments = ActiveRecord::Base.protected_environments
current_env = ActiveRecord::Base.connection.migration_context.current_environment
+ InternalMetadata[:environment] = current_env
+
assert_called_on_instance_of(
ActiveRecord::MigrationContext,
:current_version,
@@ -73,6 +75,9 @@ module ActiveRecord
def test_raises_an_error_when_called_with_protected_environment_which_name_is_a_symbol
protected_environments = ActiveRecord::Base.protected_environments
current_env = ActiveRecord::Base.connection.migration_context.current_environment
+
+ InternalMetadata[:environment] = current_env
+
assert_called_on_instance_of(
ActiveRecord::MigrationContext,
:current_version,
@@ -951,11 +956,22 @@ module ActiveRecord
fixtures :authors, :author_addresses
+ def setup
+ SchemaMigration.create_table
+ SchemaMigration.create!(version: SchemaMigration.table_name)
+ InternalMetadata.create_table
+ InternalMetadata.create!(key: InternalMetadata.table_name)
+ end
+
def teardown
+ SchemaMigration.delete_all
+ InternalMetadata.delete_all
ActiveRecord::Base.connection_handlers = { writing: ActiveRecord::Base.default_connection_handler }
end
def test_truncate_tables
+ assert_operator SchemaMigration.count, :>, 0
+ assert_operator InternalMetadata.count, :>, 0
assert_operator Author.count, :>, 0
assert_operator AuthorAddress.count, :>, 0
@@ -969,12 +985,46 @@ module ActiveRecord
)
end
+ assert_operator SchemaMigration.count, :>, 0
+ assert_operator InternalMetadata.count, :>, 0
assert_equal 0, Author.count
assert_equal 0, AuthorAddress.count
ensure
ActiveRecord::Base.configurations = old_configurations
end
end
+
+ class DatabaseTasksTruncateAllWithPrefixTest < DatabaseTasksTruncateAllTest
+ setup do
+ ActiveRecord::Base.table_name_prefix = "p_"
+
+ SchemaMigration.reset_table_name
+ InternalMetadata.reset_table_name
+ end
+
+ teardown do
+ ActiveRecord::Base.table_name_prefix = nil
+
+ SchemaMigration.reset_table_name
+ InternalMetadata.reset_table_name
+ end
+ end
+
+ class DatabaseTasksTruncateAllWithSuffixTest < DatabaseTasksTruncateAllTest
+ setup do
+ ActiveRecord::Base.table_name_suffix = "_s"
+
+ SchemaMigration.reset_table_name
+ InternalMetadata.reset_table_name
+ end
+
+ teardown do
+ ActiveRecord::Base.table_name_suffix = nil
+
+ SchemaMigration.reset_table_name
+ InternalMetadata.reset_table_name
+ end
+ end
end
class DatabaseTasksTruncateAllWithMultipleDatabasesTest < ActiveRecord::TestCase