diff --git a/internal/utils/kvstore/store.go b/internal/utils/kvstore/store.go index f3f7658..6eee28f 100644 --- a/internal/utils/kvstore/store.go +++ b/internal/utils/kvstore/store.go @@ -13,6 +13,7 @@ import ( "github.com/iwind/TeaGo/Tea" "io" "os" + "path/filepath" "strings" "sync" ) @@ -52,6 +53,31 @@ func NewStore(storeName string) (*Store, error) { }, nil } +// NewStoreWithPath create store with path +func NewStoreWithPath(path string) (*Store, error) { + if !strings.HasSuffix(path, ".store") { + return nil, errors.New("store path must contains a '.store' suffix") + } + + _, err := os.Stat(path) + if err != nil && os.IsNotExist(err) { + _ = os.MkdirAll(path, 0777) + } + + var storeName = filepath.Base(path) + storeName = strings.TrimSuffix(storeName, ".store") + + if !IsValidName(storeName) { + return nil, errors.New("invalid store name '" + storeName + "'") + } + + return &Store{ + name: storeName, + path: path, + locker: fsutils.NewLocker(path + "/.fs"), + }, nil +} + func OpenStore(storeName string) (*Store, error) { store, err := NewStore(storeName) if err != nil { @@ -117,6 +143,10 @@ func DefaultStore() (*Store, error) { return defaultSore, resultErr } +func (this *Store) Path() string { + return this.path +} + func (this *Store) Open() error { err := this.locker.Lock() if err != nil { diff --git a/internal/utils/kvstore/table.go b/internal/utils/kvstore/table.go index 0216b72..9d017bd 100644 --- a/internal/utils/kvstore/table.go +++ b/internal/utils/kvstore/table.go @@ -196,12 +196,15 @@ func (this *Table[T]) ReadTx(fn func(tx *Tx[T]) error) error { return NewTableClosedErr(this.name) } - var tx = NewTx[T](this, true) + tx, err := NewTx[T](this, true) + if err != nil { + return err + } defer func() { _ = tx.Close() }() - err := fn(tx) + err = fn(tx) if err != nil { return err } @@ -214,12 +217,15 @@ func (this *Table[T]) WriteTx(fn func(tx *Tx[T]) error) error { return NewTableClosedErr(this.name) } - var tx = NewTx[T](this, false) + tx, err := NewTx[T](this, false) + if err != nil { + return err + } defer func() { _ = tx.Close() }() - err := fn(tx) + err = fn(tx) if err != nil { return err } @@ -232,12 +238,15 @@ func (this *Table[T]) WriteTxSync(fn func(tx *Tx[T]) error) error { return NewTableClosedErr(this.name) } - var tx = NewTx[T](this, false) + tx, err := NewTx[T](this, false) + if err != nil { + return err + } defer func() { _ = tx.Close() }() - err := fn(tx) + err = fn(tx) if err != nil { return err } diff --git a/internal/utils/kvstore/tx.go b/internal/utils/kvstore/tx.go index 6b047f6..070c06f 100644 --- a/internal/utils/kvstore/tx.go +++ b/internal/utils/kvstore/tx.go @@ -15,12 +15,22 @@ type Tx[T any] struct { batch *pebble.Batch } -func NewTx[T any](table *Table[T], readOnly bool) *Tx[T] { +func NewTx[T any](table *Table[T], readOnly bool) (*Tx[T], error) { + if table.db == nil { + return nil, errors.New("the table has not been added to a db") + } + if table.db.store == nil { + return nil, errors.New("the db has not been added to a store") + } + if table.db.store.rawDB == nil { + return nil, errors.New("the store has not been opened") + } + return &Tx[T]{ table: table, readOnly: readOnly, batch: table.db.store.rawDB.NewIndexedBatch(), - } + }, nil } func (this *Tx[T]) Set(key string, value T) error {