github.com/wfusion/gofusion@v1.1.14/mongo/mongo.go (about)

     1  package mongo
     2  
     3  import (
     4  	"fmt"
     5  	"sync"
     6  
     7  	"go.mongodb.org/mongo-driver/bson/bsoncodec"
     8  	"go.mongodb.org/mongo-driver/mongo/options"
     9  	"go.mongodb.org/mongo-driver/mongo/readconcern"
    10  	"go.mongodb.org/mongo-driver/mongo/readpref"
    11  	"go.mongodb.org/mongo-driver/mongo/writeconcern"
    12  
    13  	"github.com/wfusion/gofusion/common/infra/drivers/mongo"
    14  	"github.com/wfusion/gofusion/common/utils"
    15  
    16  	mgoDrv "go.mongodb.org/mongo-driver/mongo"
    17  )
    18  
    19  var (
    20  	rwlock       = new(sync.RWMutex)
    21  	appInstances map[string]map[string]*instance
    22  )
    23  
    24  type instance struct {
    25  	name     string
    26  	database string
    27  	mongo    *mongo.Mongo
    28  }
    29  
    30  func (d *instance) GetProxy() *mgoDrv.Client {
    31  	return d.mongo.GetProxy()
    32  }
    33  
    34  func (d *instance) Database(opts ...*options.DatabaseOptions) *mgoDrv.Database {
    35  	return d.mongo.Database(d.database, opts...)
    36  }
    37  
    38  type Mongo struct {
    39  	*mgoDrv.Database
    40  	Name string
    41  }
    42  
    43  type useOption struct {
    44  	appName string
    45  
    46  	// readConcern is the read concern to use for operations executed on the Database.
    47  	// The default value is nil, which means that
    48  	// the read concern of the Client used to configure the Database will be used.
    49  	readConcern *readconcern.ReadConcern
    50  
    51  	// writeConcern is the write concern to use for operations executed on the Database.
    52  	// The default value is nil, which means that the
    53  	// write concern of the Client used to configure the Database will be used.
    54  	writeConcern *writeconcern.WriteConcern
    55  
    56  	// readPreference is the read preference to use for operations executed on the Database.
    57  	// The default value is nil, which means that
    58  	// the read preference of the Client used to configure the Database will be used.
    59  	readPreference *readpref.ReadPref
    60  
    61  	// bsonOptions configures optional BSON marshaling and unmarshaling
    62  	// behavior.
    63  	bsonOptions *options.BSONOptions
    64  
    65  	// registry is the BSON registry to marshal and unmarshal documents for operations executed on the Database.
    66  	// The default value is nil,
    67  	// which means that the registry of the Client used to configure the Database will be used.
    68  	registry *bsoncodec.Registry
    69  }
    70  
    71  func AppName(name string) utils.OptionFunc[useOption] {
    72  	return func(o *useOption) {
    73  		o.appName = name
    74  	}
    75  }
    76  
    77  func ReadConcern(readConcern *readconcern.ReadConcern) utils.OptionFunc[useOption] {
    78  	return func(o *useOption) {
    79  		o.readConcern = readConcern
    80  	}
    81  }
    82  func WriteConcern(writeConcern *writeconcern.WriteConcern) utils.OptionFunc[useOption] {
    83  	return func(o *useOption) {
    84  		o.writeConcern = writeConcern
    85  	}
    86  }
    87  func ReadPreference(readPreference *readpref.ReadPref) utils.OptionFunc[useOption] {
    88  	return func(o *useOption) {
    89  		o.readPreference = readPreference
    90  	}
    91  }
    92  func BsonOptions(bsonOptions *options.BSONOptions) utils.OptionFunc[useOption] {
    93  	return func(o *useOption) {
    94  		o.bsonOptions = bsonOptions
    95  	}
    96  }
    97  func Registry(registry *bsoncodec.Registry) utils.OptionFunc[useOption] {
    98  	return func(o *useOption) {
    99  		o.registry = registry
   100  	}
   101  }
   102  
   103  func Use(name string, opts ...utils.OptionExtender) *Mongo {
   104  	opt := utils.ApplyOptions[useOption](opts...)
   105  	dbOpt := options.
   106  		Database().
   107  		SetReadConcern(opt.readConcern).
   108  		SetWriteConcern(opt.writeConcern).
   109  		SetReadPreference(opt.readPreference).
   110  		SetBSONOptions(opt.bsonOptions).
   111  		SetRegistry(opt.registry)
   112  
   113  	rwlock.RLock()
   114  	defer rwlock.RUnlock()
   115  	instances, ok := appInstances[opt.appName]
   116  	if !ok {
   117  		panic(fmt.Errorf("mongo database instance not found for app: %s", opt.appName))
   118  	}
   119  	instance, ok := instances[name]
   120  	if !ok {
   121  		panic(fmt.Errorf("mongo database instance not found for name: %s", name))
   122  	}
   123  	return &Mongo{Database: instance.Database(dbOpt), Name: name}
   124  }