package db import ( "github.com/jordic/goics" "github.com/pocketbase/dbx" "github.com/pocketbase/pocketbase" "github.com/pocketbase/pocketbase/models" "htwkalender/model" "log" "strings" "time" ) 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 contains(s []string, e string) bool { for _, a := range s { if a == e { return true } } return false } // GetRooms function to get all rooms from database that are stored as a string in the Event struct func GetRooms(app *pocketbase.PocketBase) []string { var events []struct { Rooms string `db:"Rooms" json:"Rooms"` } // get all rooms from event records in the events collection err := app.Dao().DB().Select("Rooms").From("events").All(&events) if err != nil { print("Error while getting rooms from database: ", err) return nil } var roomArray []string for _, event := range events { var room = strings.Split(event.Rooms, " ") //split string room by space and add each room to array if it is not already in there for _, r := range room { var text = strings.TrimSpace(r) if !contains(roomArray, text) && !strings.Contains(text, " ") && len(text) >= 1 { roomArray = append(roomArray, text) } } } return roomArray } type Events []*model.Event // EmitICal implements the interface for goics func (e Events) EmitICal() goics.Componenter { layout := "2006-01-02 15:04:05 -0700 MST" c := goics.NewComponent() c.SetType("VCALENDAR") c.AddProperty("VERSION", "2.0") c.AddProperty("CALSCAL", "GREGORIAN") for _, event := range e { s := goics.NewComponent() s.SetType("VEVENT") timeEnd, _ := time.Parse(layout, event.End) timeStart, _ := time.Parse(layout, event.Start) k, v := goics.FormatDateTimeField("DTEND", timeEnd) s.AddProperty(k, v) k, v = goics.FormatDateTimeField("DTSTART", timeStart) s.AddProperty(k, v) s.AddProperty("SUMMARY", event.Name) s.AddProperty("DESCRIPTION", "Notizen: "+event.Notes+"\n Prof: "+event.Prof) s.AddProperty("LOCATION", event.Rooms) c.AddComponent(s) } return c } // gets all events for specific course and semester // TODO add filter for year func GetPlanForCourseAndSemester(app *pocketbase.PocketBase, course string, semester string) Events { var events 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})).All(&events) if err != nil { print("Error while getting events from database: ", err) return nil } return events } func GetPlanForModules(app *pocketbase.PocketBase, modules []struct { Name string `db:"Name" json:"Name"` Course string `db:"course" json:"Course"` }) Events { // build query string with name equals elements in modules for dbx query var queryString string for i, module := range modules { if i == 0 { queryString = "Name = '" + module.Name + "' AND course = '" + module.Course + "'" } else { queryString = queryString + " OR Name = '" + module.Name + "' AND course = '" + module.Course + "'" } } var events Events // get all events from event records in the events collection err := app.Dao().DB().Select("*").From("events").Where(dbx.NewExp(queryString)).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) ([]string, error) { var events []struct { Name string `db:"Name" json:"Name"` } var eventArray []string // get all events from event records in the events collection err := app.Dao().DB().Select("Name").From("events").Where(dbx.NewExp("course = {:course} AND semester = {:semester}", dbx.Params{"course": course, "semester": semester})).Distinct(true).All(&events) if err != nil { print("Error while getting events from database: ", err) return eventArray, err } for _, event := range events { eventArray = append(eventArray, event.Name) } return eventArray, nil } func GetAllModulesDistinct(app *pocketbase.PocketBase) ([]struct { Name string Course string }, error) { var events []struct { Name string `db:"Name" json:"Name"` Course string `db:"course" json:"course"` } var eventArray []struct { Name string Course string } err := app.Dao().DB().Select("Name", "course").From("events").Distinct(true).All(&events) if err != nil { print("Error while getting events from database: ", err) return eventArray, err } for _, event := range events { eventArray = append(eventArray, struct { Name string Course string }{event.Name, event.Course}) } return eventArray, nil }