mirror of
https://github.com/mainflux/mainflux.git
synced 2025-05-02 22:17:10 +08:00

* Add mongodb reader service Signed-off-by: Aleksandar Novakovic <aleksandar.novakovic@mainflux.com> * Add tests for mongodb reader service Signed-off-by: Aleksandar Novakovic <aleksandar.novakovic@mainflux.com> * Add documentation for mongodb reader service Signed-off-by: Aleksandar Novakovic <aleksandar.novakovic@mainflux.com> * Fix test function name Signed-off-by: Aleksandar Novakovic <aleksandar.novakovic@mainflux.com> * Update comment in docker-compose for mongodb-reader service Signed-off-by: Aleksandar Novakovic <aleksandar.novakovic@mainflux.com>
185 lines
3.9 KiB
Go
185 lines
3.9 KiB
Go
package dbopt
|
|
|
|
import (
|
|
"reflect"
|
|
|
|
"github.com/mongodb/mongo-go-driver/core/readconcern"
|
|
"github.com/mongodb/mongo-go-driver/core/readpref"
|
|
"github.com/mongodb/mongo-go-driver/core/session"
|
|
"github.com/mongodb/mongo-go-driver/core/writeconcern"
|
|
)
|
|
|
|
var dbBundle = new(DatabaseBundle)
|
|
|
|
// Option represents a DB option.
|
|
type Option interface {
|
|
dbOption()
|
|
}
|
|
|
|
// optionFunc adds the option to the DB
|
|
type optionFunc func(*Database) error
|
|
|
|
// Database represents a database.
|
|
type Database struct {
|
|
ReadConcern *readconcern.ReadConcern
|
|
WriteConcern *writeconcern.WriteConcern
|
|
ReadPreference *readpref.ReadPref
|
|
}
|
|
|
|
// DatabaseBundle is a bundle of database options.
|
|
type DatabaseBundle struct {
|
|
option Option
|
|
next *DatabaseBundle
|
|
}
|
|
|
|
func (*DatabaseBundle) dbOption() {}
|
|
|
|
func (optionFunc) dbOption() {}
|
|
|
|
// DropDB represents all possible params for the dropDatabase() function
|
|
type DropDB interface {
|
|
dropDB()
|
|
}
|
|
|
|
// DropDBSession is the session for the dropDatabase() function.
|
|
type DropDBSession interface {
|
|
DropDB
|
|
ConvertDropDBSession() *session.Client
|
|
}
|
|
|
|
// DropDBSessionOpt is a dropDatabase session option.
|
|
type DropDBSessionOpt struct{}
|
|
|
|
func (DropDBSessionOpt) dropDB() {}
|
|
|
|
// ConvertDropDBSession implements the DropDBSession interface.
|
|
func (DropDBSessionOpt) ConvertDropDBSession() *session.Client {
|
|
return nil
|
|
}
|
|
|
|
// BundleDatabase bundles database options
|
|
func BundleDatabase(opts ...Option) *DatabaseBundle {
|
|
head := dbBundle
|
|
|
|
for _, opt := range opts {
|
|
newBundle := DatabaseBundle{
|
|
option: opt,
|
|
next: head,
|
|
}
|
|
head = &newBundle
|
|
}
|
|
|
|
return head
|
|
}
|
|
|
|
// ReadConcern sets the read concern.
|
|
func (db *DatabaseBundle) ReadConcern(rc *readconcern.ReadConcern) *DatabaseBundle {
|
|
return &DatabaseBundle{
|
|
option: ReadConcern(rc),
|
|
next: db,
|
|
}
|
|
}
|
|
|
|
// WriteConcern sets the write concern.
|
|
func (db *DatabaseBundle) WriteConcern(wc *writeconcern.WriteConcern) *DatabaseBundle {
|
|
return &DatabaseBundle{
|
|
option: WriteConcern(wc),
|
|
next: db,
|
|
}
|
|
}
|
|
|
|
// ReadPreference sets the read preference.
|
|
func (db *DatabaseBundle) ReadPreference(rp *readpref.ReadPref) *DatabaseBundle {
|
|
return &DatabaseBundle{
|
|
option: ReadPreference(rp),
|
|
next: db,
|
|
}
|
|
}
|
|
|
|
// Unbundle unbundles the options, returning a collection.
|
|
func (db *DatabaseBundle) Unbundle() (*Database, error) {
|
|
database := &Database{}
|
|
err := db.unbundle(database)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return database, nil
|
|
}
|
|
|
|
// Helper that recursively unwraps the bundle.
|
|
func (db *DatabaseBundle) unbundle(database *Database) error {
|
|
if db == nil {
|
|
return nil
|
|
}
|
|
|
|
for head := db; head != nil && head.option != nil; head = head.next {
|
|
var err error
|
|
switch opt := head.option.(type) {
|
|
case *DatabaseBundle:
|
|
err = opt.unbundle(database) // add all bundle's options to database
|
|
case optionFunc:
|
|
err = opt(database) // add option to database
|
|
default:
|
|
return nil
|
|
}
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// String implements the Stringer interface
|
|
func (db *DatabaseBundle) String() string {
|
|
if db == nil {
|
|
return ""
|
|
}
|
|
|
|
str := ""
|
|
for head := db; head != nil && head.option != nil; head = head.next {
|
|
switch opt := head.option.(type) {
|
|
case *DatabaseBundle:
|
|
str += opt.String()
|
|
case optionFunc:
|
|
str += reflect.TypeOf(opt).String() + "\n"
|
|
}
|
|
}
|
|
|
|
return str
|
|
}
|
|
|
|
// ReadConcern sets the read concern.
|
|
func ReadConcern(rc *readconcern.ReadConcern) Option {
|
|
return optionFunc(
|
|
func(d *Database) error {
|
|
if d.ReadConcern == nil {
|
|
d.ReadConcern = rc
|
|
}
|
|
return nil
|
|
})
|
|
}
|
|
|
|
// WriteConcern sets the write concern.
|
|
func WriteConcern(wc *writeconcern.WriteConcern) Option {
|
|
return optionFunc(
|
|
func(d *Database) error {
|
|
if d.WriteConcern == nil {
|
|
d.WriteConcern = wc
|
|
}
|
|
return nil
|
|
})
|
|
}
|
|
|
|
// ReadPreference sets the read preference.
|
|
func ReadPreference(rp *readpref.ReadPref) Option {
|
|
return optionFunc(
|
|
func(d *Database) error {
|
|
if d.ReadPreference == nil {
|
|
d.ReadPreference = rp
|
|
}
|
|
return nil
|
|
})
|
|
}
|