add mongodb.go file with all methodes provide by storage interface
This commit is contained in:
789
storage/mongodb.go
Normal file
789
storage/mongodb.go
Normal file
@@ -0,0 +1,789 @@
|
||||
package storage
|
||||
|
||||
import (
|
||||
"github.com/paulmach/orb"
|
||||
"github.com/paulmach/orb/geojson"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"github.com/spf13/viper"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
"solidarity-service/utils"
|
||||
"context"
|
||||
"github.com/google/uuid"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
_ "github.com/lib/pq"
|
||||
"github.com/rs/zerolog/log"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"solidarity-service/internal"
|
||||
|
||||
)
|
||||
|
||||
type MongoDBStorage struct {
|
||||
*mongo.Client
|
||||
DbName string
|
||||
Collections map[string]string
|
||||
}
|
||||
|
||||
func NewMongoDBStorage(cfg *viper.Viper) (MongoDBStorage, error) {
|
||||
var (
|
||||
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_groups = cfg.GetString("storage.db.mongodb.collections.groups")
|
||||
////////////////////////code
|
||||
mongodb_groups_members = cfg.GetString("storage.db.mongodb.collections.groups_member")
|
||||
)
|
||||
|
||||
client, err := mongo.NewClient(options.Client().ApplyURI("mongodb://" + mongodb_host + ":" + mongodb_port))
|
||||
if err != nil {
|
||||
return MongoDBStorage{}, err
|
||||
}
|
||||
|
||||
err = client.Connect(context.TODO())
|
||||
|
||||
if err != nil {
|
||||
return MongoDBStorage{}, err
|
||||
}
|
||||
|
||||
storage := MongoDBStorage{
|
||||
Client: client,
|
||||
DbName: mongodb_dbname,
|
||||
Collections: map[string]string{
|
||||
"groups": mongodb_groups,
|
||||
/////////////////////////////code
|
||||
"groups_member": mongodb_groups_members,
|
||||
},
|
||||
}
|
||||
//TODO Indexes
|
||||
return storage, err
|
||||
}
|
||||
|
||||
func (s MongoDBStorage) CreatePassenger(passenger internal.Passenger) (err error) {
|
||||
collection := s.Client.Database(s.DbName).Collection(s.Collections["users"])
|
||||
|
||||
_, err = uuid.Parse(passenger.Passenger.ID)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("MongoDB Storage CreatePassenger invalid ID")
|
||||
return err
|
||||
}
|
||||
|
||||
if passenger.Passenger.Alias == "" || passenger.Passenger.Operator == "" {
|
||||
errMsg := "MongoDB Storage CreatePassenger empty alias or operator FQDN."
|
||||
log.Error().Msg(errMsg)
|
||||
return errors.New(errMsg)
|
||||
}
|
||||
// preferencesJSON, err := json.Marshal(passenger.Preferences)
|
||||
if err != nil {
|
||||
errMsg := "MongoDB Storage CreatePassenger Error encoding Preferences to JSON"
|
||||
log.Error().Err(err).Msg(errMsg)
|
||||
return errors.New(errMsg + err.Error())
|
||||
}
|
||||
if _, err := collection.InsertOne(context.TODO(), passenger); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// if err != nil {
|
||||
// if strings.Contains(err.Error(), utils.SQL_DUPLICATE) {
|
||||
// err = s.UpdatePassenger(passenger)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
// return nil
|
||||
// }
|
||||
// errMsg := "Postgresql Storage CreatePassenger Error inserting data into the database"
|
||||
// log.Error().Err(err).Msg(errMsg)
|
||||
// return errors.New(errMsg + err.Error())
|
||||
// }
|
||||
return nil
|
||||
}
|
||||
func (s MongoDBStorage) UpdatePassenger(passenger internal.Passenger) (err error) {
|
||||
collection := s.Client.Database(s.DbName).Collection(s.Collections["users"])
|
||||
|
||||
_, err = uuid.Parse(passenger.Passenger.ID)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("MongoDB Storage UpdatePassenger invalid ID")
|
||||
return err
|
||||
}
|
||||
if passenger.Passenger.Alias == "" || passenger.Passenger.Operator == "" {
|
||||
errMsg := "MongoDB Storage UpdatePassenger empty alias or operator FQDN."
|
||||
log.Error().Msg(errMsg)
|
||||
return errors.New(errMsg)
|
||||
}
|
||||
// preferencesJSON, err := json.Marshal(passenger.Preferences)
|
||||
if err != nil {
|
||||
errMsg := "MongoDB Storage UpdatePassenger Error encoding Preferences to JSON"
|
||||
log.Error().Err(err).Msg(errMsg)
|
||||
return errors.New(errMsg + err.Error())
|
||||
}
|
||||
if _, err := collection.ReplaceOne(context.TODO(), bson.M{"_id": passenger.Passenger.ID}, passenger); err != nil {
|
||||
fmt.Println(err)
|
||||
return err
|
||||
}
|
||||
if err != nil {
|
||||
errMsg := "MongoDB Storage UpdatePassenger Error updating data in the database"
|
||||
log.Error().Err(err).Msg(errMsg)
|
||||
return errors.New(errMsg + err.Error())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s MongoDBStorage) GetPassenger(passengerID string) (passenger internal.Passenger, err error) {
|
||||
collection := s.Client.Database(s.DbName).Collection(s.Collections["users"])
|
||||
|
||||
var preferencesJSON []byte
|
||||
_ , err = uuid.Parse(passenger.Passenger.ID)
|
||||
if len(passengerID) == 0 {
|
||||
return passenger, errors.New("no group id provided")
|
||||
} else {
|
||||
_, err = collection.Find(context.TODO(), bson.M{"_id": bson.M{"$in": passengerID}})
|
||||
if err != nil {
|
||||
return passenger, err
|
||||
}
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
errMsg := "MongoDB Storage GetPassenger Error querying data from the database"
|
||||
log.Error().Err(err).Msg(errMsg)
|
||||
return passenger, errors.New(errMsg + err.Error())
|
||||
}
|
||||
|
||||
err = json.Unmarshal(preferencesJSON, &passenger.Preferences)
|
||||
if err != nil {
|
||||
errMsg := "MongoDB Storage GetPassenger Error decoding Preferences from JSON"
|
||||
log.Error().Err(err).Msg(errMsg)
|
||||
return passenger, errors.New(errMsg + err.Error())
|
||||
}
|
||||
return passenger, nil
|
||||
}
|
||||
|
||||
func (s MongoDBStorage) CreateDriver(driver internal.Driver) (err error) {
|
||||
collection := s.Client.Database(s.DbName).Collection(s.Collections["users"])
|
||||
//var availabilities []byte
|
||||
_, err = uuid.Parse(driver.Driver.ID)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("MongoDB Storage CreateDriver invalid ID")
|
||||
return err
|
||||
}
|
||||
//departureJSON, err := json.Marshal(driver.Driver_departure_address)
|
||||
if err != nil {
|
||||
errMsg := "MongoDB Storage CreateDriver Error encoding departure Feature to JSON"
|
||||
log.Error().Err(err).Msg(errMsg)
|
||||
return errors.New(errMsg + err.Error())
|
||||
}
|
||||
//preferencesJSON, err := json.Marshal(driver.Preferences)
|
||||
if err != nil {
|
||||
errMsg := "MongoDB Storage CreateDriver Error encoding Preferences to JSON"
|
||||
log.Error().Err(err).Msg(errMsg + err.Error())
|
||||
return errors.New(errMsg)
|
||||
}
|
||||
//carJSON, err := json.Marshal(driver.Car)
|
||||
if err != nil {
|
||||
errMsg := "MongoDB Storage CreateDriver Error encoding Car to JSON"
|
||||
log.Error().Err(err).Msg(errMsg)
|
||||
return errors.New(errMsg + err.Error())
|
||||
}
|
||||
if driver.Driver.Alias == "" || driver.Driver.Operator == "" {
|
||||
errMsg := "MongoDB Storage CreateDriver empty alias or operator FQDN."
|
||||
log.Error().Msg(errMsg)
|
||||
return errors.New(errMsg)
|
||||
}
|
||||
if driver.AvailabilitiesType != internal.Punctual && driver.AvailabilitiesType != internal.Regular {
|
||||
errMsg := "MongoDB Storage CreateDriver invalid Availabilities Type"
|
||||
log.Error().Msg(errMsg)
|
||||
return errors.New(errMsg)
|
||||
}
|
||||
if driver.Radius == 0 {
|
||||
errMsg := "MongoDB Storage CreateDriver Radius has to be defined"
|
||||
log.Error().Msg(errMsg)
|
||||
return errors.New(errMsg)
|
||||
}
|
||||
switch driver.AvailabilitiesType {
|
||||
case internal.Punctual:
|
||||
//availabilities, err = json.Marshal(driver.PunctualAvailabilities)
|
||||
if err != nil {
|
||||
errMsg := "MongoDB Storage CreateDriver error converting Punctual availabilities"
|
||||
log.Error().Msg(errMsg)
|
||||
return errors.New(errMsg + err.Error())
|
||||
}
|
||||
case internal.Regular:
|
||||
//availabilities, err = json.Marshal(driver.RegularAvailabilities)
|
||||
if err != nil {
|
||||
errMsg := "MongoDB Storage CreateDriver error converting Regular availabilities"
|
||||
log.Error().Msg(errMsg)
|
||||
return errors.New(errMsg + err.Error())
|
||||
}
|
||||
}
|
||||
if _, err := collection.InsertOne(context.TODO(), driver); err != nil {
|
||||
return err
|
||||
}
|
||||
// if err != nil {
|
||||
// if strings.Contains(err.Error(), utils.SQL_DUPLICATE) {
|
||||
// err = s.UpdateDriver(driver)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
// return nil
|
||||
// }
|
||||
// errMsg := "MongoDB Storage CreateDriver Error inserting data into the database"
|
||||
// log.Error().Err(err).Msg(errMsg)
|
||||
// return errors.New(errMsg + err.Error())
|
||||
// }
|
||||
return nil
|
||||
}
|
||||
func (s MongoDBStorage) UpdateDriver(driver internal.Driver) (err error) {
|
||||
collection := s.Client.Database(s.DbName).Collection(s.Collections["groups"])
|
||||
//var availabilities []byte
|
||||
_, err = uuid.Parse(driver.Driver.ID)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("MongoDB Storage UpdateDriver invalid ID")
|
||||
return err
|
||||
}
|
||||
//departureJSON, err := json.Marshal(driver.Driver_departure_address)
|
||||
if err != nil {
|
||||
errMsg := "MongoDB Storage UpdateDriver Error encoding departure Feature to JSON"
|
||||
log.Error().Err(err).Msg(errMsg)
|
||||
return errors.New(errMsg + err.Error())
|
||||
}
|
||||
//preferencesJSON, err := json.Marshal(driver.Preferences)
|
||||
if err != nil {
|
||||
errMsg := "MongoDB Storage UpdateDriver Error encoding Preferences to JSON"
|
||||
log.Error().Err(err).Msg(errMsg + err.Error())
|
||||
return errors.New(errMsg)
|
||||
}
|
||||
//carJSON, err := json.Marshal(driver.Car)
|
||||
if err != nil {
|
||||
errMsg := "MongoDB Storage UpdateDriver Error encoding Car to JSON"
|
||||
log.Error().Err(err).Msg(errMsg)
|
||||
return errors.New(errMsg + err.Error())
|
||||
}
|
||||
if driver.Driver.Alias == "" || driver.Driver.Operator == "" {
|
||||
errMsg := "MongoDB Storage UpdateDriver empty alias or operator FQDN."
|
||||
log.Error().Msg(errMsg)
|
||||
return errors.New(errMsg)
|
||||
}
|
||||
if driver.AvailabilitiesType != internal.Punctual && driver.AvailabilitiesType != internal.Regular {
|
||||
errMsg := "MongoDB Storage UpdateDriver invalid Availabilities Type"
|
||||
log.Error().Msg(errMsg)
|
||||
return errors.New(errMsg)
|
||||
}
|
||||
if driver.Radius == 0 {
|
||||
errMsg := "MongoDB Storage UpdateDriver Radius has to be defined"
|
||||
log.Error().Msg(errMsg)
|
||||
return errors.New(errMsg)
|
||||
}
|
||||
// switch driver.AvailabilitiesType {
|
||||
// case internal.Punctual:
|
||||
// availabilities, err = json.Marshal(driver.PunctualAvailabilities)
|
||||
// if err != nil {
|
||||
// errMsg := "MongoDB Storage UpdateDriver error converting Punctual availabilities"
|
||||
// log.Error().Msg(errMsg)
|
||||
// return errors.New(errMsg + err.Error())
|
||||
// }
|
||||
// case internal.Regular:
|
||||
// availabilities, err = json.Marshal(driver.RegularAvailabilities)
|
||||
// if err != nil {
|
||||
// errMsg := "MongoDB Storage UpdateDriver error converting Regular availabilities"
|
||||
// log.Error().Msg(errMsg)
|
||||
// return errors.New(errMsg + err.Error())
|
||||
// }
|
||||
// }
|
||||
|
||||
if _, err := collection.ReplaceOne(context.TODO(), bson.M{"_id": driver.Driver.ID}, driver); err != nil {
|
||||
fmt.Println(err)
|
||||
return err
|
||||
}
|
||||
if err != nil {
|
||||
errMsg := "MongoDB Storage UpdateDriver Error updating data in the database"
|
||||
log.Error().Err(err).Msg(errMsg)
|
||||
return errors.New(errMsg + err.Error())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s MongoDBStorage) GetDriver(driverID string) ( *internal.Driver, error) {
|
||||
collection := s.Client.Database(s.DbName).Collection(s.Collections["users"])
|
||||
// var preferencesJSON []byte
|
||||
// var departureAddress []byte
|
||||
// var availabilitiesJSON []byte
|
||||
// var carJSON []byte
|
||||
driver := &internal.Driver{}
|
||||
if err := collection.FindOne(context.TODO(), bson.M{"_id": driverID}).Decode(driver); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// if err != nil {
|
||||
// errMsg := "MongoDB Storage GetDriver Error querying data from the database"
|
||||
// log.Error().Err(err).Msg(errMsg)
|
||||
// return driver, errors.New(errMsg + err.Error())
|
||||
// }
|
||||
|
||||
// err = json.Unmarshal(preferencesJSON, &driver.Preferences)
|
||||
// if err != nil {
|
||||
// errMsg := "MongoDB Storage GetDriver Error decoding Preferences from JSON"
|
||||
// log.Error().Err(err).Msg(errMsg)
|
||||
// return driver, errors.New(errMsg + err.Error())
|
||||
// }
|
||||
// err = json.Unmarshal(carJSON, &driver.Car)
|
||||
// if err != nil {
|
||||
// errMsg := "MongoDB Storage GetDriver Error decoding Car from JSON"
|
||||
// log.Error().Err(err).Msg(errMsg)
|
||||
// return driver, errors.New(errMsg + err.Error())
|
||||
// }
|
||||
// driver.Driver_departure_address, err = geojson.UnmarshalFeature(departureAddress)
|
||||
// if err != nil {
|
||||
// errMsg := "MongoDB Storage GetDriver Error decoding Driver departure route into GeoJSON"
|
||||
// log.Error().Err(err).Msg(errMsg)
|
||||
// return driver, errors.New(errMsg + err.Error())
|
||||
// }
|
||||
|
||||
// switch driver.AvailabilitiesType {
|
||||
// case Regular:
|
||||
// err = json.Unmarshal(availabilitiesJSON, &driver.RegularAvailabilities)
|
||||
// if err != nil {
|
||||
// errMsg := "MongoDB Storage GetDriver Error decoding Regular Availabilities from JSON"
|
||||
// log.Error().Err(err).Msg(errMsg)
|
||||
// return driver, errors.New(errMsg + err.Error())
|
||||
// }
|
||||
// case Punctual:
|
||||
// err = json.Unmarshal(availabilitiesJSON, &driver.PunctualAvailabilities)
|
||||
// if err != nil {
|
||||
// errMsg := "MongoDB Storage GetDriver Error decoding Punctual Availabilities from JSON"
|
||||
// log.Error().Err(err).Msg(errMsg)
|
||||
// return driver, errors.New(errMsg + err.Error())
|
||||
// }
|
||||
// default:
|
||||
// errMsg := "MongoDB Storage GetDriver Invalid Availabilities Type"
|
||||
// log.Error().Msg(errMsg)
|
||||
// return driver, errors.New(errMsg + err.Error())
|
||||
// }
|
||||
|
||||
return driver, nil
|
||||
}
|
||||
|
||||
func (s MongoDBStorage) CreateBooking(booking internal.BookingRequest) (err error) {
|
||||
collection := s.Client.Database(s.DbName).Collection(s.Collections["users"])
|
||||
_, err = uuid.Parse(booking.Driver_id)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("MongoDB Storage CreateBooking invalid Driver ID")
|
||||
return err
|
||||
}
|
||||
_, err = uuid.Parse(booking.Passenger_id)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("MongoDB Storage CreateBooking invalid Passenger ID")
|
||||
return err
|
||||
}
|
||||
_, err = uuid.Parse(booking.ID)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("MongoDB Storage CreateBooking invalid Booking ID")
|
||||
return err
|
||||
}
|
||||
if booking.Operator == "" {
|
||||
log.Error().Err(err).Msg("MongoDB Storage CreateBooking empty operator")
|
||||
return err
|
||||
}
|
||||
//departureJSON, err := json.Marshal(booking.Departure_address)
|
||||
if err != nil {
|
||||
errMsg := "MongoDB Storage CreateBooking Error encoding departure Feature to JSON"
|
||||
log.Error().Err(err).Msg(errMsg)
|
||||
return errors.New(errMsg + err.Error())
|
||||
}
|
||||
|
||||
//destinationJSON, err := json.Marshal(booking.Destination_address)
|
||||
if err != nil {
|
||||
errMsg := "MongoDB Storage CreateBooking Error converting destination Feature to JSON"
|
||||
log.Error().Err(err).Msg(errMsg)
|
||||
return errors.New(errMsg + err.Error())
|
||||
}
|
||||
if booking.Pickup_date == 0 {
|
||||
errMsg := "MongoDB Storage CreateBooking empty UNIX pickup Date timestamp"
|
||||
log.Error().Err(err).Msg(errMsg)
|
||||
return errors.New(errMsg)
|
||||
}
|
||||
booking.Distance = utils.Haversine(booking.Departure_address.Point().Lat(), booking.Departure_address.Point().Lon(),
|
||||
booking.Destination_address.Point().Lat(), booking.Destination_address.Point().Lon())
|
||||
booking.Duration, _ = utils.CalculateDurationBetweenFeatures(booking.Departure_address, booking.Destination_address)
|
||||
if _, err := collection.InsertOne(context.TODO(), booking); err != nil {
|
||||
return err
|
||||
}
|
||||
if err != nil {
|
||||
errMsg := "MongoDB Storage CreateBooking Error inserting data into the database"
|
||||
log.Error().Err(err).Msg(errMsg)
|
||||
return errors.New(errMsg + err.Error())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s MongoDBStorage) GetBooking(bookingID string) (*internal.Booking, error) {
|
||||
collection := s.Client.Database(s.DbName).Collection(s.Collections["users"])
|
||||
//var departureAddress []byte
|
||||
//var destinationAddress []byte
|
||||
booking := &internal.Booking{}
|
||||
if err := collection.FindOne(context.TODO(), bson.M{"_id": bookingID}).Decode(booking); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// if err != nil {
|
||||
// errMsg := "MongoDB Storage GetBooking Error getting booking"
|
||||
// log.Error().Err(err).Msg(errMsg)
|
||||
// return internal.Booking{}, errors.New(errMsg + err.Error())
|
||||
// }
|
||||
// booking.PassengerPickupAddress, err = geojson.UnmarshalFeature(departureAddress)
|
||||
// if err != nil {
|
||||
// errMsg := "MongoDB Storage GetBooking Error decoding Driver departure route into GeoJSON"
|
||||
// log.Error().Err(err).Msg(errMsg)
|
||||
// return internal.Booking{}, errors.New(errMsg + err.Error())
|
||||
// }
|
||||
// booking.PassengerDropAddress, err = geojson.UnmarshalFeature(destinationAddress)
|
||||
// if err != nil {
|
||||
// errMsg := "MongoDB Storage GetBooking Error decoding Driver destination route into GeoJSON"
|
||||
// log.Error().Err(err).Msg(errMsg)
|
||||
// return internal.Booking{}, errors.New(errMsg + err.Error())
|
||||
// }
|
||||
passenger, err := s.GetPassenger(booking.Passenger.ID)
|
||||
if err != nil {
|
||||
errMsg := "MongoDB Storage GetBooking Error getting passenger"
|
||||
log.Error().Err(err).Msg(errMsg)
|
||||
return booking, errors.New(errMsg + err.Error())
|
||||
}
|
||||
booking.Passenger = passenger.Passenger
|
||||
driver, err := s.GetDriver(booking.Driver.ID)
|
||||
if err != nil {
|
||||
errMsg := "MongoDB Storage GetBooking Error getting driver"
|
||||
log.Error().Err(err).Msg(errMsg)
|
||||
return booking, errors.New(errMsg + err.Error())
|
||||
}
|
||||
booking.Driver = driver.Driver
|
||||
return booking, nil
|
||||
}
|
||||
|
||||
func (s MongoDBStorage) UpdateBookingStatus(bookingStatusID string, status internal.BookingStatus) (err error) {
|
||||
collection := s.Client.Database(s.DbName).Collection(s.Collections["users"])
|
||||
_, err = uuid.Parse(bookingStatusID)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("MongoDB Storage UpdateBookingStatus invalid Booking ID")
|
||||
return err
|
||||
}
|
||||
_, err = s.GetBooking(bookingStatusID)
|
||||
if err != nil {
|
||||
return errors.New(err.Error())
|
||||
}
|
||||
if _, err := collection.ReplaceOne(context.TODO(), bson.M{"_id": bookingStatusID}, status); err != nil {
|
||||
fmt.Println(err)
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s MongoDBStorage) FilterUserBookingsByStatus(userType string, status internal.BookingStatus, userID string) (bookings []internal.Booking, err error) {
|
||||
collection := s.Client.Database(s.DbName).Collection(s.Collections["groups"])
|
||||
if err != nil {
|
||||
return nil, errors.New("invalid UUID")
|
||||
}
|
||||
|
||||
if userType != "driver" && userType != "passenger" {
|
||||
return nil, errors.New("invalid user type")
|
||||
}
|
||||
|
||||
var cur *mongo.Cursor
|
||||
|
||||
findOptions := options.Find()
|
||||
|
||||
if len(userID) == 0 {
|
||||
return bookings, errors.New("no group id provided")
|
||||
} else {
|
||||
cur, err = collection.Find(context.TODO(), bson.M{"_id": bson.M{"$in": userID}}, findOptions)
|
||||
if err != nil {
|
||||
return bookings, err
|
||||
}
|
||||
}
|
||||
|
||||
for cur.Next(context.TODO()) {
|
||||
var group internal.Booking
|
||||
var elem bson.M
|
||||
|
||||
if err := cur.Decode(&elem); err != nil {
|
||||
return bookings, err
|
||||
}
|
||||
|
||||
bsonBytes, _ := bson.Marshal(elem)
|
||||
bson.Unmarshal(bsonBytes, &group)
|
||||
|
||||
bookings = append(bookings, group)
|
||||
|
||||
}
|
||||
var wg sync.WaitGroup
|
||||
//var mu sync.Mutex
|
||||
|
||||
// for rows.Next() {
|
||||
// var departureAddress []byte
|
||||
// var destinationAddress []byte
|
||||
// var booking internal.Booking
|
||||
|
||||
// if err := rows.Scan(&booking.ID, &booking.Passenger.ID, &booking.Driver.ID, &booking.Status, &departureAddress, &destinationAddress, &booking.Pickup_date, &booking.Duration, &booking.Distance); err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
|
||||
// wg.Add(1)
|
||||
// go func(booking internal.Booking, departureAddress, destinationAddress []byte) {
|
||||
// defer wg.Done()
|
||||
|
||||
// // Common logic for both "driver" and "passenger" cases
|
||||
// booking, err := s.populateBookingDetails(booking, departureAddress, destinationAddress)
|
||||
// if err != nil {
|
||||
// mu.Lock()
|
||||
// err = fmt.Errorf("Error populating booking details: %w", err)
|
||||
// mu.Unlock()
|
||||
// return
|
||||
// }
|
||||
|
||||
// mu.Lock()
|
||||
// bookings = append(bookings, booking)
|
||||
// mu.Unlock()
|
||||
// }(booking, departureAddress, destinationAddress)
|
||||
// }
|
||||
|
||||
// Wait for all goroutines to finish
|
||||
wg.Wait()
|
||||
|
||||
// if err := rows.Err(); err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
|
||||
return bookings, nil
|
||||
}
|
||||
|
||||
func (s MongoDBStorage) populateBookingDetails(booking internal.Booking, departureAddress, destinationAddress []byte) (internal.Booking, error) {
|
||||
var wg sync.WaitGroup
|
||||
var mu sync.Mutex
|
||||
errCh := make(chan error, 4) // Buffered channel to handle potential errors
|
||||
|
||||
// Concurrently fetch passenger information
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
|
||||
passenger, err := s.GetPassenger(booking.Passenger.ID)
|
||||
if err != nil {
|
||||
errCh <- fmt.Errorf("MongoDB Storage GetBooking Error getting passenger: %w", err)
|
||||
return
|
||||
}
|
||||
|
||||
mu.Lock()
|
||||
booking.Passenger = passenger.Passenger
|
||||
mu.Unlock()
|
||||
}()
|
||||
|
||||
// Concurrently fetch driver information
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
|
||||
driver, err := s.GetDriver(booking.Driver.ID)
|
||||
if err != nil {
|
||||
errCh <- fmt.Errorf("MongoDB Storage GetBooking Error getting driver: %w", err)
|
||||
return
|
||||
}
|
||||
|
||||
mu.Lock()
|
||||
booking.Driver = driver.Driver
|
||||
mu.Unlock()
|
||||
}()
|
||||
|
||||
// Concurrently decode departureAddress into GeoJSON
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
|
||||
decodedDepartureAddress, err := geojson.UnmarshalFeature(departureAddress)
|
||||
if err != nil {
|
||||
errCh <- fmt.Errorf("MongoDB Storage FilterBookingsByStatus Error decoding Driver departure route into GeoJSON: %w", err)
|
||||
return
|
||||
}
|
||||
|
||||
mu.Lock()
|
||||
booking.PassengerPickupAddress = decodedDepartureAddress
|
||||
mu.Unlock()
|
||||
}()
|
||||
|
||||
// Concurrently decode destinationAddress into GeoJSON
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
|
||||
decodedDestinationAddress, err := geojson.UnmarshalFeature(destinationAddress)
|
||||
if err != nil {
|
||||
errCh <- fmt.Errorf("MongoDB Storage FilterBookingsByStatus Error decoding Driver destination route into GeoJSON: %w", err)
|
||||
return
|
||||
}
|
||||
|
||||
mu.Lock()
|
||||
booking.PassengerDropAddress = decodedDestinationAddress
|
||||
mu.Unlock()
|
||||
}()
|
||||
|
||||
// Close the error channel after all goroutines are done
|
||||
go func() {
|
||||
wg.Wait()
|
||||
close(errCh)
|
||||
}()
|
||||
|
||||
// Check for errors using a select statement
|
||||
for err := range errCh {
|
||||
return internal.Booking{}, err // Return the first error encountered
|
||||
}
|
||||
|
||||
return booking, nil
|
||||
}
|
||||
|
||||
func (s MongoDBStorage) GetAllDrivers( date int64) (drivers []internal.Driver, err error) {
|
||||
// rows := s.Client.Database(s.DbName).Collection(s.Collections["users"])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// defer rows.Close()
|
||||
|
||||
//for rows.Next(ctx) {
|
||||
var driver internal.Driver
|
||||
var departureRoute []byte
|
||||
var preferencesJSON []byte
|
||||
var availabilitiesJSON []byte
|
||||
var carJSON []byte
|
||||
|
||||
// if err := rows.Scan(
|
||||
// &driver.Driver.ID,
|
||||
// &departureRoute,
|
||||
// &driver.Radius,
|
||||
// &driver.Driver.LastName,
|
||||
// &driver.Driver.FirstName,
|
||||
// &driver.Driver.Grade,
|
||||
// &driver.Driver.Alias,
|
||||
// &driver.Driver.Picture,
|
||||
// &driver.Driver.VerifiedIdentity,
|
||||
// &preferencesJSON,
|
||||
// &driver.AvailabilitiesType,
|
||||
// &availabilitiesJSON,
|
||||
// &driver.Driver.Operator,
|
||||
// &carJSON,
|
||||
// ); err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
|
||||
if err := json.Unmarshal(departureRoute, &driver.Driver_departure_address); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := json.Unmarshal(preferencesJSON, &driver.Preferences); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := json.Unmarshal(carJSON, &driver.Car); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Filter drivers based on date and time matching punctual or regular availabilities.
|
||||
if driver.AvailabilitiesType == internal.Punctual {
|
||||
if err := json.Unmarshal(availabilitiesJSON, &driver.PunctualAvailabilities); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
year, month, day := time.Unix(date, 0).Date()
|
||||
dateHour := time.Unix(date, 0).UTC().Local()
|
||||
dateHour_string := dateHour.Format("3:04 PM")
|
||||
for _, avail := range driver.PunctualAvailabilities {
|
||||
availyear, availmonth, availday := time.Unix(avail.Date, 0).Date()
|
||||
if availyear == year && availmonth == month && availday == day {
|
||||
startTime, err := time.Parse("3:04 PM", avail.StartTime)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
endTime, err := time.Parse("3:04 PM", avail.EndTime)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Convert DateHour_string to time.Time
|
||||
dateHourTime, err := time.Parse("3:04 PM", dateHour_string)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if dateHourTime.After(startTime) || dateHourTime.Equal(startTime) {
|
||||
if dateHourTime.Before(endTime) || dateHourTime.Equal(endTime) {
|
||||
drivers = append(drivers, driver)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
// Check if the date and time match the punctual driver's availability.
|
||||
|
||||
}
|
||||
} else if driver.AvailabilitiesType == internal.Regular {
|
||||
if err := json.Unmarshal(availabilitiesJSON, &driver.RegularAvailabilities); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
dayOfWeek := strings.ToLower(time.Unix(date, 0).Local().Format("Mon"))
|
||||
dateHour := time.Unix(date, 0).UTC().Local()
|
||||
dateHour_string := dateHour.Format("3:04 PM")
|
||||
|
||||
for _, avail := range driver.RegularAvailabilities {
|
||||
|
||||
// Check if the day and time match the regular driver's availability.
|
||||
if strings.ToLower(avail.DayOfWeek) == dayOfWeek {
|
||||
startTime, err := time.Parse("3:04 PM", avail.StartTime)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
endTime, err := time.Parse("3:04 PM", avail.EndTime)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Convert DateHour_string to time.Time
|
||||
dateHourTime, err := time.Parse("3:04 PM", dateHour_string)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if dateHourTime.After(startTime) || dateHourTime.Equal(startTime) {
|
||||
if dateHourTime.Before(endTime) || dateHourTime.Equal(endTime) {
|
||||
drivers = append(drivers, driver)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//}
|
||||
|
||||
// if err := rows.Err(); err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
|
||||
return drivers, nil
|
||||
}
|
||||
|
||||
func (s MongoDBStorage) DriverJourneys(departure_route *geojson.Feature, departure_date int64) (drivers []internal.Driver, err error) {
|
||||
allDrivers, err := s.GetAllDrivers(departure_date)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, driver := range allDrivers {
|
||||
// Check if the departure route is the same as the driver's departure route.
|
||||
if departure_route.Point().Y() == driver.Driver_departure_address.Point().Y() && departure_route.Point().X() == driver.Driver_departure_address.Point().X() {
|
||||
drivers = append(drivers, driver)
|
||||
} else {
|
||||
// Calculate the distance between the departure point and the driver's departure route.
|
||||
coords1 := departure_route.Geometry.(orb.Point)
|
||||
coords2 := driver.Driver_departure_address.Geometry.(orb.Point)
|
||||
distance := utils.Haversine(coords1[1], coords1[0], coords2[1], coords2[0])
|
||||
if int64(distance) <= int64(driver.Radius) {
|
||||
drivers = append(drivers, driver)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return drivers, nil
|
||||
}
|
||||
Reference in New Issue
Block a user