github.com/go-kivik/kivik/v4@v4.3.2/x/proxydb/proxy.go (about) 1 // Licensed under the Apache License, Version 2.0 (the "License"); you may not 2 // use this file except in compliance with the License. You may obtain a copy of 3 // the License at 4 // 5 // http://www.apache.org/licenses/LICENSE-2.0 6 // 7 // Unless required by applicable law or agreed to in writing, software 8 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 9 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 // License for the specific language governing permissions and limitations under 11 // the License. 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 // CompleteClient is a composite of all compulsory and optional driver.* client 38 // interfaces. 39 type CompleteClient interface { 40 driver.Client 41 } 42 43 // NewClient wraps an existing *kivik.Client connection, allowing it to be used 44 // as a driver.Client 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 // FIXME: Unimplemented 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 // FIXME: Unimplemented 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 }