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}