package player import ( "database/sql" "log" "github.com/google/uuid" ) const PlayerTable = ` CREATE TABLE IF NOT EXISTS players ( id uuid PRIMARY KEY, name VARCHAR(100) NOT NULL, email VARCHAR(100) NOT NULL UNIQUE, password_hash VARCHAR(255) NOT NULL ); ` const RoleTable = ` CREATE TABLE IF NOT EXISTS roles ( id SERIAL PRIMARY KEY, player_id uuid NOT NULL, role VARCHAR(50) NOT NULL CHECK (role IN ('player', 'admin')), FOREIGN KEY (player_id) REFERENCES players(id) ON DELETE CASCADE ); ` type Team struct { ID string `json:"id"` Name string `json:"name"` Players []Player `json:"players"` // Players in the team // Matches []Match `json:"matches"` // Matches the team is involved in MatchesWon int `json:"matchesWon"` // Number of matches won by the team MatchesLost int `json:"matchesLost"` // Number of matches lost by the team MatchesDrawn int `json:"matchesDrawn"` // Number of matches drawn by the team MatchesPlayed int `json:"matchesPlayed"` // Total matches played by the team MatchesPlayedCount int `json:"matchesPlayedCount"` // Total matches played by the team } type Player struct { ID string `json:"id"` Name string `json:"name"` Email string `json:"email"` Password string `json:"password,omitempty"` // Password is optional for responses Role string `json:"role"` // e.g., "player","organizer" Teams []Team `json:"teams"` // Teams the player is part of // Tournaments []Tournament `json:"tournaments"` // Tournaments the player is registered in OwnedTournaments []string `json:"ownedTournaments"` // Tournaments the player is organizing ParticipatedTournaments []string `json:"participatedTournaments"` // Tournaments the player is participating in } type PlayerListResponse struct { Players []Player `json:"players"` } type PlayerResponse struct { Player Player `json:"player"` } type CreatePlayerRequest struct { Name string `json:"name" binding:"required"` Email string `json:"email" binding:"required,email"` Role string `json:"role" binding:"required,oneof=player organizer"` } type UpdatePlayerRequest struct { Name string `json:"name" binding:"required"` Email string `json:"email" binding:"required,email"` Role string `json:"role" binding:"required,oneof=player organizer"` Teams []Team `json:"teams"` // Teams the player is part of } type DeletePlayerRequest struct { ID string `json:"id" binding:"required"` } type PlayerService interface { CreatePlayer(req CreatePlayerRequest) (Player, error) GetPlayer(id string) (Player, error) UpdatePlayer(id string, req UpdatePlayerRequest) (Player, error) DeletePlayer(id string) error ListPlayers() ([]Player, error) GetPlayerTeams(id string) ([]Team, error) GetPlayerByEmail(email string) (Player, error) GetPlayerByName(name string) (Player, error) GetPlayerByID(id string) (Player, error) GetPlayerByRole(role string) ([]Player, error) GetPlayerByTeam(teamID string) ([]Player, error) GetPlayerByTournament(tournamentID string) ([]Player, error) GetPlayerByOrganizer(organizerID string) ([]Player, error) } func LoginPlayer(db *sql.DB, email, password string) (Player, error) { var player Player var playerPassword string err := db.QueryRow("SELECT id, name, email, password FROM players WHERE email = $1", email).Scan(&player.ID, &player.Name, &player.Email, playerPassword) if err != nil { log.Printf("Error logging in player with email %s: %v", email, err) return Player{}, err } if player.ID == "" { log.Printf("Player with email %s not found", email) return Player{}, sql.ErrNoRows // or a custom error } // Check if the password matches if password == playerPassword { log.Printf("Player %s logged in successfully", player.Name) } log.Printf("Player %s logged in successfully", player.Name) return player, nil } func GetPlayerRole(db *sql.DB, playerID string) (string, error) { var role string err := db.QueryRow("SELECT role FROM roles WHERE player_id = $1", playerID).Scan(&role) if err != nil { log.Printf("Error retrieving role for player ID %s: %v", playerID, err) return "", err } if role == "" { log.Printf("No role found for player ID %s", playerID) return "", sql.ErrNoRows // or a custom error } log.Printf("Retrieved role for player ID %s: %s", playerID, role) return role, nil } func savePlayer(db *sql.DB, player Player) error { // Ensure the player ID is set if player.ID == "" { player.ID = uuid.New().String() // Generate a new UUID if not set log.Printf("Generated new player ID: %s", player.ID) } // Insert the player into the database if player.Role == "" { player.Role = "player" // Default role if not specified log.Printf("Setting default role for player %s to 'player'", player.Name) } log.Printf("Saving player: ID=%v, Name=%v, Email=%v", player.ID, player.Name, player.Email) stmt := "INSERT INTO public.players (id, name, email) VALUES ($1, $2, $3)" log.Printf("Generated SQL statement: %s", stmt) _, err := db.Exec(stmt, player.ID, player.Name, player.Email) if err != nil { log.Printf("Error saving player to database: %v", err) } // lastID, err := res.LastInsertId() // if err != nil { // log.Printf("Error getting last insert ID: %v", err) // } else { // log.Printf("Last insert ID: %d", lastID) // } // if err := db.QueryRow("SELECT id, name, email FROM players WHERE id = ?", player.ID).Scan(&player.ID, &player.Name, &player.Email, &player.Role); err != nil { // log.Printf("Error retrieving player from database: %v", err) // return err // } log.Printf("Player %s saved to database", player.Name) return nil } func AddRoleToPlayer(db *sql.DB, playerID, role string) error { if playerID == "" { log.Printf("Player ID is required to add a role, but got empty ID") return sql.ErrNoRows // or a custom error } log.Printf("Adding role '%s' to player with ID: %s", role, playerID) stmt := "INSERT INTO public.roles (player_id, role) VALUES ($1, $2)" _, err := db.Exec(stmt, playerID, role) if err != nil { log.Printf("Error adding role to player with ID %s: %v", playerID, err) return err } log.Printf("Role '%s' added to player with ID %s successfully", role, playerID) return nil } func GetAllPlayers(db *sql.DB) ([]Player, error) { rows, err := db.Query("SELECT id, name, email FROM public.players") if err != nil { log.Printf("Error retrieving players: %v", err) return nil, err } defer rows.Close() var players []Player for rows.Next() { var player Player if err := rows.Scan(&player.ID, &player.Name, &player.Email); err != nil { log.Printf("Error scanning player row: %v", err) return nil, err } players = append(players, player) } if err := rows.Err(); err != nil { log.Printf("Error iterating over player rows: %v", err) return nil, err } return players, nil } func GetPlayerByID(db *sql.DB, id string) (Player, error) { var player Player err := db.QueryRow("SELECT id, name, email FROM players WHERE id = $1", id).Scan(&player.ID, &player.Name, &player.Email, &player.Role) if err != nil { log.Printf("Error retrieving player by ID %s: %v", id, err) return Player{}, err } return player, nil } func GetPlayerByEmail(db *sql.DB, email string) (Player, error) { var player Player err := db.QueryRow("SELECT id, name, email FROM players WHERE email = $1", email).Scan(&player.ID, &player.Name, &player.Email, &player.Role) if err != nil { log.Printf("Error retrieving player by email %s: %v", email, err) return Player{}, err } return player, nil } func GetPlayerByName(db *sql.DB, name string) (Player, error) { var player Player err := db.QueryRow("SELECT id, name, email FROM players WHERE name = $1", name).Scan(&player.ID, &player.Name, &player.Email, &player.Role) if err != nil { log.Printf("Error retrieving player by name %s: %v", name, err) return Player{}, err } return player, nil } // DeletePlayer deletes a player from the database by ID. func deletePlayer(db *sql.DB, id string) error { // Delete the player from the database log.Printf("Deleting player with ID: %s", id) _, err := db.Exec("DELETE FROM public.players WHERE id = $1", id) if err != nil { log.Printf("Error deleting player with ID %s: %v", id, err) return err } log.Printf("Player with ID %s deleted successfully", id) return nil } // UpdatePlayer updates an existing player in the database. // It requires the player ID to be set in the Player struct. func updatePlayer(db *sql.DB, player Player) error { // Ensure the player ID is set if player.ID == "" { log.Printf("Player ID is required for update, but got empty ID") return sql.ErrNoRows // or a custom error } log.Printf("Updating player: ID=%v, Name=%v, Email=%v", player.ID, player.Name, player.Email) stmt := "UPDATE public.players SET name = $1, email = $2 WHERE id = $3" _, err := db.Exec(stmt, player.Name, player.Email, player.ID) if err != nil { log.Printf("Error updating player in database: %v", err) return err } log.Printf("Player %s updated successfully", player.Name) return nil } var players_default = []Player{{ ID: "1", Name: "John Doe", Email: "John.Doe@example.de", Role: "player", Teams: []Team{ {ID: "team1"}, {ID: "team2"}, }, }, { ID: "2", Name: "Jane Smith", Email: "Jane-Smith@example.de", Role: "player", Teams: []Team{ {ID: "team3"}, {ID: "team1"}, }, }, }