package storage import ( "context" "fmt" "git.coopgo.io/coopgo-platform/solidarity-transport/types" "github.com/google/uuid" "github.com/rs/zerolog/log" "github.com/spf13/viper" "go.mongodb.org/mongo-driver/v2/bson" "go.mongodb.org/mongo-driver/v2/mongo" "go.mongodb.org/mongo-driver/v2/mongo/options" ) type MongoDBCollections struct { DriversRegularAvailabilities *mongo.Collection Bookings *mongo.Collection DriverJourneys *mongo.Collection } type MongoDBStorage struct { Client *mongo.Client DbName string Collections MongoDBCollections } func NewMongoDBStorage(cfg *viper.Viper) (MongoDBStorage, error) { var ( mongodb_uri = cfg.GetString("storage.db.mongodb.uri") mongodb_host = cfg.GetString("storage.db.mongodb.host") mongodb_port = cfg.GetString("storage.db.mongodb.port") mongodb_dbname = cfg.GetString("storage.db.mongodb.db_name") mongodb_drivers_regular_availabilities = cfg.GetString("storage.db.mongodb.collections.drivers_regular_availabilities") mongodb_bookings = cfg.GetString("storage.db.mongodb.collections.bookings") mongodb_driver_journeys = cfg.GetString("storage.db.mongodb.collections.driver_journeys") ) if mongodb_uri == "" { mongodb_uri = fmt.Sprintf("mongodb://%s:%s/%s", mongodb_host, mongodb_port, mongodb_dbname) } client, err := mongo.Connect(options.Client().ApplyURI(mongodb_uri)) if err != nil { return MongoDBStorage{}, err } log.Info().Str("regular availabilities", mongodb_drivers_regular_availabilities).Str("bookings", mongodb_bookings).Msg("mongodb collections") return MongoDBStorage{ Client: client, DbName: mongodb_dbname, Collections: MongoDBCollections{ DriversRegularAvailabilities: client.Database(mongodb_dbname).Collection(mongodb_drivers_regular_availabilities), Bookings: client.Database(mongodb_dbname).Collection(mongodb_bookings), DriverJourneys: client.Database(mongodb_dbname).Collection(mongodb_driver_journeys), }, }, nil } func (s MongoDBStorage) CreateDriverRegularAvailability(availability types.DriverRegularAvailability) error { if availability.ID == "" { availability.ID = uuid.NewString() } if _, err := s.Collections.DriversRegularAvailabilities.InsertOne(context.Background(), availability); err != nil { log.Error().Err(err).Msg("CreateDriverAvailability error") return err } return nil } func (s MongoDBStorage) CreateDriverRegularAvailabilities(availabilities []*types.DriverRegularAvailability) error { for _, availability := range availabilities { if availability.ID == "" { availability.ID = uuid.NewString() } } if _, err := s.Collections.DriversRegularAvailabilities.InsertMany(context.Background(), availabilities); err != nil { log.Error().Err(err).Msg("CreateDriverAvailabilities error") return err } return nil } func (s MongoDBStorage) DeleteDriverRegularAvailability(driverid string, availabilityid string) error { if _, err := s.Collections.DriversRegularAvailabilities.DeleteOne(context.Background(), bson.M{"_id": availabilityid, "driver_id": driverid}); err != nil { log.Error().Err(err).Msg("DeleteDriverRegularAvailability error") return err } return nil } func (s MongoDBStorage) GetDriverRegularAvailability(driverid string, availabilityid string) (*types.DriverRegularAvailability, error) { var result types.DriverRegularAvailability if err := s.Collections.DriversRegularAvailabilities.FindOne(context.Background(), bson.M{"_id": availabilityid, "driver_id": driverid}).Decode(&result); err != nil { log.Error().Err(err).Msg("GetDriverRegularAvailability - error") return nil, err } return &result, nil } func (s MongoDBStorage) GetDriverRegularAvailabilities(driverid string) ([]*types.DriverRegularAvailability, error) { result := []*types.DriverRegularAvailability{} cur, err := s.Collections.DriversRegularAvailabilities.Find(context.Background(), bson.M{"driver_id": driverid}) if err != nil { log.Error().Err(err).Msg("GetDriverAvailabilities DB find - error") return nil, err } if err = cur.All(context.Background(), &result); err != nil { log.Error().Err(err).Msg("GetDriverAvailabilities cursor decoding - error") return nil, err } return result, nil } func (s MongoDBStorage) GetRegularAvailabilities(day int, timeInDay string) ([]*types.DriverRegularAvailability, error) { result := []*types.DriverRegularAvailability{} cur, err := s.Collections.DriversRegularAvailabilities.Find(context.Background(), bson.M{ "day": day, "start_time": bson.M{"$lt": timeInDay}, "end_time": bson.M{"$gt": timeInDay}, }) if err != nil { log.Error().Err(err).Msg("GetDriverAvailabilities DB find - error") return nil, err } if err = cur.All(context.Background(), &result); err != nil { log.Error().Err(err).Msg("GetDriverAvailabilities cursor decoding - error") return nil, err } return result, nil } func (s MongoDBStorage) PushDriverJourneys(driverjourneys []*types.DriverJourney) error { for _, journey := range driverjourneys { if journey.Id == "" { journey.Id = uuid.NewString() } } if _, err := s.Collections.DriverJourneys.InsertMany(context.Background(), driverjourneys); err != nil { log.Error().Err(err).Msg("PushDriverJourneys error") return err } return nil } func (s MongoDBStorage) GetDriverJourney(id string) (*types.DriverJourney, error) { var res types.DriverJourney err := s.Collections.DriverJourneys.FindOne(context.Background(), bson.M{"_id": id}).Decode(&res) if err != nil { return nil, err } return &res, nil } func (s MongoDBStorage) CreateBooking(booking types.Booking) error { if booking.Id == "" { booking.Id = uuid.NewString() } if _, err := s.Collections.Bookings.InsertOne(context.Background(), booking); err != nil { log.Error().Err(err).Msg("CreateBooking error") return err } return nil } func (s MongoDBStorage) GetAllBookings() ([]*types.Booking, error) { res := []*types.Booking{} cur, err := s.Collections.Bookings.Find(context.Background(), bson.M{}) if err != nil { return nil, err } err = cur.All(context.Background(), &res) return res, err } func (s MongoDBStorage) GetBooking(id string) (*types.Booking, error) { var res types.Booking err := s.Collections.Bookings.FindOne(context.Background(), bson.M{"_id": id}).Decode(&res) if err != nil { return nil, err } return &res, nil } func (s MongoDBStorage) UpdateBookingStatus(bookingid string, newStatus string) error { // filter := bson.M{"_id": bookingid} replacement := bson.M{"$set": bson.M{"status": newStatus}} if _, err := s.Collections.Bookings.UpdateByID(context.Background(), bookingid, replacement); err != nil { return err } return nil }