diff options
| author | Mohamed Bassem <me@mbassem.com> | 2025-09-13 21:37:56 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-09-13 21:37:56 +0100 |
| commit | a92ada7727b2596414aafe204e5001eb066569cb (patch) | |
| tree | 73e289791f83135dfa2f5cecc6fa1c4019679238 /packages/trpc/lib | |
| parent | 3bae3aad9a62dbf2cc9a0038c90ea992166cc336 (diff) | |
| download | karakeep-a92ada7727b2596414aafe204e5001eb066569cb.tar.zst | |
feat(search): add title search qualifier (#1940)
* fix(search): include link titles in title matcher
* docs(search): add title qualifier
* docs: remove title qualifier from v0.27 guide
Diffstat (limited to 'packages/trpc/lib')
| -rw-r--r-- | packages/trpc/lib/__tests__/search.test.ts | 28 | ||||
| -rw-r--r-- | packages/trpc/lib/search.ts | 46 |
2 files changed, 73 insertions, 1 deletions
diff --git a/packages/trpc/lib/__tests__/search.test.ts b/packages/trpc/lib/__tests__/search.test.ts index 9d9b39d7..ee8bfb60 100644 --- a/packages/trpc/lib/__tests__/search.test.ts +++ b/packages/trpc/lib/__tests__/search.test.ts @@ -45,6 +45,7 @@ beforeEach(async () => { archived: false, favourited: false, createdAt: new Date("2024-01-01"), + title: null, }, { id: "b2", @@ -53,6 +54,7 @@ beforeEach(async () => { archived: true, favourited: true, createdAt: new Date("2024-01-02"), + title: "example domain page", }, { id: "b3", @@ -61,6 +63,7 @@ beforeEach(async () => { archived: true, favourited: false, createdAt: new Date("2024-01-03"), + title: "third bookmark", }, { id: "b4", @@ -69,6 +72,7 @@ beforeEach(async () => { archived: false, favourited: true, createdAt: new Date("2024-01-04"), + title: "another example page", }, { id: "b5", @@ -77,6 +81,7 @@ beforeEach(async () => { archived: false, favourited: false, createdAt: new Date("2024-01-05"), + title: "fifth text", }, { id: "b6", @@ -85,11 +90,12 @@ beforeEach(async () => { archived: true, favourited: false, createdAt: new Date("2024-01-06"), + title: "example asset", }, ]); await db.insert(bookmarkLinks).values([ - { id: "b1", url: "https://example.com/page1" }, + { id: "b1", url: "https://example.com/page1", title: "example link" }, { id: "b2", url: "https://test.com/page2" }, { id: "b4", url: "https://example.com/page3" }, ]); @@ -279,6 +285,26 @@ describe("getBookmarkIdsFromMatcher", () => { expect(result.sort()).toEqual(["b2"]); }); + it("should handle title matcher", async () => { + const matcher: Matcher = { + type: "title", + title: "example", + inverse: false, + }; + const result = await getBookmarkIdsFromMatcher(mockCtx, matcher); + expect(result.sort()).toEqual(["b1", "b2", "b4", "b6"]); + }); + + it("should handle title matcher with inverse=true", async () => { + const matcher: Matcher = { + type: "title", + title: "example", + inverse: true, + }; + const result = await getBookmarkIdsFromMatcher(mockCtx, matcher); + expect(result.sort()).toEqual(["b3", "b5"]); + }); + it("should handle dateAfter matcher", async () => { const matcher: Matcher = { type: "dateAfter", diff --git a/packages/trpc/lib/search.ts b/packages/trpc/lib/search.ts index d4130798..67348141 100644 --- a/packages/trpc/lib/search.ts +++ b/packages/trpc/lib/search.ts @@ -5,12 +5,14 @@ import { gt, gte, isNotNull, + isNull, like, lt, lte, ne, notExists, notLike, + or, } from "drizzle-orm"; import { @@ -245,6 +247,50 @@ async function getIds( ), ); } + case "title": { + const comp = matcher.inverse ? notLike : like; + if (matcher.inverse) { + return db + .select({ id: bookmarks.id }) + .from(bookmarks) + .leftJoin(bookmarkLinks, eq(bookmarks.id, bookmarkLinks.id)) + .where( + and( + eq(bookmarks.userId, userId), + or( + isNull(bookmarks.title), + comp(bookmarks.title, `%${matcher.title}%`), + ), + or( + isNull(bookmarkLinks.title), + comp(bookmarkLinks.title, `%${matcher.title}%`), + ), + ), + ); + } + + return db + .select({ id: bookmarks.id }) + .from(bookmarks) + .where( + and( + eq(bookmarks.userId, userId), + comp(bookmarks.title, `%${matcher.title}%`), + ), + ) + .union( + db + .select({ id: bookmarkLinks.id }) + .from(bookmarkLinks) + .leftJoin(bookmarks, eq(bookmarks.id, bookmarkLinks.id)) + .where( + and( + eq(bookmarks.userId, userId), + comp(bookmarkLinks.title, `%${matcher.title}%`), + ), + ), + ); + } case "favourited": { return db .select({ id: bookmarks.id }) |
