mirror of
https://github.com/kaspanet/kaspad.git
synced 2025-03-30 15:08:33 +00:00

* [NOD-849] Cover ffldb/transaction with tests. * [NOD-849] Cover cursor.go with tests. * [NOD-849] Cover ldb/transaction with tests. * [NOD-849] Cover location.go with tests. * [NOD-849] Write TestFlatFileMultiFileRollback. * [NOD-849] Fix merge errors. * [NOD-849] Fix a comment. * [NOD-849] Fix a comment. * [NOD-849] Add a test that makes sure that files get deleted on rollback. * [NOD-849] Add a test that makes sure that serializeLocation serialized to an expected value. * [NOD-849] Improve TestFlatFileLocationDeserializationErrors. * [NOD-849] Fix a copy+paste error. * [NOD-849] Explain maxFileSize = 16. * [NOD-849] Remove redundant RollbackUnlessClosed call. * [NOD-849] Extract bucket to a variable in TestCursorSanity. * [NOD-849] Rename TestKeyValueTransactionCommit to TestTransactionCommitForLevelDBMethods. * [NOD-849] Extract prepareXXX into separate functions. * [NOD-849] Simplify function calls in TestTransactionCloseErrors. * [NOD-849] Extract validateCurrentCursorKeyAndValue to a separate function. * [NOD-849] Add a comment over TestCursorSanity. * [NOD-849] Add a comment over function in TestCursorCloseErrors. * [NOD-849] Add a comment over function in TestTransactionCloseErrors. * [NOD-849] Separate TestTransactionCloseErrors to TestTransactionCommitErrors and TestTransactionRollbackErrors. * [NOD-849] Separate TestTransactionCloseErrors to TestTransactionCommitErrors and TestTransactionRollbackErrors. * [NOD-849] Fix copy+paste error in comments. * [NOD-849] Fix merge errors. * [NOD-849] Merge TestTransactionCommitErrors and TestTransactionRollbackErrors into TestTransactionCloseErrors. * [NOD-849] Move prepareDatabaseForTest into ffldb_test.go. * [NOD-849] Add cursorKey to Value error messages in validateCurrentCursorKeyAndValue.
138 lines
4.1 KiB
Go
138 lines
4.1 KiB
Go
package ffldb
|
|
|
|
import (
|
|
"github.com/kaspanet/kaspad/database"
|
|
"github.com/kaspanet/kaspad/database/ffldb/ff"
|
|
"github.com/kaspanet/kaspad/database/ffldb/ldb"
|
|
"github.com/pkg/errors"
|
|
)
|
|
|
|
// transaction is an ffldb transaction.
|
|
//
|
|
// Note: Transactions provide data consistency over the state of
|
|
// the database as it was when the transaction started. There is
|
|
// NO guarantee that if one puts data into the transaction then
|
|
// it will be available to get within the same transaction.
|
|
type transaction struct {
|
|
ldbTx *ldb.LevelDBTransaction
|
|
ffdb *ff.FlatFileDB
|
|
isClosed bool
|
|
}
|
|
|
|
// Put sets the value for the given key. It overwrites
|
|
// any previous value for that key.
|
|
// This method is part of the DataAccessor interface.
|
|
func (tx *transaction) Put(key *database.Key, value []byte) error {
|
|
if tx.isClosed {
|
|
return errors.New("cannot put into a closed transaction")
|
|
}
|
|
|
|
return tx.ldbTx.Put(key, value)
|
|
}
|
|
|
|
// Get gets the value for the given key. It returns
|
|
// ErrNotFound if the given key does not exist.
|
|
// This method is part of the DataAccessor interface.
|
|
func (tx *transaction) Get(key *database.Key) ([]byte, error) {
|
|
if tx.isClosed {
|
|
return nil, errors.New("cannot get from a closed transaction")
|
|
}
|
|
|
|
return tx.ldbTx.Get(key)
|
|
}
|
|
|
|
// Has returns true if the database does contains the
|
|
// given key.
|
|
// This method is part of the DataAccessor interface.
|
|
func (tx *transaction) Has(key *database.Key) (bool, error) {
|
|
if tx.isClosed {
|
|
return false, errors.New("cannot has from a closed transaction")
|
|
}
|
|
|
|
return tx.ldbTx.Has(key)
|
|
}
|
|
|
|
// Delete deletes the value for the given key. Will not
|
|
// return an error if the key doesn't exist.
|
|
// This method is part of the DataAccessor interface.
|
|
func (tx *transaction) Delete(key *database.Key) error {
|
|
if tx.isClosed {
|
|
return errors.New("cannot delete from a closed transaction")
|
|
}
|
|
|
|
return tx.ldbTx.Delete(key)
|
|
}
|
|
|
|
// AppendToStore appends the given data to the flat
|
|
// file store defined by storeName. This function
|
|
// returns a serialized location handle that's meant
|
|
// to be stored and later used when querying the data
|
|
// that has just now been inserted.
|
|
// This method is part of the DataAccessor interface.
|
|
func (tx *transaction) AppendToStore(storeName string, data []byte) ([]byte, error) {
|
|
if tx.isClosed {
|
|
return nil, errors.New("cannot append to store on a closed transaction")
|
|
}
|
|
|
|
return appendToStore(tx, tx.ffdb, storeName, data)
|
|
}
|
|
|
|
// RetrieveFromStore retrieves data from the store defined by
|
|
// storeName using the given serialized location handle. It
|
|
// returns ErrNotFound if the location does not exist. See
|
|
// AppendToStore for further details.
|
|
// This method is part of the DataAccessor interface.
|
|
func (tx *transaction) RetrieveFromStore(storeName string, location []byte) ([]byte, error) {
|
|
if tx.isClosed {
|
|
return nil, errors.New("cannot retrieve from store on a closed transaction")
|
|
}
|
|
|
|
return tx.ffdb.Read(storeName, location)
|
|
}
|
|
|
|
// Cursor begins a new cursor over the given bucket.
|
|
// This method is part of the DataAccessor interface.
|
|
func (tx *transaction) Cursor(bucket *database.Bucket) (database.Cursor, error) {
|
|
if tx.isClosed {
|
|
return nil, errors.New("cannot open a cursor from a closed transaction")
|
|
}
|
|
|
|
return tx.ldbTx.Cursor(bucket)
|
|
}
|
|
|
|
// Rollback rolls back whatever changes were made to the
|
|
// database within this transaction.
|
|
// This method is part of the Transaction interface.
|
|
func (tx *transaction) Rollback() error {
|
|
if tx.isClosed {
|
|
return errors.New("cannot rollback a closed transaction")
|
|
}
|
|
tx.isClosed = true
|
|
|
|
return tx.ldbTx.Rollback()
|
|
}
|
|
|
|
// Commit commits whatever changes were made to the database
|
|
// within this transaction.
|
|
// This method is part of the Transaction interface.
|
|
func (tx *transaction) Commit() error {
|
|
if tx.isClosed {
|
|
return errors.New("cannot commit a closed transaction")
|
|
}
|
|
tx.isClosed = true
|
|
|
|
return tx.ldbTx.Commit()
|
|
}
|
|
|
|
// RollbackUnlessClosed rolls back changes that were made to
|
|
// the database within the transaction, unless the transaction
|
|
// had already been closed using either Rollback or Commit.
|
|
func (tx *transaction) RollbackUnlessClosed() error {
|
|
if tx.isClosed {
|
|
return nil
|
|
}
|
|
tx.isClosed = true
|
|
|
|
return tx.ldbTx.RollbackUnlessClosed()
|
|
}
|