package dal import ( "context" "github.com/themakers/hlog" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" "go.mongodb.org/mongo-driver/mongo/readpref" "strings" "time" ) //#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