UNPKG

evils.db

Version:

![Image](https://img.shields.io/npm/v/evils.db) ![Image](https://img.shields.io/npm/dt/evils.db) ![Image](https://nodei.co/npm/evils.db.png)

158 lines (114 loc) 4.9 kB
import { Database } from "./Database"; import { DatabaseError } from "./Error"; import type { SqliteDatabaseOptions } from "./Interface"; import { join, sep, extname } from 'path'; import { mkdirSync, existsSync } from 'fs'; import { get, set, unset } from 'lodash'; export class SqliteDatabase extends Database { private SQLQuery: any; private options: SqliteDatabaseOptions; public constructor(options: SqliteDatabaseOptions) { super(); let notSQLQuery: any = undefined; this.options = options; try { notSQLQuery = require("better-sqlite3"); } catch { throw new DatabaseError('The "better-sqlite3" module is not installed. Please install it with "npm install better-sqlite3"'); } let paths = this.options.filePath.split(sep); let resolvedFilePath = process.cwd(); for (const path of paths) { resolvedFilePath += `${sep}${path}`; if (!existsSync(resolvedFilePath) && extname(resolvedFilePath) !== '.db') mkdirSync(resolvedFilePath); else if (!existsSync(resolvedFilePath) && extname(resolvedFilePath) === '.db') { this.SQLQuery = notSQLQuery(resolvedFilePath); break; } else if (existsSync(resolvedFilePath) && extname(resolvedFilePath) === '.db') { this.SQLQuery = notSQLQuery(resolvedFilePath); break; } } this.SQLQuery.prepare(`CREATE TABLE IF NOT EXISTS ${options.table} (key TEXT, value TEXT)`).run(); } public getAll() { return this.cache; } public get(key: string) { return get(this.cache, key); } public set(key: string, value: any) { let dotKey = key.split('.')[0]; let data = get(this.cache, dotKey); set(this.cache, key, value); if(data) { if(key.includes('.')) { let data = get(this.cache, dotKey); this.SQLQuery.prepare(`UPDATE ${this.options.table} SET value = ? WHERE key = ?`).run(JSON.stringify(data), dotKey); } else { this.SQLQuery.prepare(`UPDATE ${this.options.table} SET value = ? WHERE key = ?`).run(JSON.stringify(value), key); } } else { if(key.includes('.')) { let data = get(this.cache, dotKey); this.SQLQuery.prepare(`INSERT INTO ${this.options.table} (key, value) VALUES (?, ?)`).run(dotKey, JSON.stringify(data)); } else { this.SQLQuery.prepare(`INSERT INTO ${this.options.table} (key, value) VALUES (?, ?)`).run(key, JSON.stringify(value)); } } return value; } public remove(key: string) { unset(this.cache, key); this.SQLQuery.prepare(`DELETE FROM ${this.options.table} WHERE key = ?`).run(key); } public add(key: string, value: number) { let data = this.get(key); if (typeof data !== 'number') throw new DatabaseError(`Cannot add "${value}" to "${key}" because "${key}" is not a number.`); data += value; this.set(key, data); return data; } public push(key: string, value: any) { let data = this.get(key); if (!Array.isArray(data)) throw new DatabaseError(`Cannot push "${value}" to "${key}" because "${key}" is not an array.`); data.push(value); this.set(key, data); return data; } public pull(key: string, value: any) { let data = this.get(key); if (!Array.isArray(data)) throw new DatabaseError(`Cannot pull "${value}" from "${key}" because "${key}" is not an array.`); data = data.filter((v: any) => v !== value); this.set(key, data); return data; } public clear() { this.cache = {}; this.SQLQuery.prepare(`DELETE FROM ${this.options.table}`).run(); } public close() { this.SQLQuery.close(); } public async init() { let data = this.SQLQuery.prepare(`SELECT * FROM ${this.options.table}`).all(); for (const row of data) { this.cache[row.key] = JSON.parse(row.value); } } public async save() { for (const key in this.cache) { let data = this.cache[key]; if (typeof data === 'object') data = JSON.stringify(data); this.SQLQuery.prepare(`UPDATE ${this.options.table} SET value = ? WHERE key = ?`).run(data, key); } } public async destroy() { this.SQLQuery.prepare(`DROP TABLE ${this.options.table}`).run(); } public async delete() { this.SQLQuery.close(); this.SQLQuery = undefined; } }