From 2aca9245145a6c22fb02f6681201105f6eb581e4 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Sun, 19 Jan 2014 20:01:31 -0600 Subject: [PATCH] Allow the Open/CreateDB funcs to take any params. The specific parameters required by a backend is better left up to the backend itself. For example memdb has no need for a database path, while ldb does. This commit modifies the OpenDB and CreateDB functions to take a arbitrary arguments which are passed along to the driver. The driver is expected to verify the correct type and number of arguments and error accordingly. The existing backends have been updated accordingly. --- common_test.go | 4 ++-- db.go | 14 +++++++------- db_test.go | 16 ++++++++-------- ldb/leveldb.go | 30 +++++++++++++++++++++++++++--- memdb/driver.go | 27 +++++++++++++++++++++++---- memdb/memdb_test.go | 2 +- 6 files changed, 68 insertions(+), 25 deletions(-) diff --git a/common_test.go b/common_test.go index 31653445..ffe2653f 100644 --- a/common_test.go +++ b/common_test.go @@ -54,7 +54,7 @@ func fileExists(name string) bool { func openDB(dbType, dbName string) (btcdb.Db, error) { // Handle memdb specially since it has no files on disk. if dbType == "memdb" { - db, err := btcdb.OpenDB(dbType, "") + db, err := btcdb.OpenDB(dbType) if err != nil { return nil, fmt.Errorf("error opening db: %v", err) } @@ -78,7 +78,7 @@ func createDB(dbType, dbName string, close bool) (btcdb.Db, func(), error) { // Handle memory database specially since it doesn't need the disk // specific handling. if dbType == "memdb" { - db, err := btcdb.CreateDB(dbType, "") + db, err := btcdb.CreateDB(dbType) if err != nil { return nil, nil, fmt.Errorf("error creating db: %v", err) } diff --git a/db.go b/db.go index 4e7f03e1..c5b392de 100644 --- a/db.go +++ b/db.go @@ -106,9 +106,9 @@ type Db interface { // DriverDB defines a structure for backend drivers to use when they registered // themselves as a backend which implements the Db interface. type DriverDB struct { - DbType string - Create func(argstr string) (pbdb Db, err error) - Open func(filepath string) (pbdb Db, err error) + DbType string + CreateDB func(args ...interface{}) (pbdb Db, err error) + OpenDB func(args ...interface{}) (pbdb Db, err error) } // TxListReply is used to return individual transaction information when @@ -138,20 +138,20 @@ func AddDBDriver(instance DriverDB) { } // CreateDB intializes and opens a database. -func CreateDB(dbtype string, argstr string) (pbdb Db, err error) { +func CreateDB(dbtype string, args ...interface{}) (pbdb Db, err error) { for _, drv := range driverList { if drv.DbType == dbtype { - return drv.Create(argstr) + return drv.CreateDB(args...) } } return nil, DbUnknownType } // OpenDB opens an existing database. -func OpenDB(dbtype string, argstr string) (pbdb Db, err error) { +func OpenDB(dbtype string, args ...interface{}) (pbdb Db, err error) { for _, drv := range driverList { if drv.DbType == dbtype { - return drv.Open(argstr) + return drv.OpenDB(args...) } } return nil, DbUnknownType diff --git a/db_test.go b/db_test.go index 74a3b89b..75fc6174 100644 --- a/db_test.go +++ b/db_test.go @@ -76,7 +76,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(string) (btcdb.Db, error) { + bogusCreateDB := func(args ...interface{}) (btcdb.Db, error) { return nil, fmt.Errorf("duplicate driver allowed for database "+ "type [%v]", dbType) } @@ -85,9 +85,9 @@ func TestAddDuplicateDriver(t *testing.T) { // create and open functions to a function that causes a test failure if // they are invoked. driver := btcdb.DriverDB{ - DbType: dbType, - Create: bogusCreateDB, - Open: bogusCreateDB, + DbType: dbType, + CreateDB: bogusCreateDB, + OpenDB: bogusCreateDB, } btcdb.AddDBDriver(driver) @@ -111,16 +111,16 @@ func TestCreateOpenFail(t *testing.T) { dbType := "createopenfail" openError := fmt.Errorf("failed to create or open database for "+ "database type [%v]", dbType) - bogusCreateDB := func(string) (btcdb.Db, error) { + bogusCreateDB := func(args ...interface{}) (btcdb.Db, error) { return nil, openError } // Create and add driver that intentionally fails when created or opened // to ensure errors on database open and create are handled properly. driver := btcdb.DriverDB{ - DbType: dbType, - Create: bogusCreateDB, - Open: bogusCreateDB, + DbType: dbType, + CreateDB: bogusCreateDB, + OpenDB: bogusCreateDB, } btcdb.AddDBDriver(driver) diff --git a/ldb/leveldb.go b/ldb/leveldb.go index 8c6b5d0e..2209d833 100644 --- a/ldb/leveldb.go +++ b/ldb/leveldb.go @@ -55,14 +55,33 @@ type LevelDb struct { txSpentUpdateMap map[btcwire.ShaHash]*spentTxUpdate } -var self = btcdb.DriverDB{DbType: "leveldb", Create: CreateDB, Open: OpenDB} +var self = btcdb.DriverDB{DbType: "leveldb", CreateDB: CreateDB, OpenDB: OpenDB} func init() { btcdb.AddDBDriver(self) } +// parseArgs parses the arguments from the btcdb Open/Create methods. +func parseArgs(funcName string, args ...interface{}) (string, error) { + if len(args) != 1 { + return "", fmt.Errorf("Invalid arguments to ldb.%s -- "+ + "expected database path string", funcName) + } + dbPath, ok := args[0].(string) + if !ok { + return "", fmt.Errorf("First argument to ldb.%s is invalid -- "+ + "expected database path string", funcName) + } + return dbPath, nil +} + // OpenDB opens an existing database for use. -func OpenDB(dbpath string) (btcdb.Db, error) { +func OpenDB(args ...interface{}) (btcdb.Db, error) { + dbpath, err := parseArgs("OpenDB", args...) + if err != nil { + return nil, err + } + log = btcdb.GetLog() db, err := openDB(dbpath, false) @@ -216,7 +235,12 @@ func openDB(dbpath string, create bool) (pbdb btcdb.Db, err error) { } // CreateDB creates, initializes and opens a database for use. -func CreateDB(dbpath string) (btcdb.Db, error) { +func CreateDB(args ...interface{}) (btcdb.Db, error) { + dbpath, err := parseArgs("Create", args...) + if err != nil { + return nil, err + } + log = btcdb.GetLog() // No special setup needed, just OpenBB diff --git a/memdb/driver.go b/memdb/driver.go index 53e72c26..581c0feb 100644 --- a/memdb/driver.go +++ b/memdb/driver.go @@ -5,6 +5,7 @@ package memdb import ( + "fmt" "github.com/conformal/btcdb" "github.com/conformal/btclog" ) @@ -12,18 +13,36 @@ import ( var log = btclog.Disabled func init() { - driver := btcdb.DriverDB{DbType: "memdb", Create: CreateDB, Open: OpenDB} + driver := btcdb.DriverDB{DbType: "memdb", CreateDB: CreateDB, OpenDB: OpenDB} btcdb.AddDBDriver(driver) } +// parseArgs parses the arguments from the btcdb Open/Create methods. +func parseArgs(funcName string, args ...interface{}) error { + if len(args) != 0 { + return fmt.Errorf("memdb.%s does not accept any arguments", + funcName) + } + + return nil +} + // OpenDB opens an existing database for use. -func OpenDB(dbpath string) (btcdb.Db, error) { +func OpenDB(args ...interface{}) (btcdb.Db, error) { + if err := parseArgs("OpenDB", args...); err != nil { + return nil, err + } + // A memory database is not persistent, so let CreateDB handle it. - return CreateDB(dbpath) + return CreateDB() } // CreateDB creates, initializes, and opens a database for use. -func CreateDB(dbpath string) (btcdb.Db, error) { +func CreateDB(args ...interface{}) (btcdb.Db, error) { + if err := parseArgs("CreateDB", args...); err != nil { + return nil, err + } + log = btcdb.GetLog() return newMemDb(), nil } diff --git a/memdb/memdb_test.go b/memdb/memdb_test.go index 73a1d57b..4d96b149 100644 --- a/memdb/memdb_test.go +++ b/memdb/memdb_test.go @@ -18,7 +18,7 @@ import ( // and does not panic or otherwise misbehave for functions which do not return // errors. func TestClosed(t *testing.T) { - db, err := btcdb.CreateDB("memdb", "") + db, err := btcdb.CreateDB("memdb") if err != nil { t.Errorf("Failed to open test database %v", err) return