在BoltDB中,可以在嵌套的桶(bucket)下创建另一个嵌套的桶。

huangapple go评论73阅读模式
英文:

Can I have nested bucket under a nested bucket in boltdb?

问题

这是我需要创建嵌套桶的代码。它没有返回任何错误,但在创建嵌套桶时失败。

func CreateNestedBuckets(buckets []string) error {
	err := db.Update(func(tx *bolt.Tx) error {
		var bkt *bolt.Bucket
		var err error
		first := true
		for _, bucket := range buckets {
			log.Error(bucket)
			if first == true {
				bkt, err = tx.CreateBucketIfNotExists([]byte(bucket))
				first = false
			} else {
				bkt, err = bkt.CreateBucketIfNotExists([]byte(bucket))
			}
			if err != nil {
				log.Error("error creating nested bucket")
				return err
			}
		}
		return nil
	})
	if err != nil {
		log.Error("error creating nested bucket!!!")
		return err
	}
	return nil
}

请注意,这是一个示例代码,其中使用了一些未定义的变量和函数。你需要根据你的实际情况进行适当的修改和调整。

英文:

This is what I have to create nested buckets. It does not return any error but fails at creating nested bucket under another nested bucket.

func CreateNestedBuckets(buckets []string) error {
err := db.Update(func(tx *bolt.Tx) error {
	var bkt *bolt.Bucket
	var err error
	first := true
	for _, bucket := range buckets {
		log.Error(bucket)
		if first == true {
			bkt, err = tx.CreateBucketIfNotExists([]byte(bucket))
			first = false
		} else {
			bkt, err = bkt.CreateBucketIfNotExists([]byte(bucket))
		}
		if err != nil {
			log.Error("error creating nested bucket")
			return err
		}
	}
	return nil
})
if err != nil {
	log.Error("error creating nested bucket!!!")
	return err
}
return nil
}

答案1

得分: 3

简短回答:是的!你可以有嵌套的桶。

长回答:你的代码是可以正常工作的!以下是一些需要检查的事项:

  • 你是否检查了正确的 Bolt 数据库文件?Bolt DB 文件将会在你运行代码的目录中创建,除非你指定了绝对路径。
  • 你的输入是否包含足够的元素来创建嵌套结构?

我使用了以下设置运行了你的代码(进行了一些小的更改,但没有什么大的变动),它可以正常工作:

package main

import (
	"log"
	"os"
	"time"

	"github.com/boltdb/bolt"
)

var dbname = "test.bdb"
var dbperms os.FileMode = 0770
var options = &bolt.Options{Timeout: 1 * time.Second}

func main() {
	var names []string
	names = append(names, "bucketOne")
	names = append(names, "bucketTwo")
	names = append(names, "bucketThree")

	if err := CreateNestedBuckets(names); err != nil {
		log.Fatal(err)
	}
}

// CreateNestedBuckets - Function to create
// nested buckets from an array of Strings
func CreateNestedBuckets(buckets []string) error {
	db, dberr := bolt.Open(dbname, dbperms, options)
	if dberr != nil {
		log.Fatal(dberr)
	}
	defer db.Close()

	err := db.Update(func(tx *bolt.Tx) error {
		var bkt *bolt.Bucket
		var err error
		first := true
		for _, bucket := range buckets {
			log.Println(bucket)
			if first == true {
				bkt, err = tx.CreateBucketIfNotExists([]byte(bucket))
				first = false
			} else {
				bkt, err = bkt.CreateBucketIfNotExists([]byte(bucket))
			}
			if err != nil {
				log.Println("error creating nested bucket")
				return err
			}
		}
		return nil
	})
	if err != nil {
		log.Println("error creating nested bucket!!!")
		return err
	}
	return nil
}

要测试,你可以通过 strings 命令查看文件内容:

cat test.bdb | strings
bucketThree
bucketTwo
bucketOne

如果你使用的是 Windows,我不确定等效的命令是什么,但你可以用记事本打开文件并手动检查。虽然不会很美观,但你应该能看到桶的名称。

