impress/lib/tasks/db.rake
Emi Matchu ec6dca1c16 Improve Unicode support, emojis don't crash us anymore lol!
A few pieces here:

1. Convert all tables to `utf8mb4`+`utf8mb4_unicode_520_ci` strings.
2. Configure that as the server's default.
3. Configure the Rails database connection to use this encoding too.

Came together pretty well, whew! This has been a LONG time coming,
`latin1` is NOT a good charset for the year 2024!
2024-02-28 18:54:27 -08:00

48 lines
1.2 KiB
Ruby

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