package events import ( "github.com/johannesbuehl/golunteer/backend/pkg/db" "github.com/johannesbuehl/golunteer/backend/pkg/db/assignments" "github.com/johannesbuehl/golunteer/backend/pkg/db/availabilities" "github.com/johannesbuehl/golunteer/backend/pkg/logger" ) type EventWithAssignment struct { eventDataDB Tasks map[string]*string `json:"tasks"` } type EventWithAvailabilities struct { EventWithAssignment Availabilities map[string]string `json:"availabilities"` } type eventDataDB struct { Id int `db:"id" json:"id"` Date string `db:"date" json:"date" validate:"required"` Description string `db:"description" json:"description"` } // transform the database-entry to an Event func (e eventDataDB) Event() (EventWithAssignment, error) { // get the assignments associated with the event if assignemnts, err := assignments.Event(e.Id); err != nil { return EventWithAssignment{}, err } else { return EventWithAssignment{ eventDataDB: e, Tasks: assignemnts, }, nil } } func (e eventDataDB) EventWithAvailabilities() (EventWithAvailabilities, error) { // get the event with assignments if event, err := e.Event(); err != nil { return EventWithAvailabilities{}, err // get the availabilities } else if availabilities, err := availabilities.Event(e.Id); err != nil { return EventWithAvailabilities{}, err } else { return EventWithAvailabilities{ EventWithAssignment: event, Availabilities: availabilities, }, nil } } type EventCreate struct { eventDataDB Tasks []int `json:"tasks" validate:"required,min=1"` } func Create(event EventCreate) error { if result, err := db.DB.NamedExec("INSERT INTO EVENTS (date, description) VALUES (:date, :description)", event); err != nil { return err } else if id, err := result.LastInsertId(); err != nil { return err } else { // create an insert-slice with the id included tasks := []struct { TaskID int `db:"taskID"` EventID int64 `db:"eventID"` }{} for _, taskID := range event.Tasks { tasks = append(tasks, struct { TaskID int "db:\"taskID\"" EventID int64 "db:\"eventID\"" }{ TaskID: taskID, EventID: id, }) } // create the assignments if _, err := db.DB.NamedExec("INSERT INTO USER_ASSIGNMENTS (eventID, taskID) VALUES (:eventID, :taskID)", tasks); err != nil { // delete the event again db.DB.Query("DELETE FROM EVENTS WHERE id = ?", id) return err } } return nil } func All() ([]eventDataDB, error) { var dbRows []eventDataDB if err := db.DB.Select(&dbRows, "SELECT *, DATE_FORMAT(date, '%Y-%m-%dT%H:%i:%s') as date FROM EVENTS"); err != nil { return nil, err } else { return dbRows, nil } } func WithAssignments() ([]EventWithAssignment, error) { // get all events if eventsDB, err := All(); err != nil { return nil, err } else { events := make([]EventWithAssignment, len(eventsDB)) for ii, e := range eventsDB { if ev, err := e.Event(); err != nil { logger.Logger.Error().Msgf("can't get assignments for event with id = %d: %v", e.Id, err) } else { events[ii] = ev } } return events, nil } } func WithAvailabilities() ([]EventWithAvailabilities, error) { // get all events if eventsDB, err := All(); err != nil { return nil, err } else { events := make([]EventWithAvailabilities, len(eventsDB)) for ii, e := range eventsDB { if ev, err := e.EventWithAvailabilities(); err != nil { logger.Logger.Error().Msgf("can't get availabilities for event with id = %d: %v", e.Id, err) } else { events[ii] = ev } } return events, nil } } func UserPending(userName string) (int, error) { var result struct { Count int `db:"count(*)"` } if err := db.DB.QueryRowx("SELECT count(*) FROM EVENTS WHERE NOT EXISTS (SELECT 1 FROM USER_AVAILABILITIES WHERE USER_AVAILABILITIES.eventID = EVENTS.id AND USER_AVAILABILITIES.userName = ?)", userName).StructScan(&result); err != nil { return 0, err } else { return result.Count, nil } } func Delete(eventId int) error { _, err := db.DB.Exec("DELETE FROM EVENTS WHERE id = ?", eventId) return err }