diff options
-rw-r--r-- | courses.go | 24 | ||||
-rw-r--r-- | ws.go | 44 |
2 files changed, 63 insertions, 5 deletions
@@ -50,6 +50,12 @@ const ( culture courseTypeT = "Culture" ) +var courseTypes = map[courseTypeT]bool{ + sport: true, + enrichment: true, + culture: true, +} + const ( mw1 courseGroupT = "MW1" mw2 courseGroupT = "MW2" @@ -59,19 +65,27 @@ const ( tt3 courseGroupT = "TT3" ) -/* TODO: This may be inefficient, perhaps use a hash table */ +var courseGroups = map[courseGroupT]bool{ + mw1: true, + mw2: true, + mw3: true, + tt1: true, + tt2: true, + tt3: true, +} func checkCourseType(ct courseTypeT) bool { - return ct == sport || ct == enrichment || ct == culture + return courseTypes[ct] } func checkCourseGroup(cg courseGroupT) bool { - return cg == mw1 || cg == mw2 || cg == mw3 || cg == tt1 || cg == tt2 || cg == tt3 + return courseGroups[cg] } var ( - errInvalidCourseType = errors.New("invalid course type") - errInvalidCourseGroup = errors.New("invalid course group") + errInvalidCourseType = errors.New("invalid course type") + errInvalidCourseGroup = errors.New("invalid course group") + errMultipleChoicesInOneGroup = errors.New("multiple choices per group per user") ) /* @@ -339,6 +339,7 @@ func handleConn( ) (retErr error) { reportError := makeReportError(ctx, c) newCtx, newCancel := context.WithCancel(ctx) + func() { cancelPoolLock.Lock() defer cancelPoolLock.Unlock() @@ -377,6 +378,49 @@ func handleConn( }() /* + * userCourseGroups stores whether the user has already chosen a course + * in the courseGroup. + */ + userCourseGroups := make(map[courseGroupT]bool) + userCourseGroups[mw1] = true // TODO + rows, err := db.Query(newCtx, "SELECT courseid FROM choices WHERE userid = $1", userID) + if err != nil { + return reportError(fmt.Sprintf("cannot select choices: %v", err)) + } + for { + if !rows.Next() { + err := rows.Err() + if err != nil { + return fmt.Errorf("error iterating choices: %w", err) + } + break + } + var thisCourseID int + err := rows.Scan(&thisCourseID) + if err != nil { + return fmt.Errorf("error fetching choices: %w", err) + } + var thisGroupName courseGroupT + err = db.QueryRow(newCtx, + "SELECT cgroup FROM courses WHERE id = $1", + thisCourseID, + ).Scan(&thisGroupName) + if err != nil { + return fmt.Errorf("error querying group of course: %w", err) + } + if userCourseGroups[thisGroupName] { + return fmt.Errorf("%w: user %v, group %v", errMultipleChoicesInOneGroup, userID, thisGroupName) + } + userCourseGroups[thisGroupName] = true + } + + /* + * TODO: No more HELLO command needed? Or otherwise integrate the two. + * In any case, the database work is being duplicated. Probably move + * that up here. + */ + + /* * Later we need to select from recv and send and perform the * corresponding action. But we can't just select from c.Read because * the function blocks. Therefore, we must spawn a goroutine that |