github.com/btcsuite/btcwallet/walletdb@v1.4.2/example_test.go (about)

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