...

Source file src/github.com/go-kivik/kivik/v4/x/proxydb/proxy.go

Documentation: github.com/go-kivik/kivik/v4/x/proxydb

     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  }
   228  

View as plain text