0

In my code I use alot of repeating code to iterate over nested buckets in a bolddb database. I would like to do some refactoring, wrapping these repeating codes into new functions.

I know I need to use closures for this, but the extra db.View layer gives me headaches.

More precisely, I would like to wrap the bucket.ForEach function into a new function. This function creates a view transaction of the database, selects the nested bucket and returns a new function that lets me iterate over the given bucket.

The code signature of the newly created code would be something like this:

ForEachBucket(bucket_name string, *bolt.DB) func() {}

The code that I want to wrap:

func ForEachBucket(bucketname string, db *bolt.DB)  {

    db.View(func(tx *bolt.Tx) error {
        rootBkt := tx.Bucket([]byte("rootbucket")) // always the same
        interestingBkt := rootBkt.Bucket([]byte(bucketname))
        if nestedBkt := interestingBkt.Bucket([]byte("underlying")); nestedBkt != nil {
            mapBkt.ForEach(func(k, v []byte) error {
                // do something here
                    }
            })
            return nil
        })
}

I want to create a new function (using closures) that wraps the above code and returns a foreach like function.

Timtico
  • 377
  • 1
  • 4
  • 14
  • what is the question? – Jiang YD Apr 09 '19 at 02:13
  • I clarified my post, is it ok like this? – Timtico Apr 09 '19 at 09:44
  • still no clear question. what you want, and what you tried, and what problem you met, finally what is the question about the problem. – Jiang YD Apr 09 '19 at 09:51
  • I would like to create a new function that replaces the code I've written: opening a new (read only) database transaction with `db.View`, selectiong the right rootbucket and underlying bucket with `tx.Bucket` . If I would only wrap one level of bucket selection and subsequent looping, I could write something like this: – Timtico Apr 09 '19 at 20:35

1 Answers1

0

I didn't actually catch what you want, but I'll try to answer.

You may have an callback argument that you pass to ForEach

    func ForEachBucket(db *bolt.DB, bucketname string, f func(b *bolt.Bucket) error {
        // ...
        return mapBucket.ForEach(f) // do not forget about returned error here
    }

More general: https://play.golang.org/p/LQlZHOWZTfi

Nikifor
  • 211
  • 1
  • 4