webhooks.go

  1package database
  2
  3import (
  4	"context"
  5
  6	"github.com/charmbracelet/soft-serve/pkg/db"
  7	"github.com/charmbracelet/soft-serve/pkg/db/models"
  8	"github.com/charmbracelet/soft-serve/pkg/store"
  9	"github.com/google/uuid"
 10	"github.com/jmoiron/sqlx"
 11)
 12
 13type webhookStore struct{}
 14
 15var _ store.WebhookStore = (*webhookStore)(nil)
 16
 17// CreateWebhook implements store.WebhookStore.
 18func (*webhookStore) CreateWebhook(ctx context.Context, h db.Handler, repoID int64, url string, secret string, contentType int, active bool) (int64, error) {
 19	var id int64
 20	query := h.Rebind(`INSERT INTO webhooks (repo_id, url, secret, content_type, active, updated_at)
 21			VALUES (?, ?, ?, ?, ?, CURRENT_TIMESTAMP) RETURNING id;`)
 22	err := h.GetContext(ctx, &id, query, repoID, url, secret, contentType, active)
 23	if err != nil {
 24		return 0, err //nolint:wrapcheck
 25	}
 26
 27	return id, nil
 28}
 29
 30// CreateWebhookDelivery implements store.WebhookStore.
 31func (*webhookStore) CreateWebhookDelivery(ctx context.Context, h db.Handler, id uuid.UUID, webhookID int64, event int, url string, method string, requestError error, requestHeaders string, requestBody string, responseStatus int, responseHeaders string, responseBody string) error {
 32	query := h.Rebind(`INSERT INTO webhook_deliveries (id, webhook_id, event, request_url, request_method, request_error, request_headers, request_body, response_status, response_headers, response_body)
 33			VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);`)
 34	var reqErr string
 35	if requestError != nil {
 36		reqErr = requestError.Error()
 37	}
 38	_, err := h.ExecContext(ctx, query, id, webhookID, event, url, method, reqErr, requestHeaders, requestBody, responseStatus, responseHeaders, responseBody)
 39	return err //nolint:wrapcheck
 40}
 41
 42// CreateWebhookEvents implements store.WebhookStore.
 43func (*webhookStore) CreateWebhookEvents(ctx context.Context, h db.Handler, webhookID int64, events []int) error {
 44	query := h.Rebind(`INSERT INTO webhook_events (webhook_id, event)
 45			VALUES (?, ?);`)
 46	for _, event := range events {
 47		_, err := h.ExecContext(ctx, query, webhookID, event)
 48		if err != nil {
 49			return err //nolint:wrapcheck
 50		}
 51	}
 52	return nil
 53}
 54
 55// DeleteWebhookByID implements store.WebhookStore.
 56func (*webhookStore) DeleteWebhookByID(ctx context.Context, h db.Handler, id int64) error {
 57	query := h.Rebind(`DELETE FROM webhooks WHERE id = ?;`)
 58	_, err := h.ExecContext(ctx, query, id)
 59	return err //nolint:wrapcheck
 60}
 61
 62// DeleteWebhookForRepoByID implements store.WebhookStore.
 63func (*webhookStore) DeleteWebhookForRepoByID(ctx context.Context, h db.Handler, repoID int64, id int64) error {
 64	query := h.Rebind(`DELETE FROM webhooks WHERE repo_id = ? AND id = ?;`)
 65	_, err := h.ExecContext(ctx, query, repoID, id)
 66	return err //nolint:wrapcheck
 67}
 68
 69// DeleteWebhookDeliveryByID implements store.WebhookStore.
 70func (*webhookStore) DeleteWebhookDeliveryByID(ctx context.Context, h db.Handler, webhookID int64, id uuid.UUID) error {
 71	query := h.Rebind(`DELETE FROM webhook_deliveries WHERE webhook_id = ? AND id = ?;`)
 72	_, err := h.ExecContext(ctx, query, webhookID, id)
 73	return err //nolint:wrapcheck
 74}
 75
 76// DeleteWebhookEventsByWebhookID implements store.WebhookStore.
 77func (*webhookStore) DeleteWebhookEventsByID(ctx context.Context, h db.Handler, ids []int64) error {
 78	query, args, err := sqlx.In(`DELETE FROM webhook_events WHERE id IN (?);`, ids)
 79	if err != nil {
 80		return err //nolint:wrapcheck
 81	}
 82
 83	query = h.Rebind(query)
 84	_, err = h.ExecContext(ctx, query, args...)
 85	return err //nolint:wrapcheck
 86}
 87
 88// GetWebhookByID implements store.WebhookStore.
 89func (*webhookStore) GetWebhookByID(ctx context.Context, h db.Handler, repoID int64, id int64) (models.Webhook, error) {
 90	query := h.Rebind(`SELECT * FROM webhooks WHERE repo_id = ? AND id = ?;`)
 91	var wh models.Webhook
 92	err := h.GetContext(ctx, &wh, query, repoID, id)
 93	return wh, err //nolint:wrapcheck
 94}
 95
 96// GetWebhookDeliveriesByWebhookID implements store.WebhookStore.
 97func (*webhookStore) GetWebhookDeliveriesByWebhookID(ctx context.Context, h db.Handler, webhookID int64) ([]models.WebhookDelivery, error) {
 98	query := h.Rebind(`SELECT * FROM webhook_deliveries WHERE webhook_id = ?;`)
 99	var whds []models.WebhookDelivery
100	err := h.SelectContext(ctx, &whds, query, webhookID)
101	return whds, err //nolint:wrapcheck
102}
103
104// GetWebhookDeliveryByID implements store.WebhookStore.
105func (*webhookStore) GetWebhookDeliveryByID(ctx context.Context, h db.Handler, webhookID int64, id uuid.UUID) (models.WebhookDelivery, error) {
106	query := h.Rebind(`SELECT * FROM webhook_deliveries WHERE webhook_id = ? AND id = ?;`)
107	var whd models.WebhookDelivery
108	err := h.GetContext(ctx, &whd, query, webhookID, id)
109	return whd, err //nolint:wrapcheck
110}
111
112// GetWebhookEventByID implements store.WebhookStore.
113func (*webhookStore) GetWebhookEventByID(ctx context.Context, h db.Handler, id int64) (models.WebhookEvent, error) {
114	query := h.Rebind(`SELECT * FROM webhook_events WHERE id = ?;`)
115	var whe models.WebhookEvent
116	err := h.GetContext(ctx, &whe, query, id)
117	return whe, err //nolint:wrapcheck
118}
119
120// GetWebhookEventsByWebhookID implements store.WebhookStore.
121func (*webhookStore) GetWebhookEventsByWebhookID(ctx context.Context, h db.Handler, webhookID int64) ([]models.WebhookEvent, error) {
122	query := h.Rebind(`SELECT * FROM webhook_events WHERE webhook_id = ?;`)
123	var whes []models.WebhookEvent
124	err := h.SelectContext(ctx, &whes, query, webhookID)
125	return whes, err //nolint:wrapcheck
126}
127
128// GetWebhooksByRepoID implements store.WebhookStore.
129func (*webhookStore) GetWebhooksByRepoID(ctx context.Context, h db.Handler, repoID int64) ([]models.Webhook, error) {
130	query := h.Rebind(`SELECT * FROM webhooks WHERE repo_id = ?;`)
131	var whs []models.Webhook
132	err := h.SelectContext(ctx, &whs, query, repoID)
133	return whs, err //nolint:wrapcheck
134}
135
136// GetWebhooksByRepoIDWhereEvent implements store.WebhookStore.
137func (*webhookStore) GetWebhooksByRepoIDWhereEvent(ctx context.Context, h db.Handler, repoID int64, events []int) ([]models.Webhook, error) {
138	query, args, err := sqlx.In(`SELECT webhooks.*
139			FROM webhooks
140			INNER JOIN webhook_events ON webhooks.id = webhook_events.webhook_id
141			WHERE webhooks.repo_id = ? AND webhook_events.event IN (?);`, repoID, events)
142	if err != nil {
143		return nil, err //nolint:wrapcheck
144	}
145
146	query = h.Rebind(query)
147	var whs []models.Webhook
148	err = h.SelectContext(ctx, &whs, query, args...)
149	return whs, err //nolint:wrapcheck
150}
151
152// ListWebhookDeliveriesByWebhookID implements store.WebhookStore.
153func (*webhookStore) ListWebhookDeliveriesByWebhookID(ctx context.Context, h db.Handler, webhookID int64) ([]models.WebhookDelivery, error) {
154	query := h.Rebind(`SELECT id, response_status, event FROM webhook_deliveries WHERE webhook_id = ?;`)
155	var whds []models.WebhookDelivery
156	err := h.SelectContext(ctx, &whds, query, webhookID)
157	return whds, err //nolint:wrapcheck
158}
159
160// UpdateWebhookByID implements store.WebhookStore.
161func (*webhookStore) UpdateWebhookByID(ctx context.Context, h db.Handler, repoID int64, id int64, url string, secret string, contentType int, active bool) error {
162	query := h.Rebind(`UPDATE webhooks SET url = ?, secret = ?, content_type = ?, active = ?, updated_at = CURRENT_TIMESTAMP WHERE repo_id = ? AND id = ?;`)
163	_, err := h.ExecContext(ctx, query, url, secret, contentType, active, repoID, id)
164	return err //nolint:wrapcheck
165}