func RegisterDriver(driver Driver) error {
	const op errors.Op = "walletdb.RegisterDriver"
	if _, exists := drivers[driver.DbType]; exists {
		return errors.E(op, errors.Exist, errors.Errorf("driver %q is already registered", driver.DbType))
	}
	drivers[driver.DbType] = &driver
	return nil
}
RegisterDriver adds a backend database driver to available interfaces.
Errors if the  will be returned if the database type for the driver has
already been registered.
package walletdb
import (
	"context"
	"io"
	"runtime/trace"
	"decred.org/dcrwallet/v2/errors"
)
type ReadTx interface {
	ReadBucket(key []byte) ReadBucket
	Rollback() error
}
type ReadWriteTx interface {
	ReadTx
	ReadWriteBucket(key []byte) ReadWriteBucket
	CreateTopLevelBucket(key []byte) (ReadWriteBucket, error)
	DeleteTopLevelBucket(key []byte) error
	Commit() error
}
type ReadBucket interface {
	NestedReadBucket(key []byte) ReadBucket
	ForEach(func(k, v []byte) error) error
	Get(key []byte) []byte
	ReadCursor() ReadCursor
}
type ReadWriteBucket interface {
	ReadBucket
	NestedReadWriteBucket(key []byte) ReadWriteBucket
	CreateBucket(key []byte) (ReadWriteBucket, error)
	CreateBucketIfNotExists(key []byte) (ReadWriteBucket, error)
	DeleteNestedBucket(key []byte) error
	Put(key, value []byte) error
	Delete(key []byte) error
	ReadWriteCursor() ReadWriteCursor
}
type ReadCursor interface {
	First() (key, value []byte)
	Last() (key, value []byte)
	Next() (key, value []byte)
	Prev() (key, value []byte)
	Seek(seek []byte) (key, value []byte)
	Close()
}
type ReadWriteCursor interface {
	ReadCursor
	Delete() error
}
func BucketIsEmpty(bucket ReadBucket) bool {
	cursor := bucket.ReadCursor()
	k, v := cursor.First()
	cursor.Close()
	return k == nil && v == nil
}
type DB interface {
	BeginReadTx() (ReadTx, error)
	BeginReadWriteTx() (ReadWriteTx, error)
	Copy(w io.Writer) error
	Close() error
}
func View(ctx context.Context, db DB, f func(tx ReadTx) error) error {
	defer trace.StartRegion(ctx, "db.View").End()
	tx, err := db.BeginReadTx()
	if err != nil {
		return err
	}
	defer trace.StartRegion(ctx, "db.ReadTx").End()
	defer func() {
		rollbackErr := tx.Rollback()
		if err != nil {
			err = rollbackErr
		}
	}()
	return f(tx)
}
func Update(ctx context.Context, db DB, f func(tx ReadWriteTx) error) (err error) {
	defer trace.StartRegion(ctx, "db.Update").End()
	tx, err := db.BeginReadWriteTx()
	if err != nil {
		return err
	}
	defer trace.StartRegion(ctx, "db.ReadWriteTx").End()
	panicked := true
	defer func() {
		if panicked || err != nil {
			tx.Rollback()
			return
		}
		err = tx.Commit()
	}()
	err = f(tx)
	panicked = false
	return err
}
type Driver struct {
	DbType string
	Create func(args ...interface{}) (DB, error)
	Open func(args ...interface{}) (DB, error)
}
var drivers = make(map[string]*Driver)