diff --git a/src/server/index.js b/src/server/index.js index 674760e..4ec2cfc 100644 --- a/src/server/index.js +++ b/src/server/index.js @@ -12,6 +12,8 @@ const port = 3000; app.listen(port, () => { console.log(`Listening on port ${port}`) }) +app.use(express.json()); +app.use(express.urlencoded({ extended: true })); // #endregion // #region frontend @@ -39,4 +41,36 @@ app.get("/tournament/:tournamentId/getMatches", (req, res) => { .then(matches => res.send({"status": "OK", "data": matches})) .catch(err => res.send({"status": "error", "data": err})); }); + +app.get("/match/:matchId/getMatch", (req, res) => { + let matchId = req.params.matchId; + if (isNaN(matchId)) { + res.json({"status": "error", "data": "matchId must be a number"}); + return + } + matchId = parseInt(matchId); + tmdb.getMatch(matchId) + .then(match => res.send({"status": "OK", "data": match})) + .catch(err => res.send({"status": "error", "data": err})); +}); + +// JSON body: {"winner": "teamId"} +app.post("/match/:matchId/setWinner", (req, res) => { + let matchId = req.params.matchId; + let winnerId = req.body.winnerId; + if (isNaN(matchId)) { + res.json({"status": "error", "data": "matchId must be a number"}); + return + } + if (winnerId == undefined || isNaN(winnerId)) { + res.json({"status": "error", "data": "winnerId must be a number"}); + return + } + + matchId = parseInt(matchId); + winnerId = parseInt(winnerId); + tmdb.setMatchWinner(matchId, winnerId) + .then(match => res.send({"status": "OK", "data": match})) + .catch(err => res.send({"status": "error", "data": err})); +}); // #endregion \ No newline at end of file diff --git a/src/server/management/initDB.sql b/src/server/management/initDB.sql index f779af1..53fd002 100644 --- a/src/server/management/initDB.sql +++ b/src/server/management/initDB.sql @@ -9,6 +9,7 @@ DROP TABLE IF EXISTS tournaments; CREATE TABLE tournaments ( id INTEGER PRIMARY KEY AUTO_INCREMENT, name TEXT NOT NULL, + description TEXT, startTime DATETIME NOT NULL, endTime DATETIME NOT NULL ); @@ -43,8 +44,8 @@ CREATE TABLE players ( ); -- Example data (Two tournaments, 4 teams, single elimination) -INSERT INTO tournaments (name, startTime, endTime) VALUES ('Tournament 1', '2022-04-01 16:00:00', '2022-04-01 20:00:00'); -INSERT INTO tournaments (name, startTime, endTime) VALUES ('Tournament 2', '2022-04-03 17:30:00', '2022-04-02 21:30:00'); +INSERT INTO tournaments (name, description, startTime, endTime) VALUES ('Tournament 1', 'First tournament, single elimination', '2022-04-01 16:00:00', '2022-04-01 20:00:00'); +INSERT INTO tournaments (name, description, startTime, endTime) VALUES ('Tournament 2', 'Second tournament, four teams', '2022-04-03 17:30:00', '2022-04-02 21:30:00'); INSERT INTO teams (tournamentId, name) VALUES (1, 'Fnatic'); -- 1 INSERT INTO teams (tournamentId, name) VALUES (1, 'Cloud 9'); -- 2 diff --git a/src/server/tmdb.js b/src/server/tmdb.js index 1ae6824..a19c977 100644 --- a/src/server/tmdb.js +++ b/src/server/tmdb.js @@ -4,9 +4,11 @@ module.exports = { getMatchesByTournamentId: getMatchesByTournamentId, getTournaments: getTournaments, - executeStatement: executeStatement + getMatch: getMatch, + setMatchWinner: setMatchWinner, } +const { query } = require("express"); const mysql = require("mysql"); let connection = mysql.createConnection({ @@ -18,7 +20,7 @@ let connection = mysql.createConnection({ function getMatchesByTournamentId(tournamentId) { return new Promise(function(resolve, reject) { - connection.query("SELECT * FROM matches WHERE tournament_id = ?", [mysql.escape(tournamentId)], (err, matches) => { + connection.query("SELECT * FROM matches WHERE tournamentId = ?", [mysql.escape(tournamentId)], (err, matches) => { if (err) { console.log(err); reject(err); @@ -42,6 +44,89 @@ function getTournaments() { }); } +// Returns the match of the exact given id. +function getMatch(matchId) { + return new Promise(function(resolve, reject) { + connection.query("SELECT * FROM matches WHERE id = ?", [mysql.escape(matchId)], (err, matches) => { + if (err) { + reject(err); + } else { + if (matches.length == 0) { + reject("No such match exists"); + } + resolve(matches[0]); + } + }); + }); +} + +// Removes a given team from a given match. This is done by setting the teamId-property containing the given team to null. +function unsetContestant(matchId, teamId) { + let match = getMatch(matchId); + if (match.team1Id == teamId) { + connection.query("UPDATE matches SET team1Id = NULL WHERE id = ?", [mysql.escape(matchId)], (err, result) => { + if (err) { console.log(err); } + }); + } else if (match.team2Id == teamId) { + connection.query("UPDATE matches SET team2Id = NULL WHERE id = ?", [mysql.escape(matchId)], (err, result) => { + if (err) { console.log(err); } + }); + } else { + console.log("Error: Team not found in match"); + } +} + +// Sets the winnerId-property of a given match. +// Also appoints the winner as a contestant to the next(parent) match. +function setMatchWinner(matchId, winnerId) { + return new Promise(function(resolve, reject) { + getMatch(matchId) + .catch(err => reject(err)) + .then(match => { + if (winnerId != match.team1Id && winnerId != match.team2Id) { + reject("Winner must be one of the teams in the match"); + } + + // Final match doesn't have a parent + if (match.parentMatchId != null) { + // Enter the winner of the match into the parent match + getMatch(match.parentMatchId) + .catch(err =>reject(err)) + .then(parentMatch => { + if (parentMatch.team1Id == null) { + connection.query("UPDATE matches SET team1Id = ? WHERE id = ?", + [mysql.escape(winnerId), mysql.escape(parentMatch.id)], (err, sets) => { + if (err) { reject(err); } + }); + } else if (parentMatch.team2Id == null) { + connection.query("UPDATE matches SET team2Id = ? WHERE id = ?", + [mysql.escape(winnerId), mysql.escape(parentMatch.id)], (err, sets) => { + if (err) { reject(err); } + }); + } else { + reject("Parent match already has two teams"); + } + }); + } + + // Lastly, if all checks passed, actually set the winnerId property + connection.query("UPDATE matches SET winnerId = ? WHERE id = ?", + [mysql.escape(winnerId), mysql.escape(matchId)], (err, sets) => { + if (err) { + // If this update fails, we need to undo the parent match update + unsetContestant(parentMatchId, winnerId); + reject(err); + } + getMatch(matchId) + .catch(err => reject(err)) + .then(match => resolve(match)); + }); + + }); + }); +} + + // Dangerous function, use with caution. // Used to initialize and manage the database by management tools, not by the main application. function executeStatement(statement) {