package dbAccess import ( "git.fjla.uk/owlboard/timetable-mgr/helpers" "git.fjla.uk/owlboard/timetable-mgr/log" "go.uber.org/zap" "context" "time" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" ) // Provide the DB Connection to other functions var MongoClient (*mongo.Client) // Builds the DB URI based on the loaded configuration parameters func getDbUri(cfg *helpers.Configuration) string { var uri = "mongodb://" + cfg.DbUser + ":" + cfg.DbPass + "@" + cfg.DbHost + ":" + cfg.DbPort return uri } // Configure bsonOpts var bsonOpts = &options.BSONOptions{ UseJSONStructTags: true, } func InitDataAccess(cfg *helpers.Configuration) { log.Debug("Starting database connection") url := getDbUri(cfg) const maxRetries = 8 for attempt := 1; attempt <= maxRetries; attempt++ { log.Info("Attempting to connect to database", zap.Int("attempt", attempt), zap.Int("max-tries", maxRetries)) ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() client, err := mongo.Connect(ctx, options.Client().ApplyURI(url).SetBSONOptions(bsonOpts)) if err != nil { log.Warn("Error connecting to database", zap.Int("attempt", attempt), zap.Int("max-tries", maxRetries)) cancel() if attempt != maxRetries { helpers.BackoffDelay(attempt) } continue } err = client.Ping(ctx, nil) if err != nil { log.Warn("Error pinging database", zap.Int("attempt", attempt), zap.Int("max-tries", maxRetries)) cancel() if attempt != maxRetries { helpers.BackoffDelay(attempt) } continue } MongoClient = client log.Info("Database connection successful") return } log.Fatal("Failed to connect to database on multiple attempts", zap.Int("attempts", maxRetries)) } // Closes the connection to the database - used for cleanup functions func CloseMongoClient() { if MongoClient != nil { ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() if err := MongoClient.Disconnect(ctx); err != nil { log.Warn("Error disconnecting MongoDB client: " + err.Error()) } else { log.Info("MongoDB client disconnected.") } } }