diff --git a/src/database.ts b/src/database.ts index f9f5531..3c94f85 100644 --- a/src/database.ts +++ b/src/database.ts @@ -4,8 +4,9 @@ import fs from "fs"; const dbDirectory = "./src/db"; const dbFilePath = `${dbDirectory}/database.db`; -// Fonctions pour exécuter des requêtes SQL sur la base de données SQLite avec des promesses pour gérer les erreurs et les résultats asynchrones +/* Fonction pour exécuter une requête sur la base de données */ +/* Fonction pour exécuter une requête de modification de la base de données (INSERT, UPDATE, DELETE) */ function runDB( db: sqlite3.Database, query: string, @@ -22,6 +23,7 @@ function runDB( }); } +/* Fonction pour récupérer plusieurs lignes de la base de données */ function allDB(db: sqlite3.Database, query: string): Promise { return new Promise((resolve, reject) => { db.all(query, (err, rows) => { @@ -34,13 +36,14 @@ function allDB(db: sqlite3.Database, query: string): Promise { }); } +/* Fonction pour récupérer une seule ligne de la base de données */ function getDB( db: sqlite3.Database, query: string, params: any[] ): Promise { return new Promise((resolve, reject) => { - db.get(query, params, (err, row : any) => { + db.get(query, params, (err, row: any) => { if (err) { reject(err); } else { @@ -50,16 +53,16 @@ function getDB( }); } -// Fonctions pour la gestion de la base de données +/* Fonctions pour la gestion de la base de données */ -// Créer le répertoire db s'il n'existe pas +/* Créer le répertoire db s'il n'existe pas */ function createDbDirectory() { if (!fs.existsSync(dbDirectory)) { fs.mkdirSync(dbDirectory); } } -// Ouvrir la base de données +/* Ouvrir la base de données */ function openDatabase() { console.log("Ouverture de la connexion à la base de données."); return new sqlite3.Database( @@ -71,7 +74,7 @@ function openDatabase() { ); } -// Fermer la base de données +/* Fermer la base de données */ function closeDatabase(db: sqlite3.Database) { db.close((err) => { if (err) { @@ -81,7 +84,7 @@ function closeDatabase(db: sqlite3.Database) { }); } -// Create all the tables in the database +/* Create all the tables in the database */ function createTables(db: sqlite3.Database) { createRegisteredUserTable(db); createLanguageTable(db); @@ -97,14 +100,14 @@ function createTables(db: sqlite3.Database) { // UNIQUE (login) // ); -// Créer la table registered_user dans la base de données +/* Créer la table registered_user dans la base de données */ function createRegisteredUserTable(db: sqlite3.Database): Promise { const tableRegisteredUser = `CREATE TABLE IF NOT EXISTS registered_user (id_user INTEGER PRIMARY KEY AUTOINCREMENT, login TEXT NOT NULL, password TEXT NOT NULL, permissions INTEGER NOT NULL, UNIQUE (login))`; return runDB(db, tableRegisteredUser, []); } -// Insérer un utilisateur dans la table registered_user +/* Insérer un utilisateur dans la table registered_user */ function insertUser( db: sqlite3.Database, login: string, @@ -116,14 +119,14 @@ function insertUser( return runDB(db, insertUserQuery, [login, password, permissions]); } -// Modifier le login d'un utilisateur dans la table registered_user +/* Modifier le login d'un utilisateur dans la table registered_user */ function updateUserLogin(db: sqlite3.Database, id: number, newLogin: string) { const updateUserLoginQuery = `UPDATE registered_user SET login = ? WHERE id_user = ?`; return runDB(db, updateUserLoginQuery, [newLogin, id]); } -// Modifier le mot de passe d'un utilisateur dans la table registered_user +/* Modifier le mot de passe d'un utilisateur dans la table registered_user */ function updateUserPassword( db: sqlite3.Database, id: number, @@ -134,6 +137,7 @@ function updateUserPassword( return runDB(db, updateUserPasswordQuery, [newPassword, id]); } +/* Modifier les permissions d'un utilisateur dans la table registered_user */ function updateUserPermissions( db: sqlite3.Database, id: number, @@ -144,35 +148,42 @@ function updateUserPermissions( return runDB(db, updateUserPermissionsQuery, [newPermissions, id]); } -// Supprimer un utilisateur de la table registered_user -function deleteUser(db: sqlite3.Database, id: number) { +/* Supprimer un utilisateur de la table registered_user par son ID */ +function deleteUserById(db: sqlite3.Database, id: number) { const deleteUserQuery = `DELETE FROM registered_user WHERE id_user = ?`; return runDB(db, deleteUserQuery, [id]); } -// Supprimer tous les utilisateurs de la table registered_user +/* Supprimer un utilisateur de la table registered_user par son login */ +function deleteUserByLogin(db: sqlite3.Database, login: string) { + const deleteUserQuery = `DELETE FROM registered_user WHERE login = ?`; + + return runDB(db, deleteUserQuery, [login]); +} + +/* Supprimer tous les utilisateurs de la table registered_user */ function deleteAllUsers(db: sqlite3.Database) { const deleteAllUsersQuery = `DELETE FROM registered_user`; return runDB(db, deleteAllUsersQuery, []); } -// Sélectionner tous les utilisateurs de la table registered_user +/* Sélectionner tous les utilisateurs de la table registered_user */ function selectAllUsers(db: sqlite3.Database): Promise { const selectAllUsersQuery = `SELECT * FROM registered_user`; return allDB(db, selectAllUsersQuery); } -// Sélectionner un utilisateur par son login +/* Sélectionner un utilisateur par son login */ function selectUserByLogin(db: sqlite3.Database, login: string) { const selectUserByLoginQuery = `SELECT * FROM registered_user WHERE login = ?`; return getDB(db, selectUserByLoginQuery, [login]); } -// Sélectionner un utilisateur par son ID +/* Sélectionner un utilisateur par son ID */ function selectUserById(db: sqlite3.Database, id: number) { const selectUserByIdQuery = `SELECT * FROM registered_user WHERE id_user = ?`; @@ -186,13 +197,13 @@ function selectUserById(db: sqlite3.Database, id: number) { // version INT NOT NULL, // ); -// Créer la table language dans la base de données +/* Créer la table language dans la base de données */ function createLanguageTable(db: sqlite3.Database): Promise { const tableLanguage = `CREATE TABLE IF NOT EXISTS language (id_language INTEGER PRIMARY KEY AUTOINCREMENT, designation TEXT NOT NULL, version INTEGER NOT NULL)`; return runDB(db, tableLanguage, []); } -// Insérer un language dans la table language +/* Insérer un language dans la table language */ function insertLanguage( db: sqlite3.Database, designation: string, @@ -203,14 +214,18 @@ function insertLanguage( return runDB(db, insertLanguageQuery, [designation, version]); } -// Modifier la designation d'un language dans la table language -function updateLanguageDesignation(db: sqlite3.Database, id: number, newDesignation: string) { +/* Modifier la designation d'un language dans la table language */ +function updateLanguageDesignation( + db: sqlite3.Database, + id: number, + newDesignation: string +) { const updateLanguageDesignationQuery = `UPDATE language SET designation = ? WHERE id_language = ?`; return runDB(db, updateLanguageDesignationQuery, [newDesignation, id]); } -// Modifier la version d'un language dans la table language +/* Modifier la version d'un language dans la table language */ function updateLanguageVersion( db: sqlite3.Database, id: number, @@ -221,28 +236,28 @@ function updateLanguageVersion( return runDB(db, updateLanguageVersionQuery, [newVersion, id]); } -// Supprimer un language de la table language +/* Supprimer un language de la table language par son ID */ function deleteLanguage(db: sqlite3.Database, id: number) { const deleteLanguageQuery = `DELETE FROM language WHERE id_language = ?`; return runDB(db, deleteLanguageQuery, [id]); } -// Supprimer tous les languages de la table language +/* Supprimer tous les languages de la table language */ function deleteAllLanguages(db: sqlite3.Database) { const deleteAllLanguagesQuery = `DELETE FROM language`; return runDB(db, deleteAllLanguagesQuery, []); } -// Sélectionner tous les languages de la table language +/* Sélectionner tous les languages de la table language */ function selectAllLanguages(db: sqlite3.Database): Promise { const selectAllLanguagesQuery = `SELECT * FROM language`; return allDB(db, selectAllLanguagesQuery); } -// Sélectionner un language par son ID +/* Sélectionner un language par son ID */ function selectLanguageById(db: sqlite3.Database, id: number) { const selectLanguageByIdQuery = `SELECT * FROM language WHERE id_language = ?`; @@ -252,51 +267,53 @@ function selectLanguageById(db: sqlite3.Database, id: number) { /////////////////////////// Gestion des works /////////////////////////// // CREATE TABLE work ( // id_work SERIAL PRIMARY KEY, +// link CHAR(36) NOT NULL, // user_id INT REFERENCES registered_user(id_user), // language_id INT NOT NULL REFERENCES language(id_language) -// content TEXT NOT NULL, +// content TEXT NOT NULL, // ); -// Créer la table work dans la base de données +/* Créer la table work dans la base de données */ function createWorkTable(db: sqlite3.Database): Promise { - const tableWork = `CREATE TABLE IF NOT EXISTS work (id_work INTEGER PRIMARY KEY AUTOINCREMENT, user_id INTEGER REFERENCES registered_user(id_user), language_id INTEGER NOT NULL REFERENCES language(id_language), content TEXT NOT NULL)`; + const tableWork = `CREATE TABLE IF NOT EXISTS work (id_work INTEGER PRIMARY KEY AUTOINCREMENT, link CHAR(36) NOT NULL, user_id INTEGER REFERENCES registered_user(id_user), language_id INTEGER NOT NULL REFERENCES language(id_language), content TEXT NOT NULL)`; return runDB(db, tableWork, []); } -// Insérer un work dans la table work +/* Insérer un work dans la table work */ function insertWork( db: sqlite3.Database, + link: string, user_id: number, language_id: number, content: string ) { - const insertWorkQuery = `INSERT INTO work (user_id, language_id, content) VALUES (?, ?, ?)`; + const insertWorkQuery = `INSERT INTO work (link, user_id, language_id, content) VALUES (?, ?, ?, ?)`; - return runDB(db, insertWorkQuery, [user_id, language_id, content]); + return runDB(db, insertWorkQuery, [link, user_id, language_id, content]); } -// Sélectionner tous les works de la table work +/* Sélectionner tous les works de la table work */ function selectAllWorks(db: sqlite3.Database): Promise { const selectAllWorksQuery = `SELECT * FROM work`; return allDB(db, selectAllWorksQuery); } -// Supprimer tous les works de la table work +/* Supprimer tous les works de la table work */ function deleteAllWorks(db: sqlite3.Database) { const deleteAllWorksQuery = `DELETE FROM work`; return runDB(db, deleteAllWorksQuery, []); } -// Supprimer un work de la table work +/* Supprimer un work de la table work */ function deleteWork(db: sqlite3.Database, id: number) { const deleteWorkQuery = `DELETE FROM work WHERE id_work = ?`; return runDB(db, deleteWorkQuery, [id]); } -// Sélectionner un work par son ID +/* Sélectionner un work par son ID */ function selectWorkById(db: sqlite3.Database, id: number) { const selectWorkByIdQuery = `SELECT * FROM work WHERE id_work = ?`; @@ -313,7 +330,8 @@ export { updateUserLogin, updateUserPassword, updateUserPermissions, - deleteUser, + deleteUserById, + deleteUserByLogin, deleteAllUsers, selectAllUsers, selectUserByLogin, diff --git a/src/db/database.db b/src/db/database.db index 05f44b1..78185c2 100644 Binary files a/src/db/database.db and b/src/db/database.db differ diff --git a/src/server.ts b/src/server.ts index daff54c..5d39fb0 100644 --- a/src/server.ts +++ b/src/server.ts @@ -14,7 +14,8 @@ import { updateUserLogin, updateUserPassword, updateUserPermissions, - deleteUser, + deleteUserById, + deleteUserByLogin, deleteAllUsers, selectAllUsers, selectUserByLogin, @@ -48,9 +49,9 @@ await fastify.register(cors, { origin: process.env.ALLOW_ORIGIN || "*", }); -// Code runner in a container +/* Code runner in a container */ -// POST /run : Run code in a container +/* POST /run : Run code in a container */ fastify.post( "/run", @@ -84,18 +85,18 @@ fastify.post( } ); -// Database +/* Database */ -// Création du répertoire de la base de données s'il n'existe pas +/* Création du répertoire de la base de données s'il n'existe pas */ createDbDirectory(); -// Ouvrir la base de données +/* Ouvrir la base de données */ const db = openDatabase(); -// Créer les tables si elles n'existent pas +/* Créer les tables si elles n'existent pas */ createTables(db); -// Route pour créer un utilisateur +/* Route pour créer un utilisateur */ fastify.post<{ Body: { login: string; @@ -108,7 +109,7 @@ fastify.post<{ reply.send({ success: true }); }); -// Route pour mettre à jour le login d'un utilisateur +/* Route pour mettre à jour le login d'un utilisateur */ fastify.put<{ Params: { id: string }; Body: { newLogin: string }; @@ -119,7 +120,7 @@ fastify.put<{ reply.send({ success: true }); }); -// Route pour mettre à jour le mot de passe d'un utilisateur +/* Route pour mettre à jour le mot de passe d'un utilisateur */ fastify.put<{ Params: { id: string }; Body: { newPassword: string }; @@ -130,7 +131,7 @@ fastify.put<{ reply.send({ success: true }); }); -// Route pour mettre à jour les permissions d'un utilisateur +/* Route pour mettre à jour les permissions d'un utilisateur */ fastify.put<{ Params: { id: string }; Body: { newPermissions: number }; @@ -141,27 +142,37 @@ fastify.put<{ reply.send({ success: true }); }); -// Route pour supprimer un utilisateur +/* Route pour supprimer un utilisateur par son ID */ fastify.delete<{ Params: { id: string }; }>("/users/:id", async (request, reply) => { const { id } = request.params; - await deleteUser(db, parseInt(id)); + await deleteUserById(db, parseInt(id)); reply.send({ success: true }); }); -// Route pour supprimer tous les utilisateurs +/* Route pour supprimer un utilisateur par son login */ +fastify.delete<{ + Params: { login: string }; +}>("/users/login/:login", async (request, reply) => { + const { login } = request.params; + await deleteUserByLogin(db, login); + reply.send({ success: true }); +}); + +/* Route pour supprimer tous les utilisateurs */ fastify.delete("/users", async (request, reply) => { await deleteAllUsers(db); reply.send({ success: true }); }); -// Route pour récupérer tous les utilisateurs + +/* Route pour récupérer tous les utilisateurs */ fastify.get("/users", async (request, reply) => { const users = await selectAllUsers(db); reply.send(users); }); -// Route pour récupérer un utilisateur par son ID +/* Route pour récupérer un utilisateur par son ID */ fastify.get<{ Params: { id: string }; }>("/users/:id", async (request, reply) => { @@ -170,7 +181,7 @@ fastify.get<{ reply.send(user); }); -// Route pour récupérer un utilisateur par son login +/* Route pour récupérer un utilisateur par son login */ fastify.get<{ Params: { login: string }; }>("/users/login/:login", async (request, reply) => { @@ -179,7 +190,7 @@ fastify.get<{ reply.send(user); }); -// Route pour créer un language +/* Route pour créer un language */ fastify.post<{ Body: { designation: string; @@ -191,7 +202,7 @@ fastify.post<{ reply.send({ success: true }); }); -// Route pour mettre à jour la désignation d'un language +/* Route pour mettre à jour la désignation d'un language */ fastify.put<{ Params: { id: string }; Body: { newDesignation: string }; @@ -202,7 +213,7 @@ fastify.put<{ reply.send({ success: true }); }); -// Route pour mettre à jour la version d'un language +/* Route pour mettre à jour la version d'un language */ fastify.put<{ Params: { id: string }; Body: { newVersion: number }; @@ -213,7 +224,7 @@ fastify.put<{ reply.send({ success: true }); }); -// Route pour supprimer un language +/* Route pour supprimer un language */ fastify.delete<{ Params: { id: string }; }>("/languages/:id", async (request, reply) => { @@ -222,13 +233,13 @@ fastify.delete<{ reply.send({ success: true }); }); -// Route pour supprimer tous les languages +/* Route pour supprimer tous les languages */ fastify.delete("/languages", async (request, reply) => { deleteAllLanguages(db); reply.send({ success: true }); }); -// Route pour récupérer un language par son ID +/* Route pour récupérer un language par son ID */ fastify.get<{ Params: { id: string }; }>("/languages/:id", async (request, reply) => { @@ -237,38 +248,39 @@ fastify.get<{ reply.send(language); }); -// Route pour récupérer tous les languages +/* Route pour récupérer tous les languages */ fastify.get("/languages", async (request, reply) => { const languages = await selectAllLanguages(db); reply.send(languages); }); -// Route pour créer un work +/* Route pour créer un work */ fastify.post<{ Body: { id_user: number; + link: string; id_language: number; code: string; }; }>("/works", async (request, reply) => { - const { id_user, id_language, code } = request.body; - insertWork(db, id_user, id_language, code); + const { id_user, link, id_language, code } = request.body; + insertWork(db, link, id_user, id_language, code); reply.send({ success: true }); }); -// Route pour récupérer tous les works +/* Route pour récupérer tous les works */ fastify.get("/works", async (request, reply) => { const works = await selectAllWorks(db); reply.send(works); }); -// Route pour supprimer tous les works +/* Route pour supprimer tous les works */ fastify.delete("/works", async (request, reply) => { deleteAllWorks(db); reply.send({ success: true }); }); -// Route pour supprimer un work +/* Route pour supprimer un work par son ID */ fastify.delete<{ Params: { id: string }; }>("/works/:id", async (request, reply) => { @@ -277,7 +289,7 @@ fastify.delete<{ reply.send({ success: true }); }); -// Route pour récupérer un work par son ID +/* Route pour récupérer un work par son ID */ fastify.get<{ Params: { id: string }; }>("/works/:id", async (request, reply) => { @@ -286,8 +298,7 @@ fastify.get<{ reply.send(work); }); -// Forward output from the runner to the client - +/* Forward output est une fonction asynchrone qui permet de récupérer les messages envoyés par le container et de les renvoyer au client */ async function forwardOutput() { for await (const [buff] of receiver) { const messageType = buff.readInt8(); @@ -323,4 +334,5 @@ async function forwardOutput() { } } +/* Lancer le serveur et la fonction forwardOutput sur le même thread en parallèle */ await Promise.all([fastify.listen({ port: 3000 }), forwardOutput()]);