diff options
Diffstat (limited to 'src/dedo.go')
-rw-r--r-- | src/dedo.go | 130 |
1 files changed, 93 insertions, 37 deletions
diff --git a/src/dedo.go b/src/dedo.go index ae15ff2..f308b71 100644 --- a/src/dedo.go +++ b/src/dedo.go @@ -71,39 +71,46 @@ type CursorI interface{ Delete() error } -type BucketI interface{ +type ROBucketI interface{ Get([]byte) []byte + Cursor() CursorI + ForEach(func([]byte, []byte) error) error + ROBucket([]byte) (ROBucketI, error) +} + +type RWBucketI interface{ + Get([]byte) []byte + Cursor() CursorI + ForEach(func([]byte, []byte) error) error + RWBucket([]byte) (RWBucketI, error) Put([]byte, []byte) error Delete([]byte) error - ForEach(func([]byte, []byte) error) error - CreateBucket([]byte) (BucketI, error) - CreateBucketIfNotExists([]byte) (BucketI, error) + CreateBucket([]byte) (RWBucketI, error) + CreateBucketIfNotExists([]byte) (RWBucketI, error) DeleteBucket([]byte) error - Bucket([]byte) (BucketI, error) NextID() []byte NextSequence() (uint64, error) - Cursor() CursorI } type SnapshotI interface{ - Bucket([]byte) (BucketI, error) + ROBucket([]byte) (ROBucketI, error) Cursor() CursorI - ForEach(func([]byte, BucketI) error) error + ROForEach(func([]byte, ROBucketI) error) error WriteTo(io.Writer) (int64, error) Check() <-chan error } type TransactionI interface{ - Bucket([]byte) (BucketI, error) + RWBucket([]byte) (RWBucketI, error) Cursor() CursorI - ForEach(func([]byte, BucketI) error) error + RWForEach(func([]byte, RWBucketI) error) error WriteTo(io.Writer) (int64, error) Check() <-chan error - CreateBucket ([]byte) (BucketI, error) - CreateBucketIfNotExists([]byte) (BucketI, error) + CreateBucket ([]byte) (RWBucketI, error) + CreateBucketIfNotExists([]byte) (RWBucketI, error) DeleteBucket([]byte) error OnCommit(func()) } @@ -678,7 +685,11 @@ func bucketGetNested(b *bucketT, name []byte) (*bucketT, error) { return child, nil } -func (b *bucketT) Bucket(name []byte) (BucketI, error) { +func (b *bucketT) ROBucket(name []byte) (ROBucketI, error) { + return bucketGetNested(b, name) +} + +func (b *bucketT) RWBucket(name []byte) (RWBucketI, error) { return bucketGetNested(b, name) } @@ -749,7 +760,7 @@ func bucketCreateBucket(b *bucketT, key []byte) (*bucketT, error) { return bucketGetNested(b, key) } -func (b *bucketT) CreateBucket(key []byte) (BucketI, error) { +func (b *bucketT) CreateBucket(key []byte) (RWBucketI, error) { return bucketCreateBucket(b, key) } @@ -767,7 +778,7 @@ func bucketCreateBucketIfNotExists(b *bucketT, key []byte) (*bucketT, error) { return child, nil } -func (b *bucketT) CreateBucketIfNotExists(key []byte) (BucketI, error) { +func (b *bucketT) CreateBucketIfNotExists(key []byte) (RWBucketI, error) { return bucketCreateBucketIfNotExists(b, key) } @@ -1811,7 +1822,10 @@ func (cursor *inMemoryCursorT) Delete() error { return nil // FIXME } -func (bucket *inMemoryValueT) Bucket(name []byte) (BucketI, error) { +func memBucketGetNested( + bucket *inMemoryValueT, + name []byte, +) (*inMemoryValueT, error) { if bucket.tx.root == nil { return nil, ErrTxClosed } @@ -1828,7 +1842,15 @@ func (bucket *inMemoryValueT) Bucket(name []byte) (BucketI, error) { return value, nil } -func (bucket *inMemoryValueT) CreateBucket(name []byte) (BucketI, error) { +func (bucket *inMemoryValueT) ROBucket(name []byte) (ROBucketI, error) { + return memBucketGetNested(bucket, name) +} + +func (bucket *inMemoryValueT) RWBucket(name []byte) (RWBucketI, error) { + return memBucketGetNested(bucket, name) +} + +func (bucket *inMemoryValueT) CreateBucket(name []byte) (RWBucketI, error) { if bucket.tx.root == nil { return nil, ErrTxClosed } else if !bucket.tx.writable { @@ -1837,7 +1859,7 @@ func (bucket *inMemoryValueT) CreateBucket(name []byte) (BucketI, error) { return nil, ErrBucketNameRequired } - _, err := bucket.Bucket(name) + _, err := bucket.RWBucket(name) if err == nil { return nil, ErrBucketExists } @@ -1853,7 +1875,7 @@ func (bucket *inMemoryValueT) CreateBucket(name []byte) (BucketI, error) { return newBucket, nil } -func (bucket *inMemoryValueT) CreateBucketIfNotExists(name []byte) (BucketI, error) { +func (bucket *inMemoryValueT) CreateBucketIfNotExists(name []byte) (RWBucketI, error) { if bucket.tx.root == nil { return nil, ErrTxClosed } else if !bucket.tx.writable { @@ -1862,7 +1884,7 @@ func (bucket *inMemoryValueT) CreateBucketIfNotExists(name []byte) (BucketI, err newBucket, err := bucket.CreateBucket(name) if err == ErrBucketExists { - return bucket.Bucket(name) + return bucket.RWBucket(name) } else if err != nil { return nil, err } @@ -1956,20 +1978,28 @@ func (bucket *inMemoryValueT) NextSequence() (uint64, error) { return 0, nil // FIXME } -func (tx *inMemoryTxT) Bucket(name []byte) (BucketI, error) { +func memTxBucket(tx *inMemoryTxT, name []byte) (*inMemoryValueT, error) { if tx.root == nil { return nil, ErrTxClosed } - return tx.root.Bucket(name) + return memBucketGetNested(tx.root, name) +} + +func (tx *inMemoryTxT) ROBucket(name []byte) (ROBucketI, error) { + return memTxBucket(tx, name) +} + +func (tx *inMemoryTxT) RWBucket(name []byte) (RWBucketI, error) { + return memTxBucket(tx, name) } -func (tx *inMemoryTxT) CreateBucket(name []byte) (BucketI, error) { +func (tx *inMemoryTxT) CreateBucket(name []byte) (RWBucketI, error) { // return tx.root.CreateBucket(name) return nil, nil // FIXME } -func (tx *inMemoryTxT) CreateBucketIfNotExists(name []byte) (BucketI, error) { +func (tx *inMemoryTxT) CreateBucketIfNotExists(name []byte) (RWBucketI, error) { return nil, nil // FIXME } @@ -1985,7 +2015,11 @@ func (tx *inMemoryTxT) DeleteBucket(name []byte) error { return tx.root.DeleteBucket(name) } -func (tx *inMemoryTxT) ForEach(fn func([]byte, BucketI) error) error { +func (tx *inMemoryTxT) ROForEach(fn func([]byte, ROBucketI) error) error { + return nil // FIXME +} + +func (tx *inMemoryTxT) RWForEach(fn func([]byte, RWBucketI) error) error { return nil // FIXME } @@ -3800,7 +3834,11 @@ func txBucket(tx *transactionT, name []byte) (*bucketT, error) { return bucketGetNested(&tx.root, name) } -func (tx *transactionT) Bucket(name []byte) (BucketI, error) { +func (tx *transactionT) ROBucket(name []byte) (ROBucketI, error) { + return txBucket(tx, name) +} + +func (tx *transactionT) RWBucket(name []byte) (RWBucketI, error) { return txBucket(tx, name) } @@ -3812,7 +3850,7 @@ func txCreateBucket(tx *transactionT, name []byte) (*bucketT, error) { return bucketCreateBucket(&tx.root, name) } -func (tx *transactionT) CreateBucket(name []byte) (BucketI, error) { +func (tx *transactionT) CreateBucket(name []byte) (RWBucketI, error) { return txCreateBucket(tx, name) } @@ -3824,7 +3862,7 @@ func txCreateBucketIfNotExists(tx *transactionT, name []byte) (*bucketT, error) return bucketCreateBucketIfNotExists(&tx.root, name) } -func (tx *transactionT) CreateBucketIfNotExists(name []byte) (BucketI, error) { +func (tx *transactionT) CreateBucketIfNotExists(name []byte) (RWBucketI, error) { return txCreateBucketIfNotExists(tx, name) } @@ -3841,9 +3879,13 @@ func (tx *transactionT) DeleteBucket(name []byte) error { /// transactionT.ForEach() executes a function for each bucket in the root. If the /// provided function returns an error then the iteration is stopped and the /// error is returned to the caller. -func txForEach(tx *transactionT, fn func([]byte, BucketI) error) error { +func txForEach[T any]( + tx *transactionT, + fn func([]byte, T) error, + bucketFn func(*bucketT, []byte) (T, error), +) error { return tx.root.ForEach(func(k []byte, v []byte) error { - bucket, err := tx.root.Bucket(k) + bucket, err := bucketFn(&tx.root, k) if err != nil { return err } @@ -3851,8 +3893,22 @@ func txForEach(tx *transactionT, fn func([]byte, BucketI) error) error { }) } -func (tx *transactionT) ForEach(fn func([]byte, BucketI) error) error { - return txForEach(tx, fn) +func (tx *transactionT) ROForEach(fn func([]byte, ROBucketI) error) error { + return txForEach(tx, fn, func( + bucket *bucketT, + name []byte, + ) (ROBucketI, error) { + return bucket.ROBucket(name) + }) +} + +func (tx *transactionT) RWForEach(fn func([]byte, RWBucketI) error) error { + return txForEach(tx, fn, func( + bucket *bucketT, + name []byte, + ) (RWBucketI, error) { + return bucket.RWBucket(name) + }) } /// transactionT.OnCommit() adds a handler function to be executed after the transaction @@ -4327,7 +4383,7 @@ func checkExec(args argsT, db DatabaseI, _r io.Reader, _w io.Writer) error { func getExec(args argsT, db DatabaseI, r io.Reader, w io.Writer) error { return db.View(func(snapshot SnapshotI) error { - bucket, err := snapshot.Bucket(args.bucket) + bucket, err := snapshot.ROBucket(args.bucket) if err != nil { return err } @@ -4355,7 +4411,7 @@ func setExec(args argsT, db DatabaseI, r io.Reader, w io.Writer) error { func rmExec(args argsT, db DatabaseI, r io.Reader, w io.Writer) error { return db.Update(func(tx TransactionI) error { - bucket, err := tx.Bucket(args.bucket) + bucket, err := tx.RWBucket(args.bucket) if err != nil { return err } @@ -4367,16 +4423,16 @@ func rmExec(args argsT, db DatabaseI, r io.Reader, w io.Writer) error { func listExec(args argsT, db DatabaseI, r io.Reader, w io.Writer) error { return db.View(func(snapshot SnapshotI) error { if len(args.bucket) == 0 { - return snapshot.ForEach(func( + return snapshot.ROForEach(func( name []byte, - bucket BucketI, + bucket ROBucketI, ) error { fmt.Fprintf(w, "%s\n", string(name)) return nil }) } - bucket, err := snapshot.Bucket(args.bucket) + bucket, err := snapshot.ROBucket(args.bucket) if err != nil { return err } |