badgerkv

package module
v1.11.14 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 25, 2026 License: BSD-2-Clause Imports: 9 Imported by: 0

README

BadgerKV

Go Reference Go Report Card

BadgerKV is a Go library that provides a standardized key-value store interface built on top of BadgerDB. It implements the github.com/bborbe/kv interface, offering a clean and consistent API for database operations including transactions, buckets, and key-value operations.

Features

  • Standardized Interface: Implements the github.com/bborbe/kv interface for consistent database operations
  • Transaction Support: Full ACID transaction support with automatic rollback on errors
  • Bucket-based Organization: Organize data into logical buckets within transactions
  • Memory & Disk Storage: Support for both file-based and in-memory databases
  • Iterator Support: Forward and reverse iteration over bucket contents
  • Context-aware: Full context support for cancellation and deadlines
  • Thread-safe: Safe for concurrent use across multiple goroutines

Installation

go get github.com/bborbe/badgerkv

Quick Start

Basic Usage
package main

import (
    "context"
    "log"
    
    "github.com/bborbe/badgerkv"
)

func main() {
    ctx := context.Background()
    
    // Open a file-based database
    db, err := badgerkv.OpenPath(ctx, "/tmp/mydb")
    if err != nil {
        log.Fatal(err)
    }
    defer db.Close()
    
    // Start a transaction
    err = db.Update(ctx, func(ctx context.Context, tx badgerkv.Tx) error {
        // Get or create a bucket
        bucket, err := tx.CreateBucketIfNotExists([]byte("users"))
        if err != nil {
            return err
        }
        
        // Store a key-value pair
        return bucket.Put([]byte("user:1"), []byte(`{"name": "John", "age": 30}`))
    })
    if err != nil {
        log.Fatal(err)
    }
    
    // Read data
    err = db.View(ctx, func(ctx context.Context, tx badgerkv.Tx) error {
        bucket := tx.Bucket([]byte("users"))
        if bucket == nil {
            return nil // bucket doesn't exist
        }
        
        value, err := bucket.Get([]byte("user:1"))
        if err != nil {
            return err
        }
        
        log.Printf("User data: %s", value)
        return nil
    })
    if err != nil {
        log.Fatal(err)
    }
}
In-Memory Database
// Create an in-memory database (useful for testing)
db, err := badgerkv.OpenMemory(ctx)
if err != nil {
    log.Fatal(err)
}
defer db.Close()
Memory Optimization
// Use minimal memory settings for resource-constrained environments
db, err := badgerkv.OpenPath(ctx, "/tmp/mydb", badgerkv.MinMemoryUsageOptions)
if err != nil {
    log.Fatal(err)
}
defer db.Close()
Iteration
err = db.View(ctx, func(ctx context.Context, tx badgerkv.Tx) error {
    bucket := tx.Bucket([]byte("users"))
    if bucket == nil {
        return nil
    }
    
    // Forward iteration
    iter := bucket.Iterator()
    defer iter.Close()
    
    for iter.First(); iter.Valid(); iter.Next() {
        key := iter.Key().Data()
        value := iter.Item().Value()
        log.Printf("Key: %s, Value: %s", key, value)
    }
    
    return nil
})
Custom BadgerDB Options
import "github.com/dgraph-io/badger/v4"

// Define custom options
customOptions := func(opts *badger.Options) {
    opts.Logger = nil // Disable logging
    opts.SyncWrites = true // Force sync on writes
}

db, err := badgerkv.OpenPath(ctx, "/tmp/mydb", customOptions)

API Overview

Database Operations
  • OpenPath(ctx, path, ...options) - Open file-based database
  • OpenMemory(ctx, ...options) - Open in-memory database
  • DB.View(ctx, fn) - Read-only transaction
  • DB.Update(ctx, fn) - Read-write transaction
  • DB.Close() - Close database
Transaction Operations
  • Tx.Bucket(name) - Get existing bucket
  • Tx.CreateBucket(name) - Create new bucket (fails if exists)
  • Tx.CreateBucketIfNotExists(name) - Get or create bucket
  • Tx.DeleteBucket(name) - Delete bucket and all contents
Bucket Operations
  • Bucket.Get(key) - Retrieve value by key
  • Bucket.Put(key, value) - Store key-value pair
  • Bucket.Delete(key) - Delete key
  • Bucket.Iterator() - Create iterator for bucket contents
Iterator Operations
  • Iterator.First() - Move to first item
  • Iterator.Last() - Move to last item
  • Iterator.Next() - Move to next item
  • Iterator.Prev() - Move to previous item
  • Iterator.Valid() - Check if iterator position is valid
  • Iterator.Key() - Get current key
  • Iterator.Item() - Get current item

Transaction Context

BadgerKV prevents nested transactions by tracking transaction state in the context. Use IsTransactionOpen(ctx) to check if a transaction is already active.

if badgerkv.IsTransactionOpen(ctx) {
    // Already in a transaction, cannot start nested transaction
    return errors.New("nested transactions not supported")
}

