-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathcustom_integration_secrets.go
More file actions
145 lines (119 loc) · 3.86 KB
/
Copy pathcustom_integration_secrets.go
File metadata and controls
145 lines (119 loc) · 3.86 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
package database
import (
"context"
"github.com/jackc/pgtype"
"github.com/jackc/pgx/v4/pgxpool"
)
type CustomIntegrationSecretsTable struct {
*pgxpool.Pool
}
type CustomIntegrationSecret struct {
Id int `json:"id"`
IntegrationId int `json:"integration_id"`
Name string `json:"name"`
Description *string `json:"description"`
}
func newCustomIntegrationSecretsTable(db *pgxpool.Pool) *CustomIntegrationSecretsTable {
return &CustomIntegrationSecretsTable{
db,
}
}
func (i CustomIntegrationSecretsTable) Schema() string {
return `
CREATE TABLE IF NOT EXISTS custom_integration_secrets(
"id" SERIAL NOT NULL UNIQUE,
"integration_id" int NOT NULL,
"name" VARCHAR(32) NOT NULL,
"description" VARCHAR(255) NULL,
UNIQUE ("integration_id", "name"),
FOREIGN KEY("integration_id") REFERENCES custom_integrations("id") ON DELETE CASCADE,
PRIMARY KEY("id")
);
CREATE INDEX IF NOT EXISTS custom_integration_secrets_integration_id ON custom_integration_secrets("integration_id");
`
}
func (i *CustomIntegrationSecretsTable) GetByIntegration(ctx context.Context, integrationId int) ([]CustomIntegrationSecret, error) {
query := `SELECT "id", "integration_id", "name", "description" FROM custom_integration_secrets WHERE "integration_id" = $1;`
rows, err := i.Query(ctx, query, integrationId)
if err != nil {
return nil, err
}
var secrets []CustomIntegrationSecret
for rows.Next() {
var secret CustomIntegrationSecret
if err := rows.Scan(&secret.Id, &secret.IntegrationId, &secret.Name, &secret.Description); err != nil {
return nil, err
}
secrets = append(secrets, secret)
}
return secrets, nil
}
// / Assume that secrets[].Id is valid for the guild and integration
func (i *CustomIntegrationSecretsTable) CreateOrUpdate(ctx context.Context, integrationId int, secrets []CustomIntegrationSecret) ([]CustomIntegrationSecret, error) {
if len(secrets) == 0 {
query := `DELETE FROM custom_integration_secrets WHERE "integration_id" = $1;`
_, err := i.Exec(ctx, query, integrationId)
return nil, err
}
tx, err := i.Begin(ctx)
if err != nil {
return nil, err
}
defer tx.Rollback(ctx) // Does not matter if commit succeeds
// Delete existing secrets that are not in the new list
query := `DELETE FROM custom_integration_secrets WHERE "integration_id" = $1 AND NOT("id" = ANY($2));`
var ids []int
for _, secret := range secrets {
if secret.Id != 0 {
ids = append(ids, secret.Id)
}
}
array := &pgtype.Int4Array{}
if err := array.Set(ids); err != nil {
return nil, err
}
if _, err := tx.Exec(ctx, query, integrationId, array); err != nil {
return nil, err
}
// Create or update new secrets
var newSecrets []CustomIntegrationSecret
for _, secret := range secrets {
var res CustomIntegrationSecret
if secret.Id == 0 { // Create
query := `
INSERT INTO custom_integration_secrets("integration_id", "name", "description")
VALUES ($1, $2, $3)
RETURNING "id", "integration_id", "name", "description";
;`
err = tx.QueryRow(ctx, query, integrationId, secret.Name, secret.Description).Scan(&res.Id, &res.IntegrationId, &res.Name, &res.Description)
} else { // Update
query := `
UPDATE custom_integration_secrets
SET "name" = $3, "description" = $4
WHERE "id" = $1 AND "integration_id" = $2;`
_, err = tx.Exec(ctx, query, secret.Id, integrationId, secret.Name, secret.Description)
res = CustomIntegrationSecret{
Id: secret.Id,
IntegrationId: integrationId,
Name: secret.Name,
Description: secret.Description,
}
}
if err != nil {
return nil, err
}
newSecrets = append(newSecrets, res)
}
if err := tx.Commit(ctx); err != nil {
return nil, err
}
return newSecrets, nil
}
func (i *CustomIntegrationSecretsTable) Delete(ctx context.Context, id int) (err error) {
query := `
DELETE FROM custom_integration_secrets
WHERE "id" = $1;
`
_, err = i.Exec(ctx, query, id)
return
}