Fixed mod deletion and implemented database transactions support in backend
This commit is contained in:
parent
5af16b593c
commit
58268a94a9
|
@ -29,7 +29,7 @@ async function createMod(req, res) {
|
||||||
async function modifyMod(req, res) {
|
async function modifyMod(req, res) {
|
||||||
try {
|
try {
|
||||||
// Authorize
|
// Authorize
|
||||||
authorizeModModification(req);
|
await authorizeModModification(req);
|
||||||
// Query
|
// Query
|
||||||
const mod_data = req.body;
|
const mod_data = req.body;
|
||||||
const query_result = await mod_service.modifyMod(mod_data);
|
const query_result = await mod_service.modifyMod(mod_data);
|
||||||
|
|
|
@ -53,7 +53,7 @@ async function initDatabase() {
|
||||||
author TINYTEXT NOT NULL,
|
author TINYTEXT NOT NULL,
|
||||||
description 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
|
// Mods complementary infos
|
||||||
|
@ -66,7 +66,7 @@ async function initDatabase() {
|
||||||
creation_date TINYTEXT NOT NULL,
|
creation_date TINYTEXT NOT NULL,
|
||||||
downloads_count INT NOT NULL,
|
downloads_count INT NOT NULL,
|
||||||
|
|
||||||
FOREIGN KEY (mod) REFERENCES Mods(name)
|
FOREIGN KEY (mod) REFERENCES Mods(name) ON DELETE CASCADE
|
||||||
);`);
|
);`);
|
||||||
|
|
||||||
// Mods tags
|
// Mods tags
|
||||||
|
@ -74,7 +74,7 @@ async function initDatabase() {
|
||||||
mod TINYTEXT NOT NULL,
|
mod TINYTEXT NOT NULL,
|
||||||
tag TINYTEXT NOT NULL,
|
tag TINYTEXT NOT NULL,
|
||||||
|
|
||||||
FOREIGN KEY (mod) REFERENCES Mods(name)
|
FOREIGN KEY (mod) REFERENCES Mods(name) ON DELETE CASCADE
|
||||||
);`);
|
);`);
|
||||||
|
|
||||||
// Mods versions
|
// Mods versions
|
||||||
|
@ -89,7 +89,7 @@ async function initDatabase() {
|
||||||
environment TINYTEXT NOT NULL,
|
environment TINYTEXT NOT NULL,
|
||||||
url 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)
|
// User favorites (mods)
|
||||||
|
@ -97,8 +97,8 @@ async function initDatabase() {
|
||||||
username TINYTEXT NOT NULL,
|
username TINYTEXT NOT NULL,
|
||||||
mod TINYTEXT NOT NULL,
|
mod TINYTEXT NOT NULL,
|
||||||
|
|
||||||
FOREIGN KEY (username) REFERENCES Users(username),
|
FOREIGN KEY (username) REFERENCES Users(username) ON DELETE CASCADE,
|
||||||
FOREIGN KEY (mod) REFERENCES Mods(name)
|
FOREIGN KEY (mod) REFERENCES Mods(name) ON DELETE CASCADE
|
||||||
);`);
|
);`);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
//! Not implemented
|
||||||
|
|
||||||
class MySQLDatabase {
|
class MySQLDatabase {
|
||||||
constructor(config) {
|
constructor(config) {
|
||||||
const mysql = require("mysql2/promise");
|
const mysql = require("mysql2/promise");
|
||||||
|
|
|
@ -25,6 +25,7 @@ class SQLiteDatabase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Runs with a result (ex: SELECT)
|
||||||
async query(sql, params = []) {
|
async query(sql, params = []) {
|
||||||
try {
|
try {
|
||||||
if (params.length > 0) {
|
if (params.length > 0) {
|
||||||
|
@ -38,15 +39,17 @@ class SQLiteDatabase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// One time queries (ex: CREATE TABLE)
|
||||||
async exec(sql) {
|
async exec(sql) {
|
||||||
try {
|
try {
|
||||||
return this.db.exec(sql);
|
return this.db.exec(sql);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error("Error executing statement:", err)}
|
console.error("Error executing statement:", err)}
|
||||||
|
throw err;
|
||||||
}
|
}
|
||||||
|
|
||||||
async prepare(sql, params = []) {
|
// Queries with no results (ex: INSERT)
|
||||||
|
async run(sql, params = []) {
|
||||||
try {
|
try {
|
||||||
if (params.length > 0) {
|
if (params.length > 0) {
|
||||||
return this.db.prepare(sql).run(params);
|
return this.db.prepare(sql).run(params);
|
||||||
|
@ -55,6 +58,27 @@ class SQLiteDatabase {
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error("Error executing prepared statement:", 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) {
|
async exists(table, attribute, value) {
|
||||||
|
@ -62,6 +86,7 @@ class SQLiteDatabase {
|
||||||
return this.db.prepare(`SELECT COUNT(*) FROM ${table} WHERE ${attribute} = ?`).get(value)['COUNT(*)'] > 0;
|
return this.db.prepare(`SELECT COUNT(*) FROM ${table} WHERE ${attribute} = ?`).get(value)['COUNT(*)'] > 0;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error("Error checking item existence");
|
console.error("Error checking item existence");
|
||||||
|
throw err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ async function authenticateToken(req) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
req.token_infos = await verifyToken(token);
|
req.token_infos = await verifyToken(token);
|
||||||
console.debug("Authorizing token from", req.token_infos);
|
// console.debug("Authorizing token from", req.token_infos);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
throw new AppError(403, "Forbidden: Error verifying the authorization token");
|
throw new AppError(403, "Forbidden: Error verifying the authorization token");
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,12 +58,12 @@ async function createMod(name, display_name, author, description, mod_infos) {
|
||||||
const { full_description, license, links, creation_date, tags } = mod_infos;
|
const { full_description, license, links, creation_date, tags } = mod_infos;
|
||||||
|
|
||||||
// Mods table
|
// 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 (?, ?, ?, ?)",
|
VALUES (?, ?, ?, ?)",
|
||||||
[name, display_name, author, description]);
|
[name, display_name, author, description]);
|
||||||
|
|
||||||
// ModInfos table
|
// 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 (?, ?, ?, ?, ?, ?)`,
|
VALUES (?, ?, ?, ?, ?, ?)`,
|
||||||
[name, full_description, license.type, links.toString(), creation_date, 0]);
|
[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
|
// License
|
||||||
if (license.type == "custom") {
|
if (license.type == "custom") {
|
||||||
await db.prepare(`UPDATE ModInfos SET custom_license = ?
|
await db.run(`UPDATE ModInfos SET custom_license = ?
|
||||||
WHERE mod = ?`,
|
WHERE mod = ?`,
|
||||||
[license.content, name]);
|
[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) {
|
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 (?, ?, ?, ?, ?, ?, ?, ?, ?);`,
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?);`,
|
||||||
[mod, version_number, channel, changelog, release_date, game_version, environment, platform, url]);
|
[mod, version_number, channel, changelog, release_date, game_version, environment, platform, url]);
|
||||||
return;
|
return;
|
||||||
|
@ -130,12 +130,12 @@ async function updateMod(name, display_name, author, description) {
|
||||||
// --- Delete ---
|
// --- Delete ---
|
||||||
|
|
||||||
async function deleteMod(name) {
|
async function deleteMod(name) {
|
||||||
await db.prepare("DELETE FROM Mods WHERE name = ?", [name]);
|
await db.run("DELETE FROM Mods WHERE name = ?", [name]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function deleteVersion(name, version_number, game_version, platform, environment) {
|
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 version_number = ?
|
||||||
AND game_version = ?
|
AND game_version = ?
|
||||||
AND platform = ?
|
AND platform = ?
|
||||||
|
@ -159,12 +159,12 @@ async function deleteTags(mod, tags) {
|
||||||
// --- Utils ---
|
// --- Utils ---
|
||||||
|
|
||||||
async function updateModAttribute(name, attribute, value) {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function updateModInfosAttribute(name, attribute, value) {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@ async function exists(name) {
|
||||||
async function createUser( username, email, password, displayName, profilePicture, settings ) {
|
async function createUser( username, email, password, displayName, profilePicture, settings ) {
|
||||||
|
|
||||||
// Create user
|
// 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 (?, ?, ?, ?, ? )`,
|
VALUES (?, ?, ?, ?, ? )`,
|
||||||
[username, email, password, displayName, "user"]);
|
[username, email, password, displayName, "user"]);
|
||||||
|
|
||||||
|
@ -86,11 +86,11 @@ async function updateUser(username, display_name, email, profile_picture, settin
|
||||||
}
|
}
|
||||||
|
|
||||||
async function updateUserPassword(username, password) {
|
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) {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,7 +98,7 @@ async function updateUserAttribute(username, attribute, value) {
|
||||||
// --- Delete ---
|
// --- Delete ---
|
||||||
|
|
||||||
async function deleteUser(username) {
|
async function deleteUser(username) {
|
||||||
await db.prepare("DELETE FROM Users WHERE username = ?", [username]);
|
await db.run("DELETE FROM Users WHERE username = ?", [username]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue