From a4c51682b780668a130c27e6fc25c9f67c4f1c43 Mon Sep 17 00:00:00 2001 From: June Date: Mon, 2 Mar 2026 22:44:38 -0800 Subject: [PATCH] abstracted out sql queries using sqlc --- .../database/gamer_activity_repository.go | 383 +++++++++--------- internal/database/queries/gamer_activity.sql | 54 +++ internal/database/sqlc/gamer_activity.sql.go | 379 +++++++++++++++++ 3 files changed, 621 insertions(+), 195 deletions(-) create mode 100644 internal/database/queries/gamer_activity.sql create mode 100644 internal/database/sqlc/gamer_activity.sql.go diff --git a/internal/database/gamer_activity_repository.go b/internal/database/gamer_activity_repository.go index 42f5ab5..37f8468 100644 --- a/internal/database/gamer_activity_repository.go +++ b/internal/database/gamer_activity_repository.go @@ -7,6 +7,7 @@ import ( "time" "github.com/google/uuid" + "github.com/ubcesports/echo-base/internal/database/sqlc" "github.com/ubcesports/echo-base/internal/interfaces/gamer" "github.com/ubcesports/echo-base/internal/models" ) @@ -20,203 +21,85 @@ func NewGamerActivityRepository(db *sql.DB) gamer.GamerActivityRepository { } func (r *GamerActivityRepository) GetByStudentNumber(ctx context.Context, studentNumber string) ([]models.GamerActivity, error) { - query := ` - SELECT id, student_number, pc_number, game, started_at, ended_at, exec_name - FROM gamer_activity - WHERE student_number = $1 - ORDER BY started_at DESC - ` - - rows, err := r.db.QueryContext(ctx, query, studentNumber) + queries := sqlc.New(r.db) + rows, err := queries.GetGamerActivity(ctx, studentNumber) if err != nil { return nil, fmt.Errorf("failed to query activities: %w", err) } - defer rows.Close() - - activities := []models.GamerActivity{} - for rows.Next() { - var activity models.GamerActivity - err := rows.Scan( - &activity.ID, - &activity.StudentNumber, - &activity.PCNumber, - &activity.Game, - &activity.StartedAt, - &activity.EndedAt, - &activity.ExecName, - ) - if err != nil { - return nil, fmt.Errorf("failed to scan activity: %w", err) - } - activities = append(activities, activity) - } - - if err = rows.Err(); err != nil { - return nil, fmt.Errorf("error iterating activities: %w", err) - } - - return activities, nil + return toGamerActivities(rows), nil } func (r *GamerActivityRepository) GetTodayActivitiesByStudent(ctx context.Context, studentNumber string) ([]models.GamerActivity, error) { - query := ` - SELECT ga.id, ga.student_number, ga.pc_number, ga.game, ga.started_at, ga.ended_at, ga.exec_name - FROM gamer_activity ga - JOIN gamer_profile gp ON ga.student_number = gp.student_number - WHERE ga.student_number = $1 - AND gp.membership_tier = 1 - AND DATE(ga.started_at AT TIME ZONE 'America/Los_Angeles') = DATE(NOW() AT TIME ZONE 'America/Los_Angeles') - ` - - rows, err := r.db.QueryContext(ctx, query, studentNumber) + queries := sqlc.New(r.db) + rows, err := queries.GetTodayActivitiesByStudent(ctx, studentNumber) if err != nil { return nil, fmt.Errorf("failed to query today activities: %w", err) } - defer rows.Close() - - activities := []models.GamerActivity{} - for rows.Next() { - var activity models.GamerActivity - err := rows.Scan( - &activity.ID, - &activity.StudentNumber, - &activity.PCNumber, - &activity.Game, - &activity.StartedAt, - &activity.EndedAt, - &activity.ExecName, - ) - if err != nil { - return nil, fmt.Errorf("failed to scan activity: %w", err) - } - activities = append(activities, activity) - } - - if err = rows.Err(); err != nil { - return nil, fmt.Errorf("error iterating activities: %w", err) - } - - return activities, nil + return toGamerActivitiesBasic(rows), nil } func (r *GamerActivityRepository) GetRecentActivities(ctx context.Context, page, limit int, search string) ([]models.GamerActivity, error) { + queries := sqlc.New(r.db) offset := (page - 1) * limit - query := ` - SELECT ga.id, ga.student_number, ga.pc_number, ga.game, ga.started_at, ga.ended_at, ga.exec_name, - gp.first_name, gp.last_name - FROM gamer_activity ga - JOIN gamer_profile gp ON ga.student_number = gp.student_number - ` - - args := []interface{}{limit, offset} - if search != "" { - query += ` - WHERE ga.student_number % $3 - OR gp.first_name % $3 - OR gp.last_name % $3 - OR ga.game % $3 - OR ga.exec_name % $3 - ` - args = append(args, search) - } - - query += ` - ORDER BY ga.started_at DESC NULLS LAST - LIMIT $1 OFFSET $2 - ` - - rows, err := r.db.QueryContext(ctx, query, args...) - if err != nil { - return nil, fmt.Errorf("failed to query recent activities: %w", err) - } - defer rows.Close() - - activities := []models.GamerActivity{} - for rows.Next() { - var activity models.GamerActivity - err := rows.Scan( - &activity.ID, - &activity.StudentNumber, - &activity.PCNumber, - &activity.Game, - &activity.StartedAt, - &activity.EndedAt, - &activity.ExecName, - &activity.FirstName, - &activity.LastName, - ) + rows, err := queries.GetRecentActivitiesWithSearch(ctx, sqlc.GetRecentActivitiesWithSearchParams{ + Limit: int64(limit), + Offset: int64(offset), + Column3: sql.NullString{String: search, Valid: true}, + }) if err != nil { - return nil, fmt.Errorf("failed to scan activity: %w", err) + return nil, fmt.Errorf("failed to query recent activities: %w", err) } - activities = append(activities, activity) + return toGamerActivitiesWithNameFromSearch(rows), nil } - if err = rows.Err(); err != nil { - return nil, fmt.Errorf("error iterating activities: %w", err) + rows, err := queries.GetRecentActivities(ctx, sqlc.GetRecentActivitiesParams{ + Limit: int64(limit), + Offset: int64(offset), + }) + if err != nil { + return nil, fmt.Errorf("failed to query recent activities: %w", err) } - - return activities, nil + return toGamerActivitiesWithName(rows), nil } func (r *GamerActivityRepository) Create(ctx context.Context, activity *models.GamerActivity) (*models.GamerActivity, error) { + var activityID uuid.UUID + var err error + if activity.ID == "" { - activity.ID = uuid.New().String() + activityID = uuid.New() + } else { + activityID, err = uuid.Parse(activity.ID) + if err != nil { + return nil, fmt.Errorf("invalid UUID: %w", err) + } } - query := ` - INSERT INTO gamer_activity (id, student_number, pc_number, game, started_at) - VALUES ($1, $2, $3, $4, $5) - RETURNING id, student_number, pc_number, game, started_at, ended_at, exec_name - ` - - result := &models.GamerActivity{} - err := r.db.QueryRowContext( - ctx, - query, - activity.ID, - activity.StudentNumber, - activity.PCNumber, - activity.Game, - activity.StartedAt, - ).Scan( - &result.ID, - &result.StudentNumber, - &result.PCNumber, - &result.Game, - &result.StartedAt, - &result.EndedAt, - &result.ExecName, - ) - + queries := sqlc.New(r.db) + row, err := queries.CreateGamerActivity(ctx, sqlc.CreateGamerActivityParams{ + ID: activityID, + StudentNumber: activity.StudentNumber, + PcNumber: sql.NullInt32{Int32: int32(activity.PCNumber), Valid: true}, + Game: sql.NullString{String: activity.Game, Valid: true}, + StartedAt: sql.NullTime{Time: activity.StartedAt, Valid: true}, + }) if err != nil { return nil, fmt.Errorf("failed to create activity: %w", err) } - return result, nil + return toGamerActivityFromCreate(row), nil } func (r *GamerActivityRepository) UpdateEndTime(ctx context.Context, studentNumber string, pcNumber int, endedAt time.Time, execName string) (*models.GamerActivity, error) { - query := ` - UPDATE gamer_activity - SET ended_at = $1, exec_name = $2 - WHERE student_number = $3 - AND pc_number = $4 - AND ended_at IS NULL - RETURNING id, student_number, pc_number, game, started_at, ended_at, exec_name - ` - - result := &models.GamerActivity{} - err := r.db.QueryRowContext(ctx, query, endedAt, execName, studentNumber, pcNumber).Scan( - &result.ID, - &result.StudentNumber, - &result.PCNumber, - &result.Game, - &result.StartedAt, - &result.EndedAt, - &result.ExecName, - ) + queries := sqlc.New(r.db) + row, err := queries.UpdateActivityEndTime(ctx, sqlc.UpdateActivityEndTimeParams{ + EndedAt: sql.NullTime{Time: endedAt, Valid: true}, + ExecName: sql.NullString{String: execName, Valid: true}, + StudentNumber: studentNumber, + PcNumber: sql.NullInt32{Int32: int32(pcNumber), Valid: true}, + }) if err == sql.ErrNoRows { return nil, fmt.Errorf("no active session found for student %s on PC %d", studentNumber, pcNumber) @@ -225,47 +108,157 @@ func (r *GamerActivityRepository) UpdateEndTime(ctx context.Context, studentNumb return nil, fmt.Errorf("failed to update activity: %w", err) } - return result, nil + return toGamerActivityFromUpdate(row), nil } func (r *GamerActivityRepository) GetActiveSessions(ctx context.Context) ([]models.GamerActivity, error) { - query := ` - SELECT ga.id, ga.student_number, ga.pc_number, ga.game, ga.started_at, ga.ended_at, ga.exec_name, - gp.first_name, gp.last_name - FROM gamer_activity ga - JOIN gamer_profile gp ON ga.student_number = gp.student_number - WHERE ga.ended_at IS NULL - ` - - rows, err := r.db.QueryContext(ctx, query) + queries := sqlc.New(r.db) + rows, err := queries.GetActiveSessions(ctx) if err != nil { return nil, fmt.Errorf("failed to query active sessions: %w", err) } - defer rows.Close() + return toGamerActivitiesFromActiveSessions(rows), nil +} - activities := []models.GamerActivity{} - for rows.Next() { - var activity models.GamerActivity - err := rows.Scan( - &activity.ID, - &activity.StudentNumber, - &activity.PCNumber, - &activity.Game, - &activity.StartedAt, - &activity.EndedAt, - &activity.ExecName, - &activity.FirstName, - &activity.LastName, - ) - if err != nil { - return nil, fmt.Errorf("failed to scan activity: %w", err) +/* +sqlc model conversion helpers +*/ +func toGamerActivityFromCreate(row sqlc.CreateGamerActivityRow) *models.GamerActivity { + activity := &models.GamerActivity{ + ID: row.ID.String(), + StudentNumber: row.StudentNumber, + PCNumber: int(row.PcNumber.Int32), + Game: row.Game.String, + StartedAt: row.StartedAt.Time, + } + if row.EndedAt.Valid { + activity.EndedAt = &row.EndedAt.Time + } + if row.ExecName.Valid { + activity.ExecName = &row.ExecName.String + } + return activity +} + +func toGamerActivityFromUpdate(row sqlc.UpdateActivityEndTimeRow) *models.GamerActivity { + activity := &models.GamerActivity{ + ID: row.ID.String(), + StudentNumber: row.StudentNumber, + PCNumber: int(row.PcNumber.Int32), + Game: row.Game.String, + StartedAt: row.StartedAt.Time, + } + if row.EndedAt.Valid { + activity.EndedAt = &row.EndedAt.Time + } + if row.ExecName.Valid { + activity.ExecName = &row.ExecName.String + } + return activity +} + +func toGamerActivities(rows []sqlc.GetGamerActivityRow) []models.GamerActivity { + activities := make([]models.GamerActivity, len(rows)) + for i, row := range rows { + activities[i] = models.GamerActivity{ + ID: row.ID.String(), + StudentNumber: row.StudentNumber, + PCNumber: int(row.PcNumber.Int32), + Game: row.Game.String, + StartedAt: row.StartedAt.Time, + } + if row.EndedAt.Valid { + activities[i].EndedAt = &row.EndedAt.Time + } + if row.ExecName.Valid { + activities[i].ExecName = &row.ExecName.String } - activities = append(activities, activity) } + return activities +} - if err = rows.Err(); err != nil { - return nil, fmt.Errorf("error iterating activities: %w", err) +func toGamerActivitiesBasic(rows []sqlc.GetTodayActivitiesByStudentRow) []models.GamerActivity { + activities := make([]models.GamerActivity, len(rows)) + for i, row := range rows { + activities[i] = models.GamerActivity{ + ID: row.ID.String(), + StudentNumber: row.StudentNumber, + PCNumber: int(row.PcNumber.Int32), + Game: row.Game.String, + StartedAt: row.StartedAt.Time, + } + if row.EndedAt.Valid { + activities[i].EndedAt = &row.EndedAt.Time + } + if row.ExecName.Valid { + activities[i].ExecName = &row.ExecName.String + } } + return activities +} - return activities, nil +func toGamerActivitiesWithName(rows []sqlc.GetRecentActivitiesRow) []models.GamerActivity { + activities := make([]models.GamerActivity, len(rows)) + for i, row := range rows { + activities[i] = models.GamerActivity{ + ID: row.ID.String(), + StudentNumber: row.StudentNumber, + PCNumber: int(row.PcNumber.Int32), + Game: row.Game.String, + StartedAt: row.StartedAt.Time, + FirstName: &row.FirstName, + LastName: &row.LastName, + } + if row.EndedAt.Valid { + activities[i].EndedAt = &row.EndedAt.Time + } + if row.ExecName.Valid { + activities[i].ExecName = &row.ExecName.String + } + } + return activities +} + +func toGamerActivitiesWithNameFromSearch(rows []sqlc.GetRecentActivitiesWithSearchRow) []models.GamerActivity { + activities := make([]models.GamerActivity, len(rows)) + for i, row := range rows { + activities[i] = models.GamerActivity{ + ID: row.ID.String(), + StudentNumber: row.StudentNumber, + PCNumber: int(row.PcNumber.Int32), + Game: row.Game.String, + StartedAt: row.StartedAt.Time, + FirstName: &row.FirstName, + LastName: &row.LastName, + } + if row.EndedAt.Valid { + activities[i].EndedAt = &row.EndedAt.Time + } + if row.ExecName.Valid { + activities[i].ExecName = &row.ExecName.String + } + } + return activities +} + +func toGamerActivitiesFromActiveSessions(rows []sqlc.GetActiveSessionsRow) []models.GamerActivity { + activities := make([]models.GamerActivity, len(rows)) + for i, row := range rows { + activities[i] = models.GamerActivity{ + ID: row.ID.String(), + StudentNumber: row.StudentNumber, + PCNumber: int(row.PcNumber.Int32), + Game: row.Game.String, + StartedAt: row.StartedAt.Time, + FirstName: &row.FirstName, + LastName: &row.LastName, + } + if row.EndedAt.Valid { + activities[i].EndedAt = &row.EndedAt.Time + } + if row.ExecName.Valid { + activities[i].ExecName = &row.ExecName.String + } + } + return activities } diff --git a/internal/database/queries/gamer_activity.sql b/internal/database/queries/gamer_activity.sql new file mode 100644 index 0000000..f8f82e4 --- /dev/null +++ b/internal/database/queries/gamer_activity.sql @@ -0,0 +1,54 @@ +-- name: GetGamerActivity :many +SELECT id, student_number, pc_number, game, started_at, ended_at, exec_name +FROM gamer_activity +WHERE student_number = $1 +ORDER BY started_at DESC; + +-- name: GetTodayActivitiesByStudent :many +SELECT ga.id, ga.student_number, ga.pc_number, ga.game, ga.started_at, ga.ended_at, ga.exec_name +FROM gamer_activity ga +JOIN gamer_profile gp ON ga.student_number = gp.student_number +WHERE ga.student_number = $1 +AND gp.membership_tier = 1 +AND DATE(ga.started_at AT TIME ZONE 'America/Los_Angeles') = DATE(NOW() AT TIME ZONE 'America/Los_Angeles'); + +-- name: GetRecentActivities :many +SELECT ga.id, ga.student_number, ga.pc_number, ga.game, ga.started_at, ga.ended_at, ga.exec_name, + gp.first_name, gp.last_name +FROM gamer_activity ga +JOIN gamer_profile gp ON ga.student_number = gp.student_number +ORDER BY ga.started_at DESC NULLS LAST +LIMIT $1 OFFSET $2; + +-- name: GetRecentActivitiesWithSearch :many +SELECT ga.id, ga.student_number, ga.pc_number, ga.game, ga.started_at, ga.ended_at, ga.exec_name, + gp.first_name, gp.last_name +FROM gamer_activity ga +JOIN gamer_profile gp ON ga.student_number = gp.student_number +WHERE ga.student_number::TEXT ILIKE '%' || $3 || '%' + OR gp.first_name ILIKE '%' || $3 || '%' + OR gp.last_name ILIKE '%' || $3 || '%' + OR ga.game ILIKE '%' || $3 || '%' + OR ga.exec_name ILIKE '%' || $3 || '%' +ORDER BY ga.started_at DESC NULLS LAST +LIMIT $1 OFFSET $2; + +-- name: CreateGamerActivity :one +INSERT INTO gamer_activity (id, student_number, pc_number, game, started_at) +VALUES ($1, $2, $3, $4, $5) +RETURNING id, student_number, pc_number, game, started_at, ended_at, exec_name; + +-- name: UpdateActivityEndTime :one +UPDATE gamer_activity +SET ended_at = $1, exec_name = $2 +WHERE student_number = $3 +AND pc_number = $4 +AND ended_at IS NULL +RETURNING id, student_number, pc_number, game, started_at, ended_at, exec_name; + +-- name: GetActiveSessions :many +SELECT ga.id, ga.student_number, ga.pc_number, ga.game, ga.started_at, ga.ended_at, ga.exec_name, + gp.first_name, gp.last_name +FROM gamer_activity ga +JOIN gamer_profile gp ON ga.student_number = gp.student_number +WHERE ga.ended_at IS NULL; diff --git a/internal/database/sqlc/gamer_activity.sql.go b/internal/database/sqlc/gamer_activity.sql.go new file mode 100644 index 0000000..cf85f36 --- /dev/null +++ b/internal/database/sqlc/gamer_activity.sql.go @@ -0,0 +1,379 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.30.0 +// source: gamer_activity.sql + +package sqlc + +import ( + "context" + "database/sql" + + "github.com/google/uuid" +) + +const createGamerActivity = `-- name: CreateGamerActivity :one +INSERT INTO gamer_activity (id, student_number, pc_number, game, started_at) +VALUES ($1, $2, $3, $4, $5) +RETURNING id, student_number, pc_number, game, started_at, ended_at, exec_name +` + +type CreateGamerActivityParams struct { + ID uuid.UUID + StudentNumber string + PcNumber sql.NullInt32 + Game sql.NullString + StartedAt sql.NullTime +} + +type CreateGamerActivityRow struct { + ID uuid.UUID + StudentNumber string + PcNumber sql.NullInt32 + Game sql.NullString + StartedAt sql.NullTime + EndedAt sql.NullTime + ExecName sql.NullString +} + +func (q *Queries) CreateGamerActivity(ctx context.Context, arg CreateGamerActivityParams) (CreateGamerActivityRow, error) { + row := q.db.QueryRowContext(ctx, createGamerActivity, + arg.ID, + arg.StudentNumber, + arg.PcNumber, + arg.Game, + arg.StartedAt, + ) + var i CreateGamerActivityRow + err := row.Scan( + &i.ID, + &i.StudentNumber, + &i.PcNumber, + &i.Game, + &i.StartedAt, + &i.EndedAt, + &i.ExecName, + ) + return i, err +} + +const getActiveSessions = `-- name: GetActiveSessions :many +SELECT ga.id, ga.student_number, ga.pc_number, ga.game, ga.started_at, ga.ended_at, ga.exec_name, + gp.first_name, gp.last_name +FROM gamer_activity ga +JOIN gamer_profile gp ON ga.student_number = gp.student_number +WHERE ga.ended_at IS NULL +` + +type GetActiveSessionsRow struct { + ID uuid.UUID + StudentNumber string + PcNumber sql.NullInt32 + Game sql.NullString + StartedAt sql.NullTime + EndedAt sql.NullTime + ExecName sql.NullString + FirstName string + LastName string +} + +func (q *Queries) GetActiveSessions(ctx context.Context) ([]GetActiveSessionsRow, error) { + rows, err := q.db.QueryContext(ctx, getActiveSessions) + if err != nil { + return nil, err + } + defer rows.Close() + var items []GetActiveSessionsRow + for rows.Next() { + var i GetActiveSessionsRow + if err := rows.Scan( + &i.ID, + &i.StudentNumber, + &i.PcNumber, + &i.Game, + &i.StartedAt, + &i.EndedAt, + &i.ExecName, + &i.FirstName, + &i.LastName, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const getGamerActivity = `-- name: GetGamerActivity :many +SELECT id, student_number, pc_number, game, started_at, ended_at, exec_name +FROM gamer_activity +WHERE student_number = $1 +ORDER BY started_at DESC +` + +type GetGamerActivityRow struct { + ID uuid.UUID + StudentNumber string + PcNumber sql.NullInt32 + Game sql.NullString + StartedAt sql.NullTime + EndedAt sql.NullTime + ExecName sql.NullString +} + +func (q *Queries) GetGamerActivity(ctx context.Context, studentNumber string) ([]GetGamerActivityRow, error) { + rows, err := q.db.QueryContext(ctx, getGamerActivity, studentNumber) + if err != nil { + return nil, err + } + defer rows.Close() + var items []GetGamerActivityRow + for rows.Next() { + var i GetGamerActivityRow + if err := rows.Scan( + &i.ID, + &i.StudentNumber, + &i.PcNumber, + &i.Game, + &i.StartedAt, + &i.EndedAt, + &i.ExecName, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const getRecentActivities = `-- name: GetRecentActivities :many +SELECT ga.id, ga.student_number, ga.pc_number, ga.game, ga.started_at, ga.ended_at, ga.exec_name, + gp.first_name, gp.last_name +FROM gamer_activity ga +JOIN gamer_profile gp ON ga.student_number = gp.student_number +ORDER BY ga.started_at DESC NULLS LAST +LIMIT $1 OFFSET $2 +` + +type GetRecentActivitiesParams struct { + Limit int64 + Offset int64 +} + +type GetRecentActivitiesRow struct { + ID uuid.UUID + StudentNumber string + PcNumber sql.NullInt32 + Game sql.NullString + StartedAt sql.NullTime + EndedAt sql.NullTime + ExecName sql.NullString + FirstName string + LastName string +} + +func (q *Queries) GetRecentActivities(ctx context.Context, arg GetRecentActivitiesParams) ([]GetRecentActivitiesRow, error) { + rows, err := q.db.QueryContext(ctx, getRecentActivities, arg.Limit, arg.Offset) + if err != nil { + return nil, err + } + defer rows.Close() + var items []GetRecentActivitiesRow + for rows.Next() { + var i GetRecentActivitiesRow + if err := rows.Scan( + &i.ID, + &i.StudentNumber, + &i.PcNumber, + &i.Game, + &i.StartedAt, + &i.EndedAt, + &i.ExecName, + &i.FirstName, + &i.LastName, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const getRecentActivitiesWithSearch = `-- name: GetRecentActivitiesWithSearch :many +SELECT ga.id, ga.student_number, ga.pc_number, ga.game, ga.started_at, ga.ended_at, ga.exec_name, + gp.first_name, gp.last_name +FROM gamer_activity ga +JOIN gamer_profile gp ON ga.student_number = gp.student_number +WHERE ga.student_number::TEXT ILIKE '%' || $3 || '%' + OR gp.first_name ILIKE '%' || $3 || '%' + OR gp.last_name ILIKE '%' || $3 || '%' + OR ga.game ILIKE '%' || $3 || '%' + OR ga.exec_name ILIKE '%' || $3 || '%' +ORDER BY ga.started_at DESC NULLS LAST +LIMIT $1 OFFSET $2 +` + +type GetRecentActivitiesWithSearchParams struct { + Limit int64 + Offset int64 + Column3 sql.NullString +} + +type GetRecentActivitiesWithSearchRow struct { + ID uuid.UUID + StudentNumber string + PcNumber sql.NullInt32 + Game sql.NullString + StartedAt sql.NullTime + EndedAt sql.NullTime + ExecName sql.NullString + FirstName string + LastName string +} + +func (q *Queries) GetRecentActivitiesWithSearch(ctx context.Context, arg GetRecentActivitiesWithSearchParams) ([]GetRecentActivitiesWithSearchRow, error) { + rows, err := q.db.QueryContext(ctx, getRecentActivitiesWithSearch, arg.Limit, arg.Offset, arg.Column3) + if err != nil { + return nil, err + } + defer rows.Close() + var items []GetRecentActivitiesWithSearchRow + for rows.Next() { + var i GetRecentActivitiesWithSearchRow + if err := rows.Scan( + &i.ID, + &i.StudentNumber, + &i.PcNumber, + &i.Game, + &i.StartedAt, + &i.EndedAt, + &i.ExecName, + &i.FirstName, + &i.LastName, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const getTodayActivitiesByStudent = `-- name: GetTodayActivitiesByStudent :many +SELECT ga.id, ga.student_number, ga.pc_number, ga.game, ga.started_at, ga.ended_at, ga.exec_name +FROM gamer_activity ga +JOIN gamer_profile gp ON ga.student_number = gp.student_number +WHERE ga.student_number = $1 +AND gp.membership_tier = 1 +AND DATE(ga.started_at AT TIME ZONE 'America/Los_Angeles') = DATE(NOW() AT TIME ZONE 'America/Los_Angeles') +` + +type GetTodayActivitiesByStudentRow struct { + ID uuid.UUID + StudentNumber string + PcNumber sql.NullInt32 + Game sql.NullString + StartedAt sql.NullTime + EndedAt sql.NullTime + ExecName sql.NullString +} + +func (q *Queries) GetTodayActivitiesByStudent(ctx context.Context, studentNumber string) ([]GetTodayActivitiesByStudentRow, error) { + rows, err := q.db.QueryContext(ctx, getTodayActivitiesByStudent, studentNumber) + if err != nil { + return nil, err + } + defer rows.Close() + var items []GetTodayActivitiesByStudentRow + for rows.Next() { + var i GetTodayActivitiesByStudentRow + if err := rows.Scan( + &i.ID, + &i.StudentNumber, + &i.PcNumber, + &i.Game, + &i.StartedAt, + &i.EndedAt, + &i.ExecName, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const updateActivityEndTime = `-- name: UpdateActivityEndTime :one +UPDATE gamer_activity +SET ended_at = $1, exec_name = $2 +WHERE student_number = $3 +AND pc_number = $4 +AND ended_at IS NULL +RETURNING id, student_number, pc_number, game, started_at, ended_at, exec_name +` + +type UpdateActivityEndTimeParams struct { + EndedAt sql.NullTime + ExecName sql.NullString + StudentNumber string + PcNumber sql.NullInt32 +} + +type UpdateActivityEndTimeRow struct { + ID uuid.UUID + StudentNumber string + PcNumber sql.NullInt32 + Game sql.NullString + StartedAt sql.NullTime + EndedAt sql.NullTime + ExecName sql.NullString +} + +func (q *Queries) UpdateActivityEndTime(ctx context.Context, arg UpdateActivityEndTimeParams) (UpdateActivityEndTimeRow, error) { + row := q.db.QueryRowContext(ctx, updateActivityEndTime, + arg.EndedAt, + arg.ExecName, + arg.StudentNumber, + arg.PcNumber, + ) + var i UpdateActivityEndTimeRow + err := row.Scan( + &i.ID, + &i.StudentNumber, + &i.PcNumber, + &i.Game, + &i.StartedAt, + &i.EndedAt, + &i.ExecName, + ) + return i, err +}