Compare commits
3 Commits
c2d7ae8d3e
...
aed641de42
Author | SHA1 | Date | |
---|---|---|---|
aed641de42 | |||
509f844f49 | |||
0d6298995f |
@ -4,6 +4,8 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/fs"
|
"io/fs"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
@ -51,6 +53,43 @@ func OpenDB(path string) *DB {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Discover will discover and initialize all existing bitcask stores at the path opened by [OpenDB].
|
||||||
|
func (db *DB) Discover() ([]string, error) {
|
||||||
|
db.mu.Lock()
|
||||||
|
defer db.mu.Unlock()
|
||||||
|
stores := make([]string, 0)
|
||||||
|
errs := make([]error, 0)
|
||||||
|
if db.store == nil {
|
||||||
|
db.store = make(map[string]Store)
|
||||||
|
}
|
||||||
|
entries, err := fs.ReadDir(os.DirFS(db.path), ".")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for _, entry := range entries {
|
||||||
|
if !entry.IsDir() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
name := entry.Name()
|
||||||
|
if _, ok := db.store[name]; ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
c, e := bitcask.Open(filepath.Join(db.path, name), defaultBitcaskOptions...)
|
||||||
|
if e != nil {
|
||||||
|
errs = append(errs, e)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
db.store[name] = Store{Bitcask: c}
|
||||||
|
stores = append(stores, name)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, e := range errs {
|
||||||
|
err = fmt.Errorf("%w: %w", err, e)
|
||||||
|
}
|
||||||
|
|
||||||
|
return stores, err
|
||||||
|
}
|
||||||
|
|
||||||
// Path returns the base path where we store our bitcask "stores".
|
// Path returns the base path where we store our bitcask "stores".
|
||||||
func (db *DB) Path() string {
|
func (db *DB) Path() string {
|
||||||
return db.path
|
return db.path
|
||||||
@ -138,11 +177,11 @@ func (db *DB) WithNew(storeName string, opts ...any) database.Filer {
|
|||||||
db.mu.RUnlock()
|
db.mu.RUnlock()
|
||||||
err := db.Init(storeName)
|
err := db.Init(storeName)
|
||||||
db.mu.RLock()
|
db.mu.RLock()
|
||||||
if err == nil {
|
if err != nil {
|
||||||
return db.store[storeName]
|
fmt.Println("error creating bitcask store: ", err)
|
||||||
|
|
||||||
}
|
}
|
||||||
fmt.Println("error creating bitcask store: ", err)
|
return db.store[storeName]
|
||||||
return Store{Bitcask: nil}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close is a simple shim for bitcask's Close function.
|
// Close is a simple shim for bitcask's Close function.
|
||||||
|
@ -14,24 +14,26 @@ import (
|
|||||||
"git.tcp.direct/tcp.direct/database"
|
"git.tcp.direct/tcp.direct/database"
|
||||||
)
|
)
|
||||||
|
|
||||||
func newTestDB(t *testing.T) database.Keeper {
|
func newTestDB(t *testing.T) (string, database.Keeper) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
tpath := t.TempDir()
|
tpath := t.TempDir()
|
||||||
tdb := OpenDB(tpath)
|
tdb := OpenDB(tpath)
|
||||||
if tdb == nil {
|
if tdb == nil {
|
||||||
t.Fatalf("failed to open testdb at %s, got nil", tpath)
|
t.Fatalf("failed to open testdb at %s, got nil", tpath)
|
||||||
}
|
}
|
||||||
return tdb
|
return tpath, tdb
|
||||||
}
|
}
|
||||||
|
|
||||||
func seedRandKV(db database.Keeper, store string) error {
|
func seedRandKV(db database.Keeper, store string) error {
|
||||||
return db.With(store).Put([]byte(c.RandStr(55)), []byte(c.RandStr(55)))
|
return db.With(store).Put([]byte(c.RandStr(55)), []byte(c.RandStr(55)))
|
||||||
}
|
}
|
||||||
|
|
||||||
func seedRandStores(db database.Keeper, t *testing.T) {
|
func seedRandStores(db database.Keeper, t *testing.T) []string {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
names := make([]string, 0)
|
||||||
for n := 0; n != 5; n++ {
|
for n := 0; n != 5; n++ {
|
||||||
randstore := c.RandStr(5)
|
randstore := c.RandStr(5)
|
||||||
|
names = append(names, randstore)
|
||||||
err := db.Init(randstore)
|
err := db.Init(randstore)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("failed to initialize store for test SyncAndCloseAll: %e", err)
|
t.Errorf("failed to initialize store for test SyncAndCloseAll: %e", err)
|
||||||
@ -42,10 +44,11 @@ func seedRandStores(db database.Keeper, t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
t.Logf("seeded random stores with random values for test %s", t.Name())
|
t.Logf("seeded random stores with random values for test %s", t.Name())
|
||||||
|
return names
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDB_Init(t *testing.T) { //nolint:funlen,gocognit,cyclop
|
func TestDB_Init(t *testing.T) { //nolint:funlen,gocognit,cyclop
|
||||||
var db = newTestDB(t)
|
var _, db = newTestDB(t)
|
||||||
type args struct{ storeName string }
|
type args struct{ storeName string }
|
||||||
type test struct {
|
type test struct {
|
||||||
name string
|
name string
|
||||||
@ -170,18 +173,36 @@ func TestDB_Init(t *testing.T) { //nolint:funlen,gocognit,cyclop
|
|||||||
db = nil
|
db = nil
|
||||||
})
|
})
|
||||||
t.Run("SyncAndCloseAll", func(t *testing.T) {
|
t.Run("SyncAndCloseAll", func(t *testing.T) {
|
||||||
db = newTestDB(t)
|
var path string
|
||||||
seedRandStores(db, t)
|
path, db = newTestDB(t)
|
||||||
|
names := seedRandStores(db, t)
|
||||||
err := db.SyncAndCloseAll()
|
err := db.SyncAndCloseAll()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("[FAIL] failed to SyncAndCloseAll: %e", err)
|
t.Errorf("[FAIL] failed to SyncAndCloseAll: %e", err)
|
||||||
}
|
}
|
||||||
|
db = OpenDB(path)
|
||||||
|
found, err := db.(*DB).Discover()
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("[FAIL] failed to discover stores: %e", err)
|
||||||
|
}
|
||||||
|
for _, n := range names {
|
||||||
|
matched := false
|
||||||
|
for _, f := range found {
|
||||||
|
if f == n {
|
||||||
|
matched = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !matched {
|
||||||
|
t.Errorf("[FAIL] failed to find store %s", n)
|
||||||
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func Test_Sync(t *testing.T) {
|
func Test_Sync(t *testing.T) {
|
||||||
// TODO: make sure sync is ACTUALLY sycing instead of only checking for nil err...
|
// TODO: make sure sync is ACTUALLY sycing instead of only checking for nil err...
|
||||||
var db = newTestDB(t)
|
var _, db = newTestDB(t)
|
||||||
seedRandStores(db, t)
|
seedRandStores(db, t)
|
||||||
t.Run("Sync", func(t *testing.T) {
|
t.Run("Sync", func(t *testing.T) {
|
||||||
for d := range db.(*DB).store {
|
for d := range db.(*DB).store {
|
||||||
@ -196,7 +217,7 @@ func Test_Sync(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func Test_Close(t *testing.T) {
|
func Test_Close(t *testing.T) {
|
||||||
var db = newTestDB(t)
|
var _, db = newTestDB(t)
|
||||||
defer func() {
|
defer func() {
|
||||||
db = nil
|
db = nil
|
||||||
}()
|
}()
|
||||||
@ -231,7 +252,7 @@ func Test_Close(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func Test_withAll(t *testing.T) {
|
func Test_withAll(t *testing.T) {
|
||||||
var db = newTestDB(t)
|
var _, db = newTestDB(t)
|
||||||
asdf1 := c.RandStr(10)
|
asdf1 := c.RandStr(10)
|
||||||
asdf2 := c.RandStr(10)
|
asdf2 := c.RandStr(10)
|
||||||
|
|
||||||
@ -247,7 +268,7 @@ func Test_withAll(t *testing.T) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
t.Run("withAllNilMap", func(t *testing.T) {
|
t.Run("withAllNilMap", func(t *testing.T) {
|
||||||
nilDb := newTestDB(t)
|
_, nilDb := newTestDB(t)
|
||||||
nilDb.(*DB).store = nil
|
nilDb.(*DB).store = nil
|
||||||
err := nilDb.(*DB).withAll(dclose)
|
err := nilDb.(*DB).withAll(dclose)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
@ -473,7 +494,7 @@ func Test_WithOptions(t *testing.T) { //nolint:funlen,gocognit,cyclop
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
t.Run("InitWithBogusOption", func(t *testing.T) {
|
t.Run("InitWithBogusOption", func(t *testing.T) {
|
||||||
db := newTestDB(t)
|
_, db := newTestDB(t)
|
||||||
err := db.Init("bogus", "yeet")
|
err := db.Init("bogus", "yeet")
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Errorf("[FAIL] Init should have failed with bogus option")
|
t.Errorf("[FAIL] Init should have failed with bogus option")
|
||||||
|
7
go.mod
7
go.mod
@ -4,9 +4,10 @@ go 1.18
|
|||||||
|
|
||||||
require (
|
require (
|
||||||
git.tcp.direct/Mirrors/bitcask-mirror v0.0.0-20220228092422-1ec4297c7e34
|
git.tcp.direct/Mirrors/bitcask-mirror v0.0.0-20220228092422-1ec4297c7e34
|
||||||
git.tcp.direct/kayos/common v0.8.6
|
git.tcp.direct/kayos/common v0.9.3
|
||||||
|
github.com/akrylysov/pogreb v0.10.1
|
||||||
github.com/davecgh/go-spew v1.1.1
|
github.com/davecgh/go-spew v1.1.1
|
||||||
github.com/hashicorp/go-multierror v1.1.1
|
github.com/hashicorp/go-multierror v1.0.0
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
@ -17,6 +18,6 @@ require (
|
|||||||
github.com/plar/go-adaptive-radix-tree v1.0.4 // indirect
|
github.com/plar/go-adaptive-radix-tree v1.0.4 // indirect
|
||||||
github.com/rs/zerolog v1.26.1 // indirect
|
github.com/rs/zerolog v1.26.1 // indirect
|
||||||
golang.org/x/exp v0.0.0-20200228211341-fcea875c7e85 // indirect
|
golang.org/x/exp v0.0.0-20200228211341-fcea875c7e85 // indirect
|
||||||
golang.org/x/sys v0.8.0 // indirect
|
golang.org/x/sys v0.13.0 // indirect
|
||||||
nullprogram.com/x/rng v1.1.0 // indirect
|
nullprogram.com/x/rng v1.1.0 // indirect
|
||||||
)
|
)
|
||||||
|
16
go.sum
16
go.sum
@ -39,15 +39,15 @@ cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9
|
|||||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||||
git.tcp.direct/Mirrors/bitcask-mirror v0.0.0-20220228092422-1ec4297c7e34 h1:tvoLGGLsQ0IYKKQPweMF5qRm3qO4gcTpuzi9jAr3Wkk=
|
git.tcp.direct/Mirrors/bitcask-mirror v0.0.0-20220228092422-1ec4297c7e34 h1:tvoLGGLsQ0IYKKQPweMF5qRm3qO4gcTpuzi9jAr3Wkk=
|
||||||
git.tcp.direct/Mirrors/bitcask-mirror v0.0.0-20220228092422-1ec4297c7e34/go.mod h1:NX/Gqm/iy6Tg2CfcmmB/kW/qzKKrGR6o2koOKA5KWnc=
|
git.tcp.direct/Mirrors/bitcask-mirror v0.0.0-20220228092422-1ec4297c7e34/go.mod h1:NX/Gqm/iy6Tg2CfcmmB/kW/qzKKrGR6o2koOKA5KWnc=
|
||||||
git.tcp.direct/kayos/common v0.8.2 h1:Usev4zpFLRFGTjQ+5vhReYSS/3+XGOgYbVufIWqMMW8=
|
git.tcp.direct/kayos/common v0.9.3 h1:MnQM4MH97zin+cloTsJRA3YEzagTGm/iR5sajpT+GoQ=
|
||||||
git.tcp.direct/kayos/common v0.8.2/go.mod h1:1XroljMDSTRybzyFGPTxs0gVb45YtH7wcehelU4koW8=
|
git.tcp.direct/kayos/common v0.9.3/go.mod h1:tTqUGj50mpwoQD0Zsdsv6cpDzN9VfjnQMgpDC8aRfms=
|
||||||
git.tcp.direct/kayos/common v0.8.6 h1:lt8nv+PrgAcbiOnbKUt7diza5hifR5fV3un6uIp/YVc=
|
|
||||||
git.tcp.direct/kayos/common v0.8.6/go.mod h1:QGGn7d2l4xBG7Cs/g84JzItPpHWjtfiyy+PSMnf6TzE=
|
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||||
github.com/abcum/lcp v0.0.0-20201209214815-7a3f3840be81 h1:uHogIJ9bXH75ZYrXnVShHIyywFiUZ7OOabwd9Sfd8rw=
|
github.com/abcum/lcp v0.0.0-20201209214815-7a3f3840be81 h1:uHogIJ9bXH75ZYrXnVShHIyywFiUZ7OOabwd9Sfd8rw=
|
||||||
github.com/abcum/lcp v0.0.0-20201209214815-7a3f3840be81/go.mod h1:6ZvnjTZX1LNo1oLpfaJK8h+MXqHxcBFBIwkgsv+xlv0=
|
github.com/abcum/lcp v0.0.0-20201209214815-7a3f3840be81/go.mod h1:6ZvnjTZX1LNo1oLpfaJK8h+MXqHxcBFBIwkgsv+xlv0=
|
||||||
|
github.com/akrylysov/pogreb v0.10.1 h1:FqlR8VR7uCbJdfUob916tPM+idpKgeESDXOA1K0DK4w=
|
||||||
|
github.com/akrylysov/pogreb v0.10.1/go.mod h1:pNs6QmpQ1UlTJKDezuRWmaqkgUE2TuU0YTWyqJZ7+lI=
|
||||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||||
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
||||||
@ -182,9 +182,8 @@ github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brv
|
|||||||
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
|
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
|
||||||
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
|
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
|
||||||
github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
|
github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
|
||||||
|
github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o=
|
||||||
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
|
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
|
||||||
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
|
|
||||||
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
|
|
||||||
github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
|
github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
|
||||||
github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
|
github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
|
||||||
github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
|
github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
|
||||||
@ -488,9 +487,8 @@ golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
|
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
|
||||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
@ -13,6 +13,8 @@ type Keeper interface {
|
|||||||
// WithNew should initialize a new Filer at the given path.
|
// WithNew should initialize a new Filer at the given path.
|
||||||
WithNew(name string, options ...any) Filer
|
WithNew(name string, options ...any) Filer
|
||||||
|
|
||||||
|
Discover() ([]string, error)
|
||||||
|
|
||||||
AllStores() map[string]Filer
|
AllStores() map[string]Filer
|
||||||
// TODO: Backups
|
// TODO: Backups
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user