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"; "use strict";
const Expression = require('./expression'); import BNote = require("../../../becca/entities/bnote");
const NoteSet = require('../note_set'); 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 { 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(); super();
this.orderDefinitions = orderDefinitions; this.orderDefinitions = orderDefinitions as unknown as OrderDefinition[];
for (const od of this.orderDefinitions) { for (const od of this.orderDefinitions) {
od.smaller = od.direction === "asc" ? -1 : 1; od.smaller = od.direction === "asc" ? -1 : 1;
@ -16,11 +36,15 @@ class OrderByAndLimitExp extends Expression {
this.limit = limit || 0; this.limit = limit || 0;
/** @type {Expression} */
this.subExpression = null; // it's expected to be set after construction 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); let {notes} = this.subExpression.execute(inputNoteSet, executionContext, searchContext);
notes.sort((a, b) => { notes.sort((a, b) => {
@ -48,7 +72,8 @@ class OrderByAndLimitExp extends Expression {
} }
// if both are numbers, then parse them for numerical comparison // 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); valA = parseFloat(valA);
valB = parseFloat(valB); valB = parseFloat(valB);
} }
@ -77,16 +102,16 @@ class OrderByAndLimitExp extends Expression {
return noteSet; return noteSet;
} }
isNumber(x) { isNumber(x: number | string) {
if (typeof x === 'number') { if (typeof x === 'number') {
return true; return true;
} else if (typeof x === 'string') { } else if (typeof x === 'string') {
// isNaN will return false for blank string // isNaN will return false for blank string
return x.trim() !== "" && !isNaN(x); return x.trim() !== "" && !isNaN(parseInt(x, 10));
} else { } else {
return false; 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 LabelComparisonExp = require('../expressions/label_comparison');
const NoteFlatTextExp = require('../expressions/note_flat_text'); const NoteFlatTextExp = require('../expressions/note_flat_text');
const NoteContentFulltextExp = require('../expressions/note_content_fulltext'); 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 AncestorExp = require('../expressions/ancestor');
const buildComparator = require('./build_comparator.js'); const buildComparator = require('./build_comparator.js');
const ValueExtractor = require('../value_extractor'); const ValueExtractor = require('../value_extractor');