74 lines
1.6 KiB
Elixir
74 lines
1.6 KiB
Elixir
|
defmodule Mobilizon.Storage.Repo.Migrations.CleanupPosts do
|
||
|
use Ecto.Migration
|
||
|
|
||
|
def up do
|
||
|
# Make sure we don't have any duplicate posts
|
||
|
rows = fetch_bad_rows()
|
||
|
Enum.each(rows, &process_row/1)
|
||
|
end
|
||
|
|
||
|
def down do
|
||
|
# No way down
|
||
|
end
|
||
|
|
||
|
defp fetch_bad_rows() do
|
||
|
%Postgrex.Result{rows: rows} =
|
||
|
Ecto.Adapters.SQL.query!(
|
||
|
Mobilizon.Storage.Repo,
|
||
|
"SELECT * FROM (
|
||
|
SELECT id, url,
|
||
|
ROW_NUMBER() OVER(PARTITION BY url ORDER BY id asc) AS Row
|
||
|
FROM posts
|
||
|
) dups
|
||
|
WHERE dups.Row > 1;"
|
||
|
)
|
||
|
|
||
|
rows
|
||
|
end
|
||
|
|
||
|
defp process_row([id, url, _row]) do
|
||
|
first_id = find_first_post_id(url)
|
||
|
|
||
|
if id != first_id do
|
||
|
repair_post_medias(id, first_id)
|
||
|
repair_post_tags(id, first_id)
|
||
|
delete_row(id)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
defp find_first_post_id(url) do
|
||
|
%Postgrex.Result{rows: [[id]]} =
|
||
|
Ecto.Adapters.SQL.query!(
|
||
|
Mobilizon.Storage.Repo,
|
||
|
"SELECT id FROM posts WHERE url = $1 order by inserted_at asc limit 1",
|
||
|
[url]
|
||
|
)
|
||
|
|
||
|
id
|
||
|
end
|
||
|
|
||
|
defp repair_post_medias(id, first_id) do
|
||
|
Ecto.Adapters.SQL.query!(
|
||
|
Mobilizon.Storage.Repo,
|
||
|
"UPDATE post_medias SET post_id = $1 WHERE post_id = $2",
|
||
|
[first_id, id]
|
||
|
)
|
||
|
end
|
||
|
|
||
|
defp repair_post_tags(id, first_id) do
|
||
|
Ecto.Adapters.SQL.query!(
|
||
|
Mobilizon.Storage.Repo,
|
||
|
"UPDATE post_tags SET post_id = $1 WHERE post_id = $2",
|
||
|
[first_id, id]
|
||
|
)
|
||
|
end
|
||
|
|
||
|
defp delete_row(id) do
|
||
|
Ecto.Adapters.SQL.query!(
|
||
|
Mobilizon.Storage.Repo,
|
||
|
"DELETE FROM posts WHERE id = $1",
|
||
|
[id]
|
||
|
)
|
||
|
end
|
||
|
end
|