78 lines
2.1 KiB
Go
78 lines
2.1 KiB
Go
package storage
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
// GetCooldownMemoNames returns memo names shown within the last cooldownDays.
|
|
func (s *Storage) GetCooldownMemoNames(ctx context.Context, cooldownDays int) (map[string]struct{}, error) {
|
|
cutoff := time.Now().Unix() - int64(cooldownDays)*86400
|
|
|
|
rows, err := s.db.QueryContext(ctx,
|
|
`SELECT DISTINCT memo_name FROM show_history WHERE shown_at > ?`, cutoff)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("query cooldown memos: %w", err)
|
|
}
|
|
defer rows.Close()
|
|
|
|
result := make(map[string]struct{})
|
|
for rows.Next() {
|
|
var name string
|
|
if err := rows.Scan(&name); err != nil {
|
|
return nil, fmt.Errorf("scan memo_name: %w", err)
|
|
}
|
|
result[name] = struct{}{}
|
|
}
|
|
return result, rows.Err()
|
|
}
|
|
|
|
// GetShowCounts returns show_count for each of the given memo names.
|
|
// Memos not present in history will be absent from the result (count = 0).
|
|
func (s *Storage) GetShowCounts(ctx context.Context, memoNames []string) (map[string]int, error) {
|
|
if len(memoNames) == 0 {
|
|
return nil, nil
|
|
}
|
|
|
|
placeholders := make([]string, len(memoNames))
|
|
args := make([]any, len(memoNames))
|
|
for i, name := range memoNames {
|
|
placeholders[i] = "?"
|
|
args[i] = name
|
|
}
|
|
|
|
query := fmt.Sprintf( //nolint:gosec // placeholders are always "?"
|
|
`SELECT memo_name, COUNT(*) FROM show_history WHERE memo_name IN (%s) GROUP BY memo_name`,
|
|
strings.Join(placeholders, ","))
|
|
|
|
rows, err := s.db.QueryContext(ctx, query, args...)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("query show counts: %w", err)
|
|
}
|
|
defer rows.Close()
|
|
|
|
result := make(map[string]int)
|
|
for rows.Next() {
|
|
var name string
|
|
var count int
|
|
if err := rows.Scan(&name, &count); err != nil {
|
|
return nil, fmt.Errorf("scan show count: %w", err)
|
|
}
|
|
result[name] = count
|
|
}
|
|
return result, rows.Err()
|
|
}
|
|
|
|
// RecordShow records that a memo was shown.
|
|
func (s *Storage) RecordShow(ctx context.Context, memoName string, tier int) error {
|
|
_, err := s.db.ExecContext(ctx,
|
|
`INSERT INTO show_history (memo_name, shown_at, tier) VALUES (?, ?, ?)`,
|
|
memoName, time.Now().Unix(), tier)
|
|
if err != nil {
|
|
return fmt.Errorf("insert show history: %w", err)
|
|
}
|
|
return nil
|
|
}
|