Files
IdentityDB/src/queries/facts.ts

67 lines
1.9 KiB
TypeScript

import type { Kysely, Transaction } from 'kysely';
import type { IdentityDatabaseSchema } from '../types/database';
import type { FactRecord, TopicRecord } from '../types/domain';
export type DatabaseExecutor = Kysely<IdentityDatabaseSchema> | Transaction<IdentityDatabaseSchema>;
export interface FactTopicJoinRow extends TopicRecord {
fact_id: string;
role: string | null;
position: number;
}
export async function findFactRowsForTopicId(
executor: DatabaseExecutor,
topicId: string,
): Promise<FactRecord[]> {
return executor
.selectFrom('facts')
.innerJoin('fact_topics', 'fact_topics.fact_id', 'facts.id')
.selectAll('facts')
.where('fact_topics.topic_id', '=', topicId)
.orderBy('facts.created_at', 'asc')
.execute();
}
export async function findFactRowsConnectingTopicIds(
executor: DatabaseExecutor,
topicIds: string[],
): Promise<FactRecord[]> {
if (topicIds.length === 0) {
return [];
}
return executor
.selectFrom('facts')
.innerJoin('fact_topics', 'fact_topics.fact_id', 'facts.id')
.selectAll('facts')
.where('fact_topics.topic_id', 'in', topicIds)
.groupBy('facts.id')
.having((eb) => eb.fn.count<number>('fact_topics.topic_id'), '=', topicIds.length)
.orderBy('facts.created_at', 'asc')
.execute();
}
export async function findTopicLinksForFactIds(
executor: DatabaseExecutor,
factIds: string[],
): Promise<FactTopicJoinRow[]> {
if (factIds.length === 0) {
return [];
}
return executor
.selectFrom('fact_topics')
.innerJoin('topics', 'topics.id', 'fact_topics.topic_id')
.selectAll('topics')
.select([
'fact_topics.fact_id as fact_id',
'fact_topics.role as role',
'fact_topics.position as position',
])
.where('fact_topics.fact_id', 'in', factIds)
.orderBy('fact_topics.position', 'asc')
.execute() as Promise<FactTopicJoinRow[]>;
}