brief-05-back/src/services/mysql.service.ts

348 lines
12 KiB
TypeScript

import mysql, {type Connection, type ConnectionOptions} from 'mysql2';
import {Logger} from "tslog";
import type {IDbModel} from "@interfaces/database/IDbModel";
import type {IDbUser} from "@interfaces/database/IDbUser";
const access: ConnectionOptions = {
host: `${process.env["MYSQL_HOST"]}`,
port: Number.parseInt(`${process.env["MYSQL_PORT"]}`),
user: `${process.env["MYSQL_USER"]}`,
database: `${process.env["MYSQL_DATABASE"]}`,
password: `${process.env["MYSQL_PASS"]}`
};
class MysqlHandler {
private readonly handlerName: string;
private Logger: Logger<unknown>
private Connection: Connection;
constructor(handlerName?: string) {
this.handlerName = handlerName || 'Unknown';
this.Logger = new Logger({ name: `DB>> ${this.handlerName}` });
this.Connection = mysql.createConnection(access);
this.Connection.connect((err) => {
if (err) {
this.Logger.error(`Error connecting to MySQL: ${err}`);
throw new Error()
}
this.Logger.info(`Connected to MySQL database (${access.database})`);
});
}
closeConnection() {
this.Connection.end();
};
query(queryString: string) {
return new Promise((resolve, reject) => {
this.Connection.query(queryString, (err, results) => {
if (err) {
this.Logger.error(`Error executing query: ${err}`);
reject(err);
} else {
resolve(results);
}
});
});
}
execute(queryString: string, values: Array<string | boolean | Date | number>): Promise<unknown> {
return new Promise((resolve, reject) => {
this.Connection.execute(queryString, values, (err: mysql.QueryError | null, results: mysql.QueryResult) => {
if (err) {
this.Logger.error(`Error executing query: ${err}`);
reject(err);
} else {
resolve(results);
}
});
});
}
/**
* Unprepare a previously prepared SQL query.
*
* @param {string} queryString
* - The SQL query string to unprepare.
* @return {Promise}
* - A promise that resolves if the unprepare operation is successful,
* or rejects with an error if there was an error unpreparing the query.
*/
unprepare(queryString: string): Promise<unknown> {
return new Promise((resolve, reject) => {
try {
resolve(this.Connection.unprepare(queryString));
} catch (err) {
reject(err)
}
});
}
}
const MySqlService = {
Handler : MysqlHandler,
User: {
/**
* Insert a user into the database.
*
* @param {MysqlHandler} handler - The MySQL database handler.
* @param {IDbUser} userData - The user data to insert.
* @returns {Promise<void>} A promise that resolves if the user was inserted successfully, or rejects with an error.
* @throws {Error} If an error occurs while executing the query.
*/
insert(handler: MysqlHandler, userData: IDbUser) {
return new Promise((resolve, reject) => {
if (!userData.id) return reject('Id is undefined');
if (userData.id.length !== 36) return reject('Id invalid');
const _sql = "INSERT INTO `users`(`id`,`username`, `firstname`, `lastname`, `dob`, `email`, `is_mail_verified`, `is_admin`, `gdpr`, `hash`) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)"
const _values = [
userData.id,
userData.username,
userData.firstname,
userData.lastname,
userData.dob,
userData.email,
userData.is_mail_verified,
userData.is_admin,
userData.gdpr,
userData.hash
]
try {
resolve(handler.execute(_sql, _values))
} catch (err: unknown) {
reject(err as Error);
}
})
},
/**
* Updates user data in the database.
* @param {MysqlHandler} handler - The MySQL handler object.
* @param {IDbUser} userData - The user data to be updated.
* @returns {Promise<unknown>} - A promise that resolves when the update is successful.
* @throws {Error} - If an error occurs during the update process.
*/
update(handler: MysqlHandler, userData: IDbUser): Promise<unknown> {
return new Promise((resolve, reject) => {
if (!userData.id) return reject('Id is undefined');
if (userData.id.length !== 36) return reject('Id invalid');
try {
const _template = `
${userData.username ? "`username` = ?," : null}
${userData.firstname ? "`firstname` = ?," : null}
${userData.lastname ? "`lastname` = ?," : null}
${userData.dob ? "`dob` = ?," : null}
${userData.email ? "`email` = ?," : null}
${userData.is_mail_verified ? "`is_mail_verified` = ?," : null}
${userData.is_admin ? "`is_admin` = ?," : null}
${userData.gdpr ? "`gdpr` = ?," : null}
${userData.hash ? "`hash` = ?" : null}`
const _values = [
userData.username,
userData.firstname,
userData.lastname,
userData.dob,
userData.email,
userData.is_mail_verified,
userData.is_admin,
userData.gdpr,
userData.hash,
userData.id
]
const _sql = `UPDATE "users" SET ${_template} WHERE 'id' = ?`;
return resolve(handler.execute(_sql, _values));
} catch (err: unknown) {
reject(err as Error);
}
});
},
/**
* Retrieves a user from the database based on their ID.
*
* @param {MysqlHandler} handler - The MySQL handler object used to execute the query.
* @param {string} userId - The ID of the user to retrieve from the database.
*
* @return {Promise<IDbUser>} - A promise that resolves with the retrieved user object (of type IDbUser).
* - Rejects with an error if the ID is invalid or if an error occurs during the database operation.
*/
getById(handler: MysqlHandler, userId: string): Promise<IDbUser> {
return new Promise((resolve, reject) => {
if (userId.length !== 36) return reject('Id invalid');
const _sql = "SELECT * FROM `users` WHERE `id` = ?";
const _values = [userId];
try {
resolve(handler.execute(_sql, _values) as unknown as IDbUser);
} catch (err: unknown) {
reject(err as Error);
}
});
},
/**
* Retrieves all users from the database.
*
* @param {MysqlHandler} handler - The MySQL handler object used to query the database.
* @return {Promise<Array<IDbUser>>} - A promise that resolves with an array of user objects from the database.
* @throws {Error} - If an error occurs while querying the database.
*/
getAll(handler: MysqlHandler): Promise<Array<IDbUser>> {
return new Promise((resolve, reject) => {
const _sql = "SELECT * FROM `users`";
try {
resolve(handler.query(_sql) as unknown as Array<IDbUser>);
} catch (err: unknown) {
reject(err as Error);
}
});
},
/**
* Retrieves a user from the database by email.
*
* @param {MysqlHandler} handler - The MySQL database handler instance.
* @param {string} email - The email of the user to retrieve.
* @return {Promise<IDbUser>} - A promise that resolves to the retrieved user object.
* @throws {Error} - If an error occurs while retrieving the user.
*/
getByEmail(handler: MysqlHandler, email: string): Promise<IDbUser> {
return new Promise((resolve, reject) => {
if (!email) return reject('email is undefined')
const _sql = "SELECT * FROM `users` WHERE `email` = ?";
const _values = [email];
try {
resolve(handler.execute(_sql, _values) as unknown as IDbUser);
} catch (err: unknown) {
reject(err as Error);
}
});
},
/**
* Retrieves the admin state for a given user ID.
*
* @param {MysqlHandler} handler - The MySQL handler object used for executing the query.
* @param {string} userId - The ID of the user to get the admin state for.
* @return {Promise<boolean>} A Promise that resolves to a boolean value indicating whether the user is an admin or not.
* @throws {Error} if an error occurs during the execution of the query.
*/
getAdminStateForId(handler: MysqlHandler, userId: string) : Promise<boolean> {
return new Promise((resolve, reject) => {
const _sql = "SELECT `is_admin` FROM `users` WHERE `id` = ?";
const _values = [userId];
try {
const isAdmin = handler.execute(_sql, _values)
isAdmin.then((result) => {
if (result !== true) return resolve(false);
return resolve(true)
});
} catch (err: unknown) {
reject(err as Error);
}
});
},
/**
* Deletes a user from the database.
* @param {MysqlHandler} handler - The MySQL handler object.
* @param {string} userId - The ID of the user to delete.
* @return {Promise<unknown>} - A Promise that resolves when the deletion is successful, or rejects with an error.
*/
delete(handler: MysqlHandler, userId: string): Promise<unknown> {
return new Promise((resolve, reject) => {
if (!userId) return reject('Id is undefined');
if (userId.length !== 36) return reject('Id invalid');
const _sql = "DELETE FROM `users` WHERE `id` = ?";
const _values = [userId];
try {
resolve(handler.execute(_sql, _values));
} catch (err: unknown) {
reject(err as Error);
}
});
}
},
Model: {
/**
* Retrieves all records from the 'models' table.
*
* @param {MysqlHandler} handler - The MySQL handler object used to execute the query.
* @return {Promise<Array<IDbModel>>} - A promise that resolves to an array of IDbModel objects representing the retrieved records from the 'models' table.
* @throws {Error} - If there is an error executing the query.
*/
getAll(handler: MysqlHandler): Promise<Array<IDbModel>> {
return new Promise((resolve, reject) => {
const _sql = "SELECT * FROM `models`";
try {
resolve(handler.query(_sql) as unknown as Array<IDbModel>);
} catch (err: unknown) {
reject(err as Error);
}
});
},
/**
* Retrieves a database model by slug from a given MySQL handler.
*
* @param {MysqlHandler} handler - The MySQL handler instance.
* @param {string} slug - The slug of the model to retrieve.
* @return {Promise<IDbModel>} A promise that resolves with the retrieved model.
* @throws {Error} If there was an error executing the query.
*/
getBySlug(handler: MysqlHandler, slug: string): Promise<IDbModel> {
return new Promise((resolve, reject) => {
const _sql = "SELECT * FROM `models` WHERE `slug` = ?";
const _values = [slug];
try {
resolve(handler.execute(_sql, _values) as unknown as IDbModel);
} catch (err: unknown) {
reject(err as Error);
}
});
},
getById(handler: MysqlHandler, modelId: string): Promise<IDbModel> {
return new Promise((resolve, reject) => {
const _sql = "SELECT * FROM `models` WHERE `id` = ?";
const _values = [modelId];
try {
resolve(handler.execute(_sql, _values) as unknown as IDbModel);
} catch (err: unknown) {
reject(err as Error);
}
});
},
insert(handler: MysqlHandler, data: IDbModel) {
return new Promise((resolve, reject) => {
if (!data.id) return reject('Id is undefined');
if (data.id.length !== 36) return reject('Id invalid');
const _sql = "INSERT INTO `users`(`id`,`username`, `firstname`, `lastname`, `dob`, `email`, `is_mail_verified`, `is_admin`, `gdpr`, `hash`) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)"
const _values = [
data.slug_name,
data.display_name,
data.brand_id,
data.category_id,
data.image_blob,
data.is_trending,
data.base_price
]
try {
resolve(handler.execute(_sql, _values))
} catch (err: unknown) {
reject(err as Error);
}
})
}
}
}
export default MySqlService