first commit

This commit is contained in:
2023-10-20 13:41:39 +02:00
commit 6696cd3152
65 changed files with 11374 additions and 0 deletions

558
storage/postgresql.go Normal file
View File

@@ -0,0 +1,558 @@
package storage
import (
"database/sql"
"encoding/json"
"errors"
"fmt"
"github.com/google/uuid"
_ "github.com/lib/pq"
"github.com/paulmach/orb"
"github.com/paulmach/orb/geojson"
"github.com/rs/zerolog/log"
"github.com/spf13/viper"
"solidarity-service/internal"
"solidarity-service/servers/utils"
"strconv"
"strings"
"time"
)
type PostgresqlStorage struct {
DbConnection *sql.DB
Schema string
Tables map[string]string
}
func NewPostgresqlStorage(cfg *viper.Viper) (PostgresqlStorage, error) {
var (
host = cfg.GetString("storage.db.psql.host")
port = cfg.GetString("storage.db.psql.port")
user = cfg.GetString("storage.db.psql.user")
password = cfg.GetString("storage.db.psql.password")
dbname = cfg.GetString("storage.db.psql.dbname")
sslmode = cfg.GetString("storage.db.psql.sslmode")
pg_schema = cfg.GetString("storage.db.psql.schema")
pgtables_drivers = cfg.GetString("storage.db.psql.tables.drivers")
pgtables_passengers = cfg.GetString("storage.db.psql.tables.passengers")
pgtables_bookings = cfg.GetString("storage.db.psql.tables.bookings")
)
portInt, _ := strconv.Atoi(port)
psqlconn := fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=%s sslmode=%s", host, portInt, user, password, dbname, sslmode)
db, err := sql.Open("postgres", psqlconn)
if err != nil {
log.Error().Err(err).Msg("opening connection to postgresql failed")
return PostgresqlStorage{}, fmt.Errorf("connection to postgresql failed")
}
err = db.Ping()
if err != nil {
log.Error().Err(err).Msg("ping to postgresql failed")
return PostgresqlStorage{}, fmt.Errorf("connection to postgresql database failed")
}
return PostgresqlStorage{
DbConnection: db,
Schema: pg_schema,
Tables: map[string]string{
"drivers": fmt.Sprintf("%s.%s", pg_schema, pgtables_drivers),
"bookings": fmt.Sprintf("%s.%s", pg_schema, pgtables_bookings),
"passengers": fmt.Sprintf("%s.%s", pg_schema, pgtables_passengers),
},
}, nil
}
func (s PostgresqlStorage) CreatePassenger(passenger internal.Passenger) (err error) {
_, err = uuid.Parse(passenger.Passenger.ID)
if err != nil {
log.Error().Err(err).Msg("Postgresql Storage CreatePassenger invalid ID")
return err
}
if passenger.Passenger_pickup_date == 0 {
errMsg := "Postgresql Storage CreatePassenger empty UNIX pickup Date timestamp"
log.Error().Err(err).Msg(errMsg)
return errors.New(errMsg)
}
if passenger.Passenger.Alias == "" || passenger.Passenger.Operator == "" {
errMsg := "Postgresql 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 := "Postgresql Storage CreatePassenger Error encoding Preferences to JSON"
log.Error().Err(err).Msg(errMsg)
return errors.New(errMsg)
}
departureJSON, err := json.Marshal(passenger.Passenger_departure_address)
if err != nil {
errMsg := "Postgresql Storage CreatePassenger Error encoding departure Feature to JSON"
log.Error().Err(err).Msg(errMsg)
return errors.New(errMsg)
}
destinationJSON, err := json.Marshal(passenger.Passenger_destination_address)
if err != nil {
errMsg := "Postgresql Storage CreatePassenger Error converting destination Feature to JSON"
log.Error().Err(err).Msg(errMsg)
return errors.New(errMsg)
}
_, err = s.DbConnection.Exec(fmt.Sprintf("INSERT INTO %s (passenger_id, passenger_departure_route, passenger_destination_route, alias, last_name, first_name, grade, picture, verified_identity, operator, preferences, passenger_pickup_date) VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12)", s.Tables["passengers"]),
passenger.Passenger.ID,
departureJSON,
destinationJSON,
passenger.Passenger.Alias,
passenger.Passenger.LastName,
passenger.Passenger.FirstName,
passenger.Passenger.Grade,
passenger.Passenger.Picture,
passenger.Passenger.VerifiedIdentity,
passenger.Passenger.Operator,
preferencesJSON,
passenger.Passenger_pickup_date)
if err != nil {
errMsg := "Postgresql Storage CreatePassenger Error inserting data into the database"
log.Error().Err(err).Msg(errMsg)
return errors.New(errMsg)
}
return nil
}
func (s PostgresqlStorage) GetPassenger(passengerID string) (passenger internal.Passenger, err error) {
var preferencesJSON []byte
var departure_address []byte
var destination_address []byte
err = s.DbConnection.QueryRow(fmt.Sprintf("SELECT passenger_departure_route, passenger_destination_route, alias, last_name, first_name, grade, picture, verified_identity, operator, preferences, passenger_pickup_date , passenger_id FROM %s WHERE passenger_id = $1", s.Tables["passengers"]), passengerID).
Scan(
&departure_address,
&destination_address,
&passenger.Passenger.Alias,
&passenger.Passenger.LastName,
&passenger.Passenger.FirstName,
&passenger.Passenger.Grade,
&passenger.Passenger.Picture,
&passenger.Passenger.VerifiedIdentity,
&passenger.Passenger.Operator,
&preferencesJSON,
&passenger.Passenger_pickup_date,
&passenger.Passenger.ID,
)
if err != nil {
fmt.Println(err)
errMsg := "Postgresql Storage GetPassenger Error querying data from the database"
log.Error().Err(err).Msg(errMsg)
return passenger, errors.New(errMsg)
}
err = json.Unmarshal(preferencesJSON, &passenger.Preferences)
if err != nil {
errMsg := "Postgresql Storage GetPassenger Error decoding Preferences from JSON"
log.Error().Err(err).Msg(errMsg)
return passenger, errors.New(errMsg)
}
passenger.Passenger_destination_address, err = geojson.UnmarshalFeature(destination_address)
if err != nil {
errMsg := "Postgresql Storage GetPassenger Error decoding Passenger destination route into GeoJSON"
log.Error().Err(err).Msg(errMsg)
return passenger, errors.New(errMsg)
}
passenger.Passenger_departure_address, err = geojson.UnmarshalFeature(departure_address)
if err != nil {
errMsg := "Postgresql Storage GetPassenger Error decoding Passenger departure route into GeoJSON"
log.Error().Err(err).Msg(errMsg)
return passenger, errors.New(errMsg)
}
return passenger, nil
}
func (s PostgresqlStorage) CreateDriver(driver internal.Driver) (err error) {
var availabilities []byte
_, err = uuid.Parse(driver.Driver.ID)
if err != nil {
log.Error().Err(err).Msg("Postgresql Storage CreateDriver invalid ID")
return err
}
departureJSON, err := json.Marshal(driver.Driver_departure_address)
if err != nil {
errMsg := "Postgresql Storage CreateDriver Error encoding departure Feature to JSON"
log.Error().Err(err).Msg(errMsg)
return errors.New(errMsg)
}
preferencesJSON, err := json.Marshal(driver.Preferences)
if err != nil {
errMsg := "Postgresql Storage CreateDriver Error encoding Preferences to JSON"
log.Error().Err(err).Msg(errMsg)
return errors.New(errMsg)
}
carJSON, err := json.Marshal(driver.Car)
if err != nil {
errMsg := "Postgresql Storage CreateDriver Error encoding Car to JSON"
log.Error().Err(err).Msg(errMsg)
return errors.New(errMsg)
}
if driver.Driver.Alias == "" || driver.Driver.Operator == "" {
errMsg := "Postgresql 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 := "Postgresql Storage CreateDriver invalid Availabilities Type"
log.Error().Msg(errMsg)
return errors.New(errMsg)
}
if driver.Radius == 0 {
errMsg := "Postgresql 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 := "Postgresql Storage CreateDriver error converting Punctual availabilities"
log.Error().Msg(errMsg)
return errors.New(errMsg)
}
case internal.Regular:
availabilities, err = json.Marshal(driver.RegularAvailabilities)
if err != nil {
errMsg := "Postgresql Storage CreateDriver error converting Regular availabilities"
log.Error().Msg(errMsg)
return errors.New(errMsg)
}
}
_, err = s.DbConnection.Exec(fmt.Sprintf("INSERT INTO %s (driver_id,driver_departure_route,driver_radius,last_name,first_name,grade,alias,picture,verified_identity,preferences,availabilities_type,availabilities,operator , car) VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14)", s.Tables["drivers"]),
driver.Driver.ID,
departureJSON,
driver.Radius,
driver.Driver.LastName,
driver.Driver.FirstName,
driver.Driver.Grade,
driver.Driver.Alias,
driver.Driver.Picture,
driver.Driver.VerifiedIdentity,
preferencesJSON,
driver.AvailabilitiesType,
string(availabilities),
driver.Driver.Operator,
carJSON,
)
if err != nil {
fmt.Println(err)
errMsg := "Postgresql Storage CreateDriver Error inserting data into the database"
log.Error().Err(err).Msg(errMsg)
return errors.New(errMsg)
}
return nil
}
func (s PostgresqlStorage) GetDriver(driverID string) (driver internal.Driver, err error) {
var preferencesJSON []byte
var departureAddress []byte
var availabilitiesJSON []byte
var carJSON []byte
err = s.DbConnection.QueryRow(fmt.Sprintf("SELECT driver_departure_route, driver_radius, last_name, first_name, grade, alias, picture, verified_identity, preferences, availabilities_type, availabilities, operator , driver_id , car FROM %s WHERE driver_id = $1", s.Tables["drivers"]), driverID).
Scan(
&departureAddress,
&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,
&driver.Driver.ID,
&carJSON,
)
if err != nil {
errMsg := "Postgresql Storage GetDriver Error querying data from the database"
log.Error().Err(err).Msg(errMsg)
return driver, errors.New(errMsg)
}
err = json.Unmarshal(preferencesJSON, &driver.Preferences)
if err != nil {
errMsg := "Postgresql Storage GetDriver Error decoding Preferences from JSON"
log.Error().Err(err).Msg(errMsg)
return driver, errors.New(errMsg)
}
err = json.Unmarshal(carJSON, &driver.Car)
if err != nil {
errMsg := "Postgresql Storage GetDriver Error decoding Car from JSON"
log.Error().Err(err).Msg(errMsg)
return driver, errors.New(errMsg)
}
driver.Driver_departure_address, err = geojson.UnmarshalFeature(departureAddress)
if err != nil {
errMsg := "Postgresql Storage GetDriver Error decoding Driver departure route into GeoJSON"
log.Error().Err(err).Msg(errMsg)
return driver, errors.New(errMsg)
}
switch driver.AvailabilitiesType {
case internal.Regular:
err = json.Unmarshal(availabilitiesJSON, &driver.RegularAvailabilities)
if err != nil {
errMsg := "Postgresql Storage GetDriver Error decoding Regular Availabilities from JSON"
log.Error().Err(err).Msg(errMsg)
return driver, errors.New(errMsg)
}
case internal.Punctual:
err = json.Unmarshal(availabilitiesJSON, &driver.PunctualAvailabilities)
if err != nil {
errMsg := "Postgresql Storage GetDriver Error decoding Punctual Availabilities from JSON"
log.Error().Err(err).Msg(errMsg)
return driver, errors.New(errMsg)
}
default:
errMsg := "Postgresql Storage GetDriver Invalid Availabilities Type"
log.Error().Msg(errMsg)
return driver, errors.New(errMsg)
}
return driver, nil
}
func (s PostgresqlStorage) CreateBooking(booking internal.BookingRequest) (err error) {
_, err = uuid.Parse(booking.Driver_id)
if err != nil {
log.Error().Err(err).Msg("Postgresql Storage CreateBooking invalid Driver ID")
return err
}
_, err = uuid.Parse(booking.Passenger_id)
if err != nil {
log.Error().Err(err).Msg("Postgresql Storage CreateBooking invalid Passenger ID")
return err
}
_, err = uuid.Parse(booking.ID)
if err != nil {
log.Error().Err(err).Msg("Postgresql Storage CreateBooking invalid Booking ID")
return err
}
if booking.Operator == "" {
log.Error().Err(err).Msg("Postgresql Storage CreateBooking empty operator")
return err
}
_, err = s.DbConnection.Exec(fmt.Sprintf("INSERT INTO %s (booking_id , passenger_id , driver_id , operator, booking_status) VALUES ($1,$2,$3,$4,$5)", s.Tables["bookings"]),
booking.ID,
booking.Passenger_id,
booking.Driver_id,
booking.Operator,
booking.Status,
)
if err != nil {
errMsg := "Postgresql Storage CreateBooking Error inserting data into the database"
log.Error().Err(err).Msg(errMsg)
return errors.New(errMsg)
}
return nil
}
func (s PostgresqlStorage) GetBooking(id string) (booking internal.Booking, err error) {
err = s.DbConnection.QueryRow(fmt.Sprintf("SELECT booking_id , passenger_id , driver_id , booking_status FROM %s WHERE booking_id = $1", s.Tables["bookings"]), id).
Scan(
&booking.ID,
&booking.Passenger.ID,
&booking.Driver.ID,
&booking.Status,
)
fmt.Println(err)
if err != nil {
errMsg := "Postgresql Storage GetBooking Error getting booking"
log.Error().Err(err).Msg(errMsg)
return booking, errors.New(errMsg + err.Error())
}
passenger, err := s.GetPassenger(booking.Passenger.ID)
if err != nil {
errMsg := "Postgresql Storage GetBooking Error getting passenger"
log.Error().Err(err).Msg(errMsg)
return booking, errors.New(errMsg + err.Error())
}
booking.Passenger = passenger.Passenger
booking.PassengerPickupAddress = passenger.Passenger_departure_address
booking.PassengerDropAddress = passenger.Passenger_destination_address
driver, err := s.GetDriver(booking.Driver.ID)
if err != nil {
errMsg := "Postgresql 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 PostgresqlStorage) UpdateBookingStatus(id string, status internal.BookingStatus) (err error) {
_, err = uuid.Parse(id)
if err != nil {
log.Error().Err(err).Msg("Postgresql Storage UpdateBookingStatus invalid Booking ID")
return err
}
_, err = s.GetBooking(id)
if err != nil {
return errors.New(err.Error())
}
query := fmt.Sprintf("UPDATE %s SET booking_status = $1 WHERE booking_id = $2", s.Tables["bookings"])
_, err = s.DbConnection.Exec(query, status, id)
if err != nil {
errMsg := "Postgresql Storage UpdateBookingStatus Error updating booking status"
log.Error().Err(err).Msg(errMsg)
return errors.New(errMsg)
}
return nil
}
func (s PostgresqlStorage) FilterUserBookingsByStatus(user_type string, status internal.BookingStatus, user_id string) (bookings []internal.Booking, err error) {
_, err = uuid.Parse(user_id)
if err != nil {
return nil, errors.New("invalid uuid")
}
if user_type != "driver" && user_type != "passenger" {
return nil, errors.New("invalid user type")
}
switch user_type {
case "driver":
rows, err := s.DbConnection.Query(fmt.Sprintf("SELECT booking_id, passenger_id, driver_id, booking_status FROM %s WHERE driver_id = $1 AND booking_status = $2", s.Tables["bookings"]),
user_id, status)
if err != nil {
return nil, err
}
defer rows.Close()
for rows.Next() {
var booking internal.Booking
if err := rows.Scan(&booking.ID, &booking.Passenger.ID, &booking.Driver.ID, &booking.Status); err != nil {
return nil, err
}
bookings = append(bookings, booking)
}
if err := rows.Err(); err != nil {
return nil, err
}
case "passenger":
rows, err := s.DbConnection.Query(fmt.Sprintf("SELECT booking_id, passenger_id, driver_id, booking_status FROM %s WHERE passenger_id = $1 AND booking_status = $2", s.Tables["bookings"]),
user_id, status)
if err != nil {
return nil, err
}
defer rows.Close()
for rows.Next() {
var booking internal.Booking
if err := rows.Scan(&booking.ID, &booking.Passenger.ID, &booking.Driver.ID, &booking.Status); err != nil {
return nil, err
}
bookings = append(bookings, booking)
}
if err := rows.Err(); err != nil {
return nil, err
}
}
return bookings, nil
}
func (s PostgresqlStorage) GetAllDrivers(date int64) (drivers []internal.Driver, err error) {
rows, err := s.DbConnection.Query(fmt.Sprintf("SELECT driver_id, driver_departure_route, driver_radius, last_name, first_name, grade, alias, picture, verified_identity, preferences, availabilities_type, availabilities, operator, car FROM %s", s.Tables["drivers"]))
if err != nil {
return nil, err
}
defer rows.Close()
for rows.Next() {
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 matching punctual or regular availabilities.
if driver.AvailabilitiesType == internal.Punctual {
if err := json.Unmarshal(availabilitiesJSON, &driver.PunctualAvailabilities); err != nil {
return nil, err
}
// Convert the date to the day of the week and make it lowercase.
dayOfWeek := strings.ToLower(time.Unix(date, 0).UTC().Format("Mon"))
for _, avail := range driver.PunctualAvailabilities {
// Extract the day part of the punctual driver's date and compare.
availDate := time.Unix(avail.Date, 0)
if strings.ToLower(availDate.Format("Mon")) == dayOfWeek {
drivers = append(drivers, driver)
break
}
}
} else if driver.AvailabilitiesType == internal.Regular {
if err := json.Unmarshal(availabilitiesJSON, &driver.RegularAvailabilities); err != nil {
return nil, err
}
// Convert the date to the day of the week and make it lowercase.
dayOfWeek := strings.ToLower(time.Unix(date, 0).UTC().Format("Mon"))
for _, avail := range driver.RegularAvailabilities {
if strings.ToLower(avail.DayOfWeek) == dayOfWeek {
drivers = append(drivers, driver)
break
}
}
}
}
if err := rows.Err(); err != nil {
return nil, err
}
return drivers, nil
}
func (s PostgresqlStorage) 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
}