Error Handling

BadgerKV uses the github.com/bborbe/errors package for enhanced error handling with context preservation:

err = db.Update(ctx, func(ctx context.Context, tx badgerkv.Tx) error {
    bucket, err := tx.CreateBucket([]byte("test"))
    if err != nil {
        return errors.Wrapf(ctx, err, "create bucket failed")
    }
    
    return bucket.Put([]byte("key"), []byte("value"))
})

if err != nil {
    log.Printf("Transaction failed: %v", err)
}

Testing

BadgerKV is thoroughly tested using Ginkgo v2 and Gomega:

# Run all tests
go test ./...

# Run tests with coverage
go test -cover ./...

# Run specific test
go test -run TestSpecificFunction ./...

Dependencies

  • BadgerDB v4: High-performance key-value database
  • github.com/bborbe/kv: Common key-value interface
  • github.com/bborbe/errors: Enhanced error handling
  • github.com/bborbe/collection: Utility functions

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Add tests for new functionality
  4. Run make precommit to ensure code quality
  5. Submit a pull request

License

This project is licensed under the BSD-style license. See the LICENSE file for details.

Documentation

Overview

Package badgerkv provides a standardized key-value store interface built on top of BadgerDB. It implements the github.com/bborbe/kv interface, offering a clean and consistent API for database operations including transactions, buckets, and key-value operations.

Basic usage:

// Open a file-based database
db, err := badgerkv.OpenPath(ctx, "/path/to/db")
if err != nil {
	return err
}
defer db.Close()

// Perform operations within a transaction
err = db.Update(ctx, func(ctx context.Context, tx badgerkv.Tx) error {
	bucket, err := tx.CreateBucketIfNotExists([]byte("users"))
	if err != nil {
		return err
	}
	return bucket.Put([]byte("user:1"), []byte(`{"name": "John"}`))
})

The package supports both file-based and in-memory databases, with full transaction support and bucket-based data organization.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func BucketAddKey

func BucketAddKey(bucket libkv.BucketName, key []byte) []byte

func BucketRemoveKey

func BucketRemoveKey(bucket libkv.BucketName, key []byte) []byte

func BucketToPrefix

func BucketToPrefix(bucket libkv.BucketName) []byte

func IsTransactionOpen

func IsTransactionOpen(ctx context.Context) bool

IsTransactionOpen checks if a transaction is currently active in the given context. BadgerKV prevents nested transactions, so this function can be used to verify transaction state before attempting database operations.

func MinMemoryUsageOptions

func MinMemoryUsageOptions(opts *badger.Options)

MinMemoryUsageOptions configures BadgerDB for minimal memory usage. This is useful for resource-constrained environments or when running multiple instances.

func SetOpenState

func SetOpenState(ctx context.Context) context.Context

SetOpenState marks the context as having an active transaction. This is used internally to prevent nested transactions.

Types

type Bucket

type Bucket interface {
	libkv.Bucket
	Tx() *badger.Txn
	BucketName() libkv.BucketName
}

func NewBucket

func NewBucket(
	badgerTx *badger.Txn,
	bucketName libkv.BucketName,
) Bucket

type ChangeOptions

type ChangeOptions func(opts *badger.Options)

type DB

type DB interface {
	libkv.DB
	DB() *badger.DB
}

func NewDB

func NewDB(db *badger.DB) DB

func OpenMemory

func OpenMemory(ctx context.Context, fn ...ChangeOptions) (DB, error)

OpenMemory opens an in-memory BadgerDB database. This is useful for testing or temporary data storage. Optional ChangeOptions functions can be provided to customize BadgerDB options.

Example:

db, err := badgerkv.OpenMemory(ctx)

func OpenPath

func OpenPath(ctx context.Context, path string, fn ...ChangeOptions) (DB, error)

OpenPath opens a file-based BadgerDB database at the specified path. Optional ChangeOptions functions can be provided to customize BadgerDB options.

Example:

db, err := badgerkv.OpenPath(ctx, "/tmp/mydb")
db, err := badgerkv.OpenPath(ctx, "/tmp/mydb", badgerkv.MinMemoryUsageOptions)

type Item

type Item interface {
	libkv.Item
	BucketName() libkv.BucketName
	Item() *badger.Item
}

func NewItem

func NewItem(
	bucketName libkv.BucketName,
	badgerItem *badger.Item,
) Item

type Iterator

type Iterator interface {
	libkv.Iterator
	BucketName() libkv.BucketName
	Iterator() *badger.Iterator
}

func NewIterator

func NewIterator(
	badgerTx *badger.Txn,
	bucketName libkv.BucketName,
) Iterator

func NewIteratorReverse

func NewIteratorReverse(
	badgerTx *badger.Txn,
	bucketName libkv.BucketName,
) Iterator

type Tx

type Tx interface {
	libkv.Tx
	Tx() *badger.Txn
}

func NewTx

func NewTx(badgerTx *badger.Txn) Tx

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL