mirror of https://gitlab.com/ngerakines/tavern.git
87 lines
2.6 KiB
Go
87 lines
2.6 KiB
Go
package storage
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/gofrs/uuid"
|
|
"github.com/spaolacci/murmur3"
|
|
|
|
"github.com/ngerakines/tavern/errors"
|
|
)
|
|
|
|
type ActivityStorage interface {
|
|
RecordActivity(ctx context.Context, rowID uuid.UUID, activityID, payload string) error
|
|
GetActivitiesByIDs(ctx context.Context, activityIDs []uuid.UUID) ([]Activity, error)
|
|
RecordUserActivity(ctx context.Context, rowID, userID, activityID uuid.UUID) error
|
|
}
|
|
|
|
type Activity struct {
|
|
ID uuid.UUID
|
|
Payload string
|
|
CreatedAt time.Time
|
|
}
|
|
|
|
func (s pgStorage) RecordActivity(ctx context.Context, rowID uuid.UUID, activityID, payload string) error {
|
|
checksum := ActivityChecksum([]byte(payload))
|
|
_, err := s.db.ExecContext(ctx, "INSERT INTO activities (id, activity_id, checksum, payload, created_at) VALUES ($1, $2, $3, $4, $5)", rowID, activityID, checksum, payload, s.now())
|
|
return errors.WrapInsertQueryFailedError(err)
|
|
}
|
|
|
|
func (s pgStorage) RecordUserActivity(ctx context.Context, rowID, userID, activityID uuid.UUID) error {
|
|
_, err := s.db.ExecContext(ctx, "INSERT INTO user_activities (id, user_id, activity_id, created_at) VALUES ($1, $2, $3, $4)", rowID, userID, activityID, s.now())
|
|
return errors.WrapInsertQueryFailedError(err)
|
|
}
|
|
|
|
func (s pgStorage) GetActivitiesByIDs(ctx context.Context, activityIDs []uuid.UUID) ([]Activity, error) {
|
|
if len(activityIDs) == 0 {
|
|
return nil, nil
|
|
}
|
|
params := make([]string, len(activityIDs))
|
|
args := make([]interface{}, len(activityIDs))
|
|
for i, id := range activityIDs {
|
|
params[i] = fmt.Sprintf("$%d", i+1)
|
|
args[i] = id
|
|
}
|
|
|
|
query := fmt.Sprintf("SELECT id, payload, created_at FROM activities WHERE id IN (%s) ORDER BY created_at ASC", strings.Join(params, ", "))
|
|
|
|
return s.activitiesQuery(ctx, query, args...)
|
|
}
|
|
|
|
func (s pgStorage) activitiesQuery(ctx context.Context, query string, args ...interface{}) ([]Activity, error) {
|
|
var activities []Activity
|
|
|
|
rows, err := s.db.QueryContext(ctx, query, args...)
|
|
if err != nil {
|
|
return nil, errors.NewSelectQueryFailedError(err)
|
|
}
|
|
defer rows.Close()
|
|
for rows.Next() {
|
|
var activity Activity
|
|
if err := rows.Scan(&activity.ID, &activity.Payload, &activity.CreatedAt); err != nil {
|
|
return nil, errors.NewSelectQueryFailedError(err)
|
|
}
|
|
activities = append(activities, activity)
|
|
}
|
|
|
|
return activities, nil
|
|
}
|
|
|
|
func ActivityChecksum(raw []byte) string {
|
|
h := murmur3.New64()
|
|
h.Write(raw)
|
|
return strconv.FormatUint(h.Sum64(), 10)
|
|
}
|
|
|
|
func ValidateActivity(activity Payload) (string, error) {
|
|
id, ok := JSONString(activity, "id")
|
|
if !ok {
|
|
return "", fmt.Errorf("missing activity attribute: id")
|
|
}
|
|
return id, nil
|
|
}
|