github.com/decred/dcrlnd@v0.7.6/kvdb/interface.go (about) 1 package kvdb 2 3 import ( 4 "github.com/btcsuite/btcwallet/walletdb" 5 ) 6 7 // Update opens a database read/write transaction and executes the function f 8 // with the transaction passed as a parameter. After f exits, if f did not 9 // error, the transaction is committed. Otherwise, if f did error, the 10 // transaction is rolled back. If the rollback fails, the original error 11 // returned by f is still returned. If the commit fails, the commit error is 12 // returned. As callers may expect retries of the f closure (depending on the 13 // database backend used), the reset function will be called before each retry 14 // respectively. 15 func Update(db Backend, f func(tx RwTx) error, reset func()) error { 16 return db.Update(f, reset) 17 } 18 19 // View opens a database read transaction and executes the function f with the 20 // transaction passed as a parameter. After f exits, the transaction is rolled 21 // back. If f errors, its error is returned, not a rollback error (if any 22 // occur). The passed reset function is called before the start of the 23 // transaction and can be used to reset intermediate state. As callers may 24 // expect retries of the f closure (depending on the database backend used), the 25 // reset function will be called before each retry respectively. 26 func View(db Backend, f func(tx RTx) error, reset func()) error { 27 return db.View(f, reset) 28 } 29 30 // Batch is identical to the Update call, but it attempts to combine several 31 // individual Update transactions into a single write database transaction on 32 // an optimistic basis. This only has benefits if multiple goroutines call 33 // Batch. For etcd Batch simply does an Update since combination is more complex 34 // in that case due to STM retries. 35 func Batch(db Backend, f func(tx RwTx) error) error { 36 // Fall back to the normal Update method if the backend doesn't support 37 // batching. 38 if _, ok := db.(walletdb.BatchDB); !ok { 39 // Since Batch calls handle external state reset, we can safely 40 // pass in an empty reset closure. 41 return db.Update(f, func() {}) 42 } 43 44 return walletdb.Batch(db, f) 45 } 46 47 // Create initializes and opens a database for the specified type. The 48 // arguments are specific to the database type driver. See the documentation 49 // for the database driver for further details. 50 // 51 // ErrDbUnknownType will be returned if the database type is not registered. 52 var Create = walletdb.Create 53 54 // Backend represents an ACID database. All database access is performed 55 // through read or read+write transactions. 56 type Backend = walletdb.DB 57 58 // Open opens an existing database for the specified type. The arguments are 59 // specific to the database type driver. See the documentation for the database 60 // driver for further details. 61 // 62 // ErrDbUnknownType will be returned if the database type is not registered. 63 var Open = walletdb.Open 64 65 // Driver defines a structure for backend drivers to use when they registered 66 // themselves as a backend which implements the Backend interface. 67 type Driver = walletdb.Driver 68 69 // RBucket represents a bucket (a hierarchical structure within the 70 // database) that is only allowed to perform read operations. 71 type RBucket = walletdb.ReadBucket 72 73 // RCursor represents a bucket cursor that can be positioned at the start or 74 // end of the bucket's key/value pairs and iterate over pairs in the bucket. 75 // This type is only allowed to perform database read operations. 76 type RCursor = walletdb.ReadCursor 77 78 // RTx represents a database transaction that can only be used for reads. If 79 // a database update must occur, use a RwTx. 80 type RTx = walletdb.ReadTx 81 82 // RwBucket represents a bucket (a hierarchical structure within the database) 83 // that is allowed to perform both read and write operations. 84 type RwBucket = walletdb.ReadWriteBucket 85 86 // RwCursor represents a bucket cursor that can be positioned at the start or 87 // end of the bucket's key/value pairs and iterate over pairs in the bucket. 88 // This abstraction is allowed to perform both database read and write 89 // operations. 90 type RwCursor = walletdb.ReadWriteCursor 91 92 // RwTx represents a database transaction that can be used for both reads and 93 // writes. When only reads are necessary, consider using a RTx instead. 94 type RwTx = walletdb.ReadWriteTx 95 96 // ExtendedRTx is an extension to walletdb.ReadTx to allow prefetching of keys. 97 type ExtendedRTx interface { 98 RTx 99 100 // RootBucket returns the "root bucket" which is pseudo bucket used 101 // when prefetching (keys from) top level buckets. 102 RootBucket() RBucket 103 } 104 105 // ExtendedRBucket is an extension to walletdb.ReadBucket to allow prefetching 106 // of all values inside buckets. 107 type ExtendedRBucket interface { 108 RBucket 109 110 // Prefetch will attempt to prefetch all values under a path. 111 Prefetch(paths ...[]string) 112 113 // ForAll is an optimized version of ForEach. 114 // 115 // NOTE: ForAll differs from ForEach in that no additional queries can 116 // be executed within the callback. 117 ForAll(func(k, v []byte) error) error 118 } 119 120 // Prefetch will attempt to prefetch all values under a path from the passed 121 // bucket. 122 func Prefetch(b RBucket, paths ...[]string) { 123 if bucket, ok := b.(ExtendedRBucket); ok { 124 bucket.Prefetch(paths...) 125 } 126 } 127 128 // ForAll is an optimized version of ForEach with the limitation that no 129 // additional queries can be executed within the callback. 130 func ForAll(b RBucket, cb func(k, v []byte) error) error { 131 if bucket, ok := b.(ExtendedRBucket); ok { 132 return bucket.ForAll(cb) 133 } 134 135 return b.ForEach(cb) 136 } 137 138 // RootBucket is a wrapper to ExtendedRTx.RootBucket which does nothing if 139 // the implementation doesn't have ExtendedRTx. 140 func RootBucket(t RTx) RBucket { 141 if tx, ok := t.(ExtendedRTx); ok { 142 return tx.RootBucket() 143 } 144 145 return nil 146 } 147 148 var ( 149 // ErrBucketNotFound is returned when trying to access a bucket that 150 // has not been created yet. 151 ErrBucketNotFound = walletdb.ErrBucketNotFound 152 153 // ErrBucketExists is returned when creating a bucket that already 154 // exists. 155 ErrBucketExists = walletdb.ErrBucketExists 156 157 // ErrDatabaseNotOpen is returned when a database instance is accessed 158 // before it is opened or after it is closed. 159 ErrDatabaseNotOpen = walletdb.ErrDbNotOpen 160 )