sql: sqlite > mariadb
This commit is contained in:
parent
a4c314ca36
commit
e2c28f8735
3 changed files with 201 additions and 64 deletions
2
index.ts
2
index.ts
|
@ -28,7 +28,7 @@ const bazaarPrice = {
|
||||||
};
|
};
|
||||||
|
|
||||||
async function initialize() {
|
async function initialize() {
|
||||||
await SqlSystem.InitTable();
|
await SqlSystem.InitDB()
|
||||||
const matches = process.env.WEBHOOK_URL.match(webhookRegex);
|
const matches = process.env.WEBHOOK_URL.match(webhookRegex);
|
||||||
if (!matches) return console.log(`[Main thread] Couldn't parse Webhook URL`);
|
if (!matches) return console.log(`[Main thread] Couldn't parse Webhook URL`);
|
||||||
const webhook = new WebhookClient({ id: matches[1], token: matches[2] });
|
const webhook = new WebhookClient({ id: matches[1], token: matches[2] });
|
||||||
|
|
|
@ -17,11 +17,11 @@
|
||||||
"copy-paste": "^1.5.3",
|
"copy-paste": "^1.5.3",
|
||||||
"discord.js": "^14.16.3",
|
"discord.js": "^14.16.3",
|
||||||
"express": "^4.21.2",
|
"express": "^4.21.2",
|
||||||
|
"mariadb": "^3.4.0",
|
||||||
"node-notifier": "^10.0.1",
|
"node-notifier": "^10.0.1",
|
||||||
"open": "^8.4.2",
|
"open": "^8.4.2",
|
||||||
"prismarine-nbt": "^2.7.0",
|
"prismarine-nbt": "^2.7.0",
|
||||||
"socket.io": "^4.8.1",
|
"socket.io": "^4.8.1",
|
||||||
"sqlite3": "^5.1.7",
|
|
||||||
"toastify-js": "^1.12.0",
|
"toastify-js": "^1.12.0",
|
||||||
"ts-node": "^10.9.2",
|
"ts-node": "^10.9.2",
|
||||||
"typescript": "^5.7.2"
|
"typescript": "^5.7.2"
|
||||||
|
|
|
@ -1,72 +1,209 @@
|
||||||
import sqlite3 from 'sqlite3';
|
import mariadb from 'mariadb';
|
||||||
|
import { loadConfig } from './configLoader';
|
||||||
|
const config = loadConfig();
|
||||||
|
|
||||||
//TODO
|
|
||||||
// MUTEX functions for adding/removing/upsert
|
|
||||||
// basic read function by id
|
|
||||||
// complex read function by value range
|
|
||||||
class SqlSystem {
|
class SqlSystem {
|
||||||
private static db: sqlite3.Database;
|
|
||||||
|
|
||||||
public static async InitTable() {
|
private static pool: mariadb.Pool = mariadb.createPool({ database: process.env.DATABASE, host: process.env.DB_HOST, user: process.env.DB_USER, password: process.env.DB_PASSWORD, connectionLimit: config.data.worker_count ?? 10 })
|
||||||
const db = new sqlite3.Database('bot_data');
|
|
||||||
|
public static async InitDB() {
|
||||||
|
let conn: mariadb.PoolConnection | undefined;
|
||||||
try {
|
try {
|
||||||
await this.runQuery('CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name TEXT)')
|
conn = await this.pool.getConnection();
|
||||||
console.log('Table created successfully.');
|
//Setup tables for auctions and lifetimes
|
||||||
|
await conn.query(`
|
||||||
// Insert data
|
CREATE TABLE if NOT EXISTS auctions (
|
||||||
await this.runQuery('INSERT INTO users (name) VALUES (?)', ['Alice']);
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
console.log('Data inserted successfully.');
|
auctionid VARCHAR(255) NOT NULL,
|
||||||
|
lbin DECIMAL(65,5) SIGNED,
|
||||||
// Retrieve a single row
|
UNIQUE INDEX 'auctionid' ('auctionid')
|
||||||
const row = await this.getQuery('SELECT * FROM users WHERE name = ?', ['Alice']);
|
);
|
||||||
console.log('Retrieved row:', row);
|
CREATE TABLE if NOT EXISTS lifetimes (id INT PRIMARY KEY, insertedon DATETIME(2));
|
||||||
|
`)
|
||||||
// Retrieve all rows
|
//Setup lifetime Trigger
|
||||||
const rows = await this.allQuery('SELECT * FROM users');
|
await conn.query(`
|
||||||
console.log('All rows:', rows);
|
DELIMITER $$
|
||||||
} catch (err: any) {
|
CREATE TRIGGER IF NOT EXISTS insertLifetime
|
||||||
console.error('Database error:', err.message);
|
AFTER INSERT ON auctions
|
||||||
} finally {
|
FOR EACH ROW
|
||||||
db.close();
|
BEGIN
|
||||||
|
INSERT INTO lifetimes (id, insertedon)
|
||||||
|
VALUES (NEW.ID, NOW());
|
||||||
|
END$$
|
||||||
|
DELIMITER ;
|
||||||
|
DELIMITER $$
|
||||||
|
CREATE TRIGGER IF NOT EXISTS updateLifetime
|
||||||
|
AFTER UPDATE ON auctions
|
||||||
|
FOR EACH ROW
|
||||||
|
BEGIN
|
||||||
|
UPDATE lifetimes SET insertedon = NOW() WHERE id=NEW.ID;
|
||||||
|
END$$
|
||||||
|
DELIMITER ;
|
||||||
|
DELIMITER $$
|
||||||
|
CREATE TRIGGER IF NOT EXISTS removeLifetime
|
||||||
|
BEFORE DELETE ON auctions
|
||||||
|
FOR EACH ROW
|
||||||
|
BEGIN
|
||||||
|
DELETE FROM lifetimes WHERE id=OLD.ID;
|
||||||
|
END$$
|
||||||
|
DELIMITER ;
|
||||||
|
`)
|
||||||
|
//Setup Table sanitation
|
||||||
|
await conn.query(`
|
||||||
|
DELIMITER $$
|
||||||
|
CREATE PROCEDURE IF NOT EXISTS CleanupOldEntries()
|
||||||
|
BEGIN
|
||||||
|
DECLARE done INT DEFAULT 0;
|
||||||
|
DECLARE temp_id INT;
|
||||||
|
DECLARE cur CURSOR FOR
|
||||||
|
SELECT id
|
||||||
|
FROM lifetimes
|
||||||
|
WHERE TIMESTAMPDIFF(HOUR, insertedon, NOW()) >= 6;
|
||||||
|
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
|
||||||
|
OPEN cur;
|
||||||
|
read_loop: LOOP
|
||||||
|
FETCH cur INTO temp_id;
|
||||||
|
IF done THEN
|
||||||
|
LEAVE read_loop;
|
||||||
|
END IF;
|
||||||
|
DELETE FROM auctions WHERE id = temp_id;
|
||||||
|
END LOOP;
|
||||||
|
CLOSE cur;
|
||||||
|
END$$
|
||||||
|
DELIMITER ;
|
||||||
|
SET GLOBAL event_scheduler = ON;
|
||||||
|
CREATE EVENT IF NOT EXISTS CleanupOldEntriesEvent
|
||||||
|
ON SCHEDULE EVERY 2 MINUTE
|
||||||
|
DO
|
||||||
|
CALL CleanupOldEntries();
|
||||||
|
`)
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
console.error("InitDB Error: ", error);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
if (conn) conn.release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public static runQuery(query: string, params: string[] = []) {
|
//INSERT ELEMENT IN AUCTIONS TABLE OR UPDATE IF IT ALREADY EXISTS
|
||||||
return new Promise((resolve,reject) => {
|
public static async Upsert(auctionid: string, lbin: number) {
|
||||||
this.db.run(query, params, function (err: Error | null | undefined) {
|
let conn: mariadb.PoolConnection | undefined;
|
||||||
if(err){
|
try {
|
||||||
reject(err);
|
conn = await this.pool.getConnection();
|
||||||
|
await conn.beginTransaction();
|
||||||
|
await conn.query(`
|
||||||
|
INSERT INTO auctions (auctionid, LBin)
|
||||||
|
VALUES (?,?)
|
||||||
|
ON DUPLICATE KEY UPDATE
|
||||||
|
LBin = VALUES(LBin);
|
||||||
|
`, [auctionid, lbin]);
|
||||||
|
await conn.commit();
|
||||||
}
|
}
|
||||||
|
catch (error) {
|
||||||
|
console.error("InitDB Error: ", error);
|
||||||
|
if(conn) await conn.rollback();
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
if (conn) conn.release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//REMOVE ELEMENT IN AUCTIONS TABLE
|
||||||
|
public static async Remove(auctionId: string) {
|
||||||
|
let conn: mariadb.PoolConnection | undefined;
|
||||||
|
try {
|
||||||
|
conn = await this.pool.getConnection();
|
||||||
|
await conn.beginTransaction();
|
||||||
|
await conn.query(`
|
||||||
|
DELETE FROM auctions WHERE auctionid = ?
|
||||||
|
`,[auctionId]);
|
||||||
|
await conn.commit();
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
console.error("InitDB Error: ", error);
|
||||||
|
if(conn) await conn.rollback();
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
if (conn) conn.release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//MATCH PROVIDED ELEMENTS IN AUCTIONS TABLE - returns true/false
|
||||||
|
public static async Match(auctionid:string|string[],lbin:number|number[]): Promise<boolean|any> {
|
||||||
|
let conn: mariadb.PoolConnection | undefined;
|
||||||
|
let result;
|
||||||
|
try{
|
||||||
|
conn = await this.pool.getConnection();
|
||||||
|
if(Array.isArray(auctionid) && Array.isArray(lbin))
|
||||||
|
if(auctionid.length === lbin.length) {
|
||||||
|
result = await conn.query(`
|
||||||
|
CREATE TEMPORARY TABLE IF NOT EXISTS TEMP (
|
||||||
|
auctionID VARCHAR(255) PRIMARY KEY,
|
||||||
|
lbin DECIMAL(65,5)
|
||||||
|
);
|
||||||
|
INSERT INTO TEMP (auctionID, lbin) VALUES ?
|
||||||
|
SELECT tmp.*
|
||||||
|
FROM TEMP AS tmp
|
||||||
|
WHERE NOT EXISTS (
|
||||||
|
SELECT 1
|
||||||
|
FROM auctions AS auc
|
||||||
|
WHERE auc.auctionID = tmp.auctionID
|
||||||
|
AND auc.lbin = tmp.lbin);
|
||||||
|
`,[await this.UnifiedArray(auctionid,lbin)])
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
else if(Array.isArray(auctionid) || Array.isArray(lbin)) throw Error('Match SQL Function error - cannot match collection to singlet');
|
||||||
else {
|
else {
|
||||||
resolve(this);
|
result = await conn.query(`
|
||||||
|
SELECT CASE
|
||||||
|
WHEN COUNT(*) > 0
|
||||||
|
THEN true
|
||||||
|
ELSE false
|
||||||
|
END AS user_exists
|
||||||
|
FROM auctions WHERE auctionID = ?;
|
||||||
|
`,[auctionid])
|
||||||
|
return Boolean(result[0].result)
|
||||||
}
|
}
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
public static getQuery(query: string, params: string[] = []) {
|
catch(error)
|
||||||
return new Promise((resolve, reject) => {
|
{
|
||||||
this.db.get(query, params, (err: Error | null | undefined, row: sqlite3.RunResult) => {
|
console.error("message_before_error: ", error);
|
||||||
if (err) {
|
throw error;
|
||||||
reject(err);
|
|
||||||
} else {
|
|
||||||
resolve(row);
|
|
||||||
}
|
}
|
||||||
});
|
finally
|
||||||
});
|
{
|
||||||
|
if (conn) conn.release();
|
||||||
}
|
}
|
||||||
public static allQuery(query: string, params: string[] = []) {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
this.db.all(query, params, (err: Error | null | undefined, rows: sqlite3.RunResult) => {
|
|
||||||
if (err) {
|
|
||||||
reject(err);
|
|
||||||
} else {
|
|
||||||
resolve(rows);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
//EXAMPLE BLOCK OF CODE FOR ADDING DATABASE FUNCTIONS
|
||||||
|
/*
|
||||||
|
public static async example_name() {
|
||||||
|
let conn:mariadb.PoolConnection|undefined;
|
||||||
|
try{
|
||||||
|
conn = await this.pool.getConnection();
|
||||||
|
await conn.beginTransaction();
|
||||||
|
|
||||||
|
//CODE HERE//
|
||||||
|
|
||||||
|
await conn.commit();
|
||||||
|
}
|
||||||
|
catch(error)
|
||||||
|
{
|
||||||
|
console.error("message_before_error: ", error);
|
||||||
|
if(conn) await conn.rollback();
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if(conn) conn.release();
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
private static async UnifiedArray<T1, T2>(auctionid: string[], lbin: number[]): Promise<{ x: string[], y: number[] }> {
|
||||||
|
return { x: [...auctionid], y: [...lbin] };
|
||||||
|
}
|
||||||
|
}
|
||||||
export {
|
export {
|
||||||
SqlSystem
|
SqlSystem
|
||||||
}
|
}
|
Loading…
Reference in a new issue