decred.org/dcrwallet/v3@v3.1.0/wallet/walletdb/example_test.go (about) 1 // Copyright (c) 2014 The btcsuite developers 2 // Copyright (c) 2015 The Decred developers 3 // Use of this source code is governed by an ISC 4 // license that can be found in the LICENSE file. 5 6 // Test must be updated for API changes. 7 //go:build disabled 8 9 package walletdb_test 10 11 import ( 12 "bytes" 13 "fmt" 14 "os" 15 "path/filepath" 16 17 "decred.org/dcrwallet/v3/errors" 18 _ "decred.org/dcrwallet/v3/wallet/internal/bdb" 19 "decred.org/dcrwallet/v3/wallet/walletdb" 20 ) 21 22 // This example demonstrates creating a new database. 23 func ExampleCreate() { 24 // This example assumes the bdb (bolt db) driver is imported. 25 // 26 // import ( 27 // "github.com/btcsuite/btcwallet/walletdb" 28 // _ "github.com/btcsuite/btcwallet/walletdb/bdb" 29 // ) 30 31 // Create a database and schedule it to be closed and removed on exit. 32 // Typically you wouldn't want to remove the database right away like 33 // this, but it's done here in the example to ensure the example cleans 34 // up after itself. 35 dbPath := filepath.Join(os.TempDir(), "examplecreate.db") 36 db, err := walletdb.Create("bdb", dbPath) 37 if err != nil { 38 fmt.Println(err) 39 return 40 } 41 defer os.Remove(dbPath) 42 defer db.Close() 43 44 // Output: 45 } 46 47 // exampleNum is used as a counter in the exampleLoadDB function to provided 48 // a unique database name for each example. 49 var exampleNum = 0 50 51 // exampleLoadDB is used in the examples to elide the setup code. 52 func exampleLoadDB() (walletdb.DB, func(), error) { 53 dbName := fmt.Sprintf("exampleload%d.db", exampleNum) 54 dbPath := filepath.Join(os.TempDir(), dbName) 55 db, err := walletdb.Create("bdb", dbPath) 56 if err != nil { 57 return nil, nil, err 58 } 59 teardownFunc := func() { 60 db.Close() 61 os.Remove(dbPath) 62 } 63 exampleNum++ 64 65 return db, teardownFunc, err 66 } 67 68 // This example demonstrates creating a new namespace. 69 func ExampleDB_namespace() { 70 // Load a database for the purposes of this example and schedule it to 71 // be closed and removed on exit. See the Create example for more 72 // details on what this step is doing. 73 db, teardownFunc, err := exampleLoadDB() 74 if err != nil { 75 fmt.Println(err) 76 return 77 } 78 defer teardownFunc() 79 80 // Get or create a namespace in the database as needed. This namespace 81 // is what is typically passed to specific sub-packages so they have 82 // their own area to work in without worrying about conflicting keys. 83 namespaceKey := []byte("walletsubpackage") 84 namespace, err := db.Namespace(namespaceKey) 85 if err != nil { 86 fmt.Println(err) 87 return 88 } 89 90 // Prevent unused error. Ordinarily the namespace would be used at this 91 // point to start a managed or manual transaction. 92 _ = namespace 93 94 // Output: 95 } 96 97 // This example demonstrates creating a new database, getting a namespace from 98 // it, and using a managed read-write transaction against the namespace to store 99 // and retrieve data. 100 func Example_basicUsage() { 101 // This example assumes the bdb (bolt db) driver is imported. 102 // 103 // import ( 104 // "github.com/btcsuite/btcwallet/walletdb" 105 // _ "github.com/btcsuite/btcwallet/walletdb/bdb" 106 // ) 107 108 // Create a database and schedule it to be closed and removed on exit. 109 // Typically you wouldn't want to remove the database right away like 110 // this, but it's done here in the example to ensure the example cleans 111 // up after itself. 112 dbPath := filepath.Join(os.TempDir(), "exampleusage.db") 113 db, err := walletdb.Create("bdb", dbPath) 114 if err != nil { 115 fmt.Println(err) 116 return 117 } 118 defer os.Remove(dbPath) 119 defer db.Close() 120 121 // Get or create a namespace in the database as needed. This namespace 122 // is what is typically passed to specific sub-packages so they have 123 // their own area to work in without worrying about conflicting keys. 124 namespaceKey := []byte("walletsubpackage") 125 namespace, err := db.Namespace(namespaceKey) 126 if err != nil { 127 fmt.Println(err) 128 return 129 } 130 131 // Use the Update function of the namespace to perform a managed 132 // read-write transaction. The transaction will automatically be rolled 133 // back if the supplied inner function returns a non-nil error. 134 err = namespace.Update(func(tx walletdb.Tx) error { 135 // All data is stored against the root bucket of the namespace, 136 // or nested buckets of the root bucket. It's not really 137 // necessary to store it in a separate variable like this, but 138 // it has been done here for the purposes of the example to 139 // illustrate. 140 rootBucket := tx.RootBucket() 141 142 // Store a key/value pair directly in the root bucket. 143 key := []byte("mykey") 144 value := []byte("myvalue") 145 if err := rootBucket.Put(key, value); err != nil { 146 return err 147 } 148 149 // Read the key back and ensure it matches. 150 if !bytes.Equal(rootBucket.Get(key), value) { 151 return errors.Errorf("unexpected value for key '%s'", key) 152 } 153 154 // Create a new nested bucket under the root bucket. 155 nestedBucketKey := []byte("mybucket") 156 nestedBucket, err := rootBucket.CreateBucket(nestedBucketKey) 157 if err != nil { 158 return err 159 } 160 161 // The key from above that was set in the root bucket does not 162 // exist in this new nested bucket. 163 if nestedBucket.Get(key) != nil { 164 return errors.Errorf("key '%s' is not expected nil", key) 165 } 166 167 return nil 168 }) 169 if err != nil { 170 fmt.Println(err) 171 return 172 } 173 174 // Output: 175 }