From 6102ca9a80906332bba9e5c5809db181a4ef6748 Mon Sep 17 00:00:00 2001 From: mpl Date: Tue, 17 Dec 2013 01:53:36 +0100 Subject: [PATCH] mongo: NewKeyValue now takes a mongo.Config Change-Id: Ibfb0085836030592db4373e4ac2540355e67a9c5 --- pkg/index/mongo/mongoindex.go | 9 ++-- pkg/index/mongo/mongoindex_test.go | 7 ++- pkg/sorted/mongo/mongokv.go | 69 +++++++++++++++++------------- 3 files changed, 49 insertions(+), 36 deletions(-) diff --git a/pkg/index/mongo/mongoindex.go b/pkg/index/mongo/mongoindex.go index e8614e301..b2f1a834f 100644 --- a/pkg/index/mongo/mongoindex.go +++ b/pkg/index/mongo/mongoindex.go @@ -26,13 +26,16 @@ import ( ) func init() { - blobserver.RegisterStorageConstructor("mongodbindexer", - blobserver.StorageConstructor(newFromConfig)) + blobserver.RegisterStorageConstructor("mongodbindexer", newFromConfig) } func newFromConfig(ld blobserver.Loader, config jsonconfig.Obj) (blobserver.Storage, error) { blobPrefix := config.RequiredString("blobSource") - kv, err := mongo.NewKeyValue(config) + mongoConf, err := mongo.ConfigFromJSON(config) + if err != nil { + return nil, err + } + kv, err := mongo.NewKeyValue(mongoConf) if err != nil { return nil, err } diff --git a/pkg/index/mongo/mongoindex_test.go b/pkg/index/mongo/mongoindex_test.go index ec6bbb78e..1dd7cfe6e 100644 --- a/pkg/index/mongo/mongoindex_test.go +++ b/pkg/index/mongo/mongoindex_test.go @@ -24,7 +24,6 @@ import ( "camlistore.org/pkg/index" "camlistore.org/pkg/index/indextest" - "camlistore.org/pkg/jsonconfig" "camlistore.org/pkg/sorted" "camlistore.org/pkg/sorted/kvtest" "camlistore.org/pkg/sorted/mongo" @@ -53,9 +52,9 @@ func newSorted(t *testing.T) (kv sorted.KeyValue, cleanup func()) { skipOrFailIfNoMongo(t) // connect without credentials and wipe the database - cfg := jsonconfig.Obj{ - "host": "localhost", - "database": "camlitest", + cfg := mongo.Config{ + Server: "localhost", + Database: "camlitest", } var err error kv, err = mongo.NewKeyValue(cfg) diff --git a/pkg/sorted/mongo/mongokv.go b/pkg/sorted/mongo/mongokv.go index 43b11b3a9..65b416aac 100644 --- a/pkg/sorted/mongo/mongokv.go +++ b/pkg/sorted/mongo/mongokv.go @@ -43,29 +43,36 @@ const ( ) func init() { - sorted.RegisterKeyValue("mongo", NewKeyValue) + sorted.RegisterKeyValue("mongo", newKeyValueFromJSONConfig) } -// TODO(mpl): automatically derive the keys doc from something else. -// a JSON annotated struct? maybe from instance. -// maybe something in common with pkg/serverconfig/genconfig.go +// Config holds the parameters used to connect to MongoDB. +type Config struct { + Server string // Required. Defaults to "localhost" in ConfigFromJSON. + Database string // Required. + User string // Optional, unless the server was configured with auth on. + Password string // Optional, unless the server was configured with auth on. +} -// NewKeyValue returns a KeyValue implementation on top of MongoDB. -// cfg contains these keys: -// "host", optional string -// "database", string -// "user", optional string -// "password", optional string -func NewKeyValue(cfg jsonconfig.Obj) (sorted.KeyValue, error) { - ins := &instance{ - Servers: cfg.OptionalString("host", "localhost"), - Database: cfg.RequiredString("database"), - User: cfg.OptionalString("user", ""), - Password: cfg.OptionalString("password", ""), - Collection: CollectionName, +// ConfigFromJSON populates Config from cfg, and validates +// cfg. It returns an error if cfg fails to validate. +func ConfigFromJSON(cfg jsonconfig.Obj) (Config, error) { + conf := Config{ + Server: cfg.OptionalString("host", "localhost"), + Database: cfg.RequiredString("database"), + User: cfg.OptionalString("user", ""), + Password: cfg.OptionalString("password", ""), } if err := cfg.Validate(); err != nil { - return nil, err + return Config{}, err + } + return conf, nil +} + +// NewKeyValue returns a KeyValue implementation on top of MongoDB. +func NewKeyValue(cfg Config) (sorted.KeyValue, error) { + ins := &instance{ + conf: cfg, } db, err := ins.getCollection() if err != nil { @@ -74,6 +81,14 @@ func NewKeyValue(cfg jsonconfig.Obj) (sorted.KeyValue, error) { return &keyValue{db: db, session: ins.session}, nil } +func newKeyValueFromJSONConfig(cfg jsonconfig.Obj) (sorted.KeyValue, error) { + conf, err := ConfigFromJSON(cfg) + if err != nil { + return nil, err + } + return NewKeyValue(conf) +} + // Implementation of Iterator type iter struct { res bson.M @@ -218,25 +233,21 @@ func (kv *keyValue) Close() error { // Ping tests if MongoDB on host can be dialed. func Ping(host string, timeout time.Duration) bool { - return (&instance{Servers: host}).ping(timeout) + return (&instance{conf: Config{Server: host}}).ping(timeout) } // instance helps with the low level details about // the connection to MongoDB. type instance struct { - Servers string - User string - Password string - Database string - Collection string - session *mgo.Session + conf Config + session *mgo.Session } func (ins *instance) url() string { - if ins.User == "" || ins.Password == "" { - return ins.Servers + if ins.conf.User == "" || ins.conf.Password == "" { + return ins.conf.Server } - return ins.User + ":" + ins.Password + "@" + ins.Servers + "/" + ins.Database + return ins.conf.User + ":" + ins.conf.Password + "@" + ins.conf.Server + "/" + ins.conf.Database } // ping won't work with old (1.2) mongo servers. @@ -281,6 +292,6 @@ func (ins *instance) getCollection() (*mgo.Collection, error) { } session.SetSafe(&mgo.Safe{}) session.SetMode(mgo.Strong, true) - c := session.DB(ins.Database).C(ins.Collection) + c := session.DB(ins.conf.Database).C(CollectionName) return c, nil }