objection-paginator
Version:
Paginated queries for Objection.js
131 lines • 4.49 kB
JavaScript
import { ConfigurationError } from "./configuration-error.js";
import { SortDirection } from "./sort-descriptor.js";
import { ValidationCase } from "./get-error-class.js";
import _ from "lodash";
export class SortNode {
constructor(descriptors) {
const [firstDescriptor] = descriptors;
if (!firstDescriptor) {
throw new ConfigurationError("At least one sort descriptor is required");
}
this.descriptor = firstDescriptor;
this.anyNullable = firstDescriptor.nullable;
const subdescriptors = descriptors.slice(1);
if (!_.isEmpty(subdescriptors)) {
this.child = new SortNode(subdescriptors);
this.anyNullable = this.anyNullable || this.child.anyNullable;
}
}
apply(qry, cursorValues) {
this.applyOrder(qry);
if (cursorValues)
this.applyCursorValues(qry, cursorValues);
}
applyOrder(qry) {
if (this.anyNullable) {
qry.orderByRaw(this.getOrderByClause(qry));
}
else {
qry.orderBy(this.getOrderByDescriptors());
}
}
getOrderByDescriptors() {
const { descriptor, child } = this;
const { column, order } = descriptor;
const result = [{ column, order }];
if (child)
result.push(...child.getOrderByDescriptors());
return result;
}
getOrderByClause(qry) {
return this.getOrderByTerms(qry).join(", ");
}
getOrderByTerms(qry) {
const terms = this.getOwnOrderByTerms(qry);
if (this.child)
terms.push(...this.child.getOrderByTerms(qry));
return terms;
}
getOwnOrderByTerms(qry) {
const { descriptor } = this;
const column = descriptor.getRawColumn(qry);
const { order, nullable, nullOrder } = descriptor;
const terms = [`${column} ${order}`];
if (nullable)
terms.unshift(`(${column} is null) ${nullOrder}`);
return terms;
}
getCursorValues(entity) {
const { descriptor, child } = this;
const result = [descriptor.getCursorValue(entity)];
if (child)
result.push(...child.getCursorValues(entity));
return result;
}
applyCursorValues(qry, values) {
const [value] = values;
const childValues = values.slice(1);
this.descriptor.validateCursorValue(value, ValidationCase.Cursor);
if (value === null) {
this.applyNullCursorValue(qry, childValues);
}
else {
this.applyCursorValue(qry, value, childValues);
}
}
applyCursorValue(qry, value, childValues) {
const { descriptor, child } = this;
const { column } = descriptor;
if (child) {
qry.where(sub0 => {
sub0
.where(sub1 => {
this.applyInequality(sub1, value);
})
.orWhere(sub1 => {
sub1.where({ [column]: value });
child.applyCursorValues(sub1, childValues);
});
});
}
else {
this.applyInequality(qry, value);
}
}
applyNullCursorValue(qry, childValues) {
const { descriptor, child } = this;
const { column, direction } = descriptor;
if (child) {
this.applyNullCursorValueWithChildren(qry, childValues);
}
else if (direction !== SortDirection.Descending) {
qry.whereNull(column);
}
}
applyInequality(qry, value) {
const { column, operator, nullable } = this.descriptor;
qry.where(column, operator, value);
if (nullable)
this.handleNulls(qry);
}
handleNulls(qry) {
const { column, direction } = this.descriptor;
if (direction !== SortDirection.Descending)
qry.orWhereNull(column);
}
applyNullCursorValueWithChildren(qry, childValues) {
const { descriptor, child } = this;
const { column, direction } = descriptor;
if (direction === SortDirection.Descending) {
qry.whereNotNull(column).orWhere(sub => {
sub.whereNull(column);
child.applyCursorValues(sub, childValues);
});
}
else {
qry.whereNull(column);
child.applyCursorValues(qry, childValues);
}
}
}
//# sourceMappingURL=sort-node.js.map