UNPKG

upgrade.db

Version:

Banco de dados simples e leve em JSON para bots Node.js com suporte a tabelas e métodos modernos.

221 lines (185 loc) 5.96 kB
const fs = require('fs'); const path = require('path'); class Table { constructor(name, dir = './db') { this.name = name; this.dir = dir; this.filePath = path.join(this.dir, `${name}.json`); this.data = {}; if (!fs.existsSync(this.dir)) fs.mkdirSync(this.dir, { recursive: true }); if (fs.existsSync(this.filePath)) { try { this.data = JSON.parse(fs.readFileSync(this.filePath, 'utf8')); } catch { this.data = {}; } } else { this.save(); } } save() { try { fs.writeFileSync(this.filePath, JSON.stringify(this.data, null, 2)); } catch (err) { console.error(`Erro ao salvar o arquivo ${this.filePath}:`, err); } } set(key, value) { const keys = key.split('.'); let obj = this.data; for (let i = 0; i < keys.length - 1; i++) { if (!obj[keys[i]]) obj[keys[i]] = {}; obj = obj[keys[i]]; } obj[keys[keys.length - 1]] = value; this.save(); return true; } get(key) { const keys = key.split('.'); let obj = this.data; for (const k of keys) { if (!obj || !(k in obj)) return undefined; obj = obj[k]; } return obj; } delete(key) { const keys = key.split('.'); let obj = this.data; for (let i = 0; i < keys.length - 1; i++) { if (!obj[keys[i]]) return false; obj = obj[keys[i]]; } const deleted = delete obj[keys[keys.length - 1]]; if (deleted) this.save(); return deleted; } has(key) { const val = this.get(key); return val !== undefined && val !== null; } push(key, value) { const current = this.get(key) || []; if (!Array.isArray(current)) throw new Error(`"${key}" não é um array`); if (!current.includes(value)) { current.push(value); this.set(key, current); } return true; } add(key, number) { if (typeof number !== 'number') throw new TypeError('Valor precisa ser número'); let current = this.get(key) || 0; if (typeof current !== 'number') throw new Error(`"${key}" não é um número`); this.set(key, current + number); return true; } subtract(key, number) { if (typeof number !== 'number') throw new TypeError('Valor precisa ser número'); let current = this.get(key) || 0; if (typeof current !== 'number') throw new Error(`"${key}" não é um número`); this.set(key, current - number); return true; } includes(key, value) { const arr = this.get(key); if (!Array.isArray(arr)) return false; return arr.includes(value); } filter(callback) { const results = {}; for (const key in this.data) { if (!Object.prototype.hasOwnProperty.call(this.data, key)) continue; if (callback(this.data[key], key)) { results[key] = this.data[key]; } } return results; } math(key, operator, value) { let current = this.get(key); if (typeof current !== 'number') current = 0; if (typeof value !== 'number') throw new TypeError('Valor precisa ser número'); switch (operator) { case '+': current += value; break; case '-': current -= value; break; case '*': current *= value; break; case '/': if (value === 0) throw new Error('Divisão por zero'); current /= value; break; default: throw new Error(`Operador inválido: ${operator}`); } this.set(key, current); return current; } // Novos métodos adicionados e seguros — só funcionam se métodos base existem max(key, value, maxValue) { if (typeof value !== 'number') throw new TypeError('Valor precisa ser número'); if (typeof maxValue !== 'number') throw new TypeError('maxValue precisa ser número'); let current = typeof this.get === 'function' ? this.get(key) : 0; if (typeof current !== 'number') current = 0; let newValue = current + value; if (newValue > maxValue) newValue = maxValue; if (typeof this.set === 'function') this.set(key, newValue); return newValue; } min(key, value, minValue) { if (typeof value !== 'number') throw new TypeError('Valor precisa ser número'); if (typeof minValue !== 'number') throw new TypeError('minValue precisa ser número'); let current = typeof this.get === 'function' ? this.get(key) : 0; if (typeof current !== 'number') current = 0; let newValue = current - value; if (newValue < minValue) newValue = minValue; if (typeof this.set === 'function') this.set(key, newValue); return newValue; } reset(key, defaultValue = null) { if (defaultValue === null) { if (typeof this.delete === 'function') return this.delete(key); } else { if (typeof this.set === 'function') return this.set(key, defaultValue); } return false; } clamp(key, minValue, maxValue) { if (typeof minValue !== 'number' || typeof maxValue !== 'number') { throw new TypeError('minValue e maxValue precisam ser números'); } if (minValue > maxValue) { throw new Error('minValue não pode ser maior que maxValue'); } let current = typeof this.get === 'function' ? this.get(key) : minValue; if (typeof current !== 'number') current = minValue; if (current < minValue) current = minValue; if (current > maxValue) current = maxValue; if (typeof this.set === 'function') this.set(key, current); return current; } incrementBy(key, value = 1) { if (typeof this.add === 'function') return this.add(key, value); return false; } decrementBy(key, value = 1) { if (typeof this.subtract === 'function') return this.subtract(key, value); return false; } } class UpgradeDB { constructor(dir = './db') { this.dir = dir; if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true }); } table(name) { return new Table(name, this.dir); } } module.exports = UpgradeDB;