1
2
3
4
5
6
7
8
9
10
11
12
13 package proxydb
14
15 import (
16 "bytes"
17 "context"
18 "encoding/json"
19 "errors"
20 "io"
21 "net/http"
22
23 "github.com/go-kivik/kivik/v4"
24 "github.com/go-kivik/kivik/v4/driver"
25 )
26
27 type statusError struct {
28 error
29 status int
30 }
31
32 func (e statusError) Unwrap() error { return e.error }
33 func (e statusError) HTTPStatus() int { return e.status }
34
35 var notYetImplemented = statusError{status: http.StatusNotImplemented, error: errors.New("kivik: not yet implemented in proxy driver")}
36
37
38
39 type CompleteClient interface {
40 driver.Client
41 }
42
43
44
45 func NewClient(c *kivik.Client) driver.Client {
46 return &client{c}
47 }
48
49 type client struct {
50 *kivik.Client
51 }
52
53 var _ CompleteClient = &client{}
54
55 func (c *client) AllDBs(ctx context.Context, options driver.Options) ([]string, error) {
56 return c.Client.AllDBs(ctx, options)
57 }
58
59 func (c *client) CreateDB(ctx context.Context, dbname string, options driver.Options) error {
60 return c.Client.CreateDB(ctx, dbname, options)
61 }
62
63 func (c *client) DBExists(ctx context.Context, dbname string, options driver.Options) (bool, error) {
64 return c.Client.DBExists(ctx, dbname, options)
65 }
66
67 func (c *client) DestroyDB(ctx context.Context, dbname string, options driver.Options) error {
68 return c.Client.DestroyDB(ctx, dbname, options)
69 }
70
71 func (c *client) Version(ctx context.Context) (*driver.Version, error) {
72 ver, err := c.Client.Version(ctx)
73 if err != nil {
74 return nil, err
75 }
76 return &driver.Version{
77 Version: ver.Version,
78 Vendor: ver.Vendor,
79 RawResponse: ver.RawResponse,
80 }, nil
81 }
82
83 func (c *client) DB(name string, options driver.Options) (driver.DB, error) {
84 d := c.Client.DB(name, options)
85 return &db{d}, nil
86 }
87
88 type db struct {
89 *kivik.DB
90 }
91
92 var _ driver.DB = &db{}
93
94 func (d *db) AllDocs(ctx context.Context, opts driver.Options) (driver.Rows, error) {
95 kivikRows := d.DB.AllDocs(ctx, opts)
96 return &rows{kivikRows}, kivikRows.Err()
97 }
98
99 func (d *db) Query(ctx context.Context, ddoc, view string, opts driver.Options) (driver.Rows, error) {
100 kivikRows := d.DB.Query(ctx, ddoc, view, opts)
101 return &rows{kivikRows}, kivikRows.Err()
102 }
103
104 type atts struct {
105 *kivik.AttachmentsIterator
106 }
107
108 var _ driver.Attachments = &atts{}
109
110 func (a *atts) Close() error { return nil }
111 func (a *atts) Next(att *driver.Attachment) error {
112 next, err := a.AttachmentsIterator.Next()
113 if err != nil {
114 return err
115 }
116 *att = driver.Attachment(*next)
117 return nil
118 }
119
120 func (d *db) Get(ctx context.Context, id string, opts driver.Options) (*driver.Document, error) {
121 row := d.DB.Get(ctx, id, opts)
122 rev, err := row.Rev()
123 if err != nil {
124 return nil, err
125 }
126 var doc json.RawMessage
127 if err := row.ScanDoc(&doc); err != nil {
128 return nil, err
129 }
130 attIter, err := row.Attachments()
131 if err != nil && kivik.HTTPStatus(err) != http.StatusNotFound {
132 return nil, err
133 }
134
135 var attachments *atts
136 if attIter != nil {
137 attachments = &atts{attIter}
138 }
139
140 return &driver.Document{
141 Rev: rev,
142 Body: io.NopCloser(bytes.NewReader(doc)),
143 Attachments: attachments,
144 }, nil
145 }
146
147 func (d *db) Stats(ctx context.Context) (*driver.DBStats, error) {
148 i, err := d.DB.Stats(ctx)
149 if err != nil {
150 return nil, err
151 }
152 var cluster *driver.ClusterStats
153 if i.Cluster != nil {
154 c := driver.ClusterStats(*i.Cluster)
155 cluster = &c
156 }
157 return &driver.DBStats{
158 Name: i.Name,
159 CompactRunning: i.CompactRunning,
160 DocCount: i.DocCount,
161 DeletedCount: i.DeletedCount,
162 UpdateSeq: i.UpdateSeq,
163 DiskSize: i.DiskSize,
164 ActiveSize: i.ActiveSize,
165 ExternalSize: i.ExternalSize,
166 Cluster: cluster,
167 RawResponse: i.RawResponse,
168 }, nil
169 }
170
171 func (d *db) Security(ctx context.Context) (*driver.Security, error) {
172 s, err := d.DB.Security(ctx)
173 if err != nil {
174 return nil, err
175 }
176 sec := driver.Security{
177 Admins: driver.Members(s.Admins),
178 Members: driver.Members(s.Members),
179 }
180 return &sec, err
181 }
182
183 func (d *db) SetSecurity(ctx context.Context, security *driver.Security) error {
184 sec := &kivik.Security{
185 Admins: kivik.Members(security.Admins),
186 Members: kivik.Members(security.Members),
187 }
188 return d.DB.SetSecurity(ctx, sec)
189 }
190
191 func (d *db) Changes(context.Context, driver.Options) (driver.Changes, error) {
192 return nil, notYetImplemented
193 }
194
195 func (d *db) BulkDocs(_ context.Context, _ []interface{}) ([]driver.BulkResult, error) {
196
197 return nil, notYetImplemented
198 }
199
200 func (d *db) PutAttachment(_ context.Context, _ string, _ *driver.Attachment, _ driver.Options) (string, error) {
201 panic("PutAttachment should never be called")
202 }
203
204 func (d *db) GetAttachment(_ context.Context, _, _ string, _ driver.Options) (*driver.Attachment, error) {
205 panic("GetAttachment should never be called")
206 }
207
208 func (d *db) GetAttachmentMeta(_ context.Context, _, _, _ string, _ driver.Options) (*driver.Attachment, error) {
209
210 return nil, notYetImplemented
211 }
212
213 func (d *db) CreateDoc(_ context.Context, _ interface{}, _ driver.Options) (string, string, error) {
214 panic("CreateDoc should never be called")
215 }
216
217 func (d *db) Delete(_ context.Context, _ string, _ driver.Options) (string, error) {
218 panic("Delete should never be called")
219 }
220
221 func (d *db) DeleteAttachment(_ context.Context, _, _ string, _ driver.Options) (string, error) {
222 panic("DeleteAttachment should never be called")
223 }
224
225 func (d *db) Put(_ context.Context, _ string, _ interface{}, _ driver.Options) (string, error) {
226 panic("Put should never be called")
227 }
228
View as plain text