143 lines
6.4 KiB
JavaScript
143 lines
6.4 KiB
JavaScript
/*
|
|
! /database/index.js
|
|
? The central database worker factory for multi-project management.
|
|
*/
|
|
|
|
// % imports
|
|
/*
|
|
= The MariaDB-"Commands"-Library:
|
|
|
|
^ Create a new instance:
|
|
?? Create the command instance: "const dbName = new Commands(name, db, protocol, address);"
|
|
? Available protocols are "read", "write", "delete" and "backup".
|
|
? Address and protocol can be left empty for the default values. (selfdev-mariadb, read)
|
|
? Example: "const dbName = new Commands('reader', 'myDatabase');"
|
|
|
|
^ Connection Usage:
|
|
?? Add a new connection: "await dbName.connect();"
|
|
?? Remove a connection: "await dbName.disconnect();"
|
|
?? Check the status of a connection: "await dbName.status();"
|
|
|
|
^ Basic Query Usage:
|
|
?? Execute a basic sql query: "await dbName.query(query, params = []);"
|
|
? Example: "await dbName.query('SELECT * FROM langs');"
|
|
? Queries can be everything that is possible with mariadb.
|
|
? Returns an array of objects (for SELECT) or a result metadata object (for INSERT/UPDATE/DELETE).
|
|
|
|
^ Table Management Usage:
|
|
?? Execute a table creation: "await dbName.createTable(table, columns = 'id INT AUTO_INCREMENT PRIMARY KEY');"
|
|
? Example: "await dbName.createTable('projects', 'id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(255)');"
|
|
? Automatically applies the ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_general_ci.
|
|
? Returns an object containing metadata like { affectedRows: 0, warningCount: 0 } or execution result.
|
|
|
|
?? Execute a table alteration: "await dbName.alterTable(table, modificationClause);"
|
|
? Example: "await dbName.alterTable('projects', 'ADD COLUMN created_at TIMESTAMP');"
|
|
? Returns an object containing metadata like { affectedRows: 0, warningCount: 0 } or execution result.
|
|
|
|
^ Helper Query Command Usage:
|
|
?? Execute an insert query: "await dbName.insert(table, data);"
|
|
? Example: "await dbName.insert('users', { name: 'Dummy', role: 'admin' });"
|
|
? Returns an object containing metadata like "{ affectedRows: 1, insertId: 12n }" or null if data is empty.
|
|
|
|
?? Execute an update query: "await dbName.update(table, data, where, whereParams = []);"
|
|
? Example: "await dbName.update('users', { role: 'editor' }, 'id = ?', [1]);"
|
|
? Returns an object containing metadata like { affectedRows: 1, warningCount: 0 } or null if data is empty.
|
|
|
|
?? Execute a selection query: "await dbName.select(table, columns = '*', where = '', params = []);"
|
|
? Example: "await dbName.select('users', ['id', 'name'], 'role = ?', ['admin']);"
|
|
? Returns an array of matching row objects, e.g. [{ id: 1, name: 'Dummy' }].
|
|
|
|
?? Execute a deletion query: "await dbName.delete(table, where, params = []);"
|
|
? Example: "await dbName.delete('users', 'id = ?', [1]);"
|
|
? Returns an object containing metadata like { affectedRows: 1 }.
|
|
*/
|
|
import Commands from "./commands.js";
|
|
|
|
// % internal registry for all dynamic project database instances
|
|
const registry = new Map();
|
|
|
|
/*
|
|
= The Database-Worker-Factory:
|
|
|
|
^ Get or create a project instance:
|
|
?? Usage: "const db = dbWorker.get(projectName, address);"
|
|
? Example: "const db = dbWorker.get('myProject', 'db_host_address');"
|
|
? Returns an object containing the command instances (e.g. { read, write, delete, backup }).
|
|
|
|
^ Connect all protocols for a certain project:
|
|
?? Usage: "await dbWorker.connectProject(projectName);"
|
|
? Example: "await dbWorker.connectProject('myProject');"
|
|
? Returns nothing.
|
|
|
|
^ Disconnect all protocols for a certain project:
|
|
?? Usage: "await dbWorker.disconnectProject(projectName);"
|
|
? Example: "await dbWorker.disconnectProject('myProject');"
|
|
? Returns nothing.
|
|
|
|
^ Query Usage Example:
|
|
?? const db = dbWorker.get('myProject');
|
|
?? await db.read.connect(); // optional, if "connectProject" was not called
|
|
?? const users = await db.read.select('users', '*', 'active = ?', [1]);
|
|
?? await db.write.insert('users', { name: 'Dummy' });
|
|
*/
|
|
export default {
|
|
// $ get or initialize database for a specific project
|
|
get(projectName, address) {
|
|
if (!projectName) {
|
|
throw new Error("A project name is required to get a database instance.");
|
|
}
|
|
|
|
// ~ return an existing project instance if already created
|
|
if (registry.has(projectName)) {
|
|
console.log(`[Database] Returning existing instance for project: "${projectName}"`);
|
|
return registry.get(projectName);
|
|
}
|
|
|
|
// $ debug-output
|
|
console.log(`[Database] Initializing new instances (read, write, delete, backup) for: "${projectName}"`);
|
|
|
|
// ~ create new instances (r,w,d,b) for the given project database
|
|
const instances = {
|
|
read: new Commands(`${projectName}_reader`, projectName, 'read', address || null),
|
|
write: new Commands(`${projectName}_writer`, projectName, 'write', address || null),
|
|
delete: new Commands(`${projectName}_deleter`, projectName, 'delete', address || null),
|
|
backup: new Commands(`${projectName}_backuper`, projectName, 'backup', address || null)
|
|
};
|
|
|
|
// ~ store the instance in the registry
|
|
registry.set(projectName, instances);
|
|
|
|
// ~ return result
|
|
return instances;
|
|
},
|
|
|
|
// $ helper to connect all instances of a specific project at once
|
|
async connectProject(projectName) {
|
|
console.log(`[Database] Connecting all instances for project: "${projectName}"...`);
|
|
const db = this.get(projectName);
|
|
await Promise.all([
|
|
db.read.connect(),
|
|
db.write.connect(),
|
|
db.delete.connect(),
|
|
db.backup.connect()
|
|
]);
|
|
},
|
|
|
|
// $ helper to disconnect all instances of a specific project
|
|
async disconnectProject(projectName) {
|
|
console.log(`[Database] Disconnecting all instances for project: "${projectName}"...`);
|
|
if (registry.has(projectName)) {
|
|
const db = registry.get(projectName);
|
|
await Promise.all([
|
|
db.read.disconnect(),
|
|
db.write.disconnect(),
|
|
db.delete.disconnect(),
|
|
db.backup.disconnect()
|
|
]);
|
|
registry.delete(projectName);
|
|
console.log(`[Database] Successfully disconnected and removed from registry: "${projectName}"`);
|
|
} else {
|
|
console.log(`[Database] Tried to disconnect project "${projectName}", but it was not found in registry.`);
|
|
}
|
|
}
|
|
}; |