feat(store): add FileInfoStore

This commit is contained in:
hexxa 2021-08-11 15:25:23 +08:00 committed by Hexxa
parent 834c577a71
commit c78692df52
4 changed files with 143 additions and 0 deletions

View file

@ -0,0 +1,52 @@
package userstore
import (
"github.com/ihexxa/quickshare/src/kvstore"
)
const (
InitNs = "Init"
SharingNs = "sharing"
InitTimeKey = "initTime"
)
type IFileInfoStore interface {
AddSharing(dirPath string) error
DelSharing(dirPath string) error
ListSharings(prefix string) (map[string]bool, error)
}
type FileInfoStore struct {
store kvstore.IKVStore
}
func NewFileInfoStore(store kvstore.IKVStore) (*FileInfoStore, error) {
_, ok := store.GetStringIn(InitNs, InitTimeKey)
if !ok {
var err error
for _, nsName := range []string{
InitNs,
SharingNs,
} {
if err = store.AddNamespace(nsName); err != nil {
return nil, err
}
}
}
return &FileInfoStore{
store: store,
}, nil
}
func (us *FileInfoStore) AddSharing(dirPath string) error {
return us.store.SetBoolIn(SharingNs, dirPath, true)
}
func (us *FileInfoStore) DelSharing(dirPath string) error {
return us.store.DelBoolIn(SharingNs, dirPath)
}
func (us *FileInfoStore) ListSharings(prefix string) (map[string]bool, error) {
return us.store.ListBoolsByPrefixIn(prefix, SharingNs)
}

View file

@ -0,0 +1,70 @@
package userstore
import (
"io/ioutil"
"os"
"testing"
"github.com/ihexxa/quickshare/src/kvstore/boltdbpvd"
)
func TestUserStores(t *testing.T) {
testSharingMethods := func(t *testing.T, store IFileInfoStore) {
dirPaths := []string{"admin/path1", "admin/path1/path2"}
var err error
for _, dirPath := range dirPaths {
err = store.AddSharing(dirPath)
if err != nil {
t.Fatal(err)
}
}
prefix := "admin"
sharingMap, err := store.ListSharings(prefix)
if err != nil {
t.Fatal(err)
}
for _, sharingDir := range dirPaths {
if !sharingMap[sharingDir] {
t.Fatalf("sharing(%s) not found", sharingDir)
}
}
for _, dirPath := range dirPaths {
err = store.DelSharing(dirPath)
if err != nil {
t.Fatal(err)
}
}
sharingMap, err = store.ListSharings(prefix)
if err != nil {
t.Fatal(err)
}
for _, dirPath := range dirPaths {
if sharingMap[dirPath] {
t.Fatalf("sharing(%s) should not exist", dirPath)
}
}
}
t.Run("testing FileInfoStore", func(t *testing.T) {
rootPath, err := ioutil.TempDir("./", "quickshare_userstore_test_")
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(rootPath)
kvstore := boltdbpvd.New(rootPath, 1024)
defer kvstore.Close()
store, err := NewFileInfoStore(kvstore)
if err != nil {
t.Fatal("fail to new kvstore", err)
}
testSharingMethods(t, store)
})
}

View file

@ -1,6 +1,7 @@
package boltdbpvd
import (
"bytes"
"encoding/binary"
"errors"
"fmt"
@ -154,6 +155,25 @@ func (bp *BoltPvd) ListBoolsIn(ns string) (map[string]bool, error) {
return list, err
}
func (bp *BoltPvd) ListBoolsByPrefixIn(prefix, ns string) (map[string]bool, error) {
results := map[string]bool{}
err := bp.db.View(func(tx *bolt.Tx) error {
b := tx.Bucket([]byte(ns)).Cursor()
if b == nil {
return ErrBucketNotFound
}
prefixBytes := []byte(prefix)
for k, _ := b.Seek(prefixBytes); k != nil && bytes.HasPrefix(k, prefixBytes); k, _ = b.Next() {
results[string(k)] = true
}
return nil
})
return results, err
}
func (bp *BoltPvd) GetInt(key string) (int, bool) {
x, ok := bp.GetInt64(key)
return int(x), ok

View file

@ -17,6 +17,7 @@ type IKVStore interface {
DelBoolIn(ns, key string) error
ListBools() (map[string]bool, error)
ListBoolsIn(ns string) (map[string]bool, error)
ListBoolsByPrefixIn(prefix, ns string) (map[string]bool, error)
GetInt(key string) (int, bool)
SetInt(key string, val int) error
DelInt(key string) error