@@ -21,7 +21,7 @@ import (
2121 _ "modernc.org/sqlite"
2222)
2323
24- const CURRENT_DB_VERSION = 6
24+ const CURRENT_DB_VERSION = 7
2525
2626// Metadata is the metadata persistence layer
2727type Metadata struct {
@@ -258,6 +258,18 @@ func (m *Metadata) VersionUpgrade(config *types.ServerConfig) error {
258258 }
259259 }
260260
261+ if version < 7 {
262+ m .Info ().Msg ("Upgrading to version 7" )
263+ if _ , err := tx .ExecContext (ctx , `create table keystore(key text, value ` + system .MapDataType (m .dbType , "blob" )+
264+ `, create_time ` + system .MapDataType (m .dbType , "datetime" )+ `, delete_at ` + system .MapDataType (m .dbType , "datetime" )+ `, PRIMARY KEY(key))` ); err != nil {
265+ return err
266+ }
267+
268+ if _ , err := tx .ExecContext (ctx , `update version set version=7, last_upgraded=` + system .FuncNow (m .dbType )); err != nil {
269+ return err
270+ }
271+ }
272+
261273 if err := tx .Commit (); err != nil {
262274 return err
263275 }
@@ -754,6 +766,78 @@ func (m *Metadata) GetConfig() (*types.DynamicConfig, error) {
754766 return & config , nil
755767}
756768
769+ func (m * Metadata ) FetchKV (ctx context.Context , key string ) (map [string ]any , error ) {
770+ row := m .db .QueryRowContext (ctx , system .RebindQuery (m .dbType , `select value from keystore where key = ? and (delete_at is null or delete_at > ` + system .FuncNow (m .dbType )+ `)` ), key )
771+ var value []byte
772+ err := row .Scan (& value )
773+ if err != nil {
774+ return nil , fmt .Errorf ("error querying keystore: %w" , err )
775+ }
776+
777+ var valueMap map [string ]any
778+ err = json .Unmarshal ([]byte (value ), & valueMap )
779+ if err != nil {
780+ return nil , fmt .Errorf ("error unmarshalling value: %w" , err )
781+ }
782+ return valueMap , nil
783+ }
784+
785+ func (m * Metadata ) StoreKV (ctx context.Context , key string , value map [string ]any , expireAt * time.Time ) error {
786+ valueJson , err := json .Marshal (value )
787+ if err != nil {
788+ return fmt .Errorf ("error marshalling value: %w" , err )
789+ }
790+ return m .StoreKVBlob (ctx , key , valueJson , expireAt )
791+ }
792+
793+ func (m * Metadata ) StoreKVBlob (ctx context.Context , key string , value []byte , expireAt * time.Time ) error {
794+ _ , err := m .db .ExecContext (ctx , system .RebindQuery (m .dbType ,
795+ `insert into keystore values (?, ?, ` + system .FuncNow (m .dbType )+ `, ?)` ), key , value , toNullTime (expireAt ))
796+ if err != nil {
797+ return fmt .Errorf ("error storing value: %w" , err )
798+ }
799+ return nil
800+ }
801+
802+ func (m * Metadata ) UpdateKV (ctx context.Context , key string , value map [string ]any ) error {
803+ valueJson , err := json .Marshal (value )
804+ if err != nil {
805+ return fmt .Errorf ("error marshalling value: %w" , err )
806+ }
807+ return m .UpdateKVBlob (ctx , key , valueJson )
808+ }
809+
810+ func (m * Metadata ) UpdateKVBlob (ctx context.Context , key string , value []byte ) error {
811+ result , err := m .db .ExecContext (ctx , system .RebindQuery (m .dbType ,
812+ `update keystore set value = ? where key = ?` ), value , key )
813+ if err != nil {
814+ return fmt .Errorf ("error updating value: %w" , err )
815+ }
816+ rowsAffected , err := result .RowsAffected ()
817+ if err != nil {
818+ return fmt .Errorf ("error getting rows affected: %w" , err )
819+ }
820+ if rowsAffected == 0 {
821+ return fmt .Errorf ("no key entry found with key for update: %s" , key )
822+ }
823+ return nil
824+ }
825+
826+ func (m * Metadata ) DeleteKV (ctx context.Context , key string ) error {
827+ _ , err := m .db .ExecContext (ctx , system .RebindQuery (m .dbType , `delete from keystore where key = ?` ), key )
828+ if err != nil {
829+ return fmt .Errorf ("error deleting value: %w" , err )
830+ }
831+ return nil
832+ }
833+
834+ func toNullTime (t * time.Time ) sql.NullTime {
835+ if t == nil {
836+ return sql.NullTime {Valid : false }
837+ }
838+ return sql.NullTime {Time : * t , Valid : true }
839+ }
840+
757841// BeginTransaction starts a new Transaction
758842func (m * Metadata ) BeginTransaction (ctx context.Context ) (types.Transaction , error ) {
759843 tx , err := m .db .BeginTx (ctx , nil )
0 commit comments