OSDN Git Service

new repo
[bytom/vapor.git] / vendor / github.com / btcsuite / btcd / database / example_test.go
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.
4
5 package database_test
6
7 import (
8         "bytes"
9         "fmt"
10         "os"
11         "path/filepath"
12
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"
18 )
19
20 // This example demonstrates creating a new database.
21 func ExampleCreate() {
22         // This example assumes the ffldb driver is imported.
23         //
24         // import (
25         //      "github.com/btcsuite/btcd/database"
26         //      _ "github.com/btcsuite/btcd/database/ffldb"
27         // )
28
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)
35         if err != nil {
36                 fmt.Println(err)
37                 return
38         }
39         defer os.RemoveAll(dbPath)
40         defer db.Close()
41
42         // Output:
43 }
44
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.
49         //
50         // import (
51         //      "github.com/btcsuite/btcd/database"
52         //      _ "github.com/btcsuite/btcd/database/ffldb"
53         // )
54
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)
61         if err != nil {
62                 fmt.Println(err)
63                 return
64         }
65         defer os.RemoveAll(dbPath)
66         defer db.Close()
67
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
75                 // simplicity.
76                 key := []byte("mykey")
77                 value := []byte("myvalue")
78                 if err := tx.Metadata().Put(key, value); err != nil {
79                         return err
80                 }
81
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)
85                 }
86
87                 // Create a new nested bucket under the metadata bucket.
88                 nestedBucketKey := []byte("mybucket")
89                 nestedBucket, err := tx.Metadata().CreateBucket(nestedBucketKey)
90                 if err != nil {
91                         return err
92                 }
93
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)
98                 }
99
100                 return nil
101         })
102         if err != nil {
103                 fmt.Println(err)
104                 return
105         }
106
107         // Output:
108 }
109
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
112 // fetch the block.
113 func Example_blockStorageAndRetrieval() {
114         // This example assumes the ffldb driver is imported.
115         //
116         // import (
117         //      "github.com/btcsuite/btcd/database"
118         //      _ "github.com/btcsuite/btcd/database/ffldb"
119         // )
120
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)
127         if err != nil {
128                 fmt.Println(err)
129                 return
130         }
131         defer os.RemoveAll(dbPath)
132         defer db.Close()
133
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
136         // and example.
137         err = db.Update(func(tx database.Tx) error {
138                 genesisBlock := chaincfg.MainNetParams.GenesisBlock
139                 return tx.StoreBlock(btcutil.NewBlock(genesisBlock))
140         })
141         if err != nil {
142                 fmt.Println(err)
143                 return
144         }
145
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)
152                 if err != nil {
153                         return err
154                 }
155
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)
162                 return nil
163         })
164         if err != nil {
165                 fmt.Println(err)
166                 return
167         }
168
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))
174
175         // Output:
176         // Serialized block size: 285 bytes
177 }