diff --git a/src/server/index.js b/src/server/index.js index af48368..674760e 100644 --- a/src/server/index.js +++ b/src/server/index.js @@ -1,27 +1,32 @@ const path = require("path"); const express = require("express"); -const mysql = require("mysql"); require("dotenv").config(); -let connection = mysql.createConnection({ - host: process.env.DB_HOST, - user: process.env.DB_USER, - password: process.env.DB_PASSWORD, - database: process.env.DB_DATABASE -}); -const Match = require("./match.js"); +// Our self-written module for handling database operations +let tmdb = require("./tmdb.js"); +// #region Express setup const app = express(); const port = 3000; -app.engine('html', require('ejs').renderFile); +//app.engine('html', require('ejs').renderFile); app.listen(port, () => { console.log(`Listening on port ${port}`) }) +// #endregion - +// #region frontend +// Serve static files from the React app app.get("/", (req, res) => { res.sendFile(path.join(__dirname, "public", "landing.html")); }); +// #endregion + +// #region API +app.get("/tournament/getTournaments", (req, res) => { + tmdb.getTournaments() + .then(tournaments => {res.json({"status": "OK", "data": tournaments}); }) + .catch(err => {res.json({"status": "error", "data": err}); }); +}); app.get("/tournament/:tournamentId/getMatches", (req, res) => { let tournamentId = req.params.tournamentId; @@ -30,34 +35,8 @@ app.get("/tournament/:tournamentId/getMatches", (req, res) => { return } tournamentId = parseInt(tournamentId); - getMatchesByTournamentId(tournamentId) + tmdb.getMatchesByTournamentId(tournamentId) .then(matches => res.send({"status": "OK", "data": matches})) .catch(err => res.send({"status": "error", "data": err})); }); - -// app.get("/getMatches", (req, res) => { -// connection.query("SELECT * FROM matches", (err, matches) => { -// if (err) { -// console.log(err); -// } else { -// res.send(matches); -// } -// }); -// }); - -// app.get("/tournament/:tournamentId", (req, res) => { -// res.render(path.join(__dirname, "public", "tournament.html"), {"tournament":tournaments[req.params.tournamentId]}); -// }); - -function getMatchesByTournamentId(tournamentId) { - return new Promise(function(resolve, reject) { - connection.query("SELECT * FROM matches WHERE tournament_id = ?", [mysql.escape(tournamentId)], (err, matches) => { - if (err) { - console.log(err); - reject(err); - } else { - resolve(matches); - } - }); - }); -} +// #endregion \ No newline at end of file diff --git a/src/server/management/initDB.sql b/src/server/management/initDB.sql new file mode 100644 index 0000000..f779af1 --- /dev/null +++ b/src/server/management/initDB.sql @@ -0,0 +1,89 @@ +-- WARNING: Will delete EVERYTHING in the database! + +DROP TABLE IF EXISTS players; +DROP TABLE IF EXISTS matches; +DROP TABLE IF EXISTS teams; +DROP TABLE IF EXISTS tournaments; + +-- Create the tables +CREATE TABLE tournaments ( + id INTEGER PRIMARY KEY AUTO_INCREMENT, + name TEXT NOT NULL, + startTime DATETIME NOT NULL, + endTime DATETIME NOT NULL +); + +CREATE TABLE teams ( + id INTEGER PRIMARY KEY AUTO_INCREMENT, + tournamentId INTEGER NOT NULL, + name TEXT NOT NULL, + + FOREIGN KEY (tournamentId) REFERENCES tournaments (id) +); + +CREATE TABLE matches ( + id INTEGER PRIMARY KEY AUTO_INCREMENT, + tournamentId INTEGER NOT NULL, + parentMatchId INTEGER, + team1Id INTEGER, + team2Id INTEGER, + winnerId INTEGER, + + FOREIGN KEY (tournamentId) REFERENCES tournaments (id), + FOREIGN KEY (team1Id) REFERENCES teams (id), + FOREIGN KEY (team2Id) REFERENCES teams (id) +); + +CREATE TABLE players ( + id INTEGER PRIMARY KEY AUTO_INCREMENT, + name TEXT NOT NULL, + teamId INTEGER NOT NULL, + + FOREIGN KEY (teamId) REFERENCES teams (id) +); + +-- 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 teams (tournamentId, name) VALUES (1, 'Fnatic'); -- 1 +INSERT INTO teams (tournamentId, name) VALUES (1, 'Cloud 9'); -- 2 +INSERT INTO teams (tournamentId, name) VALUES (1, 'Team Liquid'); -- 3 +INSERT INTO teams (tournamentId, name) VALUES (1, 'LDLC'); -- 4 + +INSERT INTO teams (tournamentId, name) VALUES (2, 'Astralis'); -- 5 +INSERT INTO teams (tournamentId, name) VALUES (2, 'Entropiq'); -- 6 +INSERT INTO teams (tournamentId, name) VALUES (2, 'Team Vitality'); -- 7 +INSERT INTO teams (tournamentId, name) VALUES (2, 'Godsent'); -- 8 + +-- tournament 1 -- +-- Final match +INSERT INTO matches (tournamentId, parentMatchId, team1Id, team2Id) VALUES (1, NULL, NULL, NULL); -- 1 +-- Semi-finals +INSERT INTO matches (tournamentId, parentMatchId, team1Id, team2Id) VALUES (1, 1, 1, 2); -- 2 +INSERT INTO matches (tournamentId, parentMatchId, team1Id, team2Id) VALUES (1, 1, 3, 4); -- 3 + +-- tournament 2 -- +-- Final match +INSERT INTO matches (tournamentId, parentMatchId, team1Id, team2Id) VALUES (2, NULL, NULL, NULL); -- 4 +-- Semi-finals +INSERT INTO matches (tournamentId, parentMatchId, team1Id, team2Id) VALUES (2, 4, 5, 7); -- 5 +INSERT INTO matches (tournamentId, parentMatchId, team1Id, team2Id) VALUES (2, 4, 6, 8); -- 6 + +-- Players +INSERT INTO players (name, teamId) VALUES ('Player 1', 1); +INSERT INTO players (name, teamId) VALUES ('Player 2', 1); +INSERT INTO players (name, teamId) VALUES ('Player 3', 2); +INSERT INTO players (name, teamId) VALUES ('Player 4', 2); +INSERT INTO players (name, teamId) VALUES ('Player 5', 3); +INSERT INTO players (name, teamId) VALUES ('Player 6', 3); +INSERT INTO players (name, teamId) VALUES ('Player 7', 4); +INSERT INTO players (name, teamId) VALUES ('Player 8', 4); +INSERT INTO players (name, teamId) VALUES ('Player 9', 5); +INSERT INTO players (name, teamId) VALUES ('Player 10', 5); +INSERT INTO players (name, teamId) VALUES ('Player 11', 6); +INSERT INTO players (name, teamId) VALUES ('Player 12', 6); +INSERT INTO players (name, teamId) VALUES ('Player 13', 7); +INSERT INTO players (name, teamId) VALUES ('Player 14', 7); +INSERT INTO players (name, teamId) VALUES ('Player 15', 8); +INSERT INTO players (name, teamId) VALUES ('Player 16', 8); \ No newline at end of file diff --git a/src/server/management/startServer.sh b/src/server/management/startServer.sh new file mode 100755 index 0000000..9e08642 --- /dev/null +++ b/src/server/management/startServer.sh @@ -0,0 +1,3 @@ + autossh -L 3306:mysql.stud.ntnu.no:3306 isvegg -N & + + npm start diff --git a/src/server/match.js b/src/server/match.js deleted file mode 100644 index 03ede07..0000000 --- a/src/server/match.js +++ /dev/null @@ -1,29 +0,0 @@ -class Match { - tournamentId = null; - teamIds = []; - scores = {}; - winner = null; - - constructor(tournamentId, teamIds) { - this.tournamentId = tournamentId; - this.teamIds = teamIds; - //this.scores = Array(teamIds.length).fill(0); - for (let teamId of teamIds) { - this.scores[teamId] = 0; - } - } - - setScore = function(teamId, score) { - scores[teamId] = score; - }; - - getScore = function(teamId) { - return scores[teamId]; - }; - - setWinner = function(teamId) { - this.winner = teamId; - }; -} - -module.exports = Match; diff --git a/src/server/package.json b/src/server/package.json index 4e810b8..2888015 100644 --- a/src/server/package.json +++ b/src/server/package.json @@ -5,7 +5,8 @@ "main": "index.js", "scripts": { "start": "nodemon index.js", - "test": "echo \"Error: no test specified\" && exit 1" + "test": "echo \"Error: no test specified\" && exit 1", + "initdb": "mysql -h mysql.stud.ntnu.no -u felixalb_sysut -p felixalb_asura < ./management/initDB.sql" }, "author": "felixalb, kristoju, jonajha, krisleri", "license": "ISC", diff --git a/src/server/tmdb.js b/src/server/tmdb.js new file mode 100644 index 0000000..1ae6824 --- /dev/null +++ b/src/server/tmdb.js @@ -0,0 +1,58 @@ +// TMDB - Tournament Manager DataBase +// Handles all the database operations for the Tournament Manager +// Exports the following functions: +module.exports = { + getMatchesByTournamentId: getMatchesByTournamentId, + getTournaments: getTournaments, + executeStatement: executeStatement +} + +const mysql = require("mysql"); + +let connection = mysql.createConnection({ + host: process.env.DB_HOST, + user: process.env.DB_USER, + password: process.env.DB_PASSWORD, + database: process.env.DB_DATABASE +}); + +function getMatchesByTournamentId(tournamentId) { + return new Promise(function(resolve, reject) { + connection.query("SELECT * FROM matches WHERE tournament_id = ?", [mysql.escape(tournamentId)], (err, matches) => { + if (err) { + console.log(err); + reject(err); + } else { + resolve(matches); + } + }); + }); +} + +function getTournaments() { + return new Promise(function(resolve, reject) { + connection.query("SELECT * FROM tournaments", (err, tournaments) => { + if (err) { + console.log(err); + reject(err); + } else { + resolve(tournaments); + } + }); + }); +} + +// Dangerous function, use with caution. +// Used to initialize and manage the database by management tools, not by the main application. +function executeStatement(statement) { + return new Promise(function(resolve, reject) { + connection.query(statement, (err, sets) => { + if (err) { + console.log(err); + reject(err); + } else { + resolve(sets); + } + }); + }); +} \ No newline at end of file