Initial Fork + Updates
- New customizable storage library
This commit is contained in:
180
libStorage.js
Normal file
180
libStorage.js
Normal file
@@ -0,0 +1,180 @@
|
||||
// Customizable storage module for any mode of storage
|
||||
// Update the functions here to change the storage medium
|
||||
|
||||
// Import modules
|
||||
|
||||
// Storage Specific Modules
|
||||
// MySQL
|
||||
const e = require("express");
|
||||
const mysql = require("mysql");
|
||||
|
||||
|
||||
// Helper Functions
|
||||
// Function to run and handle SQL errors
|
||||
function runSQL(sqlQuery, connection, callback = (err, rows) => {
|
||||
console.log(err);
|
||||
throw err;
|
||||
}) {
|
||||
connection.query(sqlQuery, (err, rows) => {
|
||||
if (err) return callback(err, undefined);
|
||||
//console.log('The rows are:', rows);
|
||||
return callback(undefined, rows);
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
exports.Storage = class Storage {
|
||||
constructor(_dbTable) {
|
||||
this.connection = mysql.createConnection({
|
||||
host: process.env.DB_HOST,
|
||||
user: databaseConfig.DB_USER,
|
||||
password: databaseConfig.DB_PASS,
|
||||
database: databaseConfig.DB_NAME
|
||||
});
|
||||
|
||||
// Start the MySQL Connection
|
||||
this.connection.connect();
|
||||
|
||||
// Set the DB Table for later use
|
||||
this.dbTable = _dbTable
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper to save a new entry using the storage method configured
|
||||
* @param {*} toBeSaved Entry or Entries to be added
|
||||
* @param {function} callback The callback function to be called with the record when saved
|
||||
*/
|
||||
create(toBeSaved, callback) {
|
||||
if (!toBeSaved[0].fields?.title) callback(Error("No title given"), undefined);
|
||||
|
||||
for (const entry of toBeSaved) {
|
||||
if(!this.checkForTitleSync(entry.title)) {
|
||||
this.saveEntry(entry, (err, rows) => {
|
||||
if (err) callback(err, undefined);
|
||||
if (rows?.affectedRows) callback(undefined, rows[0]);
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper to delete an entry using the storage method configured
|
||||
* @param {} entryID The ID of the entry to be deleted
|
||||
* @param {function} callback The callback function to be called with the record when deleted
|
||||
*/
|
||||
destroy(entryID, callback) {
|
||||
if (!entryID) callback(Error("No entry ID given"), undefined);
|
||||
|
||||
const entryRecord = this.getRecordBy('id', entryID);
|
||||
|
||||
this.removeEntry(entryRecord.id, (err, results) => {
|
||||
if (err) callback(err, undefined);
|
||||
callback(undefined, results);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Check to see if an entry exists in the storage method configured
|
||||
* @param {*} title The title of the entry to check if it exists
|
||||
* @returns {true|false|*}
|
||||
*/
|
||||
checkForTitleSync(title) {
|
||||
if (!title) throw new Error("No title given when checking for title");
|
||||
const sqlQuery = `SELECT * FROM ${this.dbTable} WHERE title = ${title}`;
|
||||
|
||||
runSQL(this.connection, sqlQuery, (err, rows) => {
|
||||
if (err) throw err;
|
||||
if (rows[0]?.title) return true;
|
||||
else return false;
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a record by a specified key
|
||||
* @param {*} key The key to search for
|
||||
* @param {*} keyValue The value of the key to search for
|
||||
*/
|
||||
getRecordBy(key, keyValue) {
|
||||
const validKeys = ["link", "title", "category", "id"];
|
||||
if (!Array(validKeys).includes(key)) throw new Error("Given key not valid");
|
||||
|
||||
const sqlQuery = `SELECT * FROM ${this.dbTable} WHERE ${key} = ${keyValue}`;
|
||||
|
||||
runSQL(this.connection, sqlQuery, (err, rows) => {
|
||||
if (err) throw err;
|
||||
if (rows[0]?.title) return rows[0];
|
||||
else return false;
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the given entry to the storage medium
|
||||
* @param {Object} entryObject The entry object to be saved
|
||||
* @param {function} callback The callback to be called with either an error or undefined if successful
|
||||
*/
|
||||
saveEntry(entryObject, callback) {
|
||||
if (!entryObject?.table || entryObject?.link || entryObject?.category) {
|
||||
callback(new Error("Entry object malformed, check the object before saving it"), undefined)
|
||||
}
|
||||
|
||||
const sqlQuery = `INSERT INTO ${this.dbTable} (title, link, category) VALUES ('${entryObject.table}', '${entryObject.link}', '${entryObject.category}')`;
|
||||
|
||||
runSQL(this.connection, sqlQuery, (err, rows) => {
|
||||
if (err) callback(err, undefined);
|
||||
callback(undefined, rows);
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the given entry to the storage medium
|
||||
* @param {Object} entryObject The entry object to be saved
|
||||
* @param {function} callback The callback to be called with either an error or undefined if successful
|
||||
*/
|
||||
updateEntry(entryObject, callback) {
|
||||
let queryParams = [];
|
||||
if (!entryObject.title) callback(new Error("No title given before updating"), undefined);
|
||||
queryParams.push(`title = '${entryObject.title}`);
|
||||
if (!entryObject.link) callback(new Error("No link given before updating"), undefined);
|
||||
queryParams.push(`link = '${entryObject.link}`);
|
||||
if (entryObject.category) queryParams.push(`category = '${entryObject.category}`);
|
||||
|
||||
let sqlQuery = `UPDATE ${this.dbTable} SET`;
|
||||
|
||||
let i = 0;
|
||||
for (const param of queryParams) {
|
||||
if (i === queryParams.length-1) {
|
||||
sqlQuery = `${sqlQuery} ${param}`
|
||||
i += 1;
|
||||
}
|
||||
else {
|
||||
sqlQuery = `${sqlQuery} ${param},`
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
|
||||
sqlQuery = `${sqlQuery} WHERE title = '${entryObject.title}';`
|
||||
|
||||
runSQL(this.connection, sqlQuery, (err, rows) => {
|
||||
if (err) callback(err, undefined);
|
||||
callback(undefined, rows);
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the given entry from the storage medium
|
||||
* @param {string} title The title of the entry to be deleted
|
||||
* @param {function} callback The callback to be called with either an error or undefined if successful
|
||||
*/
|
||||
removeEntry(title, callback) {
|
||||
if (!title) {
|
||||
callback(new Error("No entry title given before deleting"), undefined)
|
||||
}
|
||||
|
||||
const sqlQuery = `DELETE FROM ${this.dbTable} WHERE title = '${title}'`;
|
||||
|
||||
runSQL(this.connection, sqlQuery, (err, rows) => {
|
||||
if (err) callback(err, undefined);
|
||||
callback(undefined, rows);
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user