json-file-database
Version:
Lightweight Database on NodeJS by JSON Files
111 lines (110 loc) • 3.37 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Collection = void 0;
/**
* A collection is like an array.
* You can insert, update, delete and find elements in it.
*
* When you apply methods affecting the collection,
* it will start a debounced saver.
*
* Using `Array.from(collection)`, `[...collection]`,
* or `for (const element of collection)` is also good practice.
*
* @template E the type of elements.
* @template I the type of id.
*/
class Collection {
constructor(options) {
this.comparator = options.comparator;
this.save = options.save;
this.name = options.name;
this.primaryKey = options.primaryKey;
this.elements = options.elements.sort(this.comparator);
}
startSaving() {
this.save(this.name, this.elements);
}
findAll(cond) {
const result = [];
for (const el of this) {
if (cond(el))
result.push(el);
}
return result;
}
removeAll(cond) {
let length = 0;
for (const el of this) {
if (cond(el)) {
length++;
this.remove(el);
}
}
return length;
}
/**
* @returns the index to insert or get, and whether it has found the element.
*/
searchIndex(el) {
if (!Reflect.has(el, this.primaryKey))
throw new TypeError('cannot find the index without the primary key');
let left = 0;
let right = this.elements.length - 1;
while (left <= right) {
const mid = Math.floor((left + right) / 2);
const cmp = this.comparator(el, this.elements[mid]);
if (cmp < 0)
right = mid - 1;
else if (cmp > 0)
left = mid + 1;
else
return [mid, true];
}
return [left, false];
}
*[Symbol.iterator]() {
for (const el of this.elements)
yield el;
}
insert(el) {
const [index, found] = this.searchIndex(el);
if (found)
return false;
this.elements.splice(index, 0, el);
this.startSaving();
return true;
}
update(el) {
if (!Reflect.has(el, this.primaryKey))
throw new TypeError('cannot update an element without the primary key');
const [index, found] = this.searchIndex(el);
if (!found)
return false;
// We need to change the found result.
Object.assign(this.elements[index], el);
this.startSaving();
return true;
}
remove(el) {
// Removing elements won't make the array unsorted.
const [index, found] = this.searchIndex(el);
if (!found)
return false;
this.elements.splice(index, 1);
this.startSaving();
return true;
}
has(el) {
if (typeof el === 'function')
return this.elements.find(el) !== undefined;
return this.find(el) !== undefined;
}
find(el) {
const [index, found] = this.searchIndex(el);
if (!found)
return undefined;
return this.elements[index];
}
}
exports.Collection = Collection;