1 // Copyright (c) 2015-2016 The btcsuite developers
2 // Use of this source code is governed by an ISC
3 // license that can be found in the LICENSE file.
13 "github.com/btcsuite/btcd/chaincfg"
14 "github.com/btcsuite/btcd/database"
15 _ "github.com/btcsuite/btcd/database/ffldb"
16 "github.com/btcsuite/btcd/wire"
17 "github.com/btcsuite/btcutil"
20 // This example demonstrates creating a new database.
21 func ExampleCreate() {
22 // This example assumes the ffldb driver is imported.
25 // "github.com/btcsuite/btcd/database"
26 // _ "github.com/btcsuite/btcd/database/ffldb"
29 // Create a database and schedule it to be closed and removed on exit.
30 // Typically you wouldn't want to remove the database right away like
31 // this, nor put it in the temp directory, but it's done here to ensure
32 // the example cleans up after itself.
33 dbPath := filepath.Join(os.TempDir(), "examplecreate")
34 db, err := database.Create("ffldb", dbPath, wire.MainNet)
39 defer os.RemoveAll(dbPath)
45 // This example demonstrates creating a new database and using a managed
46 // read-write transaction to store and retrieve metadata.
47 func Example_basicUsage() {
48 // This example assumes the ffldb driver is imported.
51 // "github.com/btcsuite/btcd/database"
52 // _ "github.com/btcsuite/btcd/database/ffldb"
55 // Create a database and schedule it to be closed and removed on exit.
56 // Typically you wouldn't want to remove the database right away like
57 // this, nor put it in the temp directory, but it's done here to ensure
58 // the example cleans up after itself.
59 dbPath := filepath.Join(os.TempDir(), "exampleusage")
60 db, err := database.Create("ffldb", dbPath, wire.MainNet)
65 defer os.RemoveAll(dbPath)
68 // Use the Update function of the database to perform a managed
69 // read-write transaction. The transaction will automatically be rolled
70 // back if the supplied inner function returns a non-nil error.
71 err = db.Update(func(tx database.Tx) error {
72 // Store a key/value pair directly in the metadata bucket.
73 // Typically a nested bucket would be used for a given feature,
74 // but this example is using the metadata bucket directly for
76 key := []byte("mykey")
77 value := []byte("myvalue")
78 if err := tx.Metadata().Put(key, value); err != nil {
82 // Read the key back and ensure it matches.
83 if !bytes.Equal(tx.Metadata().Get(key), value) {
84 return fmt.Errorf("unexpected value for key '%s'", key)
87 // Create a new nested bucket under the metadata bucket.
88 nestedBucketKey := []byte("mybucket")
89 nestedBucket, err := tx.Metadata().CreateBucket(nestedBucketKey)
94 // The key from above that was set in the metadata bucket does
95 // not exist in this new nested bucket.
96 if nestedBucket.Get(key) != nil {
97 return fmt.Errorf("key '%s' is not expected nil", key)
110 // This example demonstrates creating a new database, using a managed read-write
111 // transaction to store a block, and using a managed read-only transaction to
113 func Example_blockStorageAndRetrieval() {
114 // This example assumes the ffldb driver is imported.
117 // "github.com/btcsuite/btcd/database"
118 // _ "github.com/btcsuite/btcd/database/ffldb"
121 // Create a database and schedule it to be closed and removed on exit.
122 // Typically you wouldn't want to remove the database right away like
123 // this, nor put it in the temp directory, but it's done here to ensure
124 // the example cleans up after itself.
125 dbPath := filepath.Join(os.TempDir(), "exampleblkstorage")
126 db, err := database.Create("ffldb", dbPath, wire.MainNet)
131 defer os.RemoveAll(dbPath)
134 // Use the Update function of the database to perform a managed
135 // read-write transaction and store a genesis block in the database as
137 err = db.Update(func(tx database.Tx) error {
138 genesisBlock := chaincfg.MainNetParams.GenesisBlock
139 return tx.StoreBlock(btcutil.NewBlock(genesisBlock))
146 // Use the View function of the database to perform a managed read-only
147 // transaction and fetch the block stored above.
148 var loadedBlockBytes []byte
149 err = db.Update(func(tx database.Tx) error {
150 genesisHash := chaincfg.MainNetParams.GenesisHash
151 blockBytes, err := tx.FetchBlock(genesisHash)
156 // As documented, all data fetched from the database is only
157 // valid during a database transaction in order to support
158 // zero-copy backends. Thus, make a copy of the data so it
159 // can be used outside of the transaction.
160 loadedBlockBytes = make([]byte, len(blockBytes))
161 copy(loadedBlockBytes, blockBytes)
169 // Typically at this point, the block could be deserialized via the
170 // wire.MsgBlock.Deserialize function or used in its serialized form
171 // depending on need. However, for this example, just display the
172 // number of serialized bytes to show it was loaded as expected.
173 fmt.Printf("Serialized block size: %d bytes\n", len(loadedBlockBytes))
176 // Serialized block size: 285 bytes