另外,你的错误处理会导致连续打印非常相似的消息。以下是一个稍微更清晰的解决方案:

// CreateNestedBucketsNew - function to create
// nested buckets from an array of Strings - my implementation
func CreateNestedBucketsNew(buckets []string) (err error) {
	err = db.Update(func(tx *bolt.Tx) (err error) {
		var bkt *bolt.Bucket

		for index, bucket := range buckets {
			if index == 0 {
				bkt, err = tx.CreateBucketIfNotExists([]byte(bucket))
			} else {
				bkt, err = bkt.CreateBucketIfNotExists([]byte(bucket))
			}

			if err != nil {
				return fmt.Errorf("Error creating nested bucket [%s]: %v", bucket, err)
			}
		}
		return err
	})
	return err
}
英文:

Short answer: yes! You can have nested buckets: https://twitter.com/boltdb/status/454730212010254336

Long answer: your code works fine! Heres some things to check though:

  • Are you checking the correct bolt database file? The botlt db file will be created in the directory you run your code from, unless you've specified an absolute path.
  • Does your input actually contain enough elements to create a nested structure?

I've ran your code with the following setup (a couple of small changes but nothing major) and it works fine:

package main
import (
"log"
"os"
"time"
"github.com/boltdb/bolt"
)
var dbname = "test.bdb"
var dbperms os.FileMode = 0770
var options = &bolt.Options{Timeout: 1 * time.Second}
func main() {
var names []string
names = append(names, "bucketOne")
names = append(names, "bucketTwo")
names = append(names, "bucketThree")
if err := CreateNestedBuckets(names); err != nil {
log.Fatal(err)
}
}
// CreateNestedBuckets - Function to create
// nested buckets from an array of Strings
func CreateNestedBuckets(buckets []string) error {
db, dberr := bolt.Open(dbname, dbperms, options)
if dberr != nil {
log.Fatal(dberr)
}
defer db.Close()
err := db.Update(func(tx *bolt.Tx) error {
var bkt *bolt.Bucket
var err error
first := true
for _, bucket := range buckets {
log.Println(bucket)
if first == true {
bkt, err = tx.CreateBucketIfNotExists([]byte(bucket))
first = false
} else {
bkt, err = bkt.CreateBucketIfNotExists([]byte(bucket))
}
if err != nil {
log.Println("error creating nested bucket")
return err
}
}
return nil
})
if err != nil {
log.Println("error creating nested bucket!!!")
return err
}
return nil
}

To test you can cat the file through the strings command:

cat test.bdb | strings
bucketThree
bucketTwo
bucketOne

If you're on Windows, I'm not sure what the equivalent command is, but you can open the file with Notepad and inspect it manually. It won't be pretty, but you should still see the name of your buckets in there.

On another note, you error handling is going to result in very similar messages being printed in succession. Here's a slightly cleaner solution you can use:

// CreateNestedBucketsNew - function to create
// nested buckets from an array of Strings - my implementation
func CreateNestedBucketsNew(buckets []string) (err error) {
err = db.Update(func(tx *bolt.Tx) (err error) {
var bkt *bolt.Bucket
for index, bucket := range buckets {
if index == 0 {
bkt, err = tx.CreateBucketIfNotExists([]byte(bucket))
} else {
bkt, err = bkt.CreateBucketIfNotExists([]byte(bucket))
}
if err != nil {
return fmt.Errorf("Error creating nested bucket [%s]: %v", bucket, err)
}
}
return err
})
return err
}

答案2

得分: 0

fste89的演示有一些调试信息;这是正确的代码:

package main

import (
	"fmt"
	"time"

	"github.com/boltdb/bolt"
)

