diff --git a/src/database/index.js b/src/database/index.js index 0e7bed9..90483ff 100644 --- a/src/database/index.js +++ b/src/database/index.js @@ -34,14 +34,14 @@ async function initDatabase() { // --- Users --- // Uers table - db.exec("CREATE TABLE IF NOT EXISTS Users ( \ - username TINYTEXT PRIMARY KEY, \ - display_name TINYTEXT, \ - email TINYTEXT,\ - password TINYTEXT,\ - profile_picture LONGTEXT,\ - settings LONGTEXT, \ - );"); + db.exec(`CREATE TABLE IF NOT EXISTS Users ( + username TINYTEXT PRIMARY KEY, + display_name TINYTEXT NOT NULL, + email TINYTEXT NOT NULL, + password TINYTEXT NOT NULL, + profile_picture LONGTEXT, + settings LONGTEXT, + );`); // --- Mods --- diff --git a/src/models/mod.js b/src/models/mod.js index 11f30e9..1b409d6 100644 --- a/src/models/mod.js +++ b/src/models/mod.js @@ -2,8 +2,11 @@ const { getDatabase } = require('../database/index'); const AppError = require('../utils/appError'); const db = getDatabase(); + +// --- Get --- + async function getAllMods() { - return db.query("SELECT name FROM Mods"); + return await db.query("SELECT name, display_name, author, description FROM Mods"); } async function getModByName(name) { @@ -11,39 +14,136 @@ async function getModByName(name) { } +async function getFullModInfos(name) { + + // Query + const base_infos = db.query(`SELECT * FROM Mods WHERE name = ?`, [name]); + const other_infos = db.query(`SELECT full_description, license, links, creation_date + FROM ModInfos WHERE name = ?`, [name]); + + // Merge + const res = {...await base_infos, ...await other_infos}; + + return res; +} + async function exists(name) { return db.exists("Mods", "name", name); } -async function createMod(mod_data) { - const { name, displayName, author, versions, otherInfos } = mod_data; - const { description, links, tags, screenshots, license, changelogs, counts } = otherInfos; +// --- Create --- + +async function createMod(name, display_name, author, description, mod_infos) { + + // Extract infos + const { full_description, license, links, creation_date, tags } = mod_infos; + + // Mods table + await db.prepare("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) + VALUES (?, ?, ?, ?, ?)`, + [name, full_description, license.type, links.toString(), creation_date]); + + // Tags + const tags_proc = updateTags(name, tags, []); + + // License + if (license_type == "custom") { + await db.prepare(`UPDATE ModInfos SET custom_license = ? + WHERE mod = ?`, + [license.content, name]); + } + + // Await + await tags_proc; - await db.prepare("INSERT INTO mods (name, display_name, author) \ - VALUES (?, ?, ?, ?)", [name, displayName, author]); - // db.prepare("INSERT INTO modsDescription (Name, Description, Links, Tags, Screenshots, License, Changelogs, Counts) \ - // VALUES (?, ?, ?, ?, ?, ?, ?, ?)", [name, description, links, tags, screenshots, license, changelogs, counts]); return; } +async function addVersion(version_number, channel, changelog, release_date, game_version, platform, environment, url) { + + await db.prepare(`INSERT INTO ModVersions (version_number, channel, changelog, release_date, game_version, platform, url) + VALUES (?, ?, ?, ?, ?, ?, ?);`, + [version_number, channel, changelog, release_date, game_version, platform, url]); + return; +} + +async function AddTags(tags) { + // Add asynchronously + const promises = tags.map(async (mod) => { + db.query(`INSERT INTO UserFavoriteMods (username, mod) + VALUES (?, ?);`, + [username, mod]); + }); + await Promise.all(promises); + + return; +} + + +// --- Update --- + +async function updateMod(name, display_name, author, description) { + + if (display_name) { + await updateModAttributes(name, "display_name", display_name); + } + + if (author) { + await updateModAttribute(nale, "author", author); + } + + if (profile_picture) { + await updateUserAttribute(name, "description", description) + } +} + +async function updateModAttribute(name, attribute, value) { + await db.prepare(`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]); + return; +} + + +// --- Delete --- + async function deleteMod(name) { - console.log("WARNING: using a WIP function : deleteMod (models/mods.js)"); - db.prepare("DELETE FROM Mods WHERE name = ?", [name]); - // db.prepare("DELETE FROM modsDescription WHERE Name = ?", [name]); + await db.prepare("DELETE FROM Mods WHERE name = ?", [name]); return; } -// --- WIP --- +async function deleteVersion(name, version_number, channel, game_version, platform, environment) { + await db.prepare(`DELETE FROM ModVersions WHERE name = ? + AND version_number = ? + AND channel = ? + AND game_version = ? + AND platform = ? + AND environment = ?;`, + [name, version_number, channel, game_version, platform, environment]); + return; +} -async function updateMod(mod_data) { - console.log("WARNING: using a WIP function : updateMod (models/mods.js)"); - throw new AppError(501, "Not implemented"); - // const { name, description } = mod_data; - // return db.query("INSERT INTO mods (name, description) VALUES (?, ?)", [name, description]); +async function deleteTags(tags) { + // Remove asynchronously + const promises = tags.map(async (mod) => { + db.query(`DELETE FROM UserFavoriteMods + WHERE username = ? AND mod = ?;`, [username, mod]); + }); + await Promise.all(promises); + + return; } - +// --- Exports --- module.exports = { getAllMods, getModByName, createMod, deleteMod, exists } \ No newline at end of file diff --git a/src/models/user.js b/src/models/user.js index 9be6cb9..4c26fba 100644 --- a/src/models/user.js +++ b/src/models/user.js @@ -2,47 +2,118 @@ const { getDatabase } = require('../database/index'); const AppError = require('../utils/appError'); const db = getDatabase(); -async function getAllUsers() { - return db.query("SELECT * FROM users"); + +// --- Get --- + +async function getAllUsers(name) { + return db.query("SELECT username, display_name, email, profile_picture FROM Users WHERE username = ?", [name]); } async function getUserByName(name) { - return await db.query("SELECT * FROM Users WHERE username = ?;", [name]); + return await db.query("SELECT username, display_name, profile_picture FROM Users WHERE username = ?;", [name]); } async function getUserByEmail(email) { - return await db.query("SELECT * FROM Users WHERE email = ?;", [email]); + return await db.query("SELECT email, username, display_name, FROM Users WHERE email = ?;", [email]); +} + +async function getFullUserInfos(name) { + return await db.query("SELECT username, display_name, email, profile_picture, settings FROM Users WHERE username = ?;", [name]); +} + +async function getUserPassword(name) { + return await db.query("SELECT username, password FROM Users WHERE username = ?;", [name]); } async function exists(name) { - return db.exists("Users", "username", name); + return await db.exists("Users", "username", name); } -async function createUser(user_data) { - const { name, email, password, displayName, profilePicture, favorites, preferences } = user_data; +// --- Create --- - //TODO breakdown to handle partial updates - await db.prepare("INSERT INTO Users (username, email, password, display_name, profile_picture, favorites, preferences) \ - VALUES (?, ?, ?, ?)", [name, email, password, displayName, profilePicture, favorites, preferences]); +async function createUser( username, email, password, displayName, profilePicture, settings ) { + + // Create user + await db.prepare("INSERT INTO Users (username, email, password, display_name) \ + VALUES (?, ?, ?, ?)", [username, email, password, displayName]); + + // Handle nullable fields + if (profilePicture) { + await updateUserAttribute(username, "profile_picture", profilePicture); + } + + if (settings) { + await updateUserAttribute(username, "settings", settings); + } return; } -async function deleteUser(name) { - await db.prepare("DELETE FROM Users WHERE username = ?", [name]); + +// --- Update --- + +async function updateUser(username, display_name, email, profile_picture, settings) { + + if (display_name) { + await updateUserAttribute(username, "display_name", display_name); + } + + if (email) { + await updateUserAttribute(username, "email", email); + } + + if (profile_picture) { + await updateUserAttribute(username, "profile_picture", profile_picture) + } + + if (settings) { + await updateUserAttribute(username, "settings", settings); + } +} + +async function updateUserPassword(username, password) { + await db.prepare(`UPDATE Users SET password = ? WHERE username = ?`, [password, username]); +} + +async function updateUserFavoriteMods(username, new_favs, deleted_favs) { + + // Delete / Add asynchronously + const promises_new = new_favs.map(async (mod) => { + db.query(`INSERT INTO UserFavoriteMods + (username, mod) VALUES (?, ?);`, + [username, mod]); + + }); + const promises_deleted = deleted_favs.map(async (mod) => { + db.query(`DELETE FROM UserFavoriteMods + WHERE username = ? AND mod = ?;`, [username, mod]); + }); + + // Await + await Promise.all(promises_new); + await Promise.all(promises_deleted); + return; } -// --- WIP --- - -async function updateUser(user_data) { - console.log("WARNING: using a WIP function : updateUser (userels/users.js)"); - throw new AppError(501, "Not implemented"); - // const { name, description } = user_data; - // return db.query("INSERT INTO users (name, description) VALUES (?, ?)", [name, description]); +async function updateUserAttribute(username, attribute, value) { + await db.prepare(`UPDATE Users SET ${attribute} = ? WHERE username = ?`, [value, username]); + return; } +// --- Delete --- + +async function deleteUser(username) { + await db.prepare("DELETE FROM Users WHERE username = ?", [username]); + return; +} -module.exports = { getAllUsers, getUserByName, getUserByEmail, createUser, deleteUser, exists } \ No newline at end of file +// --- Exports --- + +module.exports = { getAllUsers, getUserByName, getUserByEmail, getFullUserInfos, getUserPassword, + createUser, + updateUser, updateUserFavoriteMods, + deleteUser, + exists } \ No newline at end of file