Skip to content

Commit

Permalink
Merge pull request #45723 from ilianah/optimize_add_timestamps
Browse files Browse the repository at this point in the history
Optimize add_timestamps to use a single SQL statement when supported
  • Loading branch information
yahonda committed Aug 12, 2022
2 parents 63d4f99 + 7909661 commit 0c21283
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 8 deletions.
14 changes: 14 additions & 0 deletions activerecord/CHANGELOG.md
@@ -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
Expand Down
Expand Up @@ -1355,14 +1355,8 @@ def distinct_relation_for_primary_key(relation) # :nodoc:
# 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.
Expand Down
Expand Up @@ -318,6 +318,19 @@ def rename_column(table_name, column_name, new_column_name) # :nodoc:
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
Expand Down
17 changes: 17 additions & 0 deletions activerecord/test/cases/migration/columns_test.rb
Expand Up @@ -368,6 +368,23 @@ def test_remove_columns_single_statement
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

0 comments on commit 0c21283

Please sign in to comment.