-
Notifications
You must be signed in to change notification settings - Fork 0
/
instances.go
152 lines (122 loc) · 3.62 KB
/
instances.go
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
146
147
148
149
150
151
152
package turso
import (
"context"
"errors"
"fmt"
"net/http"
)
type Instance struct {
Uuid string
Name string
Type string
Region string
Hostname string
}
type InstancesClient client
type CreateInstanceLocationError struct {
err string
}
func (e *CreateInstanceLocationError) Error() string {
return e.err
}
func (c *InstancesClient) List(ctx context.Context, db string) ([]Instance, error) {
res, err := c.client.Get(ctx, c.URL(db, ""), nil)
if err != nil {
return nil, fmt.Errorf("failed to list instances of %s: %s", db, err)
}
defer res.Body.Close()
if c.client.isNotMemberErr(res.StatusCode) {
return nil, c.client.notMemberErr()
}
if res.StatusCode != http.StatusOK {
return nil, fmt.Errorf("response with status code %d", res.StatusCode)
}
type ListResponse struct{ Instances []Instance }
resp, err := unmarshal[ListResponse](res)
if err != nil {
return nil, err
}
return resp.Instances, nil
}
func (c *InstancesClient) Delete(ctx context.Context, db, instance string) error {
url := c.URL(db, "/"+instance)
res, err := c.client.Delete(ctx, url, nil)
if err != nil {
return fmt.Errorf("failed to destroy instances %s of %s: %s", instance, db, err)
}
defer res.Body.Close()
if c.client.isNotMemberErr(res.StatusCode) {
return c.client.notMemberErr()
}
if res.StatusCode == http.StatusBadRequest {
body, _ := unmarshal[struct{ Error string }](res)
return errors.New(body.Error)
}
if res.StatusCode == http.StatusNotFound {
body, _ := unmarshal[struct{ Error string }](res)
return errors.New(body.Error)
}
if res.StatusCode != http.StatusOK {
return fmt.Errorf("response with status code %d", res.StatusCode)
}
return nil
}
func (c *InstancesClient) Create(ctx context.Context, dbName, location string) (*Instance, error) {
type Body struct {
Location string
}
body, err := marshal(Body{location})
if err != nil {
return nil, fmt.Errorf("could not serialize request body: %w", err)
}
url := c.URL(dbName, "")
res, err := c.client.Post(ctx, url, body)
if err != nil {
return nil, fmt.Errorf("failed to create new instances for %s: %s", dbName, err)
}
defer res.Body.Close()
if c.client.isNotMemberErr(res.StatusCode) {
return nil, c.client.notMemberErr()
}
if res.StatusCode >= http.StatusInternalServerError {
return nil, &CreateInstanceLocationError{fmt.Sprintf("failed to create new instance: %s", res.Status)}
}
if res.StatusCode != http.StatusOK {
return nil, parseResponseError(res)
}
data, err := unmarshal[struct{ Instance Instance }](res)
if err != nil {
return nil, fmt.Errorf("failed to deserialize response: %w", err)
}
return &data.Instance, nil
}
func (c *InstancesClient) Wait(ctx context.Context, db, instance string) error {
url := c.URL(db, "/"+instance+"/wait")
res, err := c.client.Get(ctx, url, nil)
if err != nil {
return fmt.Errorf("failed to wait for instance %s to of %s be ready: %s", instance, db, err)
}
defer res.Body.Close()
if c.client.isNotMemberErr(res.StatusCode) {
return c.client.notMemberErr()
}
if res.StatusCode == http.StatusBadRequest {
body, _ := unmarshal[struct{ Error string }](res)
return errors.New(body.Error)
}
if res.StatusCode == http.StatusNotFound {
body, _ := unmarshal[struct{ Error string }](res)
return errors.New(body.Error)
}
if res.StatusCode != http.StatusOK {
return fmt.Errorf("response with status code %d", res.StatusCode)
}
return nil
}
func (d *InstancesClient) URL(database, suffix string) string {
prefix := "/v1"
if d.client.Org != "" {
prefix = "/v1/organizations/" + d.client.Org
}
return fmt.Sprintf("%s/databases/%s/instances%s", prefix, database, suffix)
}