impress/lib/tasks/db.rake

49 lines
1.2 KiB
Ruby
Raw Permalink Normal View History

namespace :db do
desc "Generate SQL to convert all tables and columns to utf8mb4"
task :utf8_migration => :environment do
target_charset = "utf8mb4"
target_collation = "utf8mb4_unicode_520_ci"
db = ApplicationRecord.connection
# Don't mess with ActiveRecord's internal tables!
tables = db.tables.reject { |t| t.start_with? "ar_internal_" }
ups = []
downs = []
tables.sort.each do |table|
# If the table's default charset/collation doesn't match our goal, we'll
# modify it!
db.table_options(table) => {charset:, collation:}
if charset != target_charset || collation != target_collation
ups << "ALTER TABLE #{table} CONVERT TO CHARACTER SET " +
"#{target_charset} COLLATE #{target_collation}"
downs << "ALTER TABLE #{table} CONVERT TO CHARACTER SET " +
"#{charset} COLLATE #{collation}"
end
end
puts <<~MIGRATION_RB
reversible do |direction|
direction.up do
#{sql_as_ruby(ups).indent(2, "\t")}
end
direction.down do
#{sql_as_ruby(downs).indent(2, "\t")}
end
end
MIGRATION_RB
end
end
def sql_as_ruby(statements)
statements.map do |sql|
<<~EXECUTE_RB
execute <<-SQL
#{sql}
SQL
EXECUTE_RB
end.join("")
end