package boltutil import ( "time" "github.com/boltdb/bolt" "github.com/pkg/errors" ) var ( bucketKeyLabels = []byte("labels") bucketKeyCreatedAt = []byte("createdat") bucketKeyUpdatedAt = []byte("updatedat") ) // ReadLabels reads the labels key from the bucket // Uses the key "labels" func ReadLabels(bkt *bolt.Bucket) (map[string]string, error) { lbkt := bkt.Bucket(bucketKeyLabels) if lbkt == nil { return nil, nil } labels := map[string]string{} if err := lbkt.ForEach(func(k, v []byte) error { labels[string(k)] = string(v) return nil }); err != nil { return nil, err } return labels, nil } // WriteLabels will write a new labels bucket to the provided bucket at key // bucketKeyLabels, replacing the contents of the bucket with the provided map. // // The provide map labels will be modified to have the final contents of the // bucket. Typically, this removes zero-value entries. // Uses the key "labels" func WriteLabels(bkt *bolt.Bucket, labels map[string]string) error { // Remove existing labels to keep from merging if lbkt := bkt.Bucket(bucketKeyLabels); lbkt != nil { if err := bkt.DeleteBucket(bucketKeyLabels); err != nil { return err } } if len(labels) == 0 { return nil } lbkt, err := bkt.CreateBucket(bucketKeyLabels) if err != nil { return err } for k, v := range labels { if v == "" { delete(labels, k) // remove since we don't actually set it continue } if err := lbkt.Put([]byte(k), []byte(v)); err != nil { return errors.Wrapf(err, "failed to set label %q=%q", k, v) } } return nil } // ReadTimestamps reads created and updated timestamps from a bucket. // Uses keys "createdat" and "updatedat" func ReadTimestamps(bkt *bolt.Bucket, created, updated *time.Time) error { for _, f := range []struct { b []byte t *time.Time }{ {bucketKeyCreatedAt, created}, {bucketKeyUpdatedAt, updated}, } { v := bkt.Get(f.b) if v != nil { if err := f.t.UnmarshalBinary(v); err != nil { return err } } } return nil } // WriteTimestamps writes created and updated timestamps to a bucket. // Uses keys "createdat" and "updatedat" func WriteTimestamps(bkt *bolt.Bucket, created, updated time.Time) error { createdAt, err := created.MarshalBinary() if err != nil { return err } updatedAt, err := updated.MarshalBinary() if err != nil { return err } for _, v := range [][2][]byte{ {bucketKeyCreatedAt, createdAt}, {bucketKeyUpdatedAt, updatedAt}, } { if err := bkt.Put(v[0], v[1]); err != nil { return err } } return nil }