import { Rules } from "./rules"; import Settings from "../settings"; import getLevelDB, { LevelDB, deleteLevelDB } from "../storage"; import DocumentLock from "./lock"; import Query from "./query"; export class DatabaseManager { static databases = new Map(); static async init() { let databases = await Settings.getDatabases(); databases.forEach(dbconfig => { let db = new Database(dbconfig.name, dbconfig.accesskey, dbconfig.rules, dbconfig.publickey, dbconfig.rootkey); this.databases.set(dbconfig.name, db); }) } static async addDatabase(name: string) { if (this.databases.has(name)) throw new Error("Database already exists!"); await Settings.addDatabase(name); let database = new Database(name); this.databases.set(name, database); return database; } static getDatabase(name: string) { return this.databases.get(name); } static async deleteDatabase(name: string) { let db = this.databases.get(name) if (db) { await Settings.deleteDatabase(name); await db.stop(); await deleteLevelDB(db.name) } } } export type ChangeTypes = "added" | "modified" | "deleted"; export type Change = { data: any; document: string; type: ChangeTypes; sender: string; } export class Database { private level = getLevelDB(this.name); get data() { return this.level.data; } get collections() { return this.level.collection; } public rules: Rules; public locks = new DocumentLock() public collectionLocks = new DocumentLock() public changes = new Map void>>(); toJSON() { return { name: this.name, accesskey: this.accesskey, publickey: this.publickey, rules: this.rules } } constructor(public name: string, public accesskey?: string, rawRules?: string, public publickey?: string, public rootkey?: string) { if (rawRules) this.rules = new Rules(rawRules); } async setRules(rawRules: string) { let rules = new Rules(rawRules); await Settings.setDatabaseRules(this.name, rawRules); this.rules = rules; } async setAccessKey(key: string) { await Settings.setDatabaseAccessKey(this.name, key); this.accesskey = key; } async setRootKey(key: string) { await Settings.setDatabaseRootKey(this.name, key); this.rootkey = key; } async setPublicKey(key: string) { await Settings.setDatabasePublicKey(this.name, key); this.publickey = key; } getQuery(path: string[], sender: string) { return new Query(this, path, sender); } async stop() { await this.data.close(); } }