A social knowledge tool for researchers built on ATProto
1import { eq } from 'drizzle-orm';
2import { PostgresJsDatabase } from 'drizzle-orm/postgres-js';
3import { ICardLibraryQueryService } from '../../application/services/ICardLibraryQueryService';
4import { CardId } from '../../domain/value-objects/CardId';
5import { libraryMemberships } from '../repositories/schema/libraryMembership.sql';
6import { Result, ok, err } from '../../../../shared/core/Result';
7
8export class DrizzleCardLibraryQueryService
9 implements ICardLibraryQueryService
10{
11 constructor(private db: PostgresJsDatabase) {}
12
13 async getLibrariesForCard(cardId: CardId): Promise<Result<string[]>> {
14 try {
15 const results = await this.db
16 .select({ userId: libraryMemberships.userId })
17 .from(libraryMemberships)
18 .where(eq(libraryMemberships.cardId, cardId.getStringValue()));
19
20 return ok(results.map((r) => r.userId));
21 } catch (error) {
22 return err(error as Error);
23 }
24 }
25
26 async getCardsInLibrary(userId: string): Promise<Result<CardId[]>> {
27 try {
28 const results = await this.db
29 .select({ cardId: libraryMemberships.cardId })
30 .from(libraryMemberships)
31 .where(eq(libraryMemberships.userId, userId));
32
33 const cardIds: CardId[] = [];
34 for (const result of results) {
35 const cardIdResult = CardId.createFromString(result.cardId);
36 if (cardIdResult.isOk()) {
37 cardIds.push(cardIdResult.value);
38 }
39 }
40
41 return ok(cardIds);
42 } catch (error) {
43 return err(error as Error);
44 }
45 }
46
47 async isCardInLibrary(
48 cardId: CardId,
49 userId: string,
50 ): Promise<Result<boolean>> {
51 try {
52 const result = await this.db
53 .select({ cardId: libraryMemberships.cardId })
54 .from(libraryMemberships)
55 .where(
56 eq(libraryMemberships.cardId, cardId.getStringValue()) &&
57 eq(libraryMemberships.userId, userId),
58 )
59 .limit(1);
60
61 return ok(result.length > 0);
62 } catch (error) {
63 return err(error as Error);
64 }
65 }
66
67 async getLibraryMembershipCount(cardId: CardId): Promise<Result<number>> {
68 try {
69 const results = await this.db
70 .select({ userId: libraryMemberships.userId })
71 .from(libraryMemberships)
72 .where(eq(libraryMemberships.cardId, cardId.getStringValue()));
73
74 return ok(results.length);
75 } catch (error) {
76 return err(error as Error);
77 }
78 }
79
80 async getLibraryCardCount(userId: string): Promise<Result<number>> {
81 try {
82 const results = await this.db
83 .select({ cardId: libraryMemberships.cardId })
84 .from(libraryMemberships)
85 .where(eq(libraryMemberships.userId, userId));
86
87 return ok(results.length);
88 } catch (error) {
89 return err(error as Error);
90 }
91 }
92}