import * as fs from "fs"; if (!fs.existsSync("./databases/")) { fs.mkdirSync("./databases"); } import * as LUR from "levelup"; import * as LDR from "leveldown"; const LevelUp = LUR as any; const LevelDown = LDR as any; import type { LevelUp as LU } from "levelup"; import type { LevelDown as LD } from "leveldown"; import { AbstractIterator } from "abstract-leveldown"; export type LevelDB = LU>; export type DBSet = { data: LevelDB; collection: LevelDB }; const databases = new Map(); export function resNull(err): null { if (!err.notFound) throw err; return null; } async function rmRecursice(path: string) { if (fs.existsSync(path)) { await Promise.all( fs.readdirSync(path).map(async (file) => { var curPath = path + "/" + file; if (fs.lstatSync(curPath).isDirectory()) { // recurse await rmRecursice(curPath); } else { // delete file await fs.promises.unlink(curPath); } }) ); await fs.promises.rmdir(path); } } export async function deleteLevelDB(name: string) { if (!name || name === "") return; let db = databases.get(name); if (db) { if (db.data.isOpen()) await db.data.close(); if (db.collection.isOpen()) await db.collection.close(); } //TODO make sure, that name doesn't make it possible to delete all databases :) await rmRecursice("./databases/" + name); } export default function getLevelDB(name: string): DBSet { let db = databases.get(name); if (!db) { if (!fs.existsSync("./databases/" + name)) { fs.mkdirSync("./databases/" + name); } } db = { data: db && db.data.isOpen() ? db.data : LevelUp(LevelDown("./databases/" + name + "/data")), collection: db && db.collection.isOpen() ? db.collection : LevelUp(LevelDown("./databases/" + name + "/collection")), }; databases.set(name, db); return db; }