...

Source file src/github.com/go-kivik/kivik/v4/x/fsdb/put.go

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

     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 fs
    14  
    15  import (
    16  	"context"
    17  	"errors"
    18  	"net/http"
    19  	"net/url"
    20  	"os"
    21  	"strings"
    22  
    23  	"github.com/go-kivik/kivik/v4"
    24  	"github.com/go-kivik/kivik/v4/driver"
    25  	"github.com/go-kivik/kivik/v4/x/fsdb/cdb"
    26  	"github.com/go-kivik/kivik/v4/x/fsdb/cdb/decode"
    27  )
    28  
    29  func filename2id(filename string) (string, error) {
    30  	return url.PathUnescape(filename)
    31  }
    32  
    33  type metaDoc struct {
    34  	Rev     cdb.RevID `json:"_rev" yaml:"_rev"`
    35  	Deleted bool      `json:"_deleted" yaml:"_deleted"`
    36  }
    37  
    38  func (d *db) metadata(docID, ext string) (rev string, deleted bool, err error) {
    39  	f, err := os.Open(d.path(docID))
    40  	if err != nil {
    41  		if os.IsNotExist(err) {
    42  			err = nil
    43  		}
    44  		return "", false, err
    45  	}
    46  	md := new(metaDoc)
    47  	err = decode.Decode(f, ext, md)
    48  	return md.Rev.String(), md.Deleted, err
    49  }
    50  
    51  var reservedPrefixes = []string{"_local/", "_design/"}
    52  
    53  func validateID(id string) error {
    54  	if id[0] != '_' {
    55  		return nil
    56  	}
    57  	for _, prefix := range reservedPrefixes {
    58  		if strings.HasPrefix(id, prefix) && len(id) > len(prefix) {
    59  			return nil
    60  		}
    61  	}
    62  	return statusError{status: http.StatusBadRequest, error: errors.New("only reserved document ids may start with underscore")}
    63  }
    64  
    65  /*
    66  TODO:
    67  URL query params:
    68  batch
    69  new_edits
    70  
    71  output_format?
    72  
    73  X-Couch-Full-Commit header/option
    74  */
    75  
    76  func (d *db) Put(ctx context.Context, docID string, i interface{}, options driver.Options) (string, error) {
    77  	if err := validateID(docID); err != nil {
    78  		return "", err
    79  	}
    80  	rev, err := d.cdb.NewRevision(i)
    81  	if err != nil {
    82  		return "", err
    83  	}
    84  	doc, err := d.cdb.OpenDocID(docID, options)
    85  	switch {
    86  	case kivik.HTTPStatus(err) == http.StatusNotFound:
    87  		// Create new doc
    88  		doc = d.cdb.NewDocument(docID)
    89  	case err != nil:
    90  		return "", err
    91  	}
    92  	return doc.AddRevision(ctx, rev, options)
    93  }
    94  

View as plain text