mirror of https://github.com/artifacthub/hub.git
85 lines
2.5 KiB
Go
85 lines
2.5 KiB
Go
package notification
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
|
|
"github.com/artifacthub/hub/internal/hub"
|
|
"github.com/jackc/pgx/v4"
|
|
"github.com/satori/uuid"
|
|
)
|
|
|
|
const (
|
|
// Database queries
|
|
addNotificationDBQ = `select add_notification($1::jsonb)`
|
|
getPendingNotificationDBQ = `select get_pending_notification()`
|
|
updateNotificationStatusDBQ = `select update_notification_status($1::uuid, $2::boolean, $3::text)`
|
|
)
|
|
|
|
// Manager provides an API to manage notifications.
|
|
type Manager struct{}
|
|
|
|
// NewManager creates a new Manager instance.
|
|
func NewManager() *Manager {
|
|
return &Manager{}
|
|
}
|
|
|
|
// Add adds the provided notification to the database.
|
|
func (m *Manager) Add(ctx context.Context, tx pgx.Tx, n *hub.Notification) error {
|
|
if _, err := uuid.FromString(n.Event.EventID); err != nil {
|
|
return fmt.Errorf("%w: %s", hub.ErrInvalidInput, "invalid event id")
|
|
}
|
|
if n.User == nil && n.Webhook == nil {
|
|
return fmt.Errorf("%w: %s", hub.ErrInvalidInput, "user or webhook must be provided")
|
|
}
|
|
if n.User != nil && n.Webhook != nil {
|
|
return fmt.Errorf("%w: %s", hub.ErrInvalidInput, "both user and webhook were provided")
|
|
}
|
|
if n.User != nil {
|
|
if _, err := uuid.FromString(n.User.UserID); err != nil {
|
|
return fmt.Errorf("%w: %s", hub.ErrInvalidInput, "invalid user id")
|
|
}
|
|
}
|
|
if n.Webhook != nil {
|
|
if _, err := uuid.FromString(n.Webhook.WebhookID); err != nil {
|
|
return fmt.Errorf("%w: %s", hub.ErrInvalidInput, "invalid webhook id")
|
|
}
|
|
}
|
|
nJSON, _ := json.Marshal(n)
|
|
_, err := tx.Exec(ctx, addNotificationDBQ, nJSON)
|
|
return err
|
|
}
|
|
|
|
// GetPending returns a pending notification to be delivered if available.
|
|
func (m *Manager) GetPending(ctx context.Context, tx pgx.Tx) (*hub.Notification, error) {
|
|
var dataJSON []byte
|
|
if err := tx.QueryRow(ctx, getPendingNotificationDBQ).Scan(&dataJSON); err != nil {
|
|
return nil, err
|
|
}
|
|
var n *hub.Notification
|
|
if err := json.Unmarshal(dataJSON, &n); err != nil {
|
|
return nil, err
|
|
}
|
|
return n, nil
|
|
}
|
|
|
|
// UpdateStatus the provided notification status in the database.
|
|
func (m *Manager) UpdateStatus(
|
|
ctx context.Context,
|
|
tx pgx.Tx,
|
|
notificationID string,
|
|
processed bool,
|
|
processedErr error,
|
|
) error {
|
|
if _, err := uuid.FromString(notificationID); err != nil {
|
|
return fmt.Errorf("%w: %s", hub.ErrInvalidInput, "invalid notification id")
|
|
}
|
|
var processedErrStr string
|
|
if processedErr != nil {
|
|
processedErrStr = processedErr.Error()
|
|
}
|
|
_, err := tx.Exec(ctx, updateNotificationStatusDBQ, notificationID, processed, processedErrStr)
|
|
return err
|
|
}
|