timetable-mgr/dbAccess/stations.go

111 lines
2.8 KiB
Go

package dbAccess
import (
"context"
"errors"
"time"
"git.fjla.uk/owlboard/go-types/pkg/database"
"git.fjla.uk/owlboard/timetable-mgr/log"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
"go.uber.org/zap"
)
const StationsMetaDoctype string = "StationsMetadata"
type StationsMetadata struct {
Doctype string
LastUpdate time.Time
}
// Fetches the CifMetadata from the database, returns nil if no metadata exists - before first initialisation for example.
func GetStationsMetadata() (*StationsMetadata, error) {
database := MongoClient.Database(DatabaseName)
collection := database.Collection(MetaCollection)
filter := bson.M{"type": StationsMetaDoctype}
var result StationsMetadata
err := collection.FindOne(context.Background(), filter).Decode(&result)
if err != nil {
if errors.Is(err, mongo.ErrNoDocuments) {
return nil, nil
}
return nil, err
}
log.Debug("Fetched Stations Metadata from database", zap.Any("Metadata", result))
return &result, nil
}
func SetStationsMetadata(time time.Time) bool {
database := MongoClient.Database(DatabaseName)
collection := database.Collection(MetaCollection)
options := options.Update().SetUpsert(true)
filter := bson.M{"type": StationsMetaDoctype}
update := bson.M{
"$set": bson.M{
"type": StationsMetaDoctype,
"lastUpdate": time,
},
}
_, err := collection.UpdateOne(context.Background(), filter, update, options)
if err != nil {
log.Error("Error updating Stations Metadata", zap.Error(err))
return false
}
log.Info("New Stations Metadata written", zap.Time("Update time", time))
return true
}
// Puts an array of Stations documents into the database
func PutManyNewStations(stationsData *[]database.Station) error {
collection := MongoClient.Database(DatabaseName).Collection(StationsCollection)
documents := convertNewStationsToInterfaceSlice(stationsData)
_, err := collection.InsertMany(context.Background(), *documents)
if err != nil {
return err
}
return nil
}
// Converts []database.Station types into interface slices required to put them into the database
func convertNewStationsToInterfaceSlice(stationsData *[]database.Station) *[]interface{} {
interfaceSlice := make([]interface{}, len(*stationsData))
for i, doc := range *stationsData {
interfaceSlice[i] = doc
}
return &interfaceSlice
}
func CreateStationIndeces() error {
coll := MongoClient.Database(DatabaseName).Collection(StationsCollection)
locationIndex := mongo.IndexModel{
Keys: bson.D{{"location", "2dsphere"}},
Options: nil,
}
crsIndex := mongo.IndexModel{
Keys: bson.D{{"3ALPHA", 1}},
}
tiplocIndex := mongo.IndexModel{
Keys: bson.D{{"TIPLOC", 1}},
}
_, err := coll.Indexes().CreateMany(context.Background(), []mongo.IndexModel{locationIndex, crsIndex, tiplocIndex})
if err != nil {
return err
}
return nil
}