nuts

package module
v0.4.0 Latest Latest
Warning

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

Go to latest
Published: Oct 27, 2019 License: MIT Imports: 2 Imported by: 92

README

Nuts - BoltDB Utilities

GoDoc Go Report Card Coverage Status

A collection of BoltDB utilities.

Path Prefix Scans

The prefix scanning functions SeekPathConflict and SeekPathMatch facilitate maintenance and access to buckets of paths supporting variable elements with exclusive matches. Paths are / delimited, must begin with a /, and elements beginning with : or * are variable.

Examples:

/
/blogs/
/blogs/:blog_id
Variable Elements

Path elements beginning with a : match any single element. Path elements beginning with * match any remaining elements, and therefore must be last.

Examples:

Path:  /blogs/:blog_id
Match: /blogs/someblog
Path:  /blogs/:blog_id/comments/:comment_id/*suffix
Match: /blogs/42/comments/100/edit
Exclusive Matches

Using SeekPathConflict before putting new paths to ensure the bucket remains conflict-free guarantees that SeekPathMatch will never match more than one path.

Examples:

Conflicts: `/blogs/:blog_id`, `/blogs/golang`
Match:     `/blogs/golang`
Conflicts: `/blogs/*`, `/blogs/:blog_id/comments`
Match:     `/blogs/42/comments`

Documentation

Overview

Package nuts is a collection of utilities for BoltDB (https://github.com/boltdb/bolt).

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func KeyLen

func KeyLen(x uint64) int

KeyLen returns the minimum number of bytes required to represent x; the result is 1 for x == 0. Returns 1-8.

func SeekPathConflict

func SeekPathConflict(c *bolt.Cursor, path []byte) ([]byte, []byte)

SeekPathConflict seeks an entry which conflicts with `path`, and returns the first encountered or `nil, nil` if none is found.

Example
exDB(func(db *bolt.DB) {
	insert := func(path string) {
		if err := db.Update(func(tx *bolt.Tx) error {
			b, err := tx.CreateBucketIfNotExists(bucketName)
			if err != nil {
				return err
			}

			// Check for conflicts.
			if k, _ := SeekPathConflict(b.Cursor(), []byte(path)); k != nil {
				fmt.Printf("Put(%s) blocked - conflict: %s\n", path, string(k))
				return nil
			}

			// Put.
			if err := b.Put([]byte(path), []byte{}); err != nil {
				return err
			}
			fmt.Printf("Put(%s)\n", path)
			return nil
		}); err != nil {
			log.Fatal(err)
		}
	}
	// Put
	insert("/blogs/")
	// Put
	insert("/blogs/:blog_id")
	// Conflict
	insert("/blogs/a_blog")
})
Output:

Put(/blogs/)
Put(/blogs/:blog_id)
Put(/blogs/a_blog) blocked - conflict: /blogs/:blog_id

func SeekPathMatch

func SeekPathMatch(c *bolt.Cursor, path []byte) ([]byte, []byte)

SeekPathMatch seeks an entry which matches `path`, or returns `nil, nil` when no match is found. Returned key may be `path`, or a matching dynamic path. Matches are exclusive if the set of keys are conflict free (see SeekPathConflict).

Example
exDB(func(db *bolt.DB) {
	if err := db.Update(func(tx *bolt.Tx) error {
		b, err := tx.CreateBucket(bucketName)
		if err != nil {
			return err
		}

		// Put a variable path.
		return b.Put([]byte("/blogs/:blog_id/comments/:comment_id"), []byte{})
	}); err != nil {
		log.Fatal(err)
	}

	if err := db.View(func(tx *bolt.Tx) error {
		b := tx.Bucket(bucketName)

		// Match path.
		path, _ := SeekPathMatch(b.Cursor(), []byte("/blogs/asdf/comments/42"))
		fmt.Println(string(path))

		return nil
	}); err != nil {
		log.Fatal(err)
	}
})
Output:

/blogs/:blog_id/comments/:comment_id

Types

type Buckets added in v0.2.0

type Buckets interface {
	Bucket([]byte) *bolt.Bucket
	CreateBucket([]byte) (*bolt.Bucket, error)
	CreateBucketIfNotExists([]byte) (*bolt.Bucket, error)
	DeleteBucket([]byte) error
	Cursor() *bolt.Cursor
}

Buckets is a collection of methods for managing bolt.Buckets which is satisfied by *bolt.Tx and *bolt.Bucket.

type Key

type Key []byte

Key is a byte slice with methods for serializing uint64 (big endian). Length can minimized (<8) with KeyLen.

make(Key, KeyLen(uint64(max)))

Large Keys can constructed by slicing.

uuid := make(Key, 16)
uuid[:8].Put(a)
uuid[8:].Put(b)

func (Key) Put

func (c Key) Put(x uint64)

Put serializes x into the buffer (big endian). Behavior is undefined when x does not fit, so the caller must ensure c is large enough.

Directories

Path Synopsis
cmd
testdb
Command testdb recursively walks the directory given as the first (and only) argument, and copies paths from .txt files into .db BoltDB database files by the same name.
Command testdb recursively walks the directory given as the first (and only) argument, and copies paths from .txt files into .db BoltDB database files by the same name.
testpaths
Command testpaths generates files with one path per line.
Command testpaths generates files with one path per line.

Jump to

Keyboard shortcuts

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