154 lines
3.8 KiB
Go
154 lines
3.8 KiB
Go
// ©AngelaMos | 2026
|
|
// repository.go
|
|
|
|
package token
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"errors"
|
|
"fmt"
|
|
|
|
"github.com/jmoiron/sqlx"
|
|
)
|
|
|
|
var ErrNotFound = errors.New("token not found")
|
|
|
|
const defaultListLimit = 50
|
|
|
|
type Repository struct {
|
|
db *sqlx.DB
|
|
}
|
|
|
|
func NewRepository(db *sqlx.DB) *Repository {
|
|
return &Repository{db: db}
|
|
}
|
|
|
|
const insertSQL = `
|
|
INSERT INTO tokens (
|
|
id, manage_id, type, memo, filename,
|
|
alert_channel, telegram_bot, telegram_chat, webhook_url,
|
|
created_ip, created_fp, metadata, enabled
|
|
) VALUES (
|
|
:id, :manage_id, :type, :memo, :filename,
|
|
:alert_channel, :telegram_bot, :telegram_chat, :webhook_url,
|
|
:created_ip, :created_fp, :metadata, :enabled
|
|
)
|
|
RETURNING created_at, trigger_count, last_triggered`
|
|
|
|
func (r *Repository) Insert(ctx context.Context, t *Token) error {
|
|
stmt, err := r.db.PrepareNamedContext(ctx, insertSQL)
|
|
if err != nil {
|
|
return fmt.Errorf("prepare insert token: %w", err)
|
|
}
|
|
defer stmt.Close()
|
|
|
|
if err := stmt.GetContext(ctx, t, t); err != nil {
|
|
return fmt.Errorf("insert token: %w", err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
const selectColumns = `
|
|
id, manage_id, type, memo, filename,
|
|
alert_channel, telegram_bot, telegram_chat, webhook_url,
|
|
created_at, created_ip, created_fp, enabled,
|
|
trigger_count, last_triggered, metadata`
|
|
|
|
func (r *Repository) GetByID(ctx context.Context, id string) (*Token, error) {
|
|
var t Token
|
|
q := `SELECT ` + selectColumns + ` FROM tokens WHERE id = $1`
|
|
err := r.db.GetContext(ctx, &t, q, id)
|
|
if errors.Is(err, sql.ErrNoRows) {
|
|
return nil, ErrNotFound
|
|
}
|
|
if err != nil {
|
|
return nil, fmt.Errorf("get token by id: %w", err)
|
|
}
|
|
return &t, nil
|
|
}
|
|
|
|
func (r *Repository) GetByManageID(ctx context.Context, manageID string) (*Token, error) {
|
|
var t Token
|
|
q := `SELECT ` + selectColumns + ` FROM tokens WHERE manage_id = $1`
|
|
err := r.db.GetContext(ctx, &t, q, manageID)
|
|
if errors.Is(err, sql.ErrNoRows) {
|
|
return nil, ErrNotFound
|
|
}
|
|
if err != nil {
|
|
return nil, fmt.Errorf("get token by manage_id: %w", err)
|
|
}
|
|
return &t, nil
|
|
}
|
|
|
|
func (r *Repository) DeleteByManageID(ctx context.Context, manageID string) error {
|
|
res, err := r.db.ExecContext(ctx,
|
|
`DELETE FROM tokens WHERE manage_id = $1`, manageID)
|
|
if err != nil {
|
|
return fmt.Errorf("delete token: %w", err)
|
|
}
|
|
n, err := res.RowsAffected()
|
|
if err != nil {
|
|
return fmt.Errorf("rows affected: %w", err)
|
|
}
|
|
if n == 0 {
|
|
return ErrNotFound
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (r *Repository) IncrementTriggerCount(ctx context.Context, id string) error {
|
|
_, err := r.db.ExecContext(ctx, `
|
|
UPDATE tokens
|
|
SET trigger_count = trigger_count + 1,
|
|
last_triggered = NOW()
|
|
WHERE id = $1`, id)
|
|
if err != nil {
|
|
return fmt.Errorf("increment trigger count: %w", err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (r *Repository) SetEnabled(ctx context.Context, id string, enabled bool) error {
|
|
res, err := r.db.ExecContext(ctx,
|
|
`UPDATE tokens SET enabled = $2 WHERE id = $1`, id, enabled)
|
|
if err != nil {
|
|
return fmt.Errorf("set enabled: %w", err)
|
|
}
|
|
n, err := res.RowsAffected()
|
|
if err != nil {
|
|
return fmt.Errorf("rows affected: %w", err)
|
|
}
|
|
if n == 0 {
|
|
return ErrNotFound
|
|
}
|
|
return nil
|
|
}
|
|
|
|
type ListOptions struct {
|
|
Limit int
|
|
Offset int
|
|
}
|
|
|
|
func (r *Repository) ListAll(ctx context.Context, opts ListOptions) ([]Token, error) {
|
|
if opts.Limit <= 0 {
|
|
opts.Limit = defaultListLimit
|
|
}
|
|
q := `SELECT ` + selectColumns + ` FROM tokens
|
|
ORDER BY created_at DESC
|
|
LIMIT $1 OFFSET $2`
|
|
var tokens []Token
|
|
if err := r.db.SelectContext(ctx, &tokens, q, opts.Limit, opts.Offset); err != nil {
|
|
return nil, fmt.Errorf("list all tokens: %w", err)
|
|
}
|
|
return tokens, nil
|
|
}
|
|
|
|
func (r *Repository) CountAll(ctx context.Context) (int64, error) {
|
|
var n int64
|
|
if err := r.db.GetContext(ctx, &n, `SELECT COUNT(*) FROM tokens`); err != nil {
|
|
return 0, fmt.Errorf("count tokens: %w", err)
|
|
}
|
|
return n, nil
|
|
}
|