mirror of
https://github.com/kaspanet/kaspad.git
synced 2025-06-15 02:26:40 +00:00

* [DEV-81] Overwrite maxOpenFiles for testInterface to force tests to check the LRU-mechanism in openFile * [DEV-81] Added database.UseLogger test * [DEV-81] Completed coverage of reconcileDB() * [DEV-81] Added some tests for dbcache * [DEV-81] Moved init and UseLogger to separate file to make them more easily-testable + added tests * [DEV-81] Added tests for deleteFile * [DEV-81] Added tests to cursor.Delete + made sure it returns error when transaction is not writable * [DEV-81] Moved database/error_test.go from database_test package to database package + added test for IsErrorCode * [DEV-81] Added tests for handleRollback error-cases * [DEV-81] Added tests for cursor.skipPendingUpdates * [DEV-81] Added tests for various cursor edge-cases * [DEV-81] tx.putKey no longer returns error, because there is no case when it does * [DEV-81] Added tests to CreateBucket error cases * [DEV-81] Added tests to bucket.Get and .Delete error cases + .Delete now returns error on empty key * [DEV-81] Added test for ForEachBucket * [DEV-81] Added tests to StoreBlock * [DEV-81] Added test for deleting a double nested bucket * [DEV-81] Removed log_test, as it is no longer necessary with the logging system re-design * [DEV-81] Added test to some of writePendingAndCommit error-cases * [DEV-81] Update references from btcutil to btcd/util * [DEV-81] Add tests for dbCacheIterator{.Next(), .Prev(), .Key, .Value()} in cases when iterator is exhausted * [DEV-81] Added tests for ldbIterator placeholder functions * [DEV-81] Added test name to Error messsages in TestSkipPendingUpdates * [DEV-81] Begin writing TestSkipPendingUpdatesCache * [DEV-81] Added error-cases for DBCache.flush() and DBCache.commitTreaps() * [DEV-81] Use monkey.patch from bou.ke and not from github * [DEV-81] Rewrote IsErrorCode in both database and txscript packages to be more concise * [DEV-81] Rename any database.Tx to dbTx instead of tx - to remove confusion with coin Tx * [DEV-81] Fix typo * [DEV-81] Use os.TempDir() instead of /tmp/ to be cross-platform * [DEV-81] use SimNet for database tests + Error if testDB exists after deleting it * [DEV-81] Removed useLogger - it's redundant * [DEV-81] Added comment on how CRC32 checksums are calculated in reconcile_test.go * [DEV-81] Added comment that explains what setWriteRow does * [DEV-81] Use constant instead of hard-coded value * [DEV-81] Fixed some typo's + better formatting
178 lines
5.4 KiB
Go
178 lines
5.4 KiB
Go
// Copyright (c) 2015-2016 The btcsuite developers
|
|
// Use of this source code is governed by an ISC
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package database_test
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
|
|
"github.com/daglabs/btcd/dagconfig"
|
|
"github.com/daglabs/btcd/database"
|
|
_ "github.com/daglabs/btcd/database/ffldb"
|
|
"github.com/daglabs/btcd/util"
|
|
"github.com/daglabs/btcd/wire"
|
|
)
|
|
|
|
// This example demonstrates creating a new database.
|
|
func ExampleCreate() {
|
|
// This example assumes the ffldb driver is imported.
|
|
//
|
|
// import (
|
|
// "github.com/daglabs/btcd/database"
|
|
// _ "github.com/daglabs/btcd/database/ffldb"
|
|
// )
|
|
|
|
// Create a database and schedule it to be closed and removed on exit.
|
|
// Typically you wouldn't want to remove the database right away like
|
|
// this, nor put it in the temp directory, but it's done here to ensure
|
|
// the example cleans up after itself.
|
|
dbPath := filepath.Join(os.TempDir(), "examplecreate")
|
|
db, err := database.Create("ffldb", dbPath, wire.MainNet)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
defer os.RemoveAll(dbPath)
|
|
defer db.Close()
|
|
|
|
// Output:
|
|
}
|
|
|
|
// This example demonstrates creating a new database and using a managed
|
|
// read-write transaction to store and retrieve metadata.
|
|
func Example_basicUsage() {
|
|
// This example assumes the ffldb driver is imported.
|
|
//
|
|
// import (
|
|
// "github.com/daglabs/btcd/database"
|
|
// _ "github.com/daglabs/btcd/database/ffldb"
|
|
// )
|
|
|
|
// Create a database and schedule it to be closed and removed on exit.
|
|
// Typically you wouldn't want to remove the database right away like
|
|
// this, nor put it in the temp directory, but it's done here to ensure
|
|
// the example cleans up after itself.
|
|
dbPath := filepath.Join(os.TempDir(), "exampleusage")
|
|
db, err := database.Create("ffldb", dbPath, wire.MainNet)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
defer os.RemoveAll(dbPath)
|
|
defer db.Close()
|
|
|
|
// Use the Update function of the database to perform a managed
|
|
// read-write transaction. The transaction will automatically be rolled
|
|
// back if the supplied inner function returns a non-nil error.
|
|
err = db.Update(func(dbTx database.Tx) error {
|
|
// Store a key/value pair directly in the metadata bucket.
|
|
// Typically a nested bucket would be used for a given feature,
|
|
// but this example is using the metadata bucket directly for
|
|
// simplicity.
|
|
key := []byte("mykey")
|
|
value := []byte("myvalue")
|
|
if err := dbTx.Metadata().Put(key, value); err != nil {
|
|
return err
|
|
}
|
|
|
|
// Read the key back and ensure it matches.
|
|
if !bytes.Equal(dbTx.Metadata().Get(key), value) {
|
|
return fmt.Errorf("unexpected value for key '%s'", key)
|
|
}
|
|
|
|
// Create a new nested bucket under the metadata bucket.
|
|
nestedBucketKey := []byte("mybucket")
|
|
nestedBucket, err := dbTx.Metadata().CreateBucket(nestedBucketKey)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// The key from above that was set in the metadata bucket does
|
|
// not exist in this new nested bucket.
|
|
if nestedBucket.Get(key) != nil {
|
|
return fmt.Errorf("key '%s' is not expected nil", key)
|
|
}
|
|
|
|
return nil
|
|
})
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
|
|
// Output:
|
|
}
|
|
|
|
// This example demonstrates creating a new database, using a managed read-write
|
|
// transaction to store a block, and using a managed read-only transaction to
|
|
// fetch the block.
|
|
func Example_blockStorageAndRetrieval() {
|
|
// This example assumes the ffldb driver is imported.
|
|
//
|
|
// import (
|
|
// "github.com/daglabs/btcd/database"
|
|
// _ "github.com/daglabs/btcd/database/ffldb"
|
|
// )
|
|
|
|
// Create a database and schedule it to be closed and removed on exit.
|
|
// Typically you wouldn't want to remove the database right away like
|
|
// this, nor put it in the temp directory, but it's done here to ensure
|
|
// the example cleans up after itself.
|
|
dbPath := filepath.Join(os.TempDir(), "exampleblkstorage")
|
|
db, err := database.Create("ffldb", dbPath, wire.MainNet)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
defer os.RemoveAll(dbPath)
|
|
defer db.Close()
|
|
|
|
// Use the Update function of the database to perform a managed
|
|
// read-write transaction and store a genesis block in the database as
|
|
// and example.
|
|
err = db.Update(func(dbTx database.Tx) error {
|
|
genesisBlock := dagconfig.MainNetParams.GenesisBlock
|
|
return dbTx.StoreBlock(util.NewBlock(genesisBlock))
|
|
})
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
|
|
// Use the View function of the database to perform a managed read-only
|
|
// transaction and fetch the block stored above.
|
|
var loadedBlockBytes []byte
|
|
err = db.Update(func(dbTx database.Tx) error {
|
|
genesisHash := dagconfig.MainNetParams.GenesisHash
|
|
blockBytes, err := dbTx.FetchBlock(genesisHash)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// As documented, all data fetched from the database is only
|
|
// valid during a database transaction in order to support
|
|
// zero-copy backends. Thus, make a copy of the data so it
|
|
// can be used outside of the transaction.
|
|
loadedBlockBytes = make([]byte, len(blockBytes))
|
|
copy(loadedBlockBytes, blockBytes)
|
|
return nil
|
|
})
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
|
|
// Typically at this point, the block could be deserialized via the
|
|
// wire.MsgBlock.Deserialize function or used in its serialized form
|
|
// depending on need. However, for this example, just display the
|
|
// number of serialized bytes to show it was loaded as expected.
|
|
fmt.Printf("Serialized block size: %d bytes\n", len(loadedBlockBytes))
|
|
|
|
// Output:
|
|
// Serialized block size: 270 bytes
|
|
}
|