package database import ( "encoding/json" "log" "os" "git.phc.dm.unipi.it/phc/storage/store" ) type Database interface { Buckets() ([]string, error) CreateBucket(bucket string, options ...any) error Bucket(bucket string) (store.Store, error) } type bucketInfo struct { Name string `json:"name"` Path string `json:"path"` } type jsonDB struct { file string BucketsInfo map[string]bucketInfo `json:"buckets"` } func NewJSON(file string) Database { db := &jsonDB{ file: file, BucketsInfo: map[string]bucketInfo{}, } err := db.load() if err != nil { panic(err) } return db } func (db *jsonDB) setup() error { if _, err := os.Stat(db.file); !os.IsNotExist(err) { return nil } log.Printf("missing %q, creating empty database file", db.file) f, err := os.Create(db.file) defer f.Close() if err != nil { return err } enc := json.NewEncoder(f) enc.SetIndent("", " ") if err := enc.Encode(&db); err != nil { return err } return nil } func (db *jsonDB) store() error { f, err := os.Create(db.file) defer f.Close() if err != nil { return err } enc := json.NewEncoder(f) enc.SetIndent("", " ") if err := enc.Encode(&db); err != nil { return err } return nil } func (db *jsonDB) load() error { if err := db.setup(); err != nil { return err } f, err := os.Open(db.file) defer f.Close() if err != nil { return err } if err := json.NewDecoder(f).Decode(&db); err != nil { return err } return nil } func (db *jsonDB) Buckets() ([]string, error) { db.load() buckets := make([]string, 0, len(db.BucketsInfo)) for _, b := range db.BucketsInfo { buckets = append(buckets, b.Name) } return buckets, nil } func (db *jsonDB) CreateBucket(bucket string, options ...any) error { db.load() defer db.store() bi := bucketInfo{Name: bucket, Path: bucket + "/"} if len(options) > 0 { bi.Path = options[0].(string) } db.BucketsInfo[bucket] = bi return nil } func (db *jsonDB) Bucket(bucket string) (store.Store, error) { b := db.BucketsInfo[bucket] return &store.DirStore{ BaseDir: b.Path, Prefix: 2, }, nil }