| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657 |
- // Copyright (c) Tailscale Inc & AUTHORS
- // SPDX-License-Identifier: BSD-3-Clause
- // Package jsondb provides a trivial "database": a Go object saved to
- // disk as JSON.
- package jsondb
- import (
- "encoding/json"
- "errors"
- "io/fs"
- "os"
- "tailscale.com/atomicfile"
- )
- // DB is a database backed by a JSON file.
- type DB[T any] struct {
- // Data is the contents of the database.
- Data *T
- path string
- }
- // Open opens the database at path, creating it with a zero value if
- // necessary.
- func Open[T any](path string) (*DB[T], error) {
- bs, err := os.ReadFile(path)
- if errors.Is(err, fs.ErrNotExist) {
- return &DB[T]{
- Data: new(T),
- path: path,
- }, nil
- } else if err != nil {
- return nil, err
- }
- var val T
- if err := json.Unmarshal(bs, &val); err != nil {
- return nil, err
- }
- return &DB[T]{
- Data: &val,
- path: path,
- }, nil
- }
- // Save writes db.Data back to disk.
- func (db *DB[T]) Save() error {
- bs, err := json.Marshal(db.Data)
- if err != nil {
- return err
- }
- return atomicfile.WriteFile(db.path, bs, 0600)
- }
|