package db import ( "github.com/pocketbase/dbx" "github.com/pocketbase/pocketbase" "github.com/pocketbase/pocketbase/models" "htwkalender/model" "log" ) func SaveEvents(seminarGroup []model.SeminarGroup, collection *models.Collection, app *pocketbase.PocketBase) ([]*models.Record, error) { var toBeSavedEvents []struct { model.Event string } var savedRecords []*models.Record var insertRecords []*models.Record // check if event is already in database and add to toBeSavedEvents if not for _, seminarGroup := range seminarGroup { for _, event := range seminarGroup.Events { dbGroup, err := findEventByDayWeekStartEndNameCourse(event, seminarGroup.Course, app) if dbGroup == nil && err.Error() == "sql: no rows in result set" { toBeSavedEvents = append(toBeSavedEvents, struct { model.Event string }{event, seminarGroup.Course}) } else if err != nil { return nil, err } } } // create record for each event that's not already in the database for _, event := range toBeSavedEvents { record := models.NewRecord(collection) record.Set("Day", event.Day) record.Set("Week", event.Week) record.Set("Start", event.Start) record.Set("End", event.End) record.Set("Name", event.Name) record.Set("EventType", event.EventType) record.Set("Prof", event.Prof) record.Set("Rooms", event.Rooms) record.Set("Notes", event.Notes) record.Set("BookedAt", event.BookedAt) record.Set("course", event.string) record.Set("semester", event.Semester) insertRecords = append(insertRecords, record) } // save all records for _, record := range insertRecords { if record != nil { err := app.Dao().SaveRecord(record) if err == nil { savedRecords = append(savedRecords, record) } else { log.Println("Error while saving record: ", err) return nil, err } } } return savedRecords, nil } func findEventByDayWeekStartEndNameCourse(event model.Event, course string, app *pocketbase.PocketBase) (*model.Event, error) { err := app.Dao().DB().Select("*").From("events").Where( dbx.NewExp("Day = {:day} AND Week = {:week} AND Start = {:start} AND End = {:end} AND Name = {:name} AND course = {:course} AND Prof = {:prof} AND Rooms = {:rooms} AND EventType = {:eventType}", dbx.Params{"day": event.Day, "week": event.Week, "start": event.Start, "end": event.End, "name": event.Name, "course": course, "prof": event.Prof, "rooms": event.Rooms, "eventType": event.EventType}), ).One(&event) if err != nil { return nil, err } return &event, err } func buildIcalQueryForModules(modules []model.FeedCollection) dbx.Expression { // build where conditions for each module //first check if modules is empty if len(modules) == 0 { return dbx.HashExp{} } //second check if modules has only one element if len(modules) == 1 { return dbx.And( dbx.HashExp{"Name": modules[0].Name}, dbx.HashExp{"course": modules[0].Course}, ) } //third check if modules has more than one element var wheres []dbx.Expression for _, module := range modules { where := dbx.And( dbx.HashExp{"Name": module.Name}, dbx.HashExp{"course": module.Course}, ) wheres = append(wheres, where) } // Use dbx.And or dbx.Or to combine the where conditions as needed where := dbx.Or(wheres...) return where } // GetPlanForModules returns all events for the given modules with the given course // used for the ical feed func GetPlanForModules(app *pocketbase.PocketBase, modules []model.FeedCollection) model.Events { var events model.Events // iterate over modules in 100 batch sizes for i := 0; i < len(modules); i += 100 { var moduleBatch []model.FeedCollection if i+100 > len(modules) { moduleBatch = modules[i:] } else { moduleBatch = modules[i : i+100] } var selectedModulesQuery = buildIcalQueryForModules(moduleBatch) // get all events from event records in the events collection err := app.Dao().DB().Select("*").From("events").Where(selectedModulesQuery).All(&events) if err != nil { print("Error while getting events from database: ", err) return nil } } return events } func GetAllModulesForCourse(app *pocketbase.PocketBase, course string, semester string) (model.Events, error) { var events model.Events // get all events from event records in the events collection err := app.Dao().DB().Select("*").From("events").Where(dbx.NewExp("course = {:course} AND semester = {:semester}", dbx.Params{"course": course, "semester": semester})).GroupBy("Name").Distinct(true).All(&events) if err != nil { print("Error while getting events from database: ", err) return nil, err } return events, nil } func GetAllModulesDistinctByNameAndCourse(app *pocketbase.PocketBase) (model.Events, error) { var events model.Events err := app.Dao().DB().Select("*").From("events").GroupBy("Name", "course").Distinct(true).All(&events) if err != nil { print("Error while getting events from database: ", err) return nil, err } return events, nil } func DeleteAllEventsForCourse(app *pocketbase.PocketBase, course string, semester string) error { _, err := app.Dao().DB().Delete("events", dbx.NewExp("course = {:course} AND semester = {:semester}", dbx.Params{"course": course, "semester": semester})).Execute() if err != nil { print("Error while deleting events from database: ", err) return err } return nil } func FindAllEventsByModule(app *pocketbase.PocketBase, moduleName string) (model.Events, error) { var events model.Events err := app.Dao().DB().Select("*").From("events").Where(dbx.NewExp("Name = {:moduleName}", dbx.Params{"moduleName": moduleName})).All(&events) if err != nil { print("Error while getting events from database: ", err) return nil, err } return events, nil }