diff options
Diffstat (limited to 'internal/db/posts.go')
| -rw-r--r-- | internal/db/posts.go | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/internal/db/posts.go b/internal/db/posts.go index f6c23cc..d391c3e 100644 --- a/internal/db/posts.go +++ b/internal/db/posts.go @@ -137,3 +137,63 @@ func (m *MetaDB) CollapseRedirects(oldSlug, newSlug string) error { ) return err } + +// RenamePost atomically renames a post from oldSlug to newSlug, +// updates any existing redirect chains, and adds a redirect from oldSlug to newSlug. +func (m *MetaDB) RenamePost(oldSlug, newSlug string) error { + tx, err := m.db.Begin() + if err != nil { + return err + } + defer tx.Rollback() + + // Fetch existing record + var p PostRecord + var tagsJSON string + var draft int + row := tx.QueryRow( + `SELECT slug, title, date, tags, draft, blocks, updated_at FROM posts WHERE slug = ?`, oldSlug) + if err := row.Scan(&p.Slug, &p.Title, &p.Date, &tagsJSON, &draft, &p.Blocks, &p.UpdatedAt); err != nil { + return err + } + p.Draft = draft != 0 + _ = json.Unmarshal([]byte(tagsJSON), &p.Tags) + + // Insert with new slug + tags, _ := json.Marshal(p.Tags) + draftInt := 0 + if p.Draft { + draftInt = 1 + } + _, err = tx.Exec(` + INSERT INTO posts (slug, title, date, tags, draft, blocks, updated_at) + VALUES (?, ?, ?, ?, ?, ?, ?)`, + newSlug, p.Title, p.Date, string(tags), draftInt, p.Blocks, p.UpdatedAt, + ) + if err != nil { + return err + } + + // Delete old record + if _, err = tx.Exec(`DELETE FROM posts WHERE slug = ?`, oldSlug); err != nil { + return err + } + + // Collapse existing redirect chains: anything pointing to oldSlug now points to newSlug + if _, err = tx.Exec( + `UPDATE redirects SET to_slug = ? WHERE to_slug = ?`, newSlug, oldSlug, + ); err != nil { + return err + } + + // Add redirect from oldSlug to newSlug + if _, err = tx.Exec(` + INSERT INTO redirects (from_slug, to_slug) VALUES (?, ?) + ON CONFLICT(from_slug) DO UPDATE SET to_slug = excluded.to_slug`, + oldSlug, newSlug, + ); err != nil { + return err + } + + return tx.Commit() +} |
