...
1
2
3
4
5
6
7
8
9
10
11
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
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
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