140 lines
3.2 KiB
Go
140 lines
3.2 KiB
Go
package dal
|
||
|
||
import (
|
||
//"bitbucket.org/skeris/bbfoundation/sse"
|
||
"context"
|
||
"strings"
|
||
"time"
|
||
|
||
"github.com/themakers/hlog"
|
||
"go.mongodb.org/mongo-driver/mongo"
|
||
"go.mongodb.org/mongo-driver/mongo/options"
|
||
"go.mongodb.org/mongo-driver/mongo/readpref"
|
||
)
|
||
|
||
//#region ======== Data Access Layer structs ========
|
||
|
||
// MongoConnection - Constructor LayerMongoDb
|
||
type MongoConnection struct {
|
||
conn *mongo.Client // Mongo connected pairCache
|
||
hl hlog.Logger // HLogger for Data Access Layer
|
||
opts MongoDbOptions // Database options
|
||
db *mongo.Database // Database
|
||
coll map[string]*mongo.Collection // Collections map
|
||
}
|
||
|
||
// MongoDbOptions - Connect params
|
||
type MongoDbOptions struct {
|
||
DalName string // Name of the Data Access Layer
|
||
URI string // MongoDB URI
|
||
DbTable string // MongoDB name
|
||
Collections string // MongoDB list collection names
|
||
}
|
||
|
||
//#endregion
|
||
|
||
//#region ======== Data Access Layer Constructor ========
|
||
|
||
// CreateMongo подключается к MongoDB.
|
||
//
|
||
// Input:
|
||
// ctx - Application context
|
||
// hlogger - Application logger
|
||
// opts - Application options for MongoDB
|
||
//
|
||
// Return: MongoConnection, error
|
||
//
|
||
// Logger:
|
||
// ErrorDalNewClient - mongo.NewClient return error
|
||
// ErrorDalUnableToConnect - Unable to connect to MongoDB
|
||
// InfoDalConnected - Successfully connected to MongoDB
|
||
func CreateMongo(ctx context.Context, hlogger hlog.Logger, opts MongoDbOptions) (*MongoConnection, error) {
|
||
hlogger = hlogger.With(opts)
|
||
|
||
conn, err := mongo.NewClient(options.Client().ApplyURI(opts.URI))
|
||
|
||
if err != nil {
|
||
hlogger.Emit(ErrorDalNewClient{err})
|
||
return nil, err
|
||
}
|
||
|
||
ctxTO, cancel := context.WithTimeout(ctx, 10*time.Second)
|
||
defer cancel()
|
||
|
||
err = conn.Connect(ctxTO)
|
||
|
||
if err != nil {
|
||
hlogger.Emit(ErrorDalUnableToConnect{err})
|
||
}
|
||
|
||
collections := map[string]*mongo.Collection{}
|
||
|
||
for _, name := range strings.Split(opts.Collections, ",") {
|
||
collections[name] = conn.Database(opts.DbTable).Collection(name)
|
||
}
|
||
|
||
mongoConn := &MongoConnection{
|
||
conn: conn,
|
||
hl: hlogger,
|
||
opts: opts,
|
||
db: conn.Database(opts.DbTable),
|
||
coll: collections,
|
||
}
|
||
|
||
_, err = mongoConn.Ping(ctx)
|
||
|
||
if err == nil {
|
||
hlogger.Emit(InfoDalConnected{})
|
||
}
|
||
|
||
return mongoConn, err
|
||
}
|
||
|
||
//#endregion
|
||
|
||
//#region ======== Data Access Layer functions ========
|
||
|
||
// DisconnectFromDb разрывает соединение с MongoDB
|
||
//
|
||
// Return: error
|
||
//
|
||
// Logger:
|
||
// ErrorDalDisconnectFailure - Something is wrong
|
||
// InfoDalDisconnected - Successfully disconnected from MongoDB
|
||
func (mc *MongoConnection) DisconnectFromDb() error {
|
||
err := mc.conn.Disconnect(context.TODO())
|
||
|
||
if err != nil {
|
||
mc.hl.Emit(ErrorDalDisconnectFailure{err})
|
||
}
|
||
|
||
mc.hl.Emit(InfoDalDisconnected{})
|
||
|
||
return err
|
||
}
|
||
|
||
// Ping пингует соединение MongoDB.
|
||
//
|
||
// Return:
|
||
// int64 - ping delay in milliseconds
|
||
// error
|
||
//
|
||
// Logger:
|
||
// ErrorDalPingFailed - Ping received an error
|
||
// InfoDalPing - Ping delay in milliseconds
|
||
func (mc *MongoConnection) Ping(ctx context.Context) (int64, error) {
|
||
start := time.Now()
|
||
err := mc.conn.Ping(ctx, readpref.Primary())
|
||
delay := time.Since(start).Milliseconds()
|
||
|
||
if err != nil {
|
||
mc.hl.Emit(ErrorDalPingFailed{err})
|
||
} else {
|
||
mc.hl.Emit(InfoDalPing{delay})
|
||
}
|
||
|
||
return delay, err
|
||
}
|
||
|
||
//#endregion
|