Initial commit
This commit is contained in:
17
storage/bookings.go
Normal file
17
storage/bookings.go
Normal file
@@ -0,0 +1,17 @@
|
||||
package storage
|
||||
|
||||
import "time"
|
||||
|
||||
type Booking struct {
|
||||
ID string `json:"id" bson:"_id"`
|
||||
Vehicleid string `json:"vehicleid"`
|
||||
Driver string `json:"driver"`
|
||||
Startdate time.Time `json:"startdate"`
|
||||
Enddate time.Time `json:"enddate"`
|
||||
Unavailablefrom time.Time `json:"unavailablefrom"`
|
||||
Unavailableto time.Time `json:"unavailableto"`
|
||||
Data map[string]any `json:"data"`
|
||||
|
||||
Deleted bool
|
||||
Vehicle Vehicle
|
||||
}
|
||||
169
storage/mongodb.go
Normal file
169
storage/mongodb.go
Normal file
@@ -0,0 +1,169 @@
|
||||
package storage
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/spf13/viper"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
)
|
||||
|
||||
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_vehicles = cfg.GetString("storage.db.mongodb.collections.vehicles")
|
||||
mongodb_bookings = cfg.GetString("storage.db.mongodb.collections.bookings")
|
||||
)
|
||||
|
||||
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{
|
||||
"vehicles": mongodb_vehicles,
|
||||
"bookings": mongodb_bookings,
|
||||
},
|
||||
}
|
||||
//TODO Indexes
|
||||
return storage, err
|
||||
}
|
||||
|
||||
func (s MongoDBStorage) CreateVehicle(vehicle Vehicle) error {
|
||||
collection := s.Client.Database(s.DbName).Collection(s.Collections["vehicles"])
|
||||
if _, err := collection.InsertOne(context.TODO(), vehicle); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s MongoDBStorage) GetVehicles(namespaces []string) (vehicles []Vehicle, err error) {
|
||||
collection := s.Client.Database(s.DbName).Collection(s.Collections["vehicles"])
|
||||
|
||||
var cur *mongo.Cursor
|
||||
|
||||
findOptions := options.Find()
|
||||
|
||||
if len(namespaces) == 0 {
|
||||
cur, err = collection.Find(context.TODO(), bson.D{}, findOptions)
|
||||
if err != nil {
|
||||
return vehicles, err
|
||||
}
|
||||
} else {
|
||||
cur, err = collection.Find(context.TODO(), bson.M{"namespace": bson.M{"$in": namespaces}}, findOptions)
|
||||
if err != nil {
|
||||
return vehicles, err
|
||||
}
|
||||
}
|
||||
|
||||
for cur.Next(context.TODO()) {
|
||||
var vehicle Vehicle
|
||||
var elem bson.M
|
||||
|
||||
if err := cur.Decode(&elem); err != nil {
|
||||
return vehicles, err
|
||||
}
|
||||
|
||||
bsonBytes, _ := bson.Marshal(elem)
|
||||
bson.Unmarshal(bsonBytes, &vehicle)
|
||||
|
||||
vehicles = append(vehicles, vehicle)
|
||||
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (s MongoDBStorage) GetVehicle(id string) (*Vehicle, error) {
|
||||
collection := s.Client.Database(s.DbName).Collection(s.Collections["vehicles"])
|
||||
|
||||
vehicle := &Vehicle{}
|
||||
if err := collection.FindOne(context.TODO(), bson.M{"_id": id}).Decode(vehicle); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return vehicle, nil
|
||||
}
|
||||
|
||||
func (s MongoDBStorage) CreateBooking(booking Booking) error {
|
||||
collection := s.Client.Database(s.DbName).Collection(s.Collections["bookings"])
|
||||
if _, err := collection.InsertOne(context.TODO(), booking); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
func (s MongoDBStorage) GetBooking(id string) (*Booking, error) {
|
||||
collection := s.Client.Database(s.DbName).Collection(s.Collections["bookings"])
|
||||
|
||||
booking := &Booking{}
|
||||
|
||||
if err := collection.FindOne(context.TODO(), bson.M{"_id": id}).Decode(booking); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return booking, nil
|
||||
}
|
||||
|
||||
func (s MongoDBStorage) GetBookingsForVehicle(vehicleid string) (bookings []Booking, err error) {
|
||||
collection := s.Client.Database(s.DbName).Collection(s.Collections["bookings"])
|
||||
|
||||
var cur *mongo.Cursor
|
||||
|
||||
findOptions := options.Find()
|
||||
cur, err = collection.Find(context.TODO(), bson.M{"vehicleid": vehicleid}, findOptions)
|
||||
if err != nil {
|
||||
return bookings, err
|
||||
}
|
||||
|
||||
for cur.Next(context.TODO()) {
|
||||
var booking Booking
|
||||
var elem bson.M
|
||||
|
||||
if err := cur.Decode(&elem); err != nil {
|
||||
return bookings, err
|
||||
}
|
||||
|
||||
bsonBytes, _ := bson.Marshal(elem)
|
||||
bson.Unmarshal(bsonBytes, &booking)
|
||||
|
||||
bookings = append(bookings, booking)
|
||||
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (s MongoDBStorage) DeleteBooking(bookingid string) error {
|
||||
collection := s.Client.Database(s.DbName).Collection(s.Collections["bookings"])
|
||||
|
||||
_, err := collection.UpdateOne(
|
||||
context.TODO(),
|
||||
bson.M{"_id": bookingid},
|
||||
bson.D{
|
||||
{"$set", bson.D{{"deleted", true}}},
|
||||
},
|
||||
)
|
||||
|
||||
return err
|
||||
|
||||
}
|
||||
35
storage/storage.go
Normal file
35
storage/storage.go
Normal file
@@ -0,0 +1,35 @@
|
||||
package storage
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
type Storage interface {
|
||||
//Vehicles management
|
||||
CreateVehicle(Vehicle) error
|
||||
GetVehicle(id string) (*Vehicle, error)
|
||||
GetVehicles(namespaces []string) ([]Vehicle, error)
|
||||
|
||||
//Bookings management
|
||||
CreateBooking(Booking) error
|
||||
GetBooking(id string) (*Booking, error)
|
||||
GetBookingsForVehicle(vehicleid string) ([]Booking, error)
|
||||
DeleteBooking(id string) error
|
||||
}
|
||||
|
||||
func NewStorage(cfg *viper.Viper) (Storage, error) {
|
||||
var (
|
||||
storage_type = cfg.GetString("storage.db.type")
|
||||
)
|
||||
|
||||
switch storage_type {
|
||||
case "mongodb":
|
||||
s, err := NewMongoDBStorage(cfg)
|
||||
return s, err
|
||||
default:
|
||||
return nil, fmt.Errorf("storage type %v is not supported", storage_type)
|
||||
}
|
||||
|
||||
}
|
||||
25
storage/vehicles.go
Normal file
25
storage/vehicles.go
Normal file
@@ -0,0 +1,25 @@
|
||||
package storage
|
||||
|
||||
import "time"
|
||||
|
||||
type Vehicle struct {
|
||||
ID string `json:"id" bson:"_id"`
|
||||
Type string `json:"type"`
|
||||
Namespace string `json:"namespace"`
|
||||
Administrators []string `json:"administrators"`
|
||||
Data map[string]any `json:"data"`
|
||||
Metadata map[string]any `json:"metadata"`
|
||||
|
||||
Bookings []Booking
|
||||
}
|
||||
|
||||
func (v Vehicle) Free(start time.Time, end time.Time) bool {
|
||||
for _, b := range v.Bookings {
|
||||
if (start.After(b.Unavailablefrom) && start.Before(b.Unavailableto)) ||
|
||||
(end.After(b.Unavailablefrom) && end.Before(b.Unavailableto)) ||
|
||||
(start.Before(b.Unavailablefrom) && end.After(b.Unavailableto)) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
Reference in New Issue
Block a user