106 lines
3.1 KiB
Go
106 lines
3.1 KiB
Go
package store
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"fmt"
|
|
"strings"
|
|
"time"
|
|
|
|
"plumber/internal/store/sqlc"
|
|
)
|
|
|
|
// DiscordLink is the bot-owned mapping from a site post to a Discord message.
|
|
type DiscordLink struct {
|
|
PostID string
|
|
MessageID string
|
|
ThreadID string
|
|
CreatedAt string
|
|
}
|
|
|
|
// DiscordLinkStore is the mapping table used only by the Discord subscriber.
|
|
// It is not part of Store.
|
|
type DiscordLinkStore interface {
|
|
GetByPostID(ctx context.Context, postID string) (*DiscordLink, error)
|
|
GetByMessageID(ctx context.Context, messageID string) (*DiscordLink, error)
|
|
GetRootByThreadID(ctx context.Context, threadID string) (*DiscordLink, error)
|
|
Upsert(ctx context.Context, link DiscordLink) error
|
|
}
|
|
|
|
// DiscordLinks implements DiscordLinkStore against Postgres.
|
|
type DiscordLinks struct {
|
|
db *sql.DB
|
|
}
|
|
|
|
// NewDiscordLinks wraps db. It is independent of Store.
|
|
func NewDiscordLinks(db *sql.DB) *DiscordLinks {
|
|
return &DiscordLinks{db: db}
|
|
}
|
|
|
|
// GetByPostID returns the link for a site post.
|
|
func (d *DiscordLinks) GetByPostID(ctx context.Context, postID string) (*DiscordLink, error) {
|
|
if d == nil || d.db == nil {
|
|
return nil, fmt.Errorf("discord links: no database")
|
|
}
|
|
row, err := sqlc.New(d.db).GetDiscordPostLinkByPostID(ctx, strings.TrimSpace(postID))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return discordLinkFromRow(row), nil
|
|
}
|
|
|
|
// GetByMessageID returns the link for a Discord message.
|
|
func (d *DiscordLinks) GetByMessageID(ctx context.Context, messageID string) (*DiscordLink, error) {
|
|
if d == nil || d.db == nil {
|
|
return nil, fmt.Errorf("discord links: no database")
|
|
}
|
|
row, err := sqlc.New(d.db).GetDiscordPostLinkByMessageID(ctx, strings.TrimSpace(messageID))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return discordLinkFromRow(row), nil
|
|
}
|
|
|
|
// GetRootByThreadID returns the root link for a Discord thread.
|
|
func (d *DiscordLinks) GetRootByThreadID(ctx context.Context, threadID string) (*DiscordLink, error) {
|
|
if d == nil || d.db == nil {
|
|
return nil, fmt.Errorf("discord links: no database")
|
|
}
|
|
row, err := sqlc.New(d.db).GetDiscordPostLinkByThreadID(ctx, strings.TrimSpace(threadID))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return discordLinkFromRow(row), nil
|
|
}
|
|
|
|
// Upsert inserts or replaces the Discord IDs for a post.
|
|
func (d *DiscordLinks) Upsert(ctx context.Context, link DiscordLink) error {
|
|
if d == nil || d.db == nil {
|
|
return fmt.Errorf("discord links: no database")
|
|
}
|
|
link.PostID = strings.TrimSpace(link.PostID)
|
|
link.MessageID = strings.TrimSpace(link.MessageID)
|
|
link.ThreadID = strings.TrimSpace(link.ThreadID)
|
|
if link.PostID == "" || link.MessageID == "" {
|
|
return fmt.Errorf("discord links: post and message ids are required")
|
|
}
|
|
if link.CreatedAt == "" {
|
|
link.CreatedAt = time.Now().UTC().Format(time.RFC3339Nano)
|
|
}
|
|
return sqlc.New(d.db).UpsertDiscordPostLink(ctx, sqlc.UpsertDiscordPostLinkParams{
|
|
PostID: link.PostID,
|
|
DiscordMessageID: link.MessageID,
|
|
DiscordThreadID: link.ThreadID,
|
|
CreatedAt: link.CreatedAt,
|
|
})
|
|
}
|
|
|
|
func discordLinkFromRow(row sqlc.DiscordPostLink) *DiscordLink {
|
|
return &DiscordLink{
|
|
PostID: row.PostID,
|
|
MessageID: row.DiscordMessageID,
|
|
ThreadID: row.DiscordThreadID,
|
|
CreatedAt: row.CreatedAt,
|
|
}
|
|
}
|