diff --git a/packages/server/src/api/routes/tests/search.spec.ts b/packages/server/src/api/routes/tests/search.spec.ts index 698ea0c10b..931510a88f 100644 --- a/packages/server/src/api/routes/tests/search.spec.ts +++ b/packages/server/src/api/routes/tests/search.spec.ts @@ -3,6 +3,7 @@ import { DatabaseName, getDatasource } from "../../../integrations/tests/utils" import * as setup from "./utilities" import { + AutoFieldSubType, Datasource, EmptyFilterOption, FieldType, @@ -18,15 +19,16 @@ import _ from "lodash" jest.unmock("mssql") describe.each([ - ["internal", undefined], - ["internal-sqs", undefined], + ["lucene", undefined], + ["sqs", undefined], [DatabaseName.POSTGRES, getDatasource(DatabaseName.POSTGRES)], [DatabaseName.MYSQL, getDatasource(DatabaseName.MYSQL)], [DatabaseName.SQL_SERVER, getDatasource(DatabaseName.SQL_SERVER)], [DatabaseName.MARIADB, getDatasource(DatabaseName.MARIADB)], ])("/api/:sourceId/search (%s)", (name, dsProvider) => { - const isSqs = name === "internal-sqs" - const isInternal = name === "internal" + const isSqs = name === "sqs" + const isLucene = name === "lucene" + const isInternal = isSqs || isLucene const config = setup.getConfig() let envCleanup: (() => void) | undefined @@ -59,7 +61,9 @@ describe.each([ } async function createRows(rows: Record[]) { - await Promise.all(rows.map(r => config.api.row.save(table._id!, r))) + for (const row of rows) { + await config.api.row.save(table._id!, row) + } } class SearchAssertion { @@ -339,14 +343,14 @@ describe.each([ }).toFindNothing()) // We never implemented half-open ranges in Lucene. - !isInternal && + !isLucene && it("can search using just a low value", () => expectQuery({ range: { age: { low: 5 } }, }).toContainExactly([{ age: 10 }])) // We never implemented half-open ranges in Lucene. - !isInternal && + !isLucene && it("can search using just a high value", () => expectQuery({ range: { age: { high: 5 } }, @@ -457,14 +461,14 @@ describe.each([ }).toFindNothing()) // We never implemented half-open ranges in Lucene. - !isInternal && + !isLucene && it("can search using just a low value", () => expectQuery({ range: { dob: { low: JAN_5TH } }, }).toContainExactly([{ dob: JAN_10TH }])) // We never implemented half-open ranges in Lucene. - !isInternal && + !isLucene && it("can search using just a high value", () => expectQuery({ range: { dob: { high: JAN_5TH } }, @@ -642,7 +646,7 @@ describe.each([ // Range searches against bigints don't seem to work at all in Lucene, and I // couldn't figure out why. Given that we're replacing Lucene with SQS, // we've decided not to spend time on it. - !isInternal && + !isLucene && describe("range", () => { it("successfully finds a row", () => expectQuery({ @@ -675,4 +679,137 @@ describe.each([ }).toContainExactly([{ num: SMALL }, { num: MEDIUM }])) }) }) + + isInternal && + describe("auto", () => { + beforeAll(async () => { + await createTable({ + auto: { + name: "auto", + type: FieldType.AUTO, + autocolumn: true, + subtype: AutoFieldSubType.AUTO_ID, + }, + }) + await createRows(new Array(10).fill({})) + }) + + describe("equal", () => { + it("successfully finds a row", () => + expectQuery({ equal: { auto: 1 } }).toContainExactly([{ auto: 1 }])) + + it("fails to find nonexistent row", () => + expectQuery({ equal: { auto: 0 } }).toFindNothing()) + }) + + describe("not equal", () => { + it("successfully finds a row", () => + expectQuery({ notEqual: { auto: 1 } }).toContainExactly([ + { auto: 2 }, + { auto: 3 }, + { auto: 4 }, + { auto: 5 }, + { auto: 6 }, + { auto: 7 }, + { auto: 8 }, + { auto: 9 }, + { auto: 10 }, + ])) + + it("fails to find nonexistent row", () => + expectQuery({ notEqual: { auto: 0 } }).toContainExactly([ + { auto: 1 }, + { auto: 2 }, + { auto: 3 }, + { auto: 4 }, + { auto: 5 }, + { auto: 6 }, + { auto: 7 }, + { auto: 8 }, + { auto: 9 }, + { auto: 10 }, + ])) + }) + + describe("oneOf", () => { + it("successfully finds a row", () => + expectQuery({ oneOf: { auto: [1] } }).toContainExactly([{ auto: 1 }])) + + it("fails to find nonexistent row", () => + expectQuery({ oneOf: { auto: [0] } }).toFindNothing()) + }) + + describe("range", () => { + it("successfully finds a row", () => + expectQuery({ + range: { auto: { low: 1, high: 1 } }, + }).toContainExactly([{ auto: 1 }])) + + it("successfully finds multiple rows", () => + expectQuery({ + range: { auto: { low: 1, high: 2 } }, + }).toContainExactly([{ auto: 1 }, { auto: 2 }])) + + it("successfully finds a row with a high bound", () => + expectQuery({ + range: { auto: { low: 2, high: 2 } }, + }).toContainExactly([{ auto: 2 }])) + + it("successfully finds no rows", () => + expectQuery({ + range: { auto: { low: 0, high: 0 } }, + }).toFindNothing()) + + isSqs && + it("can search using just a low value", () => + expectQuery({ + range: { auto: { low: 9 } }, + }).toContainExactly([{ auto: 9 }, { auto: 10 }])) + + isSqs && + it("can search using just a high value", () => + expectQuery({ + range: { auto: { high: 2 } }, + }).toContainExactly([{ auto: 1 }, { auto: 2 }])) + }) + + isSqs && + describe("sort", () => { + it("sorts ascending", () => + expectSearch({ + query: {}, + sort: "auto", + sortOrder: SortOrder.ASCENDING, + }).toMatchExactly([ + { auto: 1 }, + { auto: 2 }, + { auto: 3 }, + { auto: 4 }, + { auto: 5 }, + { auto: 6 }, + { auto: 7 }, + { auto: 8 }, + { auto: 9 }, + { auto: 10 }, + ])) + + it("sorts descending", () => + expectSearch({ + query: {}, + sort: "auto", + sortOrder: SortOrder.DESCENDING, + }).toMatchExactly([ + { auto: 10 }, + { auto: 9 }, + { auto: 8 }, + { auto: 7 }, + { auto: 6 }, + { auto: 5 }, + { auto: 4 }, + { auto: 3 }, + { auto: 2 }, + { auto: 1 }, + ])) + }) + }) }) diff --git a/packages/server/src/sdk/app/tables/internal/sqs.ts b/packages/server/src/sdk/app/tables/internal/sqs.ts index 0726c94962..65d44b9af4 100644 --- a/packages/server/src/sdk/app/tables/internal/sqs.ts +++ b/packages/server/src/sdk/app/tables/internal/sqs.ts @@ -33,7 +33,7 @@ const FieldTypeMap: Record = { [FieldType.LONGFORM]: SQLiteType.TEXT, [FieldType.NUMBER]: SQLiteType.REAL, [FieldType.STRING]: SQLiteType.TEXT, - [FieldType.AUTO]: SQLiteType.TEXT, + [FieldType.AUTO]: SQLiteType.REAL, [FieldType.OPTIONS]: SQLiteType.TEXT, [FieldType.JSON]: SQLiteType.BLOB, [FieldType.INTERNAL]: SQLiteType.BLOB,