2016-02-03 18:42:04 +01:00
|
|
|
// 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.
|
|
|
|
|
2015-08-26 11:54:55 +02:00
|
|
|
package database
|
2016-02-03 18:42:04 +01:00
|
|
|
|
|
|
|
import "fmt"
|
|
|
|
|
|
|
|
// ErrorCode identifies a kind of error.
|
|
|
|
type ErrorCode int
|
|
|
|
|
|
|
|
// These constants are used to identify a specific database Error.
|
|
|
|
const (
|
|
|
|
// **************************************
|
|
|
|
// Errors related to driver registration.
|
|
|
|
// **************************************
|
|
|
|
|
|
|
|
// ErrDbTypeRegistered indicates two different database drivers
|
|
|
|
// attempt to register with the name database type.
|
|
|
|
ErrDbTypeRegistered ErrorCode = iota
|
|
|
|
|
|
|
|
// *************************************
|
|
|
|
// Errors related to database functions.
|
|
|
|
// *************************************
|
|
|
|
|
|
|
|
// ErrDbUnknownType indicates there is no driver registered for
|
|
|
|
// the specified database type.
|
|
|
|
ErrDbUnknownType
|
|
|
|
|
|
|
|
// ErrDbDoesNotExist indicates open is called for a database that
|
|
|
|
// does not exist.
|
|
|
|
ErrDbDoesNotExist
|
|
|
|
|
|
|
|
// ErrDbExists indicates create is called for a database that
|
|
|
|
// already exists.
|
|
|
|
ErrDbExists
|
|
|
|
|
|
|
|
// ErrDbNotOpen indicates a database instance is accessed before
|
|
|
|
// it is opened or after it is closed.
|
|
|
|
ErrDbNotOpen
|
|
|
|
|
|
|
|
// ErrDbAlreadyOpen indicates open was called on a database that
|
|
|
|
// is already open.
|
|
|
|
ErrDbAlreadyOpen
|
|
|
|
|
|
|
|
// ErrInvalid indicates the specified database is not valid.
|
|
|
|
ErrInvalid
|
|
|
|
|
|
|
|
// ErrCorruption indicates a checksum failure occurred which invariably
|
|
|
|
// means the database is corrupt.
|
|
|
|
ErrCorruption
|
|
|
|
|
|
|
|
// ****************************************
|
|
|
|
// Errors related to database transactions.
|
|
|
|
// ****************************************
|
|
|
|
|
|
|
|
// ErrTxClosed indicates an attempt was made to commit or rollback a
|
|
|
|
// transaction that has already had one of those operations performed.
|
|
|
|
ErrTxClosed
|
|
|
|
|
|
|
|
// ErrTxNotWritable indicates an operation that requires write access to
|
|
|
|
// the database was attempted against a read-only transaction.
|
|
|
|
ErrTxNotWritable
|
|
|
|
|
|
|
|
// **************************************
|
|
|
|
// Errors related to metadata operations.
|
|
|
|
// **************************************
|
|
|
|
|
|
|
|
// ErrBucketNotFound indicates an attempt to access a bucket that has
|
|
|
|
// not been created yet.
|
|
|
|
ErrBucketNotFound
|
|
|
|
|
|
|
|
// ErrBucketExists indicates an attempt to create a bucket that already
|
|
|
|
// exists.
|
|
|
|
ErrBucketExists
|
|
|
|
|
|
|
|
// ErrBucketNameRequired indicates an attempt to create a bucket with a
|
|
|
|
// blank name.
|
|
|
|
ErrBucketNameRequired
|
|
|
|
|
|
|
|
// ErrKeyRequired indicates at attempt to insert a zero-length key.
|
|
|
|
ErrKeyRequired
|
|
|
|
|
|
|
|
// ErrKeyTooLarge indicates an attmempt to insert a key that is larger
|
|
|
|
// than the max allowed key size. The max key size depends on the
|
|
|
|
// specific backend driver being used. As a general rule, key sizes
|
|
|
|
// should be relatively, so this should rarely be an issue.
|
|
|
|
ErrKeyTooLarge
|
|
|
|
|
|
|
|
// ErrValueTooLarge indicates an attmpt to insert a value that is larger
|
|
|
|
// than max allowed value size. The max key size depends on the
|
|
|
|
// specific backend driver being used.
|
|
|
|
ErrValueTooLarge
|
|
|
|
|
|
|
|
// ErrIncompatibleValue indicates the value in question is invalid for
|
|
|
|
// the specific requested operation. For example, trying create or
|
|
|
|
// delete a bucket with an existing non-bucket key, attempting to create
|
|
|
|
// or delete a non-bucket key with an existing bucket key, or trying to
|
|
|
|
// delete a value via a cursor when it points to a nested bucket.
|
|
|
|
ErrIncompatibleValue
|
|
|
|
|
|
|
|
// ***************************************
|
|
|
|
// Errors related to block I/O operations.
|
|
|
|
// ***************************************
|
|
|
|
|
|
|
|
// ErrBlockNotFound indicates a block with the provided hash does not
|
|
|
|
// exist in the database.
|
|
|
|
ErrBlockNotFound
|
|
|
|
|
|
|
|
// ErrBlockExists indicates a block with the provided hash already
|
|
|
|
// exists in the database.
|
|
|
|
ErrBlockExists
|
|
|
|
|
|
|
|
// ErrBlockRegionInvalid indicates a region that exceeds the bounds of
|
|
|
|
// the specified block was requested. When the hash provided by the
|
|
|
|
// region does not correspond to an existing block, the error will be
|
|
|
|
// ErrBlockNotFound instead.
|
|
|
|
ErrBlockRegionInvalid
|
|
|
|
|
|
|
|
// ***********************************
|
|
|
|
// Support for driver-specific errors.
|
|
|
|
// ***********************************
|
|
|
|
|
|
|
|
// ErrDriverSpecific indicates the Err field is a driver-specific error.
|
|
|
|
// This provides a mechanism for drivers to plug-in their own custom
|
|
|
|
// errors for any situations which aren't already covered by the error
|
|
|
|
// codes provided by this package.
|
|
|
|
ErrDriverSpecific
|
|
|
|
|
|
|
|
// numErrorCodes is the maximum error code number used in tests.
|
|
|
|
numErrorCodes
|
|
|
|
)
|
|
|
|
|
|
|
|
// Map of ErrorCode values back to their constant names for pretty printing.
|
|
|
|
var errorCodeStrings = map[ErrorCode]string{
|
|
|
|
ErrDbTypeRegistered: "ErrDbTypeRegistered",
|
|
|
|
ErrDbUnknownType: "ErrDbUnknownType",
|
|
|
|
ErrDbDoesNotExist: "ErrDbDoesNotExist",
|
|
|
|
ErrDbExists: "ErrDbExists",
|
|
|
|
ErrDbNotOpen: "ErrDbNotOpen",
|
|
|
|
ErrDbAlreadyOpen: "ErrDbAlreadyOpen",
|
|
|
|
ErrInvalid: "ErrInvalid",
|
|
|
|
ErrCorruption: "ErrCorruption",
|
|
|
|
ErrTxClosed: "ErrTxClosed",
|
|
|
|
ErrTxNotWritable: "ErrTxNotWritable",
|
|
|
|
ErrBucketNotFound: "ErrBucketNotFound",
|
|
|
|
ErrBucketExists: "ErrBucketExists",
|
|
|
|
ErrBucketNameRequired: "ErrBucketNameRequired",
|
|
|
|
ErrKeyRequired: "ErrKeyRequired",
|
|
|
|
ErrKeyTooLarge: "ErrKeyTooLarge",
|
|
|
|
ErrValueTooLarge: "ErrValueTooLarge",
|
|
|
|
ErrIncompatibleValue: "ErrIncompatibleValue",
|
|
|
|
ErrBlockNotFound: "ErrBlockNotFound",
|
|
|
|
ErrBlockExists: "ErrBlockExists",
|
|
|
|
ErrBlockRegionInvalid: "ErrBlockRegionInvalid",
|
|
|
|
ErrDriverSpecific: "ErrDriverSpecific",
|
|
|
|
}
|
|
|
|
|
|
|
|
// String returns the ErrorCode as a human-readable name.
|
|
|
|
func (e ErrorCode) String() string {
|
|
|
|
if s := errorCodeStrings[e]; s != "" {
|
|
|
|
return s
|
|
|
|
}
|
|
|
|
return fmt.Sprintf("Unknown ErrorCode (%d)", int(e))
|
|
|
|
}
|
|
|
|
|
|
|
|
// Error provides a single type for errors that can happen during database
|
|
|
|
// operation. It is used to indicate several types of failures including errors
|
|
|
|
// with caller requests such as specifying invalid block regions or attempting
|
|
|
|
// to access data against closed database transactions, driver errors, errors
|
|
|
|
// retrieving data, and errors communicating with database servers.
|
|
|
|
//
|
|
|
|
// The caller can use type assertions to determine if an error is an Error and
|
|
|
|
// access the ErrorCode field to ascertain the specific reason for the failure.
|
|
|
|
//
|
|
|
|
// The ErrDriverSpecific error code will also have the Err field set with the
|
|
|
|
// underlying error. Depending on the backend driver, the Err field might be
|
|
|
|
// set to the underlying error for other error codes as well.
|
|
|
|
type Error struct {
|
|
|
|
ErrorCode ErrorCode // Describes the kind of error
|
|
|
|
Description string // Human readable description of the issue
|
|
|
|
Err error // Underlying error
|
|
|
|
}
|
|
|
|
|
|
|
|
// Error satisfies the error interface and prints human-readable errors.
|
|
|
|
func (e Error) Error() string {
|
|
|
|
if e.Err != nil {
|
|
|
|
return e.Description + ": " + e.Err.Error()
|
|
|
|
}
|
|
|
|
return e.Description
|
|
|
|
}
|
|
|
|
|
|
|
|
// makeError creates an Error given a set of arguments. The error code must
|
|
|
|
// be one of the error codes provided by this package.
|
|
|
|
func makeError(c ErrorCode, desc string, err error) Error {
|
|
|
|
return Error{ErrorCode: c, Description: desc, Err: err}
|
|
|
|
}
|