github.com/Azareal/Gosora@v0.0.0-20210729070923-553e66b59003/common/meta/meta_store.go (about) 1 package common 2 3 import ( 4 "database/sql" 5 6 qgen "github.com/Azareal/Gosora/query_gen" 7 ) 8 9 // MetaStore is a simple key-value store for the system to stash things in when needed 10 type MetaStore interface { 11 Get(name string) (val string, err error) 12 Set(name, val string) error 13 SetInt(name string, val int) error 14 SetInt64(name string, val int64) error 15 } 16 17 type DefaultMetaStore struct { 18 get *sql.Stmt 19 set *sql.Stmt 20 add *sql.Stmt 21 } 22 23 func NewDefaultMetaStore(acc *qgen.Accumulator) (*DefaultMetaStore, error) { 24 t := "meta" 25 m := &DefaultMetaStore{ 26 get: acc.Select(t).Columns("value").Where("name=?").Prepare(), 27 set: acc.Update(t).Set("value=?").Where("name=?").Prepare(), 28 add: acc.Insert(t).Columns("name,value").Fields("?,''").Prepare(), 29 } 30 return m, acc.FirstError() 31 } 32 33 func (s *DefaultMetaStore) Get(name string) (val string, e error) { 34 e = s.get.QueryRow(name).Scan(&val) 35 return val, e 36 } 37 38 // TODO: Use timestamped rows as a more robust method of ensuring data integrity 39 func (s *DefaultMetaStore) setVal(name string, val interface{}) error { 40 _, e := s.Get(name) 41 if e == sql.ErrNoRows { 42 _, e := s.add.Exec(name) 43 if e != nil { 44 return e 45 } 46 } 47 _, e = s.set.Exec(val, name) 48 return e 49 } 50 51 func (s *DefaultMetaStore) Set(name, val string) error { 52 return s.setVal(name, val) 53 } 54 55 func (s *DefaultMetaStore) SetInt(name string, val int) error { 56 return s.setVal(name, val) 57 } 58 59 func (s *DefaultMetaStore) SetInt64(name string, val int64) error { 60 return s.setVal(name, val) 61 }