ADD: added function to update db scheme automaticly

This commit is contained in:
hwinkel
2025-11-18 22:23:08 +01:00
parent ef396af480
commit 3818fbf460
15 changed files with 876 additions and 186 deletions

View File

@@ -32,35 +32,36 @@ func GetPlayers(c *gin.Context, db *sql.DB) {
}
func CreatePlayer(c *gin.Context, db *sql.DB) {
var newPlayer Player
var newPlayer User
var err error
if err := c.ShouldBindJSON(&newPlayer); err != nil {
log.Printf("Error binding player data: %v", err)
common.RespondError(c, http.StatusBadRequest, "Invalid player data")
return
}
newPlayer.Password, err = common.HashPassword(newPlayer.Password)
newPlayer.password, err = common.HashPassword(newPlayer.password)
if err != nil {
log.Printf("Error hashing password: %v", err)
common.RespondError(c, http.StatusInternalServerError, "Failed to hash password")
return
}
newPlayer.ID = uuid.New().String()
newPlayer.UUID = uuid.New().String()
err = savePlayer(db, newPlayer)
if err != nil {
log.Printf("Error saving player: %v", err)
common.RespondError(c, http.StatusInternalServerError, "Failed to create player")
return
}
err = AddRoleToPlayer(db, newPlayer.ID, "player")
var roles = []string{"player"}
err = AddRoleToPlayer(db, newPlayer.UUID, roles)
if err != nil {
log.Printf("Error adding role to player: %v", err)
common.RespondError(c, http.StatusInternalServerError, "Failed to assign role to player")
return
}
log.Printf("User %s (%s) created player: %s", c.GetString("userId"), c.GetString("email"), newPlayer.Name)
log.Printf("User %s (%s) created player: %s", c.GetString("userId"), c.GetString("email"), newPlayer.Username)
common.RespondCreated(c, newPlayer)
}
@@ -80,19 +81,19 @@ func GetPlayer(c *gin.Context, db *sql.DB, id string) {
return
}
if player.ID == "" {
if player.UUID == "" {
log.Printf("Player with ID %s not found", playerID)
common.RespondError(c, http.StatusNotFound, "Player not found")
return
}
role, err := GetPlayerRole(db, player.ID)
role, err := GetPlayerRole(db, player.UUID)
if err != nil {
log.Printf("Error retrieving role for player ID %s: %v", player.ID, err)
log.Printf("Error retrieving role for player ID %s: %v", player.UUID, err)
common.RespondError(c, http.StatusInternalServerError, "Failed to retrieve player role")
return
}
player.Role = role
log.Printf(player.ID, player.Name, player.Email, player.Role)
log.Printf(player.UUID, player.Username, player.Email, player.Role)
c.JSON(http.StatusOK, player)
}
@@ -109,14 +110,14 @@ func UpdatePlayer(c *gin.Context, db *sql.DB) {
return
}
var updatedPlayer Player
var updatedPlayer User
if err := c.ShouldBindJSON(&updatedPlayer); err != nil {
log.Printf("Error binding player data: %v", err)
common.RespondError(c, http.StatusBadRequest, "Invalid player data")
return
}
updatedPlayer.ID = playerID
updatedPlayer.UUID = playerID
err := updatePlayer(db, updatedPlayer)
if err != nil {
log.Printf("Error updating player with ID %s: %v", playerID, err)
@@ -124,7 +125,7 @@ func UpdatePlayer(c *gin.Context, db *sql.DB) {
return
}
log.Printf("User %s (%s) updated player: %s", c.GetString("userId"), c.GetString("email"), updatedPlayer.Name)
log.Printf("User %s (%s) updated player: %s", c.GetString("userId"), c.GetString("email"), updatedPlayer.Username)
c.JSON(http.StatusOK, updatedPlayer)
}

View File

