hmn/src/migration/migrations/2021-07-28T020000Z_ReworkTh...

161 lines
3.9 KiB
Go

package migrations
import (
"context"
"time"
"git.handmade.network/hmn/hmn/src/migration/types"
"git.handmade.network/hmn/hmn/src/oops"
"github.com/jackc/pgx/v5"
)
func init() {
registerMigration(ReworkThreads{})
}
type ReworkThreads struct{}
func (m ReworkThreads) Version() types.MigrationVersion {
return types.MigrationVersion(time.Date(2021, 7, 28, 2, 0, 0, 0, time.UTC))
}
func (m ReworkThreads) Name() string {
return "ReworkThreads"
}
func (m ReworkThreads) Description() string {
return "Detach threads from categories and make them more independent"
}
func (m ReworkThreads) Up(ctx context.Context, tx pgx.Tx) error {
// add and rename columns
_, err := tx.Exec(ctx, `
ALTER TABLE handmade_thread
ADD type INT,
ADD project_id INT REFERENCES handmade_project (id) ON DELETE RESTRICT, -- used to associate project articles
ALTER category_id DROP NOT NULL,
ADD personal_article_user_id INT REFERENCES auth_user (id) ON DELETE RESTRICT; -- used to associate personal articles
ALTER TABLE handmade_thread
RENAME category_id TO subforum_id; -- preemptive, we're renaming categories next
ALTER TABLE handmade_post
RENAME category_kind TO thread_type;
ALTER TABLE handmade_post
DROP category_id,
DROP CONSTRAINT post_category_kind_from_category,
DROP CONSTRAINT post_project_id_from_category;
DROP FUNCTION category_id_for_thread(int);
DROP FUNCTION category_kind_for_post(int);
DROP FUNCTION project_id_for_post(int);
`)
if err != nil {
return oops.New(err, "failed to add and rename columns")
}
// fill out null thread fields
_, err = tx.Exec(ctx, `
UPDATE handmade_thread AS thread
SET (type, project_id, subforum_id) = (
SELECT kind, project_id, CASE WHEN cat.kind = 2 THEN cat.id ELSE NULL END
FROM handmade_category AS cat
WHERE cat.id = thread.subforum_id
);
ALTER TABLE handmade_thread
ALTER type SET NOT NULL,
ALTER project_id SET NOT NULL;
`)
if err != nil {
return oops.New(err, "failed to copy category kind to thread type")
}
// move wiki posts to personal articles
_, err = tx.Exec(ctx, `
-- turn wiki threads into personal articles
UPDATE handmade_thread
SET
type = 7, -- new "personal article" type
personal_article_user_id = 1979 -- assign to Ben for now
WHERE type = 5;
-- update the denormalized field on posts
UPDATE handmade_post
SET thread_type = 7
WHERE thread_type = 5;
`)
if err != nil {
return oops.New(err, "failed to turn wiki posts into personal articles")
}
// delete talk pages
_, err = tx.Exec(ctx, `
DELETE FROM handmade_post
WHERE
thread_type = 7 -- personal articles, see above
AND parent_id IS NOT NULL;
UPDATE handmade_thread
SET last_id = first_id
WHERE type = 7;
`)
if err != nil {
return oops.New(err, "failed to delete wiki talk pages")
}
// delete library discussions
_, err = tx.Exec(ctx, `
DELETE FROM handmade_threadlastreadinfo
WHERE thread_id IN (
SELECT id
FROM handmade_thread
WHERE type = 6
);
DELETE FROM handmade_thread
WHERE type = 6;
DELETE FROM handmade_post
WHERE thread_type = 6;
ALTER TABLE handmade_libraryresource
DROP category_id;
`)
if err != nil {
return oops.New(err, "failed to delete library discussions")
}
// delete references to weirdo categories
_, err = tx.Exec(ctx, `
ALTER TABLE handmade_project
DROP blog_id,
DROP annotation_id,
DROP wiki_id;
`)
if err != nil {
return oops.New(err, "failed to delete references to categories from projects")
}
// delete categories we no longer need
_, err = tx.Exec(ctx, `
DELETE FROM handmade_categorylastreadinfo
WHERE category_id IN (
SELECT id
FROM handmade_category
WHERE kind != 2
);
DELETE FROM handmade_category
WHERE kind != 2;
`)
if err != nil {
return oops.New(err, "failed to delete categories")
}
return nil
}
func (m ReworkThreads) Down(ctx context.Context, tx pgx.Tx) error {
panic("Implement me")
}