View File

@@ -0,0 +1,168 @@
table "passengers" {
schema = schema.solidarity_service
column "passenger_id" {
null = false
type = uuid
}
column "passenger_departure_route" {
null = false
type = jsonb
}
column "passenger_destination_route" {
null = false
type = jsonb
}
column "alias" {
null = false
type = varchar(15)
}
column "last_name" {
null = true
type = text
}
column "first_name" {
null = true
type = text
}
column "grade" {
null = true
type = int
}
column "picture" {
null = true
type = varchar(200)
}
column "verified_identity"{
null = true
type = bool
}
column "operator" {
null = false
type = varchar(35)
}
column "preferences" {
null = true
type = jsonb
}
column "passenger_pickup_date" {
null = false
type = int
}
primary_key {
columns = [column.passenger_id]
}
}
table "drivers" {
schema = schema.solidarity_service
column "driver_id" {
null = false
type = uuid
}
column "driver_departure_route" {
null = false
type = jsonb
}
column "driver_radius" {
null = false
type = integer
}
column "last_name" {
null = true
type = text
}
column "first_name" {
null = true
type = text
}
column "grade" {
null = true
type = int
}
column "alias" {
null = false
type = varchar(15)
}
column "picture" {
null = true
type = text
}
column "verified_identity"{
null = true
type = bool
}
column "preferences" {
null = true
type = jsonb
}
column "availabilities_type" {
null = false
type = enum.availabilities_type
}
column "availabilities" {
null = false
type = jsonb
}
column "car" {
null = true
type = jsonb
}
column "operator" {
null = false
type = varchar(35)
}
primary_key {
columns = [column.driver_id]
}
}
table "bookings" {
schema = schema.solidarity_service
column "booking_id" {
null = false
type = uuid
}
column "driver_id" {
null = false
type = uuid
}
column "operator" {
null = false
type = varchar(35)
}
column "passenger_id" {
null = false
type = uuid
}
column "booking_status" {
null = false
type = enum.booking_status
}
primary_key {
columns = [column.booking_id]
}
foreign_key "bookings_driver_id_fkey" {
columns = [column.driver_id]
ref_columns = [table.drivers.column.driver_id]
}
foreign_key "group_members_passenger_id_fkey" {
columns = [column.passenger_id]
ref_columns = [table.passengers.column.passenger_id]
}
}
enum "booking_status" {
schema = schema.solidarity_service
values = ["INITIATED", "WAITING_PASSENGER_CONFIRMATION", "WAITING_DRIVER_CONFIRMATION", "CONFIRMED", "CANCELLED", "COMPLETED_PENDING_VALIDATION", "VALIDATED"]
}
enum "availabilities_type" {
schema = schema.solidarity_service
values = ["PUNCTUAL","REGULAR"]
}
schema "solidarity_service" {
}

