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 }