Skip to content

Commit

Permalink
implement result api
Browse files Browse the repository at this point in the history
  • Loading branch information
Igor Polyakov committed Jun 8, 2024
1 parent 9b17d05 commit 2be1830
Show file tree
Hide file tree
Showing 6 changed files with 83 additions and 22 deletions.
2 changes: 1 addition & 1 deletion api/swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -688,7 +688,7 @@ components:
type: object
properties:
id:
type: string
type: integer
description: Unique identifier for the result entry
team_id:
type: string
Expand Down
58 changes: 52 additions & 6 deletions internal/app/api/results.go
Original file line number Diff line number Diff line change
@@ -1,21 +1,67 @@
package api

import (
apimodels "ctf01d/internal/app/apimodels"
dbmodel "ctf01d/internal/app/db"
"ctf01d/internal/app/repository"
api_helpers "ctf01d/internal/app/utils"
"ctf01d/internal/app/view"
"database/sql"
"encoding/json"
"log/slog"
"net/http"
"strconv"

"github.com/gorilla/mux"
)

func CreateResultHandler(db *sql.DB, w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
w.WriteHeader(http.StatusOK)
var result apimodels.ResultRequest
if err := json.NewDecoder(r.Body).Decode(&result); err != nil {
slog.Warn(err.Error(), "handler", "CreateResultHandler")
api_helpers.RespondWithJSON(w, http.StatusBadRequest, map[string]string{"error": "Invalid request payload"})
return
}
repo := repository.NewResultRepository(db)
newResult := &dbmodel.Result{
TeamId: result.TeamId,
GameId: result.GameId,
Score: result.Score,
Rank: result.Rank,
}
if err := repo.Create(r.Context(), newResult); err != nil {
slog.Warn(err.Error(), "handler", "CreateGameHandler")
api_helpers.RespondWithJSON(w, http.StatusInternalServerError, map[string]string{"error": "Failed to create result"})
return
}
api_helpers.RespondWithJSON(w, http.StatusOK, map[string]string{"data": "Game created successfully"})
}

func GetResultByIdHandler(db *sql.DB, w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
w.WriteHeader(http.StatusOK)
vars := mux.Vars(r)
id, err := strconv.Atoi(vars["id"])
if err != nil {
slog.Warn(err.Error(), "handler", "GetGameByIdHandler")
api_helpers.RespondWithJSON(w, http.StatusBadRequest, map[string]string{"error": "Bad request"})
return
}
repo := repository.NewResultRepository(db)
result, err := repo.GetById(r.Context(), id)
if err != nil {
slog.Warn(err.Error(), "handler", "GetGameByIdHandler")
api_helpers.RespondWithJSON(w, http.StatusInternalServerError, map[string]string{"error": "Failed to fetch result"})
return
}
api_helpers.RespondWithJSON(w, http.StatusOK, view.NewResultFromModel(result))
}

func ListResultsHandler(db *sql.DB, w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
w.WriteHeader(http.StatusOK)
repo := repository.NewResultRepository(db)
results, err := repo.List(r.Context())
if err != nil {
slog.Warn(err.Error(), "handler", "ListGamesHandler")
api_helpers.RespondWithJSON(w, http.StatusBadRequest, map[string]string{"error": "Failed to fetch results"})
return
}
api_helpers.RespondWithJSON(w, http.StatusOK, view.NewResultFromModels(results))
}
2 changes: 1 addition & 1 deletion internal/app/apimodels/models.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions internal/app/db/result.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ type Result struct {
Id int `db:"id"`
TeamId string `db:"team_id"`
GameId string `db:"game_id"`
Score int32 `db:"score"`
Rank int32 `db:"rank"`
Score int `db:"score"`
Rank int `db:"rank"`
}
12 changes: 6 additions & 6 deletions internal/app/repository/result.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ import (

type ResultRepository interface {
Create(ctx context.Context, result *models.Result) error
GetById(ctx context.Context, id string) (*models.Result, error)
GetById(ctx context.Context, id int) (*models.Result, error)
Update(ctx context.Context, result *models.Result) error
Delete(ctx context.Context, id string) error
List(ctx context.Context) ([]models.Result, error)
List(ctx context.Context) ([]*models.Result, error)
}

type resultRepo struct {
Expand All @@ -28,7 +28,7 @@ func (r *resultRepo) Create(ctx context.Context, result *models.Result) error {
return err
}

func (r *resultRepo) GetById(ctx context.Context, id string) (*models.Result, error) {
func (r *resultRepo) GetById(ctx context.Context, id int) (*models.Result, error) {
query := `SELECT id, team_id, game_id, score, rank FROM results WHERE id = $1`
result := &models.Result{}
err := r.db.QueryRowContext(ctx, query, id).Scan(&result.Id, &result.TeamId, &result.GameId, &result.Score, &result.Rank)
Expand All @@ -50,21 +50,21 @@ func (r *resultRepo) Delete(ctx context.Context, id string) error {
return err
}

func (r *resultRepo) List(ctx context.Context) ([]models.Result, error) {
func (r *resultRepo) List(ctx context.Context) ([]*models.Result, error) {
query := `SELECT id, team_id, game_id, score, rank FROM results`
rows, err := r.db.QueryContext(ctx, query)
if err != nil {
return nil, err
}
defer rows.Close()

var results []models.Result
var results []*models.Result
for rows.Next() {
var result models.Result
if err := rows.Scan(&result.Id, &result.TeamId, &result.GameId, &result.Score, &result.Rank); err != nil {
return nil, err
}
results = append(results, result)
results = append(results, &result)
}
return results, nil
}
27 changes: 21 additions & 6 deletions internal/app/view/result.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,24 @@
package view

type Result struct {
Id string `json:"id"`
TeamId string `json:"team_id"`
GameId string `json:"game_id"`
Score int32 `json:"score"`
Rank int32 `json:"rank"`
import (
apimodels "ctf01d/internal/app/apimodels"
"ctf01d/internal/app/db"
)

func NewResultFromModel(s *db.Result) *apimodels.ResultResponse {
return &apimodels.ResultResponse{
Id: s.Id,
GameId: s.GameId,
Rank: s.Rank,
Score: s.Score,
TeamId: s.TeamId,
}
}

func NewResultFromModels(rm []*db.Result) []*apimodels.ResultResponse {
var services []*apimodels.ResultResponse
for _, s := range rm {
services = append(services, NewResultFromModel(s))
}
return services
}

0 comments on commit 2be1830

Please sign in to comment.