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) {
// 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)
}

14
db.go
View file

@ -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

View file

@ -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)

View file

@ -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

View file

@ -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
}

View file

@ -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