github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/storage/badger/operation/init.go (about) 1 package operation 2 3 import ( 4 "errors" 5 "fmt" 6 7 "github.com/dgraph-io/badger/v2" 8 9 "github.com/onflow/flow-go/storage" 10 ) 11 12 // marker used to denote a database type 13 type dbTypeMarker int 14 15 func (marker dbTypeMarker) String() string { 16 return [...]string{ 17 "dbMarkerPublic", 18 "dbMarkerSecret", 19 }[marker] 20 } 21 22 const ( 23 // dbMarkerPublic denotes the public database 24 dbMarkerPublic dbTypeMarker = iota 25 // dbMarkerSecret denotes the secrets database 26 dbMarkerSecret 27 ) 28 29 func InsertPublicDBMarker(txn *badger.Txn) error { 30 return insertDBTypeMarker(dbMarkerPublic)(txn) 31 } 32 33 func InsertSecretDBMarker(txn *badger.Txn) error { 34 return insertDBTypeMarker(dbMarkerSecret)(txn) 35 } 36 37 func EnsurePublicDB(db *badger.DB) error { 38 return ensureDBWithType(db, dbMarkerPublic) 39 } 40 41 func EnsureSecretDB(db *badger.DB) error { 42 return ensureDBWithType(db, dbMarkerSecret) 43 } 44 45 // insertDBTypeMarker inserts a database type marker if none exists. If a marker 46 // already exists in the database, this function will return an error if the 47 // marker does not match the argument, or return nil if it matches. 48 func insertDBTypeMarker(marker dbTypeMarker) func(*badger.Txn) error { 49 return func(txn *badger.Txn) error { 50 var storedMarker dbTypeMarker 51 err := retrieveDBType(&storedMarker)(txn) 52 if err != nil && !errors.Is(err, storage.ErrNotFound) { 53 return fmt.Errorf("could not check db type marker: %w", err) 54 } 55 56 // we retrieved a marker from storage 57 if err == nil { 58 // the marker in storage does not match - error 59 if storedMarker != marker { 60 return fmt.Errorf("could not store db type marker - inconsistent marker already stored (expected: %s, actual: %s)", marker, storedMarker) 61 } 62 // the marker is already in storage - we're done 63 return nil 64 } 65 66 // no marker in storage, insert it 67 return insert(makePrefix(codeDBType), marker)(txn) 68 } 69 } 70 71 // ensureDBWithType ensures the given database has been initialized with the 72 // given database type marker. If the given database has not been initialized 73 // with any marker, or with a different marker than expected, returns an error. 74 func ensureDBWithType(db *badger.DB, expectedMarker dbTypeMarker) error { 75 var actualMarker dbTypeMarker 76 err := db.View(retrieveDBType(&actualMarker)) 77 if err != nil { 78 return fmt.Errorf("could not get db type: %w", err) 79 } 80 if actualMarker != expectedMarker { 81 return fmt.Errorf("wrong db type (expected: %s, actual: %s)", expectedMarker, actualMarker) 82 } 83 return nil 84 } 85 86 func retrieveDBType(marker *dbTypeMarker) func(*badger.Txn) error { 87 return retrieve(makePrefix(codeDBType), marker) 88 }