Merge pull request #45723 from ilianah/optimize_add_timestamps

Optimize add_timestamps to use a single SQL statement when supported
This commit is contained in:
Yasuo Honda 2022-08-12 10:30:04 +09:00 committed by GitHub
commit 0c212836bc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 46 additions and 8 deletions

View File

@ -1,3 +1,17 @@
* Optimize `add_timestamps` to use a single SQL statement.
```ruby
add_timestamps :my_table
```
Now results in the following SQL:
```sql
ALTER TABLE "my_table" ADD COLUMN "created_at" datetime(6) NOT NULL, ADD COLUMN "updated_at" datetime(6) NOT NULL
```
*Iliana Hadzhiatanasova*
* Add `drop_enum` migration command for PostgreSQL
This does the inverse of `create_enum`. Before dropping an enum, ensure you have

View File

@ -1355,14 +1355,8 @@ module ActiveRecord
# add_timestamps(:suppliers, null: true)
#
def add_timestamps(table_name, **options)
options[:null] = false if options[:null].nil?
if !options.key?(:precision) && supports_datetime_with_precision?
options[:precision] = 6
end
add_column table_name, :created_at, :datetime, **options
add_column table_name, :updated_at, :datetime, **options
fragments = add_timestamps_for_alter(table_name, **options)
execute "ALTER TABLE #{quote_table_name(table_name)} #{fragments.join(', ')}"
end
# Removes the timestamp columns (+created_at+ and +updated_at+) from the table definition.

View File

@ -318,6 +318,19 @@ module ActiveRecord
rename_column_indexes(table_name, column.name, new_column_name)
end
def add_timestamps(table_name, **options)
options[:null] = false if options[:null].nil?
if !options.key?(:precision)
options[:precision] = 6
end
alter_table(table_name) do |definition|
definition.column :created_at, :datetime, **options
definition.column :updated_at, :datetime, **options
end
end
def add_reference(table_name, ref_name, **options) # :nodoc:
super(table_name, ref_name, type: :integer, **options)
end

View File

@ -368,6 +368,23 @@ module ActiveRecord
ensure
connection.drop_table :my_table, if_exists: true
end
def test_add_timestamps_single_statement
connection.create_table "my_table"
# SQLite3's ALTER TABLE statement has several limitations. To manage
# this, the adapter creates a temporary table, copies the data, drops
# the old table, creates the new table, then copies the data back.
expected_query_count = current_adapter?(:SQLite3Adapter) ? 12 : 1
assert_queries(expected_query_count) do
connection.add_timestamps("my_table")
end
columns = connection.columns("my_table").map(&:name)
assert_equal ["id", "created_at", "updated_at"], columns
ensure
connection.drop_table :my_table, if_exists: true
end
end
end
end