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.
This commit is contained in:
Dave Collins 2014-01-19 20:01:31 -06:00
parent 2eea55ae1d
commit 2aca924514
6 changed files with 68 additions and 25 deletions

View file

@ -54,7 +54,7 @@ func fileExists(name string) bool {
func openDB(dbType, dbName string) (btcdb.Db, error) { func openDB(dbType, dbName string) (btcdb.Db, error) {
// Handle memdb specially since it has no files on disk. // Handle memdb specially since it has no files on disk.
if dbType == "memdb" { if dbType == "memdb" {
db, err := btcdb.OpenDB(dbType, "") db, err := btcdb.OpenDB(dbType)
if err != nil { if err != nil {
return nil, fmt.Errorf("error opening db: %v", err) 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 // Handle memory database specially since it doesn't need the disk
// specific handling. // specific handling.
if dbType == "memdb" { if dbType == "memdb" {
db, err := btcdb.CreateDB(dbType, "") db, err := btcdb.CreateDB(dbType)
if err != nil { if err != nil {
return nil, nil, fmt.Errorf("error creating db: %v", err) return nil, nil, fmt.Errorf("error creating db: %v", err)
} }

12
db.go
View file

@ -107,8 +107,8 @@ type Db interface {
// themselves as a backend which implements the Db interface. // themselves as a backend which implements the Db interface.
type DriverDB struct { type DriverDB struct {
DbType string DbType string
Create func(argstr string) (pbdb Db, err error) CreateDB func(args ...interface{}) (pbdb Db, err error)
Open func(filepath string) (pbdb Db, err error) OpenDB func(args ...interface{}) (pbdb Db, err error)
} }
// TxListReply is used to return individual transaction information when // TxListReply is used to return individual transaction information when
@ -138,20 +138,20 @@ func AddDBDriver(instance DriverDB) {
} }
// CreateDB intializes and opens a database. // 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 { for _, drv := range driverList {
if drv.DbType == dbtype { if drv.DbType == dbtype {
return drv.Create(argstr) return drv.CreateDB(args...)
} }
} }
return nil, DbUnknownType return nil, DbUnknownType
} }
// OpenDB opens an existing database. // 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 { for _, drv := range driverList {
if drv.DbType == dbtype { if drv.DbType == dbtype {
return drv.Open(argstr) return drv.OpenDB(args...)
} }
} }
return nil, DbUnknownType return nil, DbUnknownType

View file

@ -76,7 +76,7 @@ func TestAddDuplicateDriver(t *testing.T) {
// driver function and intentionally returns a failure that can be // driver function and intentionally returns a failure that can be
// detected if the interface allows a duplicate driver to overwrite an // detected if the interface allows a duplicate driver to overwrite an
// existing one. // existing one.
bogusCreateDB := func(string) (btcdb.Db, error) { bogusCreateDB := func(args ...interface{}) (btcdb.Db, error) {
return nil, fmt.Errorf("duplicate driver allowed for database "+ return nil, fmt.Errorf("duplicate driver allowed for database "+
"type [%v]", dbType) "type [%v]", dbType)
} }
@ -86,8 +86,8 @@ func TestAddDuplicateDriver(t *testing.T) {
// they are invoked. // they are invoked.
driver := btcdb.DriverDB{ driver := btcdb.DriverDB{
DbType: dbType, DbType: dbType,
Create: bogusCreateDB, CreateDB: bogusCreateDB,
Open: bogusCreateDB, OpenDB: bogusCreateDB,
} }
btcdb.AddDBDriver(driver) btcdb.AddDBDriver(driver)
@ -111,7 +111,7 @@ func TestCreateOpenFail(t *testing.T) {
dbType := "createopenfail" dbType := "createopenfail"
openError := fmt.Errorf("failed to create or open database for "+ openError := fmt.Errorf("failed to create or open database for "+
"database type [%v]", dbType) "database type [%v]", dbType)
bogusCreateDB := func(string) (btcdb.Db, error) { bogusCreateDB := func(args ...interface{}) (btcdb.Db, error) {
return nil, openError return nil, openError
} }
@ -119,8 +119,8 @@ func TestCreateOpenFail(t *testing.T) {
// to ensure errors on database open and create are handled properly. // to ensure errors on database open and create are handled properly.
driver := btcdb.DriverDB{ driver := btcdb.DriverDB{
DbType: dbType, DbType: dbType,
Create: bogusCreateDB, CreateDB: bogusCreateDB,
Open: bogusCreateDB, OpenDB: bogusCreateDB,
} }
btcdb.AddDBDriver(driver) btcdb.AddDBDriver(driver)

View file

@ -55,14 +55,33 @@ type LevelDb struct {
txSpentUpdateMap map[btcwire.ShaHash]*spentTxUpdate 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() { func init() {
btcdb.AddDBDriver(self) 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. // 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() log = btcdb.GetLog()
db, err := openDB(dbpath, false) 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. // 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() log = btcdb.GetLog()
// No special setup needed, just OpenBB // No special setup needed, just OpenBB

View file

@ -5,6 +5,7 @@
package memdb package memdb
import ( import (
"fmt"
"github.com/conformal/btcdb" "github.com/conformal/btcdb"
"github.com/conformal/btclog" "github.com/conformal/btclog"
) )
@ -12,18 +13,36 @@ import (
var log = btclog.Disabled var log = btclog.Disabled
func init() { func init() {
driver := btcdb.DriverDB{DbType: "memdb", Create: CreateDB, Open: OpenDB} driver := btcdb.DriverDB{DbType: "memdb", CreateDB: CreateDB, OpenDB: OpenDB}
btcdb.AddDBDriver(driver) 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. // 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. // 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. // 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() log = btcdb.GetLog()
return newMemDb(), nil return newMemDb(), nil
} }

View file

@ -18,7 +18,7 @@ import (
// and does not panic or otherwise misbehave for functions which do not return // and does not panic or otherwise misbehave for functions which do not return
// errors. // errors.
func TestClosed(t *testing.T) { func TestClosed(t *testing.T) {
db, err := btcdb.CreateDB("memdb", "") db, err := btcdb.CreateDB("memdb")
if err != nil { if err != nil {
t.Errorf("Failed to open test database %v", err) t.Errorf("Failed to open test database %v", err)
return return