warehouse
Version:
Simple JSON-based database
308 lines • 8.36 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const bluebird_1 = __importDefault(require("bluebird"));
const util_1 = require("./util");
class Query {
/**
* Query constructor.
*
* @param {Array} data
*/
constructor(data) {
this.data = data;
this.length = data.length;
}
/**
* Returns the number of elements.
*
* @return Number
*/
count() {
return this.length;
}
/**
* Iterates over all documents.
*
* @param {Function} iterator
*/
forEach(iterator) {
const { data, length } = this;
for (let i = 0; i < length; i++) {
iterator(data[i], i);
}
}
/**
* Returns an array containing all documents.
*
* @return {Array}
*/
toArray() {
return this.data;
}
/**
* Returns the document at the specified index. `num` can be a positive or
* negative number.
*
* @param {Number} i
* @return {Document|Object}
*/
eq(i) {
const index = i < 0 ? this.length + i : i;
return this.data[index];
}
/**
* Returns the first document.
*
* @return {Document|Object}
*/
first() {
return this.eq(0);
}
/**
* Returns the last document.
*
* @return {Document|Object}
*/
last() {
return this.eq(-1);
}
/**
* Returns the specified range of documents.
*
* @param {Number} start
* @param {Number} [end]
* @return {Query}
*/
slice(start, end) {
return Reflect.construct(this.constructor, [this.data.slice(start, end)]);
}
/**
* Limits the number of documents returned.
*
* @param {Number} i
* @return {Query}
*/
limit(i) {
return this.slice(0, i);
}
/**
* Specifies the number of items to skip.
*
* @param {Number} i
* @return {Query}
*/
skip(i) {
return this.slice(i);
}
/**
* Returns documents in a reversed order.
*
* @return {Query}
*/
reverse() {
return Reflect.construct(this.constructor, [this.data.slice().reverse()]);
}
/**
* Returns documents in random order.
*
* @return {Query}
*/
shuffle() {
return Reflect.construct(this.constructor, [(0, util_1.shuffle)(this.data)]);
}
find(query, options = {}) {
const filter = this._schema._execQuery(query);
const { data, length } = this;
const { lean = false } = options;
let { limit = length, skip } = options;
const arr = [];
for (let i = 0; limit && i < length; i++) {
const item = data[i];
if (filter(item)) {
if (skip) {
skip--;
}
else {
arr.push(lean ? item.toObject() : item);
limit--;
}
}
}
return lean ? arr : Reflect.construct(this.constructor, [arr]);
}
findOne(query, options = {}) {
const _options = Object.assign(options, { limit: 1 });
const result = this.find(query, _options);
return Array.isArray(result) ? result[0] : result.data[0];
}
sort(orderby, order) {
const sort = (0, util_1.parseArgs)(orderby, order);
const fn = this._schema._execSort(sort);
return Reflect.construct(this.constructor, [this.data.slice().sort(fn)]);
}
/**
* Creates an array of values by iterating each element in the collection.
*
* @param {Function} iterator
* @return {Array}
*/
map(iterator) {
const { data, length } = this;
const result = new Array(length);
for (let i = 0; i < length; i++) {
result[i] = iterator(data[i], i);
}
return result;
}
/**
* Reduces a collection to a value which is the accumulated result of iterating
* each element in the collection.
*
* @param {Function} iterator
* @param {*} [initial] By default, the initial value is the first document.
* @return {*}
*/
reduce(iterator, initial) {
const { data, length } = this;
let result, i;
if (initial === undefined) {
i = 1;
result = data[0];
}
else {
i = 0;
result = initial;
}
for (; i < length; i++) {
result = iterator(result, data[i], i);
}
return result;
}
/**
* Reduces a collection to a value which is the accumulated result of iterating
* each element in the collection from right to left.
*
* @param {Function} iterator
* @param {*} [initial] By default, the initial value is the last document.
* @return {*}
*/
reduceRight(iterator, initial) {
const { data, length } = this;
let result, i;
if (initial === undefined) {
i = length - 2;
result = data[length - 1];
}
else {
i = length - 1;
result = initial;
}
for (; i >= 0; i--) {
result = iterator(result, data[i], i);
}
return result;
}
/**
* Creates a new array with all documents that pass the test implemented by the
* provided function.
*
* @param {Function} iterator
* @return {Query}
*/
filter(iterator) {
const { data, length } = this;
const arr = [];
for (let i = 0; i < length; i++) {
const item = data[i];
if (iterator(item, i))
arr.push(item);
}
return Reflect.construct(this.constructor, [arr]);
}
/**
* Tests whether all documents pass the test implemented by the provided
* function.
*
* @param {Function} iterator
* @return {Boolean}
*/
every(iterator) {
const { data, length } = this;
for (let i = 0; i < length; i++) {
if (!iterator(data[i], i))
return false;
}
return true;
}
/**
* Tests whether some documents pass the test implemented by the provided
* function.
*
* @param {Function} iterator
* @return {Boolean}
*/
some(iterator) {
const { data, length } = this;
for (let i = 0; i < length; i++) {
if (iterator(data[i], i))
return true;
}
return false;
}
/**
* Update all documents.
*
* @param {Object} data
* @param {Function} [callback]
* @return {BluebirdPromise}
*/
update(data, callback) {
const model = this._model;
const stack = this._schema._parseUpdate(data);
return bluebird_1.default.mapSeries(this.data, item => model._updateWithStack(item._id, stack)).asCallback(callback);
}
/**
* Replace all documents.
*
* @param {Object} data
* @param {Function} [callback]
* @return {BluebirdPromise}
*/
replace(data, callback) {
const model = this._model;
return bluebird_1.default.map(this.data, item => model.replaceById(item._id, data)).asCallback(callback);
}
/**
* Remove all documents.
*
* @param {Function} [callback]
* @return {BluebirdPromise}
*/
remove(callback) {
const model = this._model;
return bluebird_1.default.mapSeries(this.data, item => model.removeById(item._id)).asCallback(callback);
}
/**
* Populates document references.
*
* @param {String|Object} expr
* @return {Query}
*/
populate(expr) {
const stack = this._schema._parsePopulate(expr);
const { data, length } = this;
const model = this._model;
for (let i = 0; i < length; i++) {
data[i] = model._populate(data[i], stack);
}
return this;
}
}
Query.prototype.size = Query.prototype.count;
Query.prototype.each = Query.prototype.forEach;
Query.prototype.random = Query.prototype.shuffle;
exports.default = Query;
//# sourceMappingURL=query.js.map