tedb
Version:
TypeScript Embedded Database
184 lines • 5.84 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const utils_1 = require("./utils");
const binary_type_tree_1 = require("binary-type-tree");
const tedb_utils_1 = require("tedb-utils");
class Index {
/**
* Constructor
* @param datastore - reference to Datastore
* @param options - Options for Index, `{fieldName: string}`
*/
constructor(datastore, options) {
this.avl = options.unique ? new binary_type_tree_1.AVLTree({ unique: true }) : new binary_type_tree_1.AVLTree({});
if (options.compareKeys) {
this.avl.compareKeys = options.compareKeys;
}
if (options.checkKeyEquality) {
this.avl.checkKeyEquality = options.checkKeyEquality;
}
this.isArray = false;
this.fieldName = options.fieldName;
this.datastore = datastore;
}
traverse(fn) {
return this.avl.tree.executeOnEveryNode(fn);
}
/**
* Insert document into Index
* @param doc - document to insert into Index
* @returns {Promise<any>}
*/
insert(doc) {
return new Promise((resolve, reject) => {
// TODO: need to make Error types
if (doc === undefined) {
return reject(new Error("No document ot insert index"));
}
if (!doc.hasOwnProperty("_id")) {
return reject(new Error("Document is missing _id field"));
}
if (typeof doc._id !== "string") {
return reject(new Error("_id field needs to be type `string`"));
}
const key = tedb_utils_1.getObjValue(doc, this.fieldName);
if (key !== undefined && key !== null) {
if (Object.prototype.toString.call(key) === "[object Array]" && !this.isArray) {
this.avl.compareKeys = utils_1.compareArray;
this.isArray = true;
}
}
else {
return reject(new Error("Key was not retrieved from document, or key was set to null. No null key indices"));
}
try {
this.avl.insert(key, [doc._id]);
}
catch (e) {
return reject(e);
}
resolve(doc);
});
}
/**
* Inserts many documents and updates the indices
* @param key
* @param indices
* @returns {Promise<null>}
*/
insertMany(key, indices) {
return new Promise((resolve, reject) => {
if (key !== undefined && key !== null) {
if (Object.prototype.toString.call(key) === "[object Array]" && !this.isArray) {
this.avl.compareKeys = utils_1.compareArray;
this.isArray = true;
}
}
else {
return reject(new Error("Key was not retrieved"));
}
try {
for (const item of indices) {
this.avl.insert(item.key, tedb_utils_1.rmArrDups(item.value));
}
}
catch (e) {
return reject(e);
}
resolve();
});
}
/**
* Update a key of a tree
* - keys are actually the value, in the tree the keys are values
* of the to be updated document while the value in the tree is the
* _id of the to be updated document.
* @param key
* @param newKey
* @returns {Promise<null>}
*/
updateKey(key, newKey) {
return new Promise((resolve, reject) => {
if (this.avl.tree.search(key).length === 0) {
return reject(new Error("This key does not exist"));
}
try {
this.avl.updateKey(key, newKey);
}
catch (e) {
return reject(e);
}
resolve();
});
}
/**
* Remove document from Index
* @param doc
* @returns {Promise<any>}
*/
remove(doc) {
return new Promise((resolve, reject) => {
if (doc === undefined) {
return reject(new Error("There is no document to remove"));
}
if (!doc.hasOwnProperty("_id")) {
return reject(new Error("There is no _id to reference this document"));
}
const key = tedb_utils_1.getObjValue(doc, this.fieldName);
try {
this.avl.Delete(key, [doc._id]);
}
catch (e) {
return reject(e);
}
resolve(doc);
});
}
/**
* Made to remove an indexed item just by the key value pair itself instead
* of the full object.
* @param key
* @param {string} value
* @returns {Promise<any>}
*/
removeByPair(key, value) {
return new Promise((resolve, reject) => {
try {
this.avl.Delete(key, [value]);
}
catch (e) {
return reject(e);
}
resolve();
});
}
/**
* Return the tree as JSON [{ key, value }, ...] pairs.
* @returns {Promise<string>}
*/
toJSON() {
return this.avl.tree.toJSON();
}
/**
* Search Index for key
* @param key
* @returns {Promise<SNDBSA>}
*/
search(key) {
return new Promise((resolve) => {
resolve(this.avl.tree.search(key));
});
}
/**
* Search Index within bounds
* @param range An IRange to search within bounds
* @returns {Promise<SNDBSA>}
*/
searchRange(range) {
return new Promise((resolve) => {
resolve(this.avl.tree.query(range));
});
}
}
exports.default = Index;
//# sourceMappingURL=indices.js.map