159 lines
4.2 KiB
Go
159 lines
4.2 KiB
Go
package tenant
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
)
|
|
|
|
func (q *Queries) ListReactions(ctx context.Context, postSlug string) ([]Reaction, error) {
|
|
rows, err := q.db.QueryContext(ctx, `SELECT id, user_id, anon_id, post_slug, emoji, created_at
|
|
FROM reactions WHERE post_slug = ?`, postSlug)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
|
|
var reactions []Reaction
|
|
for rows.Next() {
|
|
r, err := scanReaction(rows)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
reactions = append(reactions, r)
|
|
}
|
|
return reactions, rows.Err()
|
|
}
|
|
|
|
func (q *Queries) GetReactionCounts(ctx context.Context, postSlug string) (map[string]int, error) {
|
|
rows, err := q.db.QueryContext(ctx, `SELECT emoji, COUNT(*) as count FROM reactions WHERE post_slug = ? GROUP BY emoji`, postSlug)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
|
|
counts := make(map[string]int)
|
|
for rows.Next() {
|
|
var emoji string
|
|
var count int64
|
|
if err := rows.Scan(&emoji, &count); err != nil {
|
|
return nil, err
|
|
}
|
|
counts[emoji] = int(count)
|
|
}
|
|
return counts, rows.Err()
|
|
}
|
|
|
|
func (q *Queries) ToggleReaction(ctx context.Context, userID, anonID, postSlug, emoji string) (bool, error) {
|
|
var exists bool
|
|
|
|
if userID != "" {
|
|
var dummy int64
|
|
err := q.db.QueryRowContext(ctx, `SELECT 1 FROM reactions WHERE user_id = ? AND post_slug = ? AND emoji = ?`,
|
|
userID, postSlug, emoji).Scan(&dummy)
|
|
exists = err == nil
|
|
} else if anonID != "" {
|
|
var dummy int64
|
|
err := q.db.QueryRowContext(ctx, `SELECT 1 FROM reactions WHERE anon_id = ? AND post_slug = ? AND emoji = ?`,
|
|
anonID, postSlug, emoji).Scan(&dummy)
|
|
exists = err == nil
|
|
} else {
|
|
return false, nil
|
|
}
|
|
|
|
if !exists {
|
|
if userID != "" {
|
|
_, err := q.db.ExecContext(ctx, `INSERT INTO reactions (user_id, post_slug, emoji) VALUES (?, ?, ?)`,
|
|
userID, postSlug, emoji)
|
|
return true, err
|
|
}
|
|
_, err := q.db.ExecContext(ctx, `INSERT INTO reactions (anon_id, post_slug, emoji) VALUES (?, ?, ?)`,
|
|
anonID, postSlug, emoji)
|
|
return true, err
|
|
}
|
|
|
|
if userID != "" {
|
|
_, err := q.db.ExecContext(ctx, `DELETE FROM reactions WHERE user_id = ? AND post_slug = ? AND emoji = ?`,
|
|
userID, postSlug, emoji)
|
|
return false, err
|
|
}
|
|
_, err := q.db.ExecContext(ctx, `DELETE FROM reactions WHERE anon_id = ? AND post_slug = ? AND emoji = ?`,
|
|
anonID, postSlug, emoji)
|
|
return false, err
|
|
}
|
|
|
|
func (q *Queries) GetUserReactions(ctx context.Context, userID, postSlug string) ([]string, error) {
|
|
rows, err := q.db.QueryContext(ctx, `SELECT emoji FROM reactions WHERE user_id = ? AND post_slug = ?`, userID, postSlug)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
|
|
var emojis []string
|
|
for rows.Next() {
|
|
var emoji string
|
|
if err := rows.Scan(&emoji); err != nil {
|
|
return nil, err
|
|
}
|
|
emojis = append(emojis, emoji)
|
|
}
|
|
return emojis, rows.Err()
|
|
}
|
|
|
|
func (q *Queries) GetAnonReactions(ctx context.Context, anonID, postSlug string) ([]string, error) {
|
|
rows, err := q.db.QueryContext(ctx, `SELECT emoji FROM reactions WHERE anon_id = ? AND post_slug = ?`, anonID, postSlug)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
|
|
var emojis []string
|
|
for rows.Next() {
|
|
var emoji string
|
|
if err := rows.Scan(&emoji); err != nil {
|
|
return nil, err
|
|
}
|
|
emojis = append(emojis, emoji)
|
|
}
|
|
return emojis, rows.Err()
|
|
}
|
|
|
|
func (q *Queries) HasUserReacted(ctx context.Context, userID, postSlug string) (bool, error) {
|
|
var dummy int64
|
|
err := q.db.QueryRowContext(ctx, `SELECT 1 FROM reactions WHERE user_id = ? AND post_slug = ? LIMIT 1`,
|
|
userID, postSlug).Scan(&dummy)
|
|
if err == sql.ErrNoRows {
|
|
return false, nil
|
|
}
|
|
if err != nil {
|
|
return false, nil
|
|
}
|
|
return true, nil
|
|
}
|
|
|
|
func (q *Queries) HasAnonReacted(ctx context.Context, anonID, postSlug string) (bool, error) {
|
|
var dummy int64
|
|
err := q.db.QueryRowContext(ctx, `SELECT 1 FROM reactions WHERE anon_id = ? AND post_slug = ? LIMIT 1`,
|
|
anonID, postSlug).Scan(&dummy)
|
|
if err == sql.ErrNoRows {
|
|
return false, nil
|
|
}
|
|
if err != nil {
|
|
return false, nil
|
|
}
|
|
return true, nil
|
|
}
|
|
|
|
func scanReaction(s scanner) (Reaction, error) {
|
|
var r Reaction
|
|
var userID, anonID, createdAt sql.NullString
|
|
|
|
err := s.Scan(&r.ID, &userID, &anonID, &r.PostSlug, &r.Emoji, &createdAt)
|
|
if err != nil {
|
|
return r, err
|
|
}
|
|
|
|
r.UserID = userID.String
|
|
r.AnonID = anonID.String
|
|
r.CreatedAt = parseTime(createdAt.String)
|
|
return r, nil
|
|
}
|