Packages
phoenix_kit
1.7.199
1.7.208
1.7.207
1.7.206
1.7.205
1.7.204
1.7.203
1.7.202
1.7.201
1.7.200
1.7.199
1.7.198
1.7.197
1.7.196
1.7.194
1.7.193
1.7.192
1.7.191
1.7.190
1.7.189
1.7.187
1.7.186
1.7.185
1.7.184
1.7.183
1.7.182
1.7.181
1.7.180
1.7.179
1.7.178
1.7.177
1.7.176
1.7.175
1.7.174
1.7.173
1.7.172
1.7.171
1.7.170
1.7.169
1.7.168
1.7.167
1.7.166
1.7.165
1.7.164
1.7.162
1.7.161
1.7.160
1.7.159
1.7.157
1.7.156
1.7.155
1.7.154
1.7.153
1.7.152
1.7.151
1.7.150
1.7.149
1.7.146
1.7.145
1.7.144
1.7.143
1.7.138
1.7.133
1.7.132
1.7.131
1.7.130
1.7.128
1.7.126
1.7.125
1.7.121
1.7.120
1.7.119
1.7.118
1.7.117
1.7.116
1.7.115
1.7.114
1.7.113
1.7.112
1.7.111
1.7.110
1.7.109
1.7.108
1.7.107
1.7.106
1.7.105
1.7.104
1.7.103
1.7.102
1.7.101
1.7.100
1.7.99
1.7.98
1.7.97
1.7.96
1.7.95
1.7.94
1.7.93
1.7.92
1.7.91
1.7.90
1.7.89
1.7.88
1.7.87
1.7.86
1.7.85
1.7.84
1.7.83
1.7.82
1.7.81
1.7.80
1.7.79
1.7.78
1.7.77
1.7.76
1.7.75
1.7.74
1.7.71
1.7.70
1.7.69
1.7.66
1.7.65
1.7.64
1.7.63
1.7.62
1.7.61
1.7.59
1.7.58
1.7.57
1.7.56
1.7.55
1.7.54
1.7.53
1.7.52
1.7.51
1.7.49
1.7.44
1.7.43
1.7.42
1.7.41
1.7.39
1.7.38
1.7.37
1.7.36
1.7.34
1.7.33
1.7.31
1.7.30
1.7.29
1.7.28
1.7.27
1.7.26
1.7.25
1.7.24
1.7.23
1.7.22
1.7.21
1.7.20
1.7.19
1.7.18
1.7.17
1.7.16
1.7.15
1.7.14
1.7.13
1.7.12
1.7.11
1.7.10
1.7.9
1.7.8
1.7.7
1.7.6
1.7.5
1.7.4
1.7.3
1.7.2
1.7.1
1.7.0
1.6.20
1.6.19
1.6.18
1.6.17
1.6.16
1.6.15
1.6.14
1.6.13
1.6.12
1.6.11
1.6.10
1.6.9
1.6.8
1.6.7
1.6.6
1.6.5
1.6.4
1.6.3
1.5.2
1.5.1
1.5.0
1.4.9
1.4.8
1.4.7
1.4.6
1.4.5
1.4.4
1.4.3
1.4.2
1.4.1
1.4.0
1.3.2
1.3.1
1.3.0
1.2.10
1.2.9
1.2.8
1.2.7
1.2.5
1.2.4
1.2.2
1.2.1
1.2.0
1.1.0
1.0.0
A foundation for building Elixir Phoenix apps — SaaS, social networks, ERP systems, marketplaces, and more
Current section
Files
Jump to
Current section
Files
lib/phoenix_kit/migrations/postgres/v80.ex
defmodule PhoenixKit.Migrations.Postgres.V80 do
@moduledoc """
V80: Emails Module i18n — JSON language fields
Converts 5 text fields in phoenix_kit_email_templates to JSONB for multilingual support.
Existing data is preserved by wrapping current values under the "en" key.
Adds `locale` field to phoenix_kit_email_logs for tracking which language was sent.
"""
use Ecto.Migration
def up(%{prefix: prefix} = _opts) do
p = prefix_str(prefix)
# Convert template content fields to JSONB. Guarded on the current type of
# `subject` (all 5 columns are converted together, so one check covers the
# group) — without it, re-running this migration against an
# already-converted database double-wraps the JSONB values
# (`jsonb_build_object('en', subject)` where `subject` is itself already
# `{"en": "..."}`). A retry can happen because this version previously
# didn't record its own "COMMENT ON TABLE ... IS '80'" marker like every
# other version module does, so a failure later in the same multi-version
# migration run (disable_ddl_transaction; each step auto-commits) would
# cause a subsequent `mix ecto.migrate` to resume from V80 again.
if column_type(prefix, "phoenix_kit_email_templates", "subject") != "jsonb" do
# Existing string values are preserved as {"en": "original_value"}
execute("""
ALTER TABLE #{p}phoenix_kit_email_templates
ALTER COLUMN subject TYPE jsonb
USING jsonb_build_object('en', subject),
ALTER COLUMN html_body TYPE jsonb
USING jsonb_build_object('en', html_body),
ALTER COLUMN text_body TYPE jsonb
USING jsonb_build_object('en', text_body),
ALTER COLUMN display_name TYPE jsonb
USING jsonb_build_object('en', display_name),
ALTER COLUMN description TYPE jsonb
USING CASE
WHEN description IS NULL THEN NULL
ELSE jsonb_build_object('en', description)
END
""")
end
# Add locale tracking to email logs
execute("""
ALTER TABLE #{p}phoenix_kit_email_logs
ADD COLUMN IF NOT EXISTS locale VARCHAR(10) NOT NULL DEFAULT 'en'
""")
execute("""
CREATE INDEX IF NOT EXISTS idx_email_logs_locale
ON #{p}phoenix_kit_email_logs (locale)
""")
execute("COMMENT ON TABLE #{p}phoenix_kit IS '80'")
end
def down(%{prefix: prefix} = _opts) do
p = prefix_str(prefix)
# Revert JSONB back to text — extract the "en" value
execute("""
ALTER TABLE #{p}phoenix_kit_email_templates
ALTER COLUMN subject TYPE varchar(300)
USING (subject->>'en'),
ALTER COLUMN html_body TYPE text
USING (html_body->>'en'),
ALTER COLUMN text_body TYPE text
USING (text_body->>'en'),
ALTER COLUMN display_name TYPE varchar(200)
USING (display_name->>'en'),
ALTER COLUMN description TYPE text
USING (description->>'en')
""")
execute("DROP INDEX IF EXISTS #{p}idx_email_logs_locale")
execute("""
ALTER TABLE #{p}phoenix_kit_email_logs
DROP COLUMN IF EXISTS locale
""")
execute("COMMENT ON TABLE #{p}phoenix_kit IS '79'")
end
defp column_type(prefix, table, column) do
schema = prefix || "public"
query = """
SELECT data_type FROM information_schema.columns
WHERE table_schema = '#{schema}' AND table_name = '#{table}' AND column_name = '#{column}'
"""
case repo().query(query, [], log: false) do
{:ok, %{rows: [[data_type]]}} -> data_type
_ -> nil
end
end
defp prefix_str(nil), do: ""
defp prefix_str("public"), do: "public."
defp prefix_str(prefix), do: "#{prefix}."
end