@@ -3,31 +3,66 @@ package player
import (
"database/sql"
"log"
"strings"
"time"
"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 User struct {
UUID string `db:"uuid" sql:"VARCHAR(255)" index:"true"`
Username string `db:"username" sql:"VARCHAR(100)"`
Email string `db:"email" sql:"VARCHAR(255)" index:"true"`
lastname string `db:"lastname" sql:"VARCHAR(100)"`
fistname string `db:"fistname" sql:"VARCHAR(100)"`
password string `db:"password_hash" sql:"VARCHAR(255)"`
phone string `db:"phone" sql:"VARCHAR(20)"`
avatarURL string `db:"avatar_url" sql:"VARCHAR(255)"`
IsActive bool `db:"is_active" sql:"BOOLEAN"`
birthday time.Time `db:"birthday" sql:"DATE"`
createdAt time.Time `db:"created_at" sql:"TIMESTAMP"`
updatedAt time.Time `db:"updated_at" sql:"TIMESTAMP"`
LastLogin time.Time `db:"last_login" sql:"TIMESTAMP"`
Role []string `ignore:"true"` // wird NICHT in der DB angelegt
}
type Roles struct {
ID int `db:"id" sql:"SERIAL PRIMARY KEY"`
PlayerID string `db:"player_id" sql:"UUID"`
Role []string `db:"role" sql:"TEXT[]"`
}
// const PlayerTable = `
// CREATE TABLE IF NOT EXISTS users (
// id uuid PRIMARY KEY,
// username VARCHAR(100) NOT NULL,
// lastname VARCHAR(100) NOT NULL,
// fistname VARCHAR(100) NOT NULL,
// email VARCHAR(100) NOT NULL UNIQUE,
// password_hash VARCHAR(255) NOT NULL,
// created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
// updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
// last_login TIMESTAMP,
// phone VARCHAR(20),
// avatar_url VARCHAR(255),
// is_active BOOLEAN NOT NULL DEFAULT TRUE
// );
// `
// 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 users(id) ON DELETE CASCADE
// );
//`
type Team struct {
ID string `json:"id"`
Name string `json:"name"`
Players []Player `json:"players"` // Players in the team
ID string `json:"id"`
Name string `json:"name"`
Players []User `json:"users"` // 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
@@ -36,22 +71,22 @@ type Team struct {
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 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"`
Players []User `json:"users"`
}
type PlayerResponse struct {
Player Player `json:"player"`
Player User `json:"player"`
}
type CreatePlayerRequest struct {
Name string `json:"name" binding:"required"`
@@ -68,75 +103,79 @@ 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)
CreatePlayer(req CreatePlayerRequest) (User, error)
GetPlayer(id string) (User, error)
UpdatePlayer(id string, req UpdatePlayerRequest) (User, error)
DeletePlayer(id string) error
ListPlayers() ([]Player, error)
ListPlayers() ([]User, 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)
GetPlayerByEmail(email string) (User, error)
GetPlayerByName(name string) (User, error)
GetPlayerByID(id string) (User, error)
GetPlayerByRole(role string) ([]User, error)
GetPlayerByTeam(teamID string) ([]User, error)
GetPlayerByTournament(tournamentID string) ([]User, error)
GetPlayerByOrganizer(organizerID string) ([]User, error)
}
func LoginPlayer(db *sql.DB, email, password string) (Player, error) {
var player Player
func LoginPlayer(db *sql.DB, email, password string) (User, error) {
var player User
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)
err := db.QueryRow("SELECT id, name, email, password FROM users WHERE email = $1", email).Scan(&player.UUID, &player.Username, &player.Email, playerPassword)
if err != nil {
log.Printf("Error logging in player with email %s: %v", email, err)
return Player{}, err
return User{}, err
}
if player.ID == "" {
log.Printf("Player with email %s not found", email)
return Player{}, sql.ErrNoRows // or a custom error
if player.UUID == "" {
log.Printf("User with email %s not found", email)
return User{}, 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("User %s logged in successfully", player.Username)
}
log.Printf("Player %s logged in successfully", player.Name)
log.Printf("User %s logged in successfully", player.Username)
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)
func GetPlayerRole(db *sql.DB, playerID string) ([]string, error) {
var role []string
var tmp string
err := db.QueryRow("SELECT role FROM roles WHERE player_id = $1", playerID).Scan(&tmp)
log.Println(tmp)
role = strings.Split(tmp, ",")
if err != nil {
log.Printf("Error retrieving role for player ID %s: %v", playerID, err)
return "", err
return nil, err
}
if role == "" {
if len(role) == 0 {
log.Printf("No role found for player ID %s", playerID)
return "", sql.ErrNoRows // or a custom error
return nil, 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 {
func savePlayer(db *sql.DB, player User) 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)
if player.UUID == "" {
player.UUID = uuid.New().String() // Generate a new UUID if not set
log.Printf("Generated new player ID: %s", player.UUID)
}
// 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)
if len(player.Role) == 0 {
player.Role = append(player.Role, "player") // Default role if not specified
log.Printf("Setting default role for player %s to 'player'", player.Username)
}
log.Printf("Saving player: ID=%v, Name=%v, Email=%v", player.ID, player.Name, player.Email)
log.Printf("Saving player: ID=%v, Name=%v, Email=%v", player.UUID, player.Username, player.Email)
stmt := "INSERT INTO public.players (id, name, email,password_hash) VALUES ($1, $2, $3,$4)"
stmt := "INSERT INTO public.users (id, name, email,password_hash) VALUES ($1, $2, $3,$4)"
log.Printf("Generated SQL statement: %s", stmt)
_, err := db.Exec(stmt, player.ID, player.Name, player.Email, player.Password)
_, err := db.Exec(stmt, player.UUID, player.Username, player.Email, player.password)
if err != nil {
log.Printf("Error saving player to database: %v", err)
@@ -147,17 +186,17 @@ func savePlayer(db *sql.DB, player Player) error {
// } 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 {
// if err := db.QueryRow("SELECT id, name, email FROM users 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)
log.Printf("User %s saved to database", player.Username)
return nil
}
func AddRoleToPlayer(db *sql.DB, playerID, role string) error {
func AddRoleToPlayer(db *sql.DB, playerID string, role []string) error {
if playerID == "" {
log.Printf("Player ID is required to add a role, but got empty ID")
log.Printf("User ID is required to add a role, but got empty ID")
return sql.ErrNoRows // or a custom error
}
@@ -174,22 +213,22 @@ func AddRoleToPlayer(db *sql.DB, playerID, role string) error {
return nil
}
func GetAllPlayers(db *sql.DB) ([]Player, error) {
rows, err := db.Query("SELECT id, name, email FROM public.players")
func GetAllPlayers(db *sql.DB) ([]User, error) {
rows, err := db.Query("SELECT id, name, email FROM public.users")
if err != nil {
log.Printf("Error retrieving players: %v", err)
log.Printf("Error retrieving users: %v", err)
return nil, err
}
defer rows.Close()
var players []Player
var users []User
for rows.Next() {
var player Player
if err := rows.Scan(&player.ID, &player.Name, &player.Email); err != nil {
var player User
if err := rows.Scan(&player.UUID, &player.Username, &player.Email); err != nil {
log.Printf("Error scanning player row: %v", err)
return nil, err
}
players = append(players, player)
users = append(users, player)
}
if err := rows.Err(); err != nil {
@@ -197,33 +236,33 @@ func GetAllPlayers(db *sql.DB) ([]Player, error) {
return nil, err
}
return players, nil
return users, 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)
func GetPlayerByID(db *sql.DB, id string) (User, error) {
var player User
err := db.QueryRow("SELECT id, name, email FROM users WHERE id = $1", id).Scan(&player.UUID, &player.Username, &player.Email)
if err != nil {
log.Printf("Error retrieving player by ID %s: %v", id, err)
return Player{}, err
return User{}, 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)
func GetPlayerByEmail(db *sql.DB, email string) (User, error) {
var player User
err := db.QueryRow("SELECT id, name, email FROM users WHERE email = $1", email).Scan(&player.UUID, &player.Username, &player.Email, &player.Role)
if err != nil {
log.Printf("Error retrieving player by email %s: %v", email, err)
return Player{}, err
return User{}, 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)
func GetPlayerByName(db *sql.DB, name string) (User, error) {
var player User
err := db.QueryRow("SELECT id, name, email FROM users WHERE name = $1", name).Scan(&player.UUID, &player.Username, &player.Email, &player.Role)
if err != nil {
log.Printf("Error retrieving player by name %s: %v", name, err)
return Player{}, err
return User{}, err
}
return player, nil
}
@@ -232,55 +271,33 @@ func GetPlayerByName(db *sql.DB, name string) (Player, error) {
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)
_, err := db.Exec("DELETE FROM public.users 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)
log.Printf("User 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 {
// It requires the player ID to be set in the User struct.
func updatePlayer(db *sql.DB, player User) error {
// Ensure the player ID is set
if player.ID == "" {
log.Printf("Player ID is required for update, but got empty ID")
if player.UUID == "" {
log.Printf("User 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)
log.Printf("Updating player: ID=%v, Name=%v, Email=%v", player.UUID, player.Username, player.Email)
stmt := "UPDATE public.players SET name = $1, email = $2 WHERE id = $3"
_, err := db.Exec(stmt, player.Name, player.Email, player.ID)
stmt := "UPDATE public.users SET name = $1, email = $2 WHERE id = $3"
_, err := db.Exec(stmt, player.Username, player.Email, player.UUID)
if err != nil {
log.Printf("Error updating player in database: %v", err)
return err
}
log.Printf("Player %s updated successfully", player.Name)
log.Printf("User %s updated successfully", player.Username)
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"},
},
},
}