我的需求:Go 应用程序中的一个简单的
map[string]string
,需要持久化到磁盘。我不想使用数据库,一个 json 文件就足够了,写入很少,不需要并行性。
数据内容:
{
"something" : "35b7bd1e-0eab-11ef-8a72-ef7c0dade844",
"something else" : "35b7bdf0-0eab-11ef-8a73-67ce44126d91"
}
对数据的基本操作是: 查找字符串,如果存在则返回 UUID,否则插入它,生成新的 uuid,然后返回。
我尝试使用jsonfile,但我不清楚如何在Read中使用Write
package main
import (
"log"
"os"
"crawshaw.dev/jsonfile"
)
type Data struct {
Identifiers map[string]string `json:"identifiers"`
}
func main() {
db, err := jsonfile.Load[Data]("resolver.json")
if os.IsNotExist(err) {
db, err = jsonfile.New[Data]("resolver.json")
}
if err != nil {
log.Fatal(err)
}
db.Read(func(d *Data) {
v, ok := d.Identifiers["MISSING-KEY"]
if !ok {
//
// HOW TO ADD THE MISSING KEY?
//
} else {
fmt.Println(v)
}
})
}
也许像这样?
package main
import (
"errors"
"fmt"
"io/fs"
"log"
"crawshaw.dev/jsonfile"
)
type Data struct {
Identifiers map[string]string `json:"identifiers"`
}
const (
dbPath = "resolver.json"
missingKey = "MISSING-KEY"
missingValue = "Hello, world"
)
func main() {
db, err := jsonfile.Load[Data](dbPath)
if errors.Is(err, fs.ErrNotExist) {
db, err = jsonfile.New[Data](dbPath)
}
if err != nil {
log.Fatal(err)
}
err = readWrite(db)
if err != nil {
log.Fatal(err)
}
}
func readWrite(db *jsonfile.JSONFile[Data]) error {
var keyExists bool
db.Read(func(d *Data) {
var v string
v, keyExists = d.Identifiers[missingKey]
if keyExists {
fmt.Println(v)
}
})
if keyExists {
return nil
}
return db.Write(func(d *Data) error {
if d.Identifiers == nil {
d.Identifiers = make(map[string]string)
}
d.Identifiers[missingKey] = missingValue
return nil
})
}
请注意,这可能存在轻微的竞争条件 - 当两个任务读取缺少密钥的同一文件时,第二个任务会覆盖第一个任务的密钥。如果密钥已经存在,我可以检查
db.Write
,但鉴于您的用例,我没有打扰。