suma-db
Version:
A Brazilian database that supports JSON(JavaScript Object Notation)
218 lines (213 loc) • 9.77 kB
JavaScript
(function () {
"use strict";
const collection = require("collections")
module.exports = function (info) {
const manager = {};
manager.key = info.key;
manager.value = info.value;
if(!manager.key) throw new RangeError('A key was expected to access the database, but that\'s not what happened.')
if(manager.key.key) manager.key = manager.key.key;
if(typeof manager.key !== 'string') throw new RangeError('Invalid key')
manager.write = function (val = manager.value, event = true) {
if (val === undefined) throw new RangeError('Expected a value to write');
const forbiddenValue = ['symbol', 'function', 'bigint'].find(a => a == typeof val)
if (forbiddenValue === 'symbol') throw new Error('do not write a symbol to the database')
if (forbiddenValue) throw new Error(`${val} is a forbidden value, because the value is a ${forbiddenValue}`)
let database = info.class.read();
database = info.class.SumaDBNotation(this.key, database, val, info.class.prefix)['data']
info.class.setValue(database);
if (event) info.class.emit('write', {
value: val,
keys: this.key.split(info.class.prefix)
})
}
manager.val = function () {
let database = info.class.read();
database = info.class.preparer(this.key, database, info.class.prefix)
return database
}
manager.pathAll = function () {
return info.class.prepare(this.key, info.class.prefix, this.val())
}
manager.push = function (...args) {
if (!Array.isArray(this.val())) {
this.write([...args], false)
info.class.emit('push', {
value: args,
replaced: true
})
} else {
this.write([...this.val().concat(...args)], false)
info.class.emit('push', {
value: args,
replaced: false,
all: [...this.val().concat(...args)]
})
}
}
manager.exist = function (reverse = false) {
reverse = reverse?.reverse ? reverse.reverse : reverse
if (reverse)
return !this.val()
return !!this.val()
}
manager.delete = function (event = true) {
let db = info.class.read(), dbReference = db, keys = this.key.split(info.class.prefix)
for (false; keys.length > 1; false) {
const _KeyShift = keys.shift()
dbReference = dbReference[_KeyShift] = dbReference[_KeyShift] || {}
}
delete dbReference[keys]
info.class.setValue(db)
if (event) info.class.emit('delete', {
db
})
}
manager.destroy = function () {
const pathOne = this.key.split(info.class.prefix)[0]
const db = info.class.read()
delete db[pathOne]
info.class.setValue(db || {})
info.class.emit('destroy', { db })
}
manager.math = function (number, operator = "+", toNegative = true, event = true) {
if (typeof number === 'number' ?? typeof number === 'string')
number = {
number: Number(number),
operator,
toNegative,
}
if (isNaN(number.number)) throw new RangeError('The value of the math operation must be a number.')
let result = number.number;
let dataVal;
number.toNegative = number.toNegative ?? true;
switch (number.operator) {
case '+':
dataVal = Number(this.val())
if (isNaN(dataVal)) dataVal = 0
result += dataVal
this.write(result, false)
break;
case "-":
dataVal = Number(this.val())
if (isNaN(dataVal)) dataVal = 0
result = dataVal - result
if (result < 0 && !number.toNegative) result = dataVal
this.write(result, false)
break;
case "*":
dataVal = Number(this.val())
if (isNaN(dataVal)) dataVal = 0
result *= dataVal
this.write(result, false)
break;
case "/":
dataVal = Number(this.val())
if (isNaN(dataVal)) dataVal = 0
result /= dataVal
if (result < 0 && !number.toNegative) result = dataVal
this.write(result)
break;
case "**":
dataVal = Number(this.val())
if (isNaN(dataVal)) dataVal = 0
result **= dataVal
this.write(result, false)
break;
case "%":
dataVal = Number(this.val())
if (isNaN(dataVal)) dataVal = 0
result %= dataVal
if (result > 0 && !number.toNegative) result = dataVal
this.write(result, false)
break;
default:
throw new RangeError('Invalid operator')
}
info.class.emit("math", {
number,
result,
beforeResult: dataVal
})
}
manager.writeIfNull = function (value) {
if (!this.exist()) this.write(value)
}
manager.writeIfNotNull = function (value) {
if (this.exist()) this.write(value)
}
manager.writeIfNumber = function (value) {
if (typeof this.val() === 'number') this.write(value)
}
manager.writeIfNotNumber = function (value) {
if (typeof this.val() !== 'number') this.write(value)
}
manager.writeIfObject = function (value) {
if (typeof this.val() === 'object') this.write(value)
}
manager.writeIfNotObject = function (value) {
if (typeof this.val() !== 'object') this.write(value)
}
manager.type = function () {
return typeof this.val()
}
manager.add = function(add=1) {
if(!add && add !== 0) throw new RangeError("No value to add")
if(add.add || add.value) add = add.add || add.value
let val = Number(this.val())
if(isNaN(val)) val = 0
if(isNaN(add)) throw new RangeError('the add number is not a number')
if(!isFinite(add)) throw new RangeError('You can\'t add infinity in db')
val += Number(add)
info.class.emit("add", val);
this.write(val)
}
manager.sub = function(sub) {
if(!sub && sub !== 0) throw new RangeError("No value to sub")
if(sub.sub || sub.value) sub = sub.sub || sub.value
let val = Number(this.val())
if(isNaN(val)) val = 0
if(isNaN(sub)) throw new RangeError('the add number is not a number')
if(!isFinite(sub)) throw new RangeError('You can\'t add infinity in db')
val -= Number(sub)
info.class.emit("sub", val);
this.write(val)
}
manager.writeIf = function(value, expression=() => true) {
if(typeof value === 'string') value = {
value,
expression
}
if(typeof value !== 'object') throw new RangeError("The value to write if a object or string!")
if(typeof value.expression !== 'function') throw new RangeError("The expression is not a callback")
if(value.expression.call(this, info.class)) this.write(value)
}
manager.deleteIf = function(expression=() => true) {
if(typeof expression !== 'function') throw new RangeError("The expression is not a callback")
if(expression.call(this, info.class)) this.delete()
}
manager.destroyIf = function(expression=() => true) {
if(typeof expression !== 'function') throw new RangeError("The expression is not a callback")
if(expression.call(this, info.class)) this.destroy()
}
manager.addIf = function(value, expression=() => true) {
if(typeof value !== 'object') value = {
value,
expression
}
if(typeof value !== 'object') throw new RangeError("The value to add if a object or string!")
if(typeof value.expression !== 'function') throw new RangeError("The expression is not a callback")
if(value.expression.call(this, info.class)) this.add(value)
}
manager.subIf = function(value, expression) {
if(typeof value !== 'object') value = {
value,
expression
}
if(typeof value !== 'object') throw new RangeError("The value to sub if a object or string!")
if(typeof value.expression !== 'function') throw new RangeError("The expression is not a callback")
if(value.expression.call(this, info.class)) this.sub(value)
}
return manager
}
}).call(this);