UNPKG

@harishreddym/baqend

Version:

Baqend JavaScript SDK

212 lines (176 loc) 5.77 kB
'use strict'; const Query = require('./Query'); const message = require('../message'); const Metadata = require('../util/Metadata'); const Entity = require('../binding/Entity'); const deprecated = require('../util/deprecated'); /** * A Query Node saves the state of the query being built * @alias query.Node<T> * @extends query.Query<T> */ class Node extends Query { /** * @param {EntityManager} entityManager The owning entity manager of this query * @param {Class<T>} resultClass The query result class */ constructor(entityManager, resultClass) { super(entityManager, resultClass); /** * The offset how many results should be skipped * @type number * @readonly */ this.firstResult = 0; /** * The limit how many objects should be returned * @type number * @readonly */ this.maxResults = -1; /** * The properties which should be used sort the result * @type Object<string,number> * @readonly */ this.order = {}; } /** * @inheritDoc */ eventStream() { throw new Error('Streaming features not available! Please use Streaming SDK!'); } /** * @inheritDoc */ resultStream() { throw new Error('Streaming features not available! Please use Streaming SDK!'); } /** * @inheritDoc */ resultList(options, doneCallback, failCallback) { if (options instanceof Function) { return this.resultList({}, options, doneCallback); } const type = this.resultClass ? this.entityManager.metamodel.entity(this.resultClass) : null; if (!type) { throw new Error('Only typed queries can be executed.'); } const query = this.serializeQuery(); const sort = this.serializeSort(); const uriSize = this.entityManager.connection.host.length + query.length + sort.length; let msg; if (uriSize > Query.MAX_URI_SIZE) { msg = new message.AdhocQueryPOST(type.name, this.firstResult, this.maxResults, sort) .entity(query, 'text'); } else { msg = new message.AdhocQuery(type.name, query, this.firstResult, this.maxResults, sort); } return this.entityManager.send(msg) .then(response => this.createResultList(response.entity, options)) .then(doneCallback, failCallback); } /** * @inheritDoc */ singleResult(options, doneCallback, failCallback) { if (options instanceof Function) { return this.singleResult({}, options, doneCallback); } const type = this.resultClass ? this.entityManager.metamodel.entity(this.resultClass) : null; if (!type) { throw new Error('Only typed queries can be executed.'); } const query = this.serializeQuery(); const sort = this.serializeSort(); const uriSize = this.entityManager.connection.host.length + query.length; let msg; if (uriSize > Query.MAX_URI_SIZE) { msg = new message.AdhocQueryPOST(type.name, query, this.firstResult, 1, sort) .entity(query, 'text'); } else { msg = new message.AdhocQuery(type.name, query, this.firstResult, 1, sort); } return this.entityManager.send(msg) .then(response => this.createResultList(response.entity, options)) .then(list => (list.length ? list[0] : null)) .then(doneCallback, failCallback); } /** * @inheritDoc */ count(doneCallback, failCallback) { const type = this.resultClass ? this.entityManager.metamodel.entity(this.resultClass) : null; if (!type) { throw new Error('Only typed queries can be executed.'); } const query = this.serializeQuery(); const uriSize = this.entityManager.connection.host.length + query.length; let msg; if (uriSize > Query.MAX_URI_SIZE) { msg = new message.AdhocCountQueryPOST(type.name) .entity(query, 'text'); } else { msg = new message.AdhocCountQuery(type.name, query); } return this.entityManager.send(msg) .then(response => response.entity.count) .then(doneCallback, failCallback); } serializeQuery() { return JSON.stringify(this, function argSerializer(k, v) { // this referees here to the objet which owns the key k const typedValue = this[k]; if (typedValue instanceof Date) { return { $date: v }; } else if (typedValue instanceof Entity) { return typedValue.id; } return v; }); } serializeSort() { return JSON.stringify(this.order); } createResultList(result, options) { if (result.length) { return Promise.all(result.map((el) => { if (el.id) { const entity = this.entityManager.getReference(this.resultClass, el.id); const metadata = Metadata.get(entity); metadata.setJson(el, { persisting: true }); return this.entityManager.resolveDepth(entity, options); } return this.entityManager.load(Object.keys(el)[0]); }, this)) .then(objects => objects.filter(val => !!val)); } return Promise.resolve([]); } addOrder(fieldOrSort, order) { if (order) { this.order[fieldOrSort] = order; } else { this.order = fieldOrSort; } return this; } addOffset(offset) { this.firstResult = offset; return this; } addLimit(limit) { this.maxResults = limit; return this; } } deprecated(Node.prototype, '_sort', 'order'); deprecated(Node.prototype, '_serializeQuery', 'serializeQuery'); deprecated(Node.prototype, '_serializeSort', 'serializeSort'); deprecated(Node.prototype, '_createResultList', 'createResultList'); deprecated(Node.prototype, '_addOrder', 'addOrder'); deprecated(Node.prototype, '_addOffset', 'addOffset'); deprecated(Node.prototype, '_addLimit', 'addLimit'); module.exports = Node;