func CreateNestedBuckets(fatherTable string, sonTables []string) error {
	db, dberr := bolt.Open("your file path", 0600, &bolt.Options{Timeout: 1 * time.Second})
	if dberr != nil {
		fmt.Println(dberr)
	}
	defer db.Close()

	err := db.Update(func(tx *bolt.Tx) error {
		var bkFather *bolt.Bucket
		var err error
		bkFather, err = tx.CreateBucketIfNotExists([]byte(fatherTable))

		for _, ta := range sonTables {
			fmt.Println(ta)

			_, err = bkFather.CreateBucketIfNotExists([]byte(ta))

			if err != nil {
				fmt.Println("error creating nested bucket")
				return err
			}
		}
		return nil
	})
	if err != nil {
		fmt.Println("error creating nested bucket!!!")
		return err
	}
	return nil
}

func main() {
	t := []string{"cc", "1", "2", "3"}
	fmt.Println(CreateNestedBuckets("sb", t))
}

输出结果:

cc
1
2
3
<nil>

可见:点击这里查看图片描述

英文:

fste89's demo has some debug;
this right:

package main
import (
&quot;fmt&quot;
&quot;time&quot;
&quot;github.com/boltdb/bolt&quot;
)
func CreateNestedBuckets(fatherTable string, sonTabls []string) error {
db, dberr := bolt.Open(&quot;your file path&quot;, 0600, &amp;bolt.Options{Timeout: 1 * time.Second})
if dberr != nil {
fmt.Println(dberr)
}
defer db.Close()
err := db.Update(func(tx *bolt.Tx) error {
var bkt *bolt.Bucket
var err error
bkFather, err = tx.CreateBucketIfNotExists([]byte(fatherTable))
for _, ta := range sonTabls {
fmt.Println(ta)
_, err = bkFather.CreateBucketIfNotExists([]byte(ta))
if err != nil {
fmt.Println(&quot;error creating nested bucket&quot;)
return err
}
}
return nil
})
if err != nil {
fmt.Println(&quot;error creating nested bucket!!!&quot;)
return err
}
return nil
}
func main() {
t := []string{&quot;cc&quot;, &quot;1&quot;, &quot;2&quot;, &quot;3&quot;}
fmt.Println(CreateNestedBuckets(&quot;sb&quot;, t))
}

echo:

cc
1
2
3
&lt;nil&gt;

Visible
enter image description here

答案3

得分: 0

func CreateNestedBuckets(fatherTable string, sonTables []string) error {
	db, dberr := bolt.Open("E:\\OneDrive\\code\\go\\project\\transmission\\static\\localstorage.db", 0600, &bolt.Options{Timeout: 1 * time.Second})
	if dberr != nil {
		fmt.Println(dberr)
	}
	defer db.Close()

	err := db.Update(func(tx *bolt.Tx) error {
		var err error
		bkFather, err := tx.CreateBucketIfNotExists([]byte(fatherTable))

		for _, ta := range sonTables {
			fmt.Println(ta)

			_, err = bkFather.CreateBucketIfNotExists([]byte(ta))

			if err != nil {
				fmt.Println("error creating nested bucket")
				return err
			}
		}
		return nil
	})
	if err != nil {
		fmt.Println("error creating nested bucket!!!")
		return err
	}
	return nil
}

<details>
<summary>英文:</summary>

func CreateNestedBuckets(fatherTable string, sonTables []string) error {
db, dberr := bolt.Open("E:\OneDrive\code\go\project\transmission\static\localstorage.db", 0600, &bolt.Options{Timeout: 1 * time.Second})
if dberr != nil {
fmt.Println(dberr)
}
defer db.Close()

err := db.Update(func(tx *bolt.Tx) error {
var err error
bkFather, err := tx.CreateBucketIfNotExists([]byte(fatherTable))
for _, ta := range sonTables {
fmt.Println(ta)
_, err = bkFather.CreateBucketIfNotExists([]byte(ta))
if err != nil {
fmt.Println(&quot;error creating nested bucket&quot;)
return err
}
}
return nil
})
if err != nil {
fmt.Println(&quot;error creating nested bucket!!!&quot;)
return err
}
return nil

}


</details>

huangapple
  • 本文由 发表于 2016年12月15日 10:04:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/41155255.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定