...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package fs
21
22 import (
23 "context"
24 "io"
25 "os"
26 "strings"
27
28 "github.com/go-kivik/kivik/v4/driver"
29 "github.com/go-kivik/kivik/v4/x/fsdb/cdb/decode"
30 )
31
32 type changes struct {
33 db *db
34 ctx context.Context
35 infos []os.FileInfo
36 }
37
38 var _ driver.Changes = &changes{}
39
40 func (c *changes) ETag() string { return "" }
41 func (c *changes) LastSeq() string { return "" }
42 func (c *changes) Pending() int64 { return 0 }
43
44 func ignoreDocID(name string) bool {
45 if name[0] != '_' {
46 return false
47 }
48 if strings.HasPrefix(name, "_design/") {
49 return false
50 }
51 if strings.HasPrefix(name, "_local/") {
52 return false
53 }
54 return true
55 }
56
57 func (c *changes) Next(ch *driver.Change) error {
58 for {
59 if len(c.infos) == 0 {
60 return io.EOF
61 }
62 candidate := c.infos[len(c.infos)-1]
63 c.infos = c.infos[:len(c.infos)-1]
64 if candidate.IsDir() {
65 continue
66 }
67 for _, ext := range decode.Extensions() {
68 if strings.HasSuffix(candidate.Name(), "."+ext) {
69 base := strings.TrimSuffix(candidate.Name(), "."+ext)
70 docid, err := filename2id(base)
71 if err != nil {
72
73 continue
74 }
75 if ignoreDocID(docid) {
76 continue
77 }
78 rev, deleted, err := c.db.metadata(candidate.Name(), ext)
79 if err != nil {
80 return err
81 }
82 if rev == "" {
83 rev = "1-"
84 }
85 ch.ID = docid
86 ch.Deleted = deleted
87 ch.Changes = []string{rev}
88 return nil
89 }
90 }
91 }
92 }
93
94 func (c *changes) Close() error {
95 return nil
96 }
97
98 func (d *db) Changes(ctx context.Context, _ driver.Options) (driver.Changes, error) {
99 f, err := os.Open(d.path())
100 if err != nil {
101 return nil, err
102 }
103 dir, err := f.Readdir(-1)
104 if err != nil {
105 return nil, err
106 }
107 return &changes{
108 db: d,
109 ctx: ctx,
110 infos: dir,
111 }, nil
112 }
113
View as plain text