mirror of
https://gitlab.dit.htwk-leipzig.de/htwk-software/htwkalender-pwa.git
synced 2025-07-16 17:48:51 +02:00
268 lines
7.6 KiB
Go
268 lines
7.6 KiB
Go
package db
|
|
|
|
import (
|
|
"fmt"
|
|
"htwkalender/model"
|
|
"log/slog"
|
|
"time"
|
|
|
|
"github.com/pocketbase/dbx"
|
|
"github.com/pocketbase/pocketbase"
|
|
)
|
|
|
|
func SaveSeminarGroupEvents(seminarGroups []model.SeminarGroup, app *pocketbase.PocketBase) ([]model.Event, error) {
|
|
var toBeSavedEvents model.Events
|
|
var savedRecords model.Events
|
|
|
|
// check if event is already in database and add to toBeSavedEvents if not
|
|
for _, seminarGroup := range seminarGroups {
|
|
for _, event := range seminarGroup.Events {
|
|
event = event.SetCourse(seminarGroup.Course)
|
|
existsInDatabase, err := findEventByDayWeekStartEndNameCourse(event, seminarGroup.Course, app)
|
|
alreadyAddedToSave := toBeSavedEvents.Contains(event)
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if !existsInDatabase && !alreadyAddedToSave {
|
|
toBeSavedEvents = append(toBeSavedEvents, event)
|
|
}
|
|
}
|
|
}
|
|
|
|
// create record for each event that's not already in the database
|
|
for _, event := range toBeSavedEvents {
|
|
event.MarkAsNew()
|
|
// auto mapping for event fields to record fields
|
|
err := app.Dao().Save(&event)
|
|
if err != nil {
|
|
return nil, err
|
|
} else {
|
|
savedRecords = append(savedRecords, event)
|
|
}
|
|
}
|
|
|
|
return savedRecords, nil
|
|
}
|
|
|
|
func SaveEvents(events []model.Event, app *pocketbase.PocketBase) ([]model.Event, error) {
|
|
var toBeSavedEvents model.Events
|
|
var savedRecords model.Events
|
|
|
|
// check if event is already in database and add to toBeSavedEvents if not
|
|
for _, event := range events {
|
|
existsInDatabase, err := findEventByDayWeekStartEndNameCourse(event, event.Course, app)
|
|
alreadyAddedToSave := toBeSavedEvents.Contains(event)
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if !existsInDatabase && !alreadyAddedToSave {
|
|
toBeSavedEvents = append(toBeSavedEvents, event)
|
|
}
|
|
}
|
|
|
|
// create record for each event that's not already in the database
|
|
for _, event := range toBeSavedEvents {
|
|
event.MarkAsNew()
|
|
// auto mapping for event fields to record fields
|
|
err := app.Dao().Save(&event)
|
|
if err != nil {
|
|
return nil, err
|
|
} else {
|
|
savedRecords = append(savedRecords, event)
|
|
}
|
|
}
|
|
return savedRecords, nil
|
|
}
|
|
|
|
// check if event is already in database and return true if it is and false if it's not
|
|
func findEventByDayWeekStartEndNameCourse(event model.Event, course string, app *pocketbase.PocketBase) (bool, error) {
|
|
|
|
var dbEvent model.Event
|
|
|
|
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(&dbEvent)
|
|
|
|
if err != nil {
|
|
if err.Error() == "sql: no rows in result set" {
|
|
return false, nil
|
|
}
|
|
return false, err
|
|
} else {
|
|
return true, nil
|
|
}
|
|
}
|
|
|
|
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.HashExp{"uuid": modules[0].UUID}
|
|
}
|
|
|
|
//third check if modules has more than one element
|
|
var wheres []dbx.Expression
|
|
|
|
for _, module := range modules {
|
|
where := dbx.HashExp{"uuid": module.UUID}
|
|
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 map[string]model.FeedCollection) (model.Events, error) {
|
|
|
|
var events model.Events
|
|
|
|
modulesArray := make([]model.FeedCollection, 0, len(modules))
|
|
for _, value := range modules {
|
|
modulesArray = append(modulesArray, value)
|
|
}
|
|
|
|
// 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 = modulesArray[i:]
|
|
} else {
|
|
moduleBatch = modulesArray[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 {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
return events, nil
|
|
}
|
|
|
|
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 {
|
|
slog.Error("Error while getting events from database: ", err)
|
|
return nil, fmt.Errorf("error while getting events from database for course %s and semester %s", course, semester)
|
|
}
|
|
|
|
return events, nil
|
|
}
|
|
|
|
func GetAllModulesDistinctByNameAndCourse(app *pocketbase.PocketBase) ([]model.ModuleDTO, error) {
|
|
var modules []model.ModuleDTO
|
|
|
|
err := app.Dao().DB().Select("Name", "EventType", "Prof", "course", "semester", "uuid").From("events").GroupBy("Name", "Course").Distinct(true).All(&modules)
|
|
if err != nil {
|
|
slog.Error("Error while getting events from database: ", err)
|
|
return nil, fmt.Errorf("error while getting events distinct by name and course from data")
|
|
}
|
|
|
|
return modules, 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 {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func DeleteAllEvents(app *pocketbase.PocketBase) error {
|
|
|
|
_, err := app.Dao().DB().Delete("events", dbx.NewExp("1=1")).Execute()
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func FindModuleByUUID(app *pocketbase.PocketBase, uuid string) (model.Module, error) {
|
|
var module model.Module
|
|
|
|
err := app.Dao().DB().Select("*").From("events").Where(dbx.NewExp("uuid = {:uuid}", dbx.Params{"uuid": uuid})).One(&module)
|
|
if err != nil {
|
|
return model.Module{}, err
|
|
}
|
|
|
|
return module, nil
|
|
}
|
|
|
|
func FindAllEventsByModule(app *pocketbase.PocketBase, module model.Module) (model.Events, error) {
|
|
var events model.Events
|
|
|
|
err := app.Dao().DB().Select("*").From("events").Where(dbx.NewExp("Name = {:moduleName} AND course = {:course}", dbx.Params{"moduleName": module.Name, "course": module.Course})).All(&events)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return events, nil
|
|
}
|
|
|
|
func GetAllModulesByNameAndDateRange(app *pocketbase.PocketBase, name string, startDate time.Time, endDate time.Time) (model.Events, error) {
|
|
var events model.Events
|
|
|
|
err := app.Dao().DB().Select("*").From("events").Where(dbx.NewExp("Name = {:name} AND Start >= {:startDate} AND End <= {:endDate}", dbx.Params{"name": name, "startDate": startDate, "endDate": endDate})).All(&events)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return events, nil
|
|
}
|
|
|
|
func GetEventsInTimeRange(app *pocketbase.PocketBase, from time.Time, to time.Time) (model.Events, error) {
|
|
var events model.Events
|
|
|
|
err := app.Dao().DB().Select("*").From("events").Where(dbx.NewExp("Start >= {:startDate} AND End <= {:endDate}", dbx.Params{"startDate": from, "endDate": to})).All(&events)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return events, nil
|
|
}
|