diff --git a/database/driver.go b/database/driver.go index cb76d2fc..9b9a8a6a 100644 --- a/database/driver.go +++ b/database/driver.go @@ -20,12 +20,12 @@ type Driver struct { // Create is the function that will be invoked with all user-specified // arguments to create the database. This function must return // ErrDbExists if the database already exists. - Create func(args ...interface{}) (DB, error) + Create func(dbType string, args ...interface{}) (DB, error) // Open is the function that will be invoked with all user-specified // arguments to open the database. This function must return // ErrDbDoesNotExist if the database has not already been created. - Open func(args ...interface{}) (DB, error) + Open func(dbType string, args ...interface{}) (DB, error) // UseLogger uses a specified Logger to output package logging info. UseLogger func(logger btclog.Logger) @@ -70,7 +70,7 @@ func Create(dbType string, args ...interface{}) (DB, error) { return nil, makeError(ErrDbUnknownType, str, nil) } - return drv.Create(args...) + return drv.Create(dbType, args...) } // Open opens an existing database for the specified type. The arguments are @@ -85,5 +85,5 @@ func Open(dbType string, args ...interface{}) (DB, error) { return nil, makeError(ErrDbUnknownType, str, nil) } - return drv.Open(args...) + return drv.Open(dbType, args...) } diff --git a/database/driver_test.go b/database/driver_test.go index 3bb48de1..201b3a11 100644 --- a/database/driver_test.go +++ b/database/driver_test.go @@ -53,7 +53,7 @@ func TestAddDuplicateDriver(t *testing.T) { // driver function and intentionally returns a failure that can be // detected if the interface allows a duplicate driver to overwrite an // existing one. - bogusCreateDB := func(args ...interface{}) (database.DB, error) { + bogusCreateDB := func(dbType string, args ...interface{}) (database.DB, error) { return nil, fmt.Errorf("duplicate driver allowed for database "+ "type [%v]", dbType) } @@ -82,7 +82,7 @@ func TestCreateOpenFail(t *testing.T) { dbType := "createopenfail" openError := fmt.Errorf("failed to create or open database for "+ "database type [%v]", dbType) - bogusCreateDB := func(args ...interface{}) (database.DB, error) { + bogusCreateDB := func(dbType string, args ...interface{}) (database.DB, error) { return nil, openError } diff --git a/database/ffldb/db.go b/database/ffldb/db.go index 60103aaa..ec30996f 100644 --- a/database/ffldb/db.go +++ b/database/ffldb/db.go @@ -1860,6 +1860,8 @@ func (tx *transaction) Rollback() error { // the database.DB interface. All database access is performed through // transactions which are obtained through the specific Namespace. type db struct { + dbType string + writeLock sync.Mutex // Limit to one write transaction at a time. closeLock sync.RWMutex // Make database close block while txns active. closed bool // Is the database closed? @@ -1875,7 +1877,7 @@ var _ database.DB = (*db)(nil) // // This function is part of the database.DB interface implementation. func (db *db) Type() string { - return dbType + return db.dbType } // begin is the implementation function for the Begin database method. See its @@ -2115,7 +2117,7 @@ func initDB(ldb *leveldb.DB) error { // openDB opens the database at the provided path. database.ErrDbDoesNotExist // is returned if the database doesn't exist and the create flag is not set. -func openDB(dbPath string, network wire.BitcoinNet, create bool) (database.DB, error) { +func openDB(dbType string, dbPath string, network wire.BitcoinNet, create bool) (database.DB, error) { // Error if the database doesn't exist and the create flag is not set. metadataDbPath := filepath.Join(dbPath, metadataDbName) dbExists := fileExists(metadataDbPath) @@ -2154,7 +2156,7 @@ func openDB(dbPath string, network wire.BitcoinNet, create bool) (database.DB, e return nil, convertErr(err.Error(), err) } cache := newDbCache(ldb, store, defaultCacheSize, defaultFlushSecs) - pdb := &db{store: store, cache: cache} + pdb := &db{dbType: dbType, store: store, cache: cache} // Perform any reconciliation needed between the block and metadata as // well as database initialization, if needed. diff --git a/database/ffldb/driver.go b/database/ffldb/driver.go index 01290bf0..cdcd7d63 100644 --- a/database/ffldb/driver.go +++ b/database/ffldb/driver.go @@ -15,11 +15,11 @@ import ( var log = btclog.Disabled const ( - dbType = "ffldb" + LevelDB = "ffldb" ) // parseArgs parses the arguments from the database Open/Create methods. -func parseArgs(funcName string, args ...interface{}) (string, wire.BitcoinNet, error) { +func parseArgs(dbType, funcName string, args ...interface{}) (string, wire.BitcoinNet, error) { if len(args) != 2 { return "", 0, fmt.Errorf("invalid arguments to %s.%s -- "+ "expected database path and block network", dbType, @@ -43,24 +43,24 @@ func parseArgs(funcName string, args ...interface{}) (string, wire.BitcoinNet, e // openDBDriver is the callback provided during driver registration that opens // an existing database for use. -func openDBDriver(args ...interface{}) (database.DB, error) { - dbPath, network, err := parseArgs("Open", args...) +func openDBDriver(dbType string, args ...interface{}) (database.DB, error) { + dbPath, network, err := parseArgs(dbType, "Open", args...) if err != nil { return nil, err } - return openDB(dbPath, network, false) + return openDB(dbType, dbPath, network, false) } // createDBDriver is the callback provided during driver registration that // creates, initializes, and opens a database for use. -func createDBDriver(args ...interface{}) (database.DB, error) { - dbPath, network, err := parseArgs("Create", args...) +func createDBDriver(dbType string, args ...interface{}) (database.DB, error) { + dbPath, network, err := parseArgs(dbType, "Create", args...) if err != nil { return nil, err } - return openDB(dbPath, network, true) + return openDB(dbType, dbPath, network, true) } // useLogger is the callback provided during driver registration that sets the @@ -70,15 +70,19 @@ func useLogger(logger btclog.Logger) { } func init() { - // Register the driver. - driver := database.Driver{ - DbType: dbType, - Create: createDBDriver, - Open: openDBDriver, - UseLogger: useLogger, + // Register the drivers. + drivers := []database.Driver{ + { + DbType: LevelDB, + Create: createDBDriver, + Open: openDBDriver, + UseLogger: useLogger, + }, } - if err := database.RegisterDriver(driver); err != nil { - panic(fmt.Sprintf("Failed to register database driver '%s': %v", - dbType, err)) + for _, driver := range drivers { + if err := database.RegisterDriver(driver); err != nil { + panic(fmt.Sprintf("Failed to register database driver '%s': %v", + driver.DbType, err)) + } } } diff --git a/database/ffldb/whitebox_test.go b/database/ffldb/whitebox_test.go index cac49840..5f4b5dff 100644 --- a/database/ffldb/whitebox_test.go +++ b/database/ffldb/whitebox_test.go @@ -179,7 +179,7 @@ func TestCornerCases(t *testing.T) { // directory is needed. testName := "openDB: fail due to file at target location" wantErrCode := database.ErrDriverSpecific - idb, err := openDB(dbPath, blockDataNet, true) + idb, err := openDB(LevelDB, dbPath, blockDataNet, true) if !checkDbError(t, testName, err, wantErrCode) { if err == nil { idb.Close() @@ -191,7 +191,7 @@ func TestCornerCases(t *testing.T) { // Remove the file and create the database to run tests against. It // should be successful this time. _ = os.RemoveAll(dbPath) - idb, err = openDB(dbPath, blockDataNet, true) + idb, err = openDB(LevelDB, dbPath, blockDataNet, true) if err != nil { t.Errorf("openDB: unexpected error: %v", err) return @@ -605,9 +605,9 @@ func TestFailureScenarios(t *testing.T) { // Create a new database to run tests against. dbPath := filepath.Join(os.TempDir(), "ffldb-failurescenarios") _ = os.RemoveAll(dbPath) - idb, err := database.Create(dbType, dbPath, blockDataNet) + idb, err := database.Create(LevelDB, dbPath, blockDataNet) if err != nil { - t.Errorf("Failed to create test database (%s) %v", dbType, err) + t.Errorf("Failed to create test database (%s) %v", LevelDB, err) return } defer os.RemoveAll(dbPath)