Skip to content

Commit

Permalink
Allow sorting for find (#30)
Browse files Browse the repository at this point in the history
* feat: implement sorting in IDatabaseCollection

* feat: implement sorting in LokiJsCollection

* feat: implement sorting in MongoDbCollection

* chore: version bumps

* chore: bump libs

* fix: remove typeroots

* test: sorting
  • Loading branch information
jkoenig134 authored Jan 27, 2025
1 parent 35858ea commit f68d148
Show file tree
Hide file tree
Showing 16 changed files with 1,035 additions and 404 deletions.
1,062 changes: 777 additions & 285 deletions package-lock.json

Large diffs are not rendered by default.

10 changes: 5 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,15 @@
"test:local": "npm run test:local --workspaces --if-present"
},
"devDependencies": {
"@js-soft/eslint-config-ts": "1.6.9",
"@js-soft/eslint-config-ts": "1.6.13",
"@js-soft/license-check": "1.0.9",
"@types/jest": "^29.5.12",
"@types/node": "^22.5.4",
"@types/jest": "^29.5.14",
"@types/node": "^22.10.10",
"eslint": "^8.57.0",
"jest": "^29.7.0",
"prettier": "^3.3.3",
"prettier": "^3.4.2",
"ts-jest": "^29.2.5",
"ts-node": "^10.9.2",
"typescript": "^5.5.4"
"typescript": "^5.7.3"
}
}
2 changes: 1 addition & 1 deletion packages/abstractions/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@js-soft/docdb-access-abstractions",
"version": "1.0.4",
"version": "1.1.0",
"description": "Database abstractions.",
"homepage": "https://github.com/js-soft/ts-documentdb-access#readme",
"repository": {
Expand Down
7 changes: 6 additions & 1 deletion packages/abstractions/src/IDatabaseCollection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ export interface DatabasePaginationOptions {
skip?: number;
}

export interface DatabaseSortOptions {
sortBy: string;
sortOrder: "asc" | "desc";
}

export interface IDatabaseCollection {
readonly databaseType: DatabaseType;
readonly name: string;
Expand All @@ -19,7 +24,7 @@ export interface IDatabaseCollection {

list(): Promise<any[]>;

find(query?: any, paginationOptions?: DatabasePaginationOptions): Promise<any[]>;
find(query?: any, paginationOptions?: DatabasePaginationOptions, sortOptions?: DatabaseSortOptions): Promise<any[]>;

findOne(query?: any): Promise<any>;

Expand Down
3 changes: 1 addition & 2 deletions packages/abstractions/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@
"downlevelIteration": true,
"noImplicitReturns": true,
"strictNullChecks": true,
"lib": ["esnext", "dom"],
"typeRoots": ["./node_modules/@types"]
"lib": ["esnext", "dom"]
},
"include": ["src/**/*.ts"]
}
4 changes: 2 additions & 2 deletions packages/loki/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@js-soft/docdb-access-loki",
"version": "1.1.0",
"version": "1.2.0",
"description": "The LokiJS implementation for the '@js-soft/@js-soft/docdb-access-abstractions' library.",
"homepage": "https://github.com/js-soft/ts-documentdb-access#readme",
"repository": {
Expand All @@ -27,7 +27,7 @@
"testTimeout": 60000
},
"dependencies": {
"@js-soft/docdb-access-abstractions": "1.0.4",
"@js-soft/docdb-access-abstractions": "1.1.0",
"@types/lokijs": "1.5.14",
"lokijs": "1.5.12"
},
Expand Down
17 changes: 15 additions & 2 deletions packages/loki/src/LokiJsCollection.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
/* eslint-disable @typescript-eslint/require-await */
import { DatabasePaginationOptions, DatabaseType, IDatabaseCollection } from "@js-soft/docdb-access-abstractions";
import {
DatabasePaginationOptions,
DatabaseSortOptions,
DatabaseType,
IDatabaseCollection
} from "@js-soft/docdb-access-abstractions";

export class LokiJsCollection implements IDatabaseCollection {
public readonly name: string;
Expand Down Expand Up @@ -60,9 +65,17 @@ export class LokiJsCollection implements IDatabaseCollection {
return this.collection.chain().data();
}

public async find(query?: any, paginationOptions?: DatabasePaginationOptions): Promise<any[]> {
public async find(
query?: any,
paginationOptions?: DatabasePaginationOptions,
sortOptions?: DatabaseSortOptions
): Promise<any[]> {
let cursor = this.collection.chain().find(query);

if (sortOptions) {
cursor = cursor.simplesort(sortOptions.sortBy, { desc: sortOptions.sortOrder === "desc" });
}

if (paginationOptions) {
if (paginationOptions.skip) cursor = cursor.offset(paginationOptions.skip);
if (paginationOptions.limit) cursor = cursor.limit(paginationOptions.limit);
Expand Down
56 changes: 56 additions & 0 deletions packages/loki/test/DatabaseCollection.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,4 +159,60 @@ describe("DatabaseCollection", () => {
expect(find1[0].id).not.toEqual(find2[0].id);
expect(find1[0].value).not.toEqual(find2[0].value);
});

test("should sort ascending", async () => {
const db = await getRandomCollection();

await db.create({ id: "id1", value: "1" });
await db.create({ id: "id2", value: "2" });

const find = await db.find(undefined, undefined, { sortBy: "value", sortOrder: "asc" });
expect(find).toHaveLength(2);

expect(find[0].id).toEqual("id1");
expect(find[1].id).toEqual("id2");
});

test("should sort descending", async () => {
const db = await getRandomCollection();

await db.create({ id: "id1", value: "1" });
await db.create({ id: "id2", value: "2" });

const find = await db.find(undefined, undefined, { sortBy: "value", sortOrder: "desc" });
expect(find).toHaveLength(2);

expect(find[0].id).toEqual("id2");
expect(find[1].id).toEqual("id1");
});

test("should query with paging and sorting ascending", async () => {
const db = await getRandomCollection();

await db.create({ id: "id1", value: "1" });
await db.create({ id: "id2", value: "2" });

const find1 = await db.find(undefined, { skip: 0, limit: 1 }, { sortBy: "value", sortOrder: "asc" });
expect(find1).toHaveLength(1);
expect(find1[0].id).toEqual("id1");

const find2 = await db.find(undefined, { skip: 1, limit: 1 }, { sortBy: "value", sortOrder: "asc" });
expect(find2).toHaveLength(1);
expect(find2[0].id).toEqual("id2");
});

test("should query with paging and sorting descending", async () => {
const db = await getRandomCollection();

await db.create({ id: "id1", value: "1" });
await db.create({ id: "id2", value: "2" });

const find1 = await db.find(undefined, { skip: 0, limit: 1 }, { sortBy: "value", sortOrder: "desc" });
expect(find1).toHaveLength(1);
expect(find1[0].id).toEqual("id2");

const find2 = await db.find(undefined, { skip: 1, limit: 1 }, { sortBy: "value", sortOrder: "desc" });
expect(find2).toHaveLength(1);
expect(find2[0].id).toEqual("id1");
});
});
3 changes: 1 addition & 2 deletions packages/loki/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@
"downlevelIteration": true,
"noImplicitReturns": true,
"strictNullChecks": true,
"lib": ["esnext", "dom"],
"typeRoots": ["./node_modules/@types"]
"lib": ["esnext", "dom"]
},
"include": ["src/**/*.ts"]
}
6 changes: 3 additions & 3 deletions packages/mongo/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@js-soft/docdb-access-mongo",
"version": "1.1.9",
"version": "1.2.0",
"description": "The MongoDB implementation for the '@js-soft/@js-soft/docdb-access-abstractions' library.",
"homepage": "https://github.com/js-soft/ts-documentdb-access#readme",
"repository": {
Expand Down Expand Up @@ -29,8 +29,8 @@
"testTimeout": 60000
},
"dependencies": {
"@js-soft/docdb-access-abstractions": "1.0.4",
"mongodb": "6.8.0"
"@js-soft/docdb-access-abstractions": "1.1.0",
"mongodb": "6.12.0"
},
"publishConfig": {
"access": "public",
Expand Down
17 changes: 15 additions & 2 deletions packages/mongo/src/MongoDbCollection.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import { DatabasePaginationOptions, DatabaseType, IDatabaseCollection } from "@js-soft/docdb-access-abstractions";
import {
DatabasePaginationOptions,
DatabaseSortOptions,
DatabaseType,
IDatabaseCollection
} from "@js-soft/docdb-access-abstractions";
import { Collection } from "mongodb";
import { removeContainsInQuery } from "./queryUtils";

Expand Down Expand Up @@ -58,9 +63,17 @@ export class MongoDbCollection implements IDatabaseCollection {
return await this.collection.find({}).toArray();
}

public async find(query?: any, paginationOptions?: DatabasePaginationOptions): Promise<any> {
public async find(
query?: any,
paginationOptions?: DatabasePaginationOptions,
sortOptions?: DatabaseSortOptions
): Promise<any> {
let cursor = this.collection.find(removeContainsInQuery(query));

if (sortOptions) {
cursor = cursor.sort(sortOptions.sortBy, sortOptions.sortOrder === "asc" ? 1 : -1);
}

if (paginationOptions) {
if (paginationOptions.skip) cursor = cursor.skip(paginationOptions.skip);
if (paginationOptions.limit) cursor = cursor.limit(paginationOptions.limit);
Expand Down
56 changes: 56 additions & 0 deletions packages/mongo/test/DatabaseCollection.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -177,4 +177,60 @@ describe("DatabaseCollection", () => {
expect(find1[0].id).not.toEqual(find2[0].id);
expect(find1[0].value).not.toEqual(find2[0].value);
});

test("should sort ascending", async () => {
const db = await getRandomCollection();

await db.create({ id: "id1", value: "1" });
await db.create({ id: "id2", value: "2" });

const find = await db.find(undefined, undefined, { sortBy: "value", sortOrder: "asc" });
expect(find).toHaveLength(2);

expect(find[0].id).toEqual("id1");
expect(find[1].id).toEqual("id2");
});

test("should sort descending", async () => {
const db = await getRandomCollection();

await db.create({ id: "id1", value: "1" });
await db.create({ id: "id2", value: "2" });

const find = await db.find(undefined, undefined, { sortBy: "value", sortOrder: "desc" });
expect(find).toHaveLength(2);

expect(find[0].id).toEqual("id2");
expect(find[1].id).toEqual("id1");
});

test("should query with paging and sorting ascending", async () => {
const db = await getRandomCollection();

await db.create({ id: "id1", value: "1" });
await db.create({ id: "id2", value: "2" });

const find1 = await db.find(undefined, { skip: 0, limit: 1 }, { sortBy: "value", sortOrder: "asc" });
expect(find1).toHaveLength(1);
expect(find1[0].id).toEqual("id1");

const find2 = await db.find(undefined, { skip: 1, limit: 1 }, { sortBy: "value", sortOrder: "asc" });
expect(find2).toHaveLength(1);
expect(find2[0].id).toEqual("id2");
});

test("should query with paging and sorting descending", async () => {
const db = await getRandomCollection();

await db.create({ id: "id1", value: "1" });
await db.create({ id: "id2", value: "2" });

const find1 = await db.find(undefined, { skip: 0, limit: 1 }, { sortBy: "value", sortOrder: "desc" });
expect(find1).toHaveLength(1);
expect(find1[0].id).toEqual("id2");

const find2 = await db.find(undefined, { skip: 1, limit: 1 }, { sortBy: "value", sortOrder: "desc" });
expect(find2).toHaveLength(1);
expect(find2[0].id).toEqual("id1");
});
});
1 change: 0 additions & 1 deletion packages/mongo/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
"noImplicitReturns": true,
"strictNullChecks": true,
"lib": ["esnext", "dom"],
"typeRoots": ["./node_modules/@types"],
"baseUrl": ""
},
"include": ["src/**/*.ts"]
Expand Down
Loading

0 comments on commit f68d148

Please sign in to comment.