You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Cryptid/cryptide_project/server/api/services/DatabaseService.js

451 lines
17 KiB

const mysql = require('mysql2');
const path = require('path');
const { rejects } = require('assert');
class DatabaseService {
// ----------------------------------------------------
// ------------------- UTILITAIRE ---------------------
// ----------------------------------------------------
async connect() {
const mysqlHost = process.env.MYSQL_HOST;
const mysqlUser = process.env.MYSQL_USER;
const mysqlPassword = process.env.MYSQL_PASSWORD;
const mysqlDatabase = process.env.MYSQL_DATABASE;
const createTables = process.env.CREATETABLES
const dbConfig = {
host: mysqlHost,
user: mysqlUser,
password: mysqlPassword,
database: mysqlDatabase
};
return new Promise((resolve, reject) => {
this.client = mysql.createConnection(dbConfig);
this.client.connect(async (err) => {
if (err) {
console.log(err)
reject(err);
} else {
if (createTables === "true"){
await this.createTables()
}
resolve();
}
});
});
}
async createTables(){
try {
// Requête SQL pour créer la table 'users'
const createTableQuery = `
CREATE TABLE IF NOT EXISTS users (
idUser INT AUTO_INCREMENT PRIMARY KEY,
pseudo VARCHAR(50) NOT NULL,
password VARCHAR(60) NOT NULL,
profilePicture LONGBLOB,
createdDate TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
`;
// Exécuter la requête SQL
this.client.query(createTableQuery, (err, result) => {
if(err){
console.log(err)
}
else{
console.log("Table users créée")
}
});
const createTableGameQuery = `
CREATE TABLE IF NOT EXISTS games (
idGame INT AUTO_INCREMENT PRIMARY KEY,
idUser INT NOT NULL,
gameType VARCHAR(50) CHECK(gameType IN ('mastermind','enigme_facile','enigme_moyenne','enigme_difficile','multijoueur')),
win INT CHECK(win IN (0,1)) DEFAULT 0,
score INT NOT NULL DEFAULT 0,
time REAL NOT NULL DEFAULT 0,
playedDate TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (idUser) REFERENCES users(idUser)
);
`;
this.client.query(createTableGameQuery, (err, result) => {
if(err){
console.log(err)
}
else{
console.log("Table games créée")
}
});
}
catch(error){
console.log(error)
}
}
async disconnect(){
return new Promise((resolve, reject) => {
this.client.end((err) => {
if(err){
reject(err);
}
else{
resolve();
}
});
});
}
// ----------------------------------------------------
// ------------------- UTILISATEUR --------------------
// ----------------------------------------------------
// Récupère l'utilisateur par son id
async getUserByID(id){
try {
const [rows] = await this.client.promise().query('SELECT * FROM users WHERE idUser = ?', [id])
return rows[0];
} catch (err) {
throw new Error(`Error fetching users: ${err.message}`);
}
}
// Récupère l'utilisateur par son pseudo
async getUserByPseudo(pseudo){
try {
const [rows] = await this.client.promise().query('SELECT * FROM users WHERE pseudo = ?', [pseudo])
return rows[0];
} catch (err) {
throw new Error(`Error fetching users: ${err.message}`);
}
}
async getUsers(){
try {
const [rows] = await this.client.promise().query('SELECT * FROM users');
return rows;
} catch (err) {
throw new Error(`Error fetching users: ${err.message}`);
}
}
async getGames(){
try {
const [rows] = await this.client.promise().query('SELECT * FROM games');
return rows;
} catch (err) {
throw new Error(`Error fetching games: ${err.message}`);
}
}
// insère un utilisateur dans la base de données
async insertUser(user) {
try {
const { pseudo, password } = user;
const [rows] = await this.client.promise().query('INSERT INTO users (pseudo, password) VALUES (?, ?)', [pseudo, password])
return rows;
} catch (err) {
throw new Error(`Error fetching users: ${err.message}`);
}
}
async deleteUser(userId){
try {
const [rows] = await this.client.promise().query('DELETE FROM users WHERE idUser=?', [userId])
return rows;
} catch (err) {
throw new Error(`Error fetching users: ${err.message}`);
}
}
async updatePseudo(userId, newPseudo){
try {
const [rows] = await this.client.promise().query('UPDATE users SET pseudo = ? WHERE idUser = ?', [newPseudo, userId])
return rows;
} catch (err) {
throw new Error(`Error fetching users: ${err.message}`);
}
}
async updatePassword(userId, newPassword){
try {
const [rows] = await this.client.promise().query('UPDATE users SET password = ? WHERE idUser = ?', [newPassword, userId])
return rows;
} catch (err) {
throw new Error(`Error fetching users: ${err.message}`);
}
}
// ---------------------------------------------------------------
// ------------------- STATS JOURNALIERE -------------------------
// ---------------------------------------------------------------
async getDailyMastermindStats() {
try {
const currentDate = new Date().toISOString().slice(0, 10);
const [rows] = await this.client.promise().query('SELECT pseudo, score FROM users INNER JOIN games ON users.idUser = games.idUser WHERE gameType = ? AND SUBSTR(playedDate, 1, 10) = ? ORDER BY score ASC LIMIT 10',
["mastermind",
currentDate])
return rows;
} catch (err) {
throw new Error(`Error fetching users: ${err.message}`);
}
}
async getDailyEnigmaStats(enigmaLevel) {
try {
const currentDate = new Date().toISOString().slice(0, 10);
const [rows] = await this.client.promise().query('SELECT pseudo, time FROM users INNER JOIN games ON users.idUser = games.idUser WHERE gameType = ? AND SUBSTR(playedDate, 1, 10) = ? ORDER BY time ASC LIMIT 10',
[enigmaLevel,
currentDate])
return rows;
} catch (err) {
throw new Error(`Error fetching users: ${err.message}`);
}
}
async getDailyOnlineStats() {
try {
const currentDate = new Date().toISOString().slice(0, 10);
const [rows] = await this.client.promise().query('SELECT pseudo, COUNT(*) AS wins FROM users INNER JOIN games ON users.idUser = games.idUser WHERE gameType = ? AND SUBSTR(playedDate, 1, 10) = ? AND win = ? GROUP BY users.idUser ORDER BY wins ASC LIMIT 10',
["multijoueur", currentDate, 1])
return rows;
} catch (err) {
throw new Error(`Error fetching users: ${err.message}`);
}
}
// ---------------------------------------------------------------
// ------------------- STATS HEBDOMADAIRE ------------------------
// ---------------------------------------------------------------
async getWeeklyMastermindStats() {
try {
const currentDate = new Date().toISOString().slice(0, 10);
const currentDay = new Date().getDay();
const firstDayOfWeek = new Date(new Date().setDate(new Date().getDate() - currentDay)).toISOString().slice(0, 10);
const [rows] = await this.client.promise().query('SELECT pseudo, score FROM users INNER JOIN games ON users.idUser = games.idUser WHERE gameType = ? AND SUBSTR(playedDate, 1, 10) BETWEEN ? AND ? ORDER BY score ASC LIMIT 10',
["mastermind",
firstDayOfWeek,
currentDate])
return rows;
} catch (err) {
throw new Error(`Error fetching users: ${err.message}`);
}
}
async getWeeklyEnigmaStats(enigmaLevel) {
try {
const currentDate = new Date().toISOString().slice(0, 10);
const currentDay = new Date().getDay();
const firstDayOfWeek = new Date(new Date().setDate(new Date().getDate() - currentDay)).toISOString().slice(0, 10);
const [rows] = await this.client.promise().query('SELECT pseudo, time FROM users INNER JOIN games ON users.idUser = games.idUser WHERE gameType = ? AND SUBSTR(playedDate, 1, 10) BETWEEN ? AND ? ORDER BY time ASC LIMIT 10',
[enigmaLevel,
firstDayOfWeek,
currentDate])
return rows;
} catch (err) {
throw new Error(`Error fetching users: ${err.message}`);
}
}
async getWeeklyOnlineStats() {
try {
const currentDate = new Date().toISOString().slice(0, 10);
const currentDay = new Date().getDay();
const firstDayOfWeek = new Date(new Date().setDate(new Date().getDate() - currentDay)).toISOString().slice(0, 10);
const [rows] = await this.client.promise().query(`
SELECT users.pseudo, COUNT(*) as wins
FROM users
INNER JOIN games ON users.idUser = games.idUser
WHERE gameType = ? AND SUBSTR(playedDate, 1, 10) BETWEEN ? AND ? AND win = ?
GROUP BY users.pseudo
ORDER BY wins ASC
LIMIT 10;
`,
["multijoueur",
firstDayOfWeek,
currentDate,
1])
return rows;
} catch (err) {
throw new Error(`Error fetching users: ${err.message}`);
}
}
// -------------------------------------------------------------
// ------------------- STATS MASTERMIND ------------------------
// -------------------------------------------------------------
async getNbGamesMastermindByUserId(userId){
try {
const [rows] = await this.client.promise().query('SELECT COUNT(*) AS nbGames FROM games WHERE idUser = ? AND gameType = ?', [userId, "mastermind"])
return rows[0];
} catch (err) {
throw new Error(`Error fetching users: ${err.message}`);
}
}
async getBestScoreMastermindByUserId(userId){
try {
const [rows] = await this.client.promise().query('SELECT MIN(score) AS bestScore FROM games WHERE idUser = ? AND gameType = ?', [userId, "mastermind"])
return rows[0];
} catch (err) {
throw new Error(`Error fetching users: ${err.message}`);
}
}
async getAvgNbTryMastermindByUserId(userId){
try {
const [rows] = await this.client.promise().query('SELECT AVG(score) AS avgNbTry FROM games WHERE idUser = ? AND gameType = ?', [userId, "mastermind"])
return rows[0];
} catch (err) {
throw new Error(`Error fetching users: ${err.message}`);
}
}
async addMastermindStats(userId, score, time){
try {
const [rows] = await this.client.promise().query('INSERT INTO games (idUser, gameType, win, score, time) VALUES (?, ?, ?, ?, ?)', [userId, "mastermind", 1, score, time])
return rows[0];
} catch (err) {
throw new Error(`Error fetching users: ${err.message}`);
}
}
// -------------------------------------------------------------
// ------------------- STATS EN LIGNE --------------------------
// -------------------------------------------------------------
async getNbGamesOnlineByUserId(userId){
try {
const [rows] = await this.client.promise().query('SELECT COUNT(*) AS nbGames FROM games WHERE idUser = ? AND gameType = ?', [userId, "multijoueur"])
return rows[0];
} catch (err) {
throw new Error(`Error fetching users: ${err.message}`);
}
}
async getNbWinsOnlineByUserId(userId){
try {
const [rows] = await this.client.promise().query('SELECT COUNT(*) AS nbWins FROM games WHERE idUser = ? AND gameType = ? AND win = ?', [userId, "multijoueur", 1])
return rows[0];
} catch (err) {
throw new Error(`Error fetching users: ${err.message}`);
}
}
async addOnlineStats(userId, win, time){
try {
const [rows] = await this.client.promise().query('INSERT INTO games (idUser, gameType, win, score, time) VALUES (?, ?, ?, ?, ?)', [userId, "multijoueur", win, 0, time])
return rows;
} catch (err) {
throw new Error(`Error fetching users: ${err.message}`);
}
}
// -------------------------------------------------------------
// ------------------- STATS ENIGME ----------------------------
// -------------------------------------------------------------
async getNbGamesEnigmeByUserId(userId, enigmaLevel){
try {
const [rows] = await this.client.promise().query('SELECT COUNT(*) AS nbGames FROM games WHERE idUser = ? AND gameType = ?', [userId, enigmaLevel])
return rows[0];
} catch (err) {
throw new Error(`Error fetching users: ${err.message}`);
}
}
async getNbWinsEnigmeByUserId(userId, enigmaLevel){
try {
const [rows] = await this.client.promise().query('SELECT COUNT(*) AS nbWins FROM games WHERE idUser = ? AND gameType = ? AND win = ?', [userId, enigmaLevel, 1])
return rows[0];
} catch (err) {
throw new Error(`Error fetching users: ${err.message}`);
}
}
async getBestScoreEnigmeByUserId(userId, enigmaLevel){
try {
const [rows] = await this.client.promise().query('SELECT MAX(score) AS bestScore FROM games WHERE idUser = ? AND gameType = ?', [userId, enigmaLevel])
return rows[0];
} catch (err) {
throw new Error(`Error fetching users: ${err.message}`);
}
}
async getAvgScoreEnigmeByUserId(userId, enigmaLevel){
try {
const [rows] = await this.client.promise().query('SELECT AVG(score) AS avgScore FROM games WHERE idUser = ? AND gameType = ?', [userId, enigmaLevel])
return rows[0];
} catch (err) {
throw new Error(`Error fetching users: ${err.message}`);
}
}
async getBestTimeEnigmeByUserId(userId, enigmaLevel){
try {
const [rows] = await this.client.promise().query('SELECT MIN(time) AS bestTime FROM games WHERE idUser = ? AND gameType = ?', [userId, enigmaLevel])
return rows[0];
} catch (err) {
throw new Error(`Error fetching users: ${err.message}`);
}
}
async getAvgTimeEnigmeByUserId(userId, enigmaLevel){
try {
const [rows] = await this.client.promise().query('SELECT AVG(time) AS avgTime FROM games WHERE idUser = ? AND gameType = ?', [userId, enigmaLevel])
return rows[0];
} catch (err) {
throw new Error(`Error fetching users: ${err.message}`);
}
}
async addEasyEnigmaStats(userId, enigmaLevel, win, time){
try {
const [rows] = await this.client.promise().query('INSERT INTO games (idUser, gameType, win, score, time) VALUES (?, ?, ?, ?, ?)', [userId, enigmaLevel, win, 0, time])
return rows;
} catch (err) {
throw new Error(`Error fetching users: ${err.message}`);
}
}
async addMediumEnigmaStats(userId, enigmaLevel, score, time){
try {
const [rows] = await this.client.promise().query('INSERT INTO games (idUser, gameType, win, score, time) VALUES (?, ?, ?, ?, ?)', [userId, enigmaLevel, 1, score, time])
return rows;
} catch (err) {
throw new Error(`Error fetching users: ${err.message}`);
}
}
async addHardEnigmaStats(userId, enigmaLevel, win, time){
try {
const [rows] = await this.client.promise().query('INSERT INTO games (idUser, gameType, win, score, time) VALUES (?, ?, ?, ?, ?)', [userId, enigmaLevel, win, 0, time])
return rows;
} catch (err) {
throw new Error(`Error fetching users: ${err.message}`);
}
}
}
module.exports = DatabaseService;