'use strict';
const Filter = require('./Filter');
const Condition = require('./Condition');
const Operator = require('./Operator');
const Query = require('./Query');
const deprecated = require('../util/deprecated');
const varargs = Query.varargs;
/**
* The Query Builder allows creating filtered and combined queries
* @alias query.Builder<T>
* @extends query.Query<T>
* @implements query.Condition<T>
*/
class Builder extends Query {
/**
* @param {EntityManager} entityManager The owning entity manager of this query
* @param {Class<T>} resultClass The query result class
* @constructor
*/
/**
* Joins the conditions by an logical AND
* @param {...(query.Query<T>|Array<query.Query<T>>)} args The query nodes to join
* @return {query.Operator<T>} Returns a new query which joins the given queries by a logical AND
*/
and(/* ...args */) {
return this.addOperator('$and', varargs(0, arguments));
}
/**
* Joins the conditions by an logical OR
* @param {...(query.Query<T>|Array<query.Query<T>>)} args The query nodes to join
* @return {query.Operator<T>} Returns a new query which joins the given queries by a logical OR
*/
or(/* ...args */) {
return this.addOperator('$or', varargs(0, arguments));
}
/**
* Joins the conditions by an logical NOR
* @param {...(query.Query<T>|Array<query.Query<T>>)} args The query nodes to join
* @return {query.Operator<T>} Returns a new query which joins the given queries by a logical NOR
*/
nor(/* ...args */) {
return this.addOperator('$nor', varargs(0, arguments));
}
/**
* @inheritDoc
*/
eventStream(options, onNext, onError, onComplete) {
return this.where({}).eventStream(options, onNext, onError, onComplete);
}
/**
* @inheritDoc
*/
resultStream(options, onNext, onError, onComplete) {
return this.where({}).resultStream(options, onNext, onError, onComplete);
}
/**
* @inheritDoc
*/
resultList(options, doneCallback, failCallback) {
return this.where({}).resultList(options, doneCallback, failCallback);
}
/**
* @inheritDoc
*/
singleResult(options, doneCallback, failCallback) {
return this.where({}).singleResult(options, doneCallback, failCallback);
}
/**
* @inheritDoc
*/
count(doneCallback, failCallback) {
return this.where({}).count(doneCallback, failCallback);
}
addOperator(operator, args) {
if (args.length < 2) {
throw new Error('Only two or more queries can be joined with an ' + operator + ' operator.');
}
args.forEach((arg, index) => {
if (!(arg instanceof Query)) {
throw new Error('Argument at index ' + index + ' is not a query.');
}
});
return new Operator(this.entityManager, this.resultClass, operator, args);
}
addOrder(fieldOrSort, order) {
return new Filter(this.entityManager, this.resultClass).addOrder(fieldOrSort, order);
}
addFilter(field, filter, value) {
return new Filter(this.entityManager, this.resultClass).addFilter(field, filter, value);
}
addOffset(offset) {
return new Filter(this.entityManager, this.resultClass).addOffset(offset);
}
addLimit(limit) {
return new Filter(this.entityManager, this.resultClass).addLimit(limit);
}
}
Object.assign(Builder.prototype, Condition);
deprecated(Builder.prototype, '_addOperator', 'addOperator');
deprecated(Builder.prototype, '_addOrder', 'addOrder');
deprecated(Builder.prototype, '_addFilter', 'addFilter');
deprecated(Builder.prototype, '_addOffset', 'addOffset');
deprecated(Builder.prototype, '_addLimit', 'addLimit');
module.exports = Builder;