Using BoltDB as internal database 💾

If you are looking for a small database for your fun project, I have something you might like. It is small, works as a key-value store and it’s pure go.



What is Bolt?

Bolt is a pure Go key/value store inspired by Howard Chu’s LMDB project. The goal of the project is to provide a simple, fast, and reliable database for projects that don’t require a full database server such as Postgres or MySQL.

Since Bolt is meant to be used as such a low-level piece of functionality, simplicity is key. The API will be small and only focus on getting values and setting values. That’s it.



How to use Bolt?



Installing

Bolt doesn’t need any install other than go get. It just works as a library. So your only need is adding it to go.mod file.

go get github.com/boltdb/bolt



Creating database

After you can create your database like this.

    db, err := bolt.Open("my.db", 0600, &bolt.Options)
    if err != nil 
        log.Fatal(err)
    
    defer db.Close()

In here you can add timeout to your database. Or you can set readonly if you don’t need writing into. Just set them in &bolt.Options.



Writing into database

You need to create bucket first. After than you can write your key/value data into bucket. Also tx.CreateBucketIfNotExists([]byte) function is life saver.

    db.Update(func(tx *bolt.Tx) error 
        bucket, err := tx.CreateBucketIfNotExists([]byte("todo"))
        if err != nil 
            return fmt.Errorf("create bucket: %s", err)
        
        return bucket.Put([]byte("task-1"), []byte("Test BoltDB"))
    )

If you have a bucket already you can write into it like this. Caution checking bucket is nil is important. Because if you try to use Put on nil bucket your program will panic.

    db.Update(func(tx *bolt.Tx) error 
        bucket := tx.Bucket([]byte("todo"))
        if bucket == nil 
            return fmt.Errorf("get bucket: FAILED")
        
        return bucket.Put([]byte("task-1"), []byte("Test BoltDB additions"))
    )



Querying data from database

Querying is as simple as writing. Just call your bucket and ask it for your data.

    db.View(func(tx *bolt.Tx) error 
        b := tx.Bucket([]byte("todo"))
        if b == nil 
            return fmt.Errorf("get bucket: FAILED")
        
        fmt.Println(b.Get([]byte("task-1")))
        // should return nil to complete the transaction
        return nil
    )

And here is simple way to iterate on all keys in one bucket.

    db.View(func(tx *bolt.Tx) error 
        b := tx.Bucket([]byte("todo"))
        if b == nil 
            return fmt.Errorf("get bucket: FAILED")
        
        // we need cursor for iteration
        c := b.Cursor()
        for k, v := c.First(); k != nil; k, v = c.Next() 
            fmt.Println("Key: ", string(k), " Value: ", string(v))
        
        // should return nil to complete the transaction
        return nil
    )



Conclusion

  • Bolt is a pure Go key/value store
  • Bolt is native go library
  • Bolt is supported everywhere which go is supported
  • Creating, Writing and Querying inside Bolt is really easy.



Simple and powerful toolkit for BoltDB

Storm is a simple and powerful toolkit for BoltDB. Basically, Storm provides indexes, a wide range of methods to store and fetch data, an advanced query system, and much more.
GitHub: https://github.com/asdine/storm



Future Readings


Source link