snapshot of https://github.com/blevesearch/bleve.git (master, 2026-09-15; blobs > 131072B omitted)
Some checks failed
Coverage / coverage (push) Failing after 6s
Tests / test (1.24.x, ubuntu-latest) (push) Failing after 42s
Tests / test (1.26.x, ubuntu-latest) (push) Failing after 38s
Tests / test (1.25.x, ubuntu-latest) (push) Failing after 35s
Tests / test (1.25.x, windows-latest) (push) Has been cancelled
Tests / test (1.26.x, macos-latest) (push) Has been cancelled
Tests / test (1.26.x, windows-latest) (push) Has been cancelled
Tests / test (1.24.x, macos-latest) (push) Has been cancelled
Tests / test (1.24.x, windows-latest) (push) Has been cancelled
Tests / test (1.25.x, macos-latest) (push) Has been cancelled
Some checks failed
Coverage / coverage (push) Failing after 6s
Tests / test (1.24.x, ubuntu-latest) (push) Failing after 42s
Tests / test (1.26.x, ubuntu-latest) (push) Failing after 38s
Tests / test (1.25.x, ubuntu-latest) (push) Failing after 35s
Tests / test (1.25.x, windows-latest) (push) Has been cancelled
Tests / test (1.26.x, macos-latest) (push) Has been cancelled
Tests / test (1.26.x, windows-latest) (push) Has been cancelled
Tests / test (1.24.x, macos-latest) (push) Has been cancelled
Tests / test (1.24.x, windows-latest) (push) Has been cancelled
Tests / test (1.25.x, macos-latest) (push) Has been cancelled
This commit is contained in:
170
util/bolt.go
Normal file
170
util/bolt.go
Normal file
@@ -0,0 +1,170 @@
|
||||
// Copyright (c) 2026 Couchbase, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package util
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
bolt "go.etcd.io/bbolt"
|
||||
)
|
||||
|
||||
// All of the bolt impls provide a layer of indirection to allow for processing
|
||||
// of values as they are read/written to bolt depending on the key or bucket name
|
||||
// This is used to allow better support for file callbacks
|
||||
|
||||
// wrapper around bolt.DB
|
||||
type RootBoltImpl struct {
|
||||
*bolt.DB
|
||||
}
|
||||
|
||||
// wrapper around bolt.Tx
|
||||
type BoltTxImpl struct {
|
||||
*bolt.Tx
|
||||
}
|
||||
|
||||
// wrapper around bolt.Bucket
|
||||
type BoltBucketImpl struct {
|
||||
*bolt.Bucket
|
||||
|
||||
name string // store the name of the bucket during creation
|
||||
}
|
||||
|
||||
func OpenBolt(path string, mode os.FileMode, options *bolt.Options) (*RootBoltImpl, error) {
|
||||
db, err := bolt.Open(path, mode, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &RootBoltImpl{DB: db}, nil
|
||||
}
|
||||
|
||||
func (r *RootBoltImpl) Begin(writable bool) (*BoltTxImpl, error) {
|
||||
tx, err := r.DB.Begin(writable)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &BoltTxImpl{Tx: tx}, nil
|
||||
}
|
||||
|
||||
func (r *RootBoltImpl) View(fn func(*BoltTxImpl) error) error {
|
||||
return r.DB.View(func(tx *bolt.Tx) error {
|
||||
return fn(&BoltTxImpl{Tx: tx})
|
||||
})
|
||||
}
|
||||
|
||||
func (r *RootBoltImpl) Update(fn func(*BoltTxImpl) error) error {
|
||||
return r.DB.Update(func(tx *bolt.Tx) error {
|
||||
return fn(&BoltTxImpl{Tx: tx})
|
||||
})
|
||||
}
|
||||
|
||||
func (tx *BoltTxImpl) CreateBucketIfNotExists(name []byte) (*BoltBucketImpl, error) {
|
||||
bucket, err := tx.Tx.CreateBucketIfNotExists(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &BoltBucketImpl{
|
||||
name: string(name),
|
||||
Bucket: bucket,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (tx *BoltTxImpl) Bucket(name []byte) *BoltBucketImpl {
|
||||
bucket := tx.Tx.Bucket(name)
|
||||
if bucket == nil {
|
||||
return nil
|
||||
}
|
||||
return &BoltBucketImpl{
|
||||
name: string(name),
|
||||
Bucket: bucket,
|
||||
}
|
||||
}
|
||||
|
||||
func (b *BoltBucketImpl) GetBucket(name []byte) *BoltBucketImpl {
|
||||
bucket := b.Bucket.Bucket(name)
|
||||
if bucket == nil {
|
||||
return nil
|
||||
}
|
||||
return &BoltBucketImpl{
|
||||
name: string(name),
|
||||
Bucket: bucket,
|
||||
}
|
||||
}
|
||||
|
||||
func (b *BoltBucketImpl) CreateBucketIfNotExists(name []byte) (*BoltBucketImpl, error) {
|
||||
bucket, err := b.Bucket.CreateBucketIfNotExists(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &BoltBucketImpl{
|
||||
name: string(name),
|
||||
Bucket: bucket,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Process values during ForEach if the bucket name or key is in the boltKeysProcessed map
|
||||
func (b *BoltBucketImpl) ForEach(fn func(key []byte, value []byte) error, reader FileReader) error {
|
||||
_, ok1 := boltKeysProcessed[b.name]
|
||||
return b.Bucket.ForEach(func(k, v []byte) error {
|
||||
v = append([]byte(nil), v...)
|
||||
if _, ok2 := boltKeysProcessed[string(k)]; ok1 || ok2 {
|
||||
if reader == nil {
|
||||
return fmt.Errorf("reader callback is required for bucket %s", b.name)
|
||||
}
|
||||
processedValue, err := reader.Process(v)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return fn(k, processedValue)
|
||||
}
|
||||
return fn(k, v)
|
||||
})
|
||||
}
|
||||
|
||||
// Process values during Put/Get if the bucket name or key is in the boltKeysProcessed map
|
||||
func (b *BoltBucketImpl) Put(key []byte, value []byte, writer FileWriter) error {
|
||||
_, ok1 := boltKeysProcessed[string(key)]
|
||||
_, ok2 := boltKeysProcessed[b.name]
|
||||
value = append([]byte(nil), value...)
|
||||
if ok1 || ok2 {
|
||||
if writer == nil {
|
||||
return fmt.Errorf("writer callback is required for key %s", string(key))
|
||||
}
|
||||
processedValue := writer.Process(value)
|
||||
return b.Bucket.Put(key, processedValue)
|
||||
}
|
||||
return b.Bucket.Put(key, value)
|
||||
}
|
||||
|
||||
// Process values during Put/Get if the bucket name or key is in the boltKeysProcessed map
|
||||
func (b *BoltBucketImpl) Get(key []byte, reader FileReader) ([]byte, error) {
|
||||
_, ok1 := boltKeysProcessed[string(key)]
|
||||
_, ok2 := boltKeysProcessed[b.name]
|
||||
if ok1 || ok2 {
|
||||
if reader == nil {
|
||||
return nil, fmt.Errorf("reader callback is required for key %s", string(key))
|
||||
}
|
||||
val := b.Bucket.Get(key)
|
||||
if val == nil {
|
||||
return nil, nil
|
||||
}
|
||||
processedVal, err := reader.Process(val)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return processedVal, nil
|
||||
}
|
||||
return b.Bucket.Get(key), nil
|
||||
}
|
||||
Reference in New Issue
Block a user