Fixed mod deletion and implemented database transactions support in backend

This commit is contained in:
Gu://em_ 2025-05-17 13:33:40 +02:00
parent 5af16b593c
commit 58268a94a9
7 changed files with 49 additions and 22 deletions

View file

@ -29,7 +29,7 @@ async function createMod(req, res) {
async function modifyMod(req, res) {
try {
// Authorize
authorizeModModification(req);
await authorizeModModification(req);
// Query
const mod_data = req.body;
const query_result = await mod_service.modifyMod(mod_data);

View file

@ -53,7 +53,7 @@ async function initDatabase() {
author TINYTEXT NOT NULL,
description TINYTEXT NOT NULL,
FOREIGN KEY (author) REFERENCES Users(username)
FOREIGN KEY (author) REFERENCES Users(username) ON DELETE CASCADE
);`);
// Mods complementary infos
@ -66,7 +66,7 @@ async function initDatabase() {
creation_date TINYTEXT NOT NULL,
downloads_count INT NOT NULL,
FOREIGN KEY (mod) REFERENCES Mods(name)
FOREIGN KEY (mod) REFERENCES Mods(name) ON DELETE CASCADE
);`);
// Mods tags
@ -74,7 +74,7 @@ async function initDatabase() {
mod TINYTEXT NOT NULL,
tag TINYTEXT NOT NULL,
FOREIGN KEY (mod) REFERENCES Mods(name)
FOREIGN KEY (mod) REFERENCES Mods(name) ON DELETE CASCADE
);`);
// Mods versions
@ -89,7 +89,7 @@ async function initDatabase() {
environment TINYTEXT NOT NULL,
url TINYTEXT NOT NULL,
FOREIGN KEY (mod) REFERENCES Mods(name)
FOREIGN KEY (mod) REFERENCES Mods(name) ON DELETE CASCADE
);`);
// User favorites (mods)
@ -97,8 +97,8 @@ async function initDatabase() {
username TINYTEXT NOT NULL,
mod TINYTEXT NOT NULL,
FOREIGN KEY (username) REFERENCES Users(username),
FOREIGN KEY (mod) REFERENCES Mods(name)
FOREIGN KEY (username) REFERENCES Users(username) ON DELETE CASCADE,
FOREIGN KEY (mod) REFERENCES Mods(name) ON DELETE CASCADE
);`);
}

View file

@ -1,3 +1,5 @@
//! Not implemented
class MySQLDatabase {
constructor(config) {
const mysql = require("mysql2/promise");

View file

@ -25,6 +25,7 @@ class SQLiteDatabase {
}
}
// Runs with a result (ex: SELECT)
async query(sql, params = []) {
try {
if (params.length > 0) {
@ -38,15 +39,17 @@ class SQLiteDatabase {
}
}
// One time queries (ex: CREATE TABLE)
async exec(sql) {
try {
return this.db.exec(sql);
} catch (err) {
console.error("Error executing statement:", err)}
throw err;
}
async prepare(sql, params = []) {
// Queries with no results (ex: INSERT)
async run(sql, params = []) {
try {
if (params.length > 0) {
return this.db.prepare(sql).run(params);
@ -55,13 +58,35 @@ class SQLiteDatabase {
}
} catch (err) {
console.error("Error executing prepared statement:", err)}
throw err;
}
// Prepare a query for run or for transaction
async prepare(sql) {
try {
return this.db.prepare(sql);
} catch (err) {
console.error("Error preparing statement:", err)}
throw err;
}
// Run a prepared transaction
async transaction(prepared_sql, items) {
try {
this.db.transaction((items) => {
for (const item of items) prepared_sql.run(item);
})
} catch (err) {
console.error("Error executing prepared statement:", err)}
throw err;
}
async exists(table, attribute, value) {
try {
return this.db.prepare(`SELECT COUNT(*) FROM ${table} WHERE ${attribute} = ?`).get(value)['COUNT(*)'] > 0;
} catch (err) {
console.error("Error checking item existence");
throw err;
}
}

View file

@ -15,7 +15,7 @@ async function authenticateToken(req) {
try {
req.token_infos = await verifyToken(token);
console.debug("Authorizing token from", req.token_infos);
// console.debug("Authorizing token from", req.token_infos);
} catch (err) {
throw new AppError(403, "Forbidden: Error verifying the authorization token");
}

View file

@ -58,12 +58,12 @@ async function createMod(name, display_name, author, description, mod_infos) {
const { full_description, license, links, creation_date, tags } = mod_infos;
// Mods table
await db.prepare("INSERT INTO Mods (name, display_name, author, description) \
await db.run("INSERT INTO Mods (name, display_name, author, description) \
VALUES (?, ?, ?, ?)",
[name, display_name, author, description]);
// ModInfos table
await db.prepare(`INSERT INTO ModInfos (mod, full_description, license, links, creation_date, downloads_count)
await db.run(`INSERT INTO ModInfos (mod, full_description, license, links, creation_date, downloads_count)
VALUES (?, ?, ?, ?, ?, ?)`,
[name, full_description, license.type, links.toString(), creation_date, 0]);
@ -75,7 +75,7 @@ async function createMod(name, display_name, author, description, mod_infos) {
// License
if (license.type == "custom") {
await db.prepare(`UPDATE ModInfos SET custom_license = ?
await db.run(`UPDATE ModInfos SET custom_license = ?
WHERE mod = ?`,
[license.content, name]);
}
@ -90,7 +90,7 @@ async function createMod(name, display_name, author, description, mod_infos) {
async function addVersion(mod, version_number, channel, changelog, release_date, game_version, platform, environment, url) {
await db.prepare(`INSERT INTO ModVersions (mod, version_number, channel, changelog, release_date, game_version, environment, platform, url)
await db.run(`INSERT INTO ModVersions (mod, version_number, channel, changelog, release_date, game_version, environment, platform, url)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?);`,
[mod, version_number, channel, changelog, release_date, game_version, environment, platform, url]);
return;
@ -130,12 +130,12 @@ async function updateMod(name, display_name, author, description) {
// --- Delete ---
async function deleteMod(name) {
await db.prepare("DELETE FROM Mods WHERE name = ?", [name]);
await db.run("DELETE FROM Mods WHERE name = ?", [name]);
return;
}
async function deleteVersion(name, version_number, game_version, platform, environment) {
await db.prepare(`DELETE FROM ModVersions WHERE mod = ?
await db.run(`DELETE FROM ModVersions WHERE mod = ?
AND version_number = ?
AND game_version = ?
AND platform = ?
@ -159,12 +159,12 @@ async function deleteTags(mod, tags) {
// --- Utils ---
async function updateModAttribute(name, attribute, value) {
await db.prepare(`UPDATE Mods SET ${attribute} = ? WHERE name = ?`, [value, name]);
await db.run(`UPDATE Mods SET ${attribute} = ? WHERE name = ?`, [value, name]);
return;
}
async function updateModInfosAttribute(name, attribute, value) {
await db.prepare(`UPDATE ModInfos SET ${attribute} = ? WHERE name = ?`, [value, name]);
await db.run(`UPDATE ModInfos SET ${attribute} = ? WHERE name = ?`, [value, name]);
return;
}

View file

@ -35,7 +35,7 @@ async function exists(name) {
async function createUser( username, email, password, displayName, profilePicture, settings ) {
// Create user
await db.prepare(`INSERT INTO Users (username, email, password, display_name, role )
await db.run(`INSERT INTO Users (username, email, password, display_name, role )
VALUES (?, ?, ?, ?, ? )`,
[username, email, password, displayName, "user"]);
@ -86,11 +86,11 @@ async function updateUser(username, display_name, email, profile_picture, settin
}
async function updateUserPassword(username, password) {
await db.prepare(`UPDATE Users SET password = ? WHERE username = ?`, [password, username]);
await db.run(`UPDATE Users SET password = ? WHERE username = ?`, [password, username]);
}
async function updateUserAttribute(username, attribute, value) {
await db.prepare(`UPDATE Users SET ${attribute} = ? WHERE username = ?`, [value, username]);
await db.run(`UPDATE Users SET ${attribute} = ? WHERE username = ?`, [value, username]);
return;
}
@ -98,7 +98,7 @@ async function updateUserAttribute(username, attribute, value) {
// --- Delete ---
async function deleteUser(username) {
await db.prepare("DELETE FROM Users WHERE username = ?", [username]);
await db.run("DELETE FROM Users WHERE username = ?", [username]);
return;
}