1package database23import (4 "context"56 "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)1213type webhookStore struct{}1415var _ store.WebhookStore = (*webhookStore)(nil)1617// 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 int6420 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, err25 }2627 return id, nil28}2930// 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 string35 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 err40}4142// 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 err50 }51 }52 return nil53}5455// 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 err60}6162// 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 err67}6869// 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 err74}7576// 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 err81 }8283 query = h.Rebind(query)84 _, err = h.ExecContext(ctx, query, args...)85 return err86}8788// 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.Webhook92 err := h.GetContext(ctx, &wh, query, repoID, id)93 return wh, err94}9596// 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.WebhookDelivery100 err := h.SelectContext(ctx, &whds, query, webhookID)101 return whds, err102}103104// 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.WebhookDelivery108 err := h.GetContext(ctx, &whd, query, webhookID, id)109 return whd, err110}111112// 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.WebhookEvent116 err := h.GetContext(ctx, &whe, query, id)117 return whe, err118}119120// 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.WebhookEvent124 err := h.SelectContext(ctx, &whes, query, webhookID)125 return whes, err126}127128// 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.Webhook132 err := h.SelectContext(ctx, &whs, query, repoID)133 return whs, err134}135136// 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 webhooks140 INNER JOIN webhook_events ON webhooks.id = webhook_events.webhook_id141 WHERE webhooks.repo_id = ? AND webhook_events.event IN (?);`, repoID, events)142 if err != nil {143 return nil, err144 }145146 query = h.Rebind(query)147 var whs []models.Webhook148 err = h.SelectContext(ctx, &whs, query, args...)149 return whs, err150}151152// 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.WebhookDelivery156 err := h.SelectContext(ctx, &whds, query, webhookID)157 return whds, err158}159160// 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 err165}