server-ts: Port services/search/expressions/order_by_and_limit

This commit is contained in:
Elian Doran 2024-02-18 01:17:02 +02:00
parent c63d05b582
commit 87708aa9c3
No known key found for this signature in database
2 changed files with 36 additions and 11 deletions

View File

@ -1,13 +1,33 @@
"use strict";
const Expression = require('./expression');
const NoteSet = require('../note_set');
import BNote = require("../../../becca/entities/bnote");
import NoteSet = require("../note_set");
import SearchContext = require("../search_context");
import Expression = require("./expression");
type Direction = "asc";
interface ValueExtractor {
extract: (note: BNote) => number | string | null;
}
interface OrderDefinition {
direction: Direction;
smaller: number;
larger: number;
valueExtractor: ValueExtractor;
}
class OrderByAndLimitExp extends Expression {
constructor(orderDefinitions, limit) {
private orderDefinitions: OrderDefinition[];
private limit: number;
private subExpression: Expression | null;
constructor(orderDefinitions: Pick<OrderDefinition, "direction">[], limit: number) {
super();
this.orderDefinitions = orderDefinitions;
this.orderDefinitions = orderDefinitions as unknown as OrderDefinition[];
for (const od of this.orderDefinitions) {
od.smaller = od.direction === "asc" ? -1 : 1;
@ -16,11 +36,15 @@ class OrderByAndLimitExp extends Expression {
this.limit = limit || 0;
/** @type {Expression} */
this.subExpression = null; // it's expected to be set after construction
}
execute(inputNoteSet, executionContext, searchContext) {
execute(inputNoteSet: NoteSet, executionContext: {}, searchContext: SearchContext) {
if (!this.subExpression) {
// FIXME: who is setting the subexpression?
throw new Error("Missing subexpression");
}
let {notes} = this.subExpression.execute(inputNoteSet, executionContext, searchContext);
notes.sort((a, b) => {
@ -48,7 +72,8 @@ class OrderByAndLimitExp extends Expression {
}
// if both are numbers, then parse them for numerical comparison
if (this.isNumber(valA) && this.isNumber(valB)) {
if (typeof valA === "string" && this.isNumber(valA) &&
typeof valB === "string" && this.isNumber(valB)) {
valA = parseFloat(valA);
valB = parseFloat(valB);
}
@ -77,16 +102,16 @@ class OrderByAndLimitExp extends Expression {
return noteSet;
}
isNumber(x) {
isNumber(x: number | string) {
if (typeof x === 'number') {
return true;
} else if (typeof x === 'string') {
// isNaN will return false for blank string
return x.trim() !== "" && !isNaN(x);
return x.trim() !== "" && !isNaN(parseInt(x, 10));
} else {
return false;
}
}
}
module.exports = OrderByAndLimitExp;
export = OrderByAndLimitExp;

View File

@ -13,7 +13,7 @@ const AttributeExistsExp = require('../expressions/attribute_exists');
const LabelComparisonExp = require('../expressions/label_comparison');
const NoteFlatTextExp = require('../expressions/note_flat_text');
const NoteContentFulltextExp = require('../expressions/note_content_fulltext');
const OrderByAndLimitExp = require('../expressions/order_by_and_limit.js');
const OrderByAndLimitExp = require('../expressions/order_by_and_limit');
const AncestorExp = require('../expressions/ancestor');
const buildComparator = require('./build_comparator.js');
const ValueExtractor = require('../value_extractor');