34
storage/storage.go Normal file
View File

@@ -0,0 +1,34 @@
package storage
import (
"fmt"
"github.com/paulmach/orb/geojson"
"github.com/spf13/viper"
"solidarity-service/internal"
)
type Storage interface {
CreatePassenger(passenger internal.Passenger) (err error)
GetPassenger(passengerID string) (passenger internal.Passenger, err error)
CreateDriver(driver internal.Driver) (err error)
GetDriver(driverID string) (driver internal.Driver, err error)
GetBooking(id string) (booking internal.Booking, err error)
CreateBooking(booking internal.BookingRequest) (err error)
UpdateBookingStatus(id string, status internal.BookingStatus) (err error)
FilterUserBookingsByStatus(user_type string, status internal.BookingStatus, user_id string) (bookings []internal.Booking, err error)
DriverJourneys(departure_route *geojson.Feature, departure_date int64) (drivers []internal.Driver, err error)
GetAllDrivers(date int64) (drivers []internal.Driver, err error)
}
func NewStorage(cfg *viper.Viper) (Storage, error) {
var (
storage_type = cfg.GetString("storage.db.type")
)
switch storage_type {
case "psql":
s, err := NewPostgresqlStorage(cfg)
return s, err
default:
return nil, fmt.Errorf("storage type %v is not supported", storage_type)
}
}