github.com/BlockABC/godash@v0.0.0-20191112120524-f4aa3a32c566/database/example_test.go (about)

     1  // Copyright (c) 2015-2016 The btcsuite developers
     2  // Copyright (c) 2016 The Dash developers
     3  // Use of this source code is governed by an ISC
     4  // license that can be found in the LICENSE file.
     5  
     6  package database_test
     7  
     8  import (
     9  	"bytes"
    10  	"fmt"
    11  	"os"
    12  	"path/filepath"
    13  
    14  	"github.com/BlockABC/godash/chaincfg"
    15  	"github.com/BlockABC/godash/database"
    16  	_ "github.com/BlockABC/godash/database/ffldb"
    17  	"github.com/BlockABC/godash/wire"
    18  	"github.com/BlockABC/godashutil"
    19  )
    20  
    21  // This example demonstrates creating a new database.
    22  func ExampleCreate() {
    23  	// This example assumes the ffldb driver is imported.
    24  	//
    25  	// import (
    26  	// 	"github.com/BlockABC/godash/database"
    27  	// 	_ "github.com/BlockABC/godash/database/ffldb"
    28  	// )
    29  
    30  	// Create a database and schedule it to be closed and removed on exit.
    31  	// Typically you wouldn't want to remove the database right away like
    32  	// this, nor put it in the temp directory, but it's done here to ensure
    33  	// the example cleans up after itself.
    34  	dbPath := filepath.Join(os.TempDir(), "examplecreate")
    35  	db, err := database.Create("ffldb", dbPath, wire.MainNet)
    36  	if err != nil {
    37  		fmt.Println(err)
    38  		return
    39  	}
    40  	defer os.RemoveAll(dbPath)
    41  	defer db.Close()
    42  
    43  	// Output:
    44  }
    45  
    46  // This example demonstrates creating a new database and using a managed
    47  // read-write transaction to store and retrieve metadata.
    48  func Example_basicUsage() {
    49  	// This example assumes the ffldb driver is imported.
    50  	//
    51  	// import (
    52  	// 	"github.com/BlockABC/godash/database"
    53  	// 	_ "github.com/BlockABC/godash/database/ffldb"
    54  	// )
    55  
    56  	// Create a database and schedule it to be closed and removed on exit.
    57  	// Typically you wouldn't want to remove the database right away like
    58  	// this, nor put it in the temp directory, but it's done here to ensure
    59  	// the example cleans up after itself.
    60  	dbPath := filepath.Join(os.TempDir(), "exampleusage")
    61  	db, err := database.Create("ffldb", dbPath, wire.MainNet)
    62  	if err != nil {
    63  		fmt.Println(err)
    64  		return
    65  	}
    66  	defer os.RemoveAll(dbPath)
    67  	defer db.Close()
    68  
    69  	// Use the Update function of the database to perform a managed
    70  	// read-write transaction.  The transaction will automatically be rolled
    71  	// back if the supplied inner function returns a non-nil error.
    72  	err = db.Update(func(tx database.Tx) error {
    73  		// Store a key/value pair directly in the metadata bucket.
    74  		// Typically a nested bucket would be used for a given feature,
    75  		// but this example is using the metadata bucket directly for
    76  		// simplicity.
    77  		key := []byte("mykey")
    78  		value := []byte("myvalue")
    79  		if err := tx.Metadata().Put(key, value); err != nil {
    80  			return err
    81  		}
    82  
    83  		// Read the key back and ensure it matches.
    84  		if !bytes.Equal(tx.Metadata().Get(key), value) {
    85  			return fmt.Errorf("unexpected value for key '%s'", key)
    86  		}
    87  
    88  		// Create a new nested bucket under the metadata bucket.
    89  		nestedBucketKey := []byte("mybucket")
    90  		nestedBucket, err := tx.Metadata().CreateBucket(nestedBucketKey)
    91  		if err != nil {
    92  			return err
    93  		}
    94  
    95  		// The key from above that was set in the metadata bucket does
    96  		// not exist in this new nested bucket.
    97  		if nestedBucket.Get(key) != nil {
    98  			return fmt.Errorf("key '%s' is not expected nil", key)
    99  		}
   100  
   101  		return nil
   102  	})
   103  	if err != nil {
   104  		fmt.Println(err)
   105  		return
   106  	}
   107  
   108  	// Output:
   109  }
   110  
   111  // This example demonstrates creating a new database, using a managed read-write
   112  // transaction to store a block, and using a managed read-only transaction to
   113  // fetch the block.
   114  func Example_blockStorageAndRetrieval() {
   115  	// This example assumes the ffldb driver is imported.
   116  	//
   117  	// import (
   118  	// 	"github.com/BlockABC/godash/database"
   119  	// 	_ "github.com/BlockABC/godash/database/ffldb"
   120  	// )
   121  
   122  	// Create a database and schedule it to be closed and removed on exit.
   123  	// Typically you wouldn't want to remove the database right away like
   124  	// this, nor put it in the temp directory, but it's done here to ensure
   125  	// the example cleans up after itself.
   126  	dbPath := filepath.Join(os.TempDir(), "exampleblkstorage")
   127  	db, err := database.Create("ffldb", dbPath, wire.MainNet)
   128  	if err != nil {
   129  		fmt.Println(err)
   130  		return
   131  	}
   132  	defer os.RemoveAll(dbPath)
   133  	defer db.Close()
   134  
   135  	// Use the Update function of the database to perform a managed
   136  	// read-write transaction and store a genesis block in the database as
   137  	// and example.
   138  	err = db.Update(func(tx database.Tx) error {
   139  		genesisBlock := chaincfg.MainNetParams.GenesisBlock
   140  		return tx.StoreBlock(godashutil.NewBlock(genesisBlock))
   141  	})
   142  	if err != nil {
   143  		fmt.Println(err)
   144  		return
   145  	}
   146  
   147  	// Use the View function of the database to perform a managed read-only
   148  	// transaction and fetch the block stored above.
   149  	var loadedBlockBytes []byte
   150  	err = db.Update(func(tx database.Tx) error {
   151  		genesisHash := chaincfg.MainNetParams.GenesisHash
   152  		blockBytes, err := tx.FetchBlock(genesisHash)
   153  		if err != nil {
   154  			return err
   155  		}
   156  
   157  		// As documented, all data fetched from the database is only
   158  		// valid during a database transaction in order to support
   159  		// zero-copy backends.  Thus, make a copy of the data so it
   160  		// can be used outside of the transaction.
   161  		loadedBlockBytes = make([]byte, len(blockBytes))
   162  		copy(loadedBlockBytes, blockBytes)
   163  		return nil
   164  	})
   165  	if err != nil {
   166  		fmt.Println(err)
   167  		return
   168  	}
   169  
   170  	// Typically at this point, the block could be deserialized via the
   171  	// wire.MsgBlock.Deserialize function or used in its serialized form
   172  	// depending on need.  However, for this example, just display the
   173  	// number of serialized bytes to show it was loaded as expected.
   174  	fmt.Printf("Serialized block size: %d bytes\n", len(loadedBlockBytes))
   175  
   176  	// Output:
   177  	// Serialized block size: 285 bytes
   178  }