sermoni

"Service monitor" / cronjob status service
Log | Files | Refs

database.go (2540B)


      1 package database
      2 
      3 import (
      4 	"encoding/binary"
      5 	"errors"
      6 	"fmt"
      7 	"log"
      8 	"time"
      9 
     10 	"go.etcd.io/bbolt"
     11 )
     12 
     13 // bbolt bucket keys
     14 var (
     15 	BucketKeyConfig        = []byte("config")         // bucket key for config bucket key
     16 	BucketKeyEvents        = []byte("events")         // bucket key for events bucket
     17 	BucketKeyServices      = []byte("services")       // bucket key for services bucket
     18 	BucketKeyServiceTokens = []byte("service-tokens") // bucket key for service-tokens bucket
     19 )
     20 
     21 // ErrConfigBucket is returned when bbolt is unable to open the config bucket
     22 // TODO: I'm not sure if this is the idiomatic way to use errors
     23 var ErrConfigBucket = errors.New("unable to open config bucket")
     24 
     25 var db *bbolt.DB
     26 
     27 // check for fatal errors
     28 func check(err error) {
     29 	if err != nil {
     30 		log.Fatal(err)
     31 	}
     32 }
     33 
     34 // Open opens the database for the given file name or creates it if it doesn't exist.
     35 // Returns true if the database is already configured, false if it was just created.
     36 func Open(dbFileName string) (configured bool) {
     37 	var err error
     38 	db, err = bbolt.Open(dbFileName, 0600, &bbolt.Options{Timeout: 1 * time.Second})
     39 	check(err)
     40 	// Create the necessary bbolt buckets if they don't exist
     41 	db.Update(func(tx *bbolt.Tx) error {
     42 		configured = tx.Bucket(BucketKeyConfig) != nil
     43 		_, err = tx.CreateBucketIfNotExists(BucketKeyConfig)
     44 		check(err)
     45 		_, err = tx.CreateBucketIfNotExists(BucketKeyServices)
     46 		check(err)
     47 		_, err = tx.CreateBucketIfNotExists(BucketKeyEvents)
     48 		check(err)
     49 		_, err = tx.CreateBucketIfNotExists(BucketKeyServiceTokens)
     50 		check(err)
     51 		return nil
     52 	})
     53 	return configured
     54 }
     55 
     56 // Close is just a wrapper around db.Close() in order to keep all database
     57 // management in one file
     58 func Close() {
     59 	db.Close()
     60 }
     61 
     62 // GetDB gets the database structure
     63 func GetDB() *bbolt.DB {
     64 	return db
     65 }
     66 
     67 // BytesToUint64 converts a byte array to a uint64 number, an operation that is
     68 // often repeated for IDs. It is assumed that the data will parse successfully
     69 // (i.e. type checking is performed in an earlier stage).
     70 // If the parsing fails, the function therefore panics
     71 func BytesToUint64(b []byte) uint64 {
     72 	return binary.BigEndian.Uint64(b)
     73 }
     74 
     75 // Uint64ToBytes converts a uint64 formatted number to a byte array
     76 func Uint64ToBytes(ui64 uint64) (b []byte) {
     77 	b = make([]byte, 8)
     78 	binary.BigEndian.PutUint64(b, ui64)
     79 	return
     80 }
     81 
     82 // PrintBucket simply prints the K-V pairs in the bucket
     83 func PrintBucket(eb *bbolt.Bucket) error {
     84 	return eb.ForEach(func(k, v []byte) error {
     85 		fmt.Printf("- %v: %v\n", string(k), string(v))
     86 		return nil
     87 	})
     88 }