aboutsummaryrefslogtreecommitdiffstats
path: root/internal/store/blogs.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/store/blogs.go')
-rw-r--r--internal/store/blogs.go84
1 files changed, 84 insertions, 0 deletions
diff --git a/internal/store/blogs.go b/internal/store/blogs.go
new file mode 100644
index 0000000..57a7c10
--- /dev/null
+++ b/internal/store/blogs.go
@@ -0,0 +1,84 @@
+package store
+
+import (
+ "context"
+ "encoding/json"
+ "time"
+)
+
+type Blog struct {
+ ID int64
+ OwnerID int64
+ Subdomain string
+ Title string
+ Tagline string
+ ThemeJSON json.RawMessage
+ CreatedAt time.Time
+ UpdatedAt time.Time
+}
+
+const blogCols = `id, owner_id, subdomain, title, tagline, theme, created_at, updated_at`
+
+func scanBlog(row interface{ Scan(...any) error }) (*Blog, error) {
+ var b Blog
+ err := row.Scan(&b.ID, &b.OwnerID, &b.Subdomain, &b.Title, &b.Tagline, &b.ThemeJSON, &b.CreatedAt, &b.UpdatedAt)
+ if err != nil {
+ return nil, wrap(err)
+ }
+ return &b, nil
+}
+
+// CreateBlogger creates a user, their blog and a default home page in one transaction.
+func (s *Store) CreateBlogger(ctx context.Context, username, passwordHash, subdomain, title string) (*User, *Blog, error) {
+ tx, err := s.db.Begin(ctx)
+ if err != nil {
+ return nil, nil, err
+ }
+ defer tx.Rollback(ctx)
+
+ u, err := scanUser(tx.QueryRow(ctx, `INSERT INTO users (username, password_hash, role) VALUES ($1,$2,$3) RETURNING `+userCols,
+ username, passwordHash, RoleBlogger))
+ if err != nil {
+ return nil, nil, err
+ }
+ b, err := scanBlog(tx.QueryRow(ctx, `INSERT INTO blogs (owner_id, subdomain, title) VALUES ($1,$2,$3) RETURNING `+blogCols,
+ u.ID, subdomain, title))
+ if err != nil {
+ return nil, nil, err
+ }
+ _, err = tx.Exec(ctx, `INSERT INTO pages (blog_id, slug, title, nav_order, is_home) VALUES ($1,'home','Home',0,true)`, b.ID)
+ if err != nil {
+ return nil, nil, wrap(err)
+ }
+ if err := tx.Commit(ctx); err != nil {
+ return nil, nil, err
+ }
+ return u, b, nil
+}
+
+func (s *Store) BlogByID(ctx context.Context, id int64) (*Blog, error) {
+ return scanBlog(s.db.QueryRow(ctx, `SELECT `+blogCols+` FROM blogs WHERE id=$1`, id))
+}
+
+func (s *Store) BlogBySubdomain(ctx context.Context, sub string) (*Blog, error) {
+ return scanBlog(s.db.QueryRow(ctx, `SELECT `+blogCols+` FROM blogs WHERE subdomain=$1`, sub))
+}
+
+func (s *Store) BlogByOwner(ctx context.Context, ownerID int64) (*Blog, error) {
+ return scanBlog(s.db.QueryRow(ctx, `SELECT `+blogCols+` FROM blogs WHERE owner_id=$1`, ownerID))
+}
+
+func (s *Store) UpdateBlogSettings(ctx context.Context, id int64, title, tagline string) error {
+ _, err := s.db.Exec(ctx, `UPDATE blogs SET title=$2, tagline=$3, updated_at=now() WHERE id=$1`, id, title, tagline)
+ return err
+}
+
+func (s *Store) UpdateBlogTheme(ctx context.Context, id int64, theme json.RawMessage) error {
+ _, err := s.db.Exec(ctx, `UPDATE blogs SET theme=$2, updated_at=now() WHERE id=$1`, id, theme)
+ return err
+}
+
+func (s *Store) DeleteBlog(ctx context.Context, id int64) error {
+ _, err := s.db.Exec(ctx, `DELETE FROM blogs WHERE id=$1`, id)
+ return err
+}