From 822f249fb1674ad7e2d4bec3e0ebdfcead046286 Mon Sep 17 00:00:00 2001 From: Hongbo Wu Date: Thu, 27 Jun 2024 19:10:50 +0800 Subject: [PATCH] cont --- packages/api/src/resolvers/article/index.ts | 128 ++++++++++-------- packages/api/src/resolvers/highlight/index.ts | 15 +- packages/api/src/resolvers/labels/index.ts | 28 ++-- 3 files changed, 101 insertions(+), 70 deletions(-) diff --git a/packages/api/src/resolvers/article/index.ts b/packages/api/src/resolvers/article/index.ts index 0fd905bf7..73f17a2c3 100644 --- a/packages/api/src/resolvers/article/index.ts +++ b/packages/api/src/resolvers/article/index.ts @@ -63,7 +63,7 @@ import { UpdatesSinceError, UpdatesSinceSuccess, } from '../../generated/graphql' -import { getColumns } from '../../repository' +import { authTrx, getColumns } from '../../repository' import { getInternalLabelWithColor } from '../../repository/label' import { libraryItemRepository } from '../../repository/library_item' import { userRepository } from '../../repository/user' @@ -376,7 +376,7 @@ export const getArticleResolver = authorized< Merge, ArticleError, QueryArticleArgs ->(async (_obj, { slug, format }, { authTrx, uid, log }, info) => { +>(async (_obj, { slug, format }, { uid, log }, info) => { try { const selectColumns = getColumns(libraryItemRepository) const includeOriginalHtml = @@ -386,36 +386,44 @@ export const getArticleResolver = authorized< selectColumns.splice(selectColumns.indexOf('originalContent'), 1) } - const libraryItem = await authTrx((tx) => { - const qb = tx - .createQueryBuilder(LibraryItem, 'libraryItem') - .select(selectColumns.map((column) => `libraryItem.${column}`)) - .leftJoinAndSelect('libraryItem.labels', 'labels') - .leftJoinAndSelect('libraryItem.highlights', 'highlights') - .leftJoinAndSelect('highlights.labels', 'highlights_labels') - .leftJoinAndSelect('highlights.user', 'highlights_user') - .leftJoinAndSelect('highlights_user.profile', 'highlights_user_profile') - .leftJoinAndSelect('libraryItem.uploadFile', 'uploadFile') - .leftJoinAndSelect('libraryItem.recommendations', 'recommendations') - .leftJoinAndSelect('recommendations.group', 'recommendations_group') - .leftJoinAndSelect( - 'recommendations.recommender', - 'recommendations_recommender' - ) - .leftJoinAndSelect( - 'recommendations_recommender.profile', - 'recommendations_recommender_profile' - ) - .where('libraryItem.user_id = :uid', { uid }) + const libraryItem = await authTrx( + (tx) => { + const qb = tx + .createQueryBuilder(LibraryItem, 'libraryItem') + .select(selectColumns.map((column) => `libraryItem.${column}`)) + .leftJoinAndSelect('libraryItem.labels', 'labels') + .leftJoinAndSelect('libraryItem.highlights', 'highlights') + .leftJoinAndSelect('highlights.labels', 'highlights_labels') + .leftJoinAndSelect('highlights.user', 'highlights_user') + .leftJoinAndSelect( + 'highlights_user.profile', + 'highlights_user_profile' + ) + .leftJoinAndSelect('libraryItem.uploadFile', 'uploadFile') + .leftJoinAndSelect('libraryItem.recommendations', 'recommendations') + .leftJoinAndSelect('recommendations.group', 'recommendations_group') + .leftJoinAndSelect( + 'recommendations.recommender', + 'recommendations_recommender' + ) + .leftJoinAndSelect( + 'recommendations_recommender.profile', + 'recommendations_recommender_profile' + ) + .where('libraryItem.user_id = :uid', { uid }) - // We allow the backend to use the ID instead of a slug to fetch the article - // query against id if slug is a uuid - slug.match(/^[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}$/i) - ? qb.andWhere('libraryItem.id = :id', { id: slug }) - : qb.andWhere('libraryItem.slug = :slug', { slug }) + // We allow the backend to use the ID instead of a slug to fetch the article + // query against id if slug is a uuid + slug.match(/^[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}$/i) + ? qb.andWhere('libraryItem.id = :id', { id: slug }) + : qb.andWhere('libraryItem.slug = :slug', { slug }) - return qb.andWhere('libraryItem.deleted_at IS NULL').getOne() - }) + return qb.andWhere('libraryItem.deleted_at IS NULL').getOne() + }, + { + replicationMode: 'replica', + } + ) if (!libraryItem) { return { errorCodes: [ArticleErrorCode.NotFound] } @@ -499,7 +507,7 @@ export const saveArticleReadingProgressResolver = authorized< force, }, }, - { authTrx, pubsub, uid, dataSources } + { pubsub, uid, dataSources } ) => { if ( readingProgressPercent < 0 || @@ -515,13 +523,17 @@ export const saveArticleReadingProgressResolver = authorized< // We don't need to update the values of reading progress here // because the function resolver will handle that for us when // it resolves the properties of the Article object - let updatedItem = await authTrx((tx) => - tx.getRepository(LibraryItem).findOne({ - where: { - id, - }, - relations: ['user'], - }) + let updatedItem = await authTrx( + (tx) => + tx.getRepository(LibraryItem).findOne({ + where: { + id, + }, + relations: ['user'], + }), + { + replicationMode: 'replica', + } ) if (!updatedItem) { return { @@ -838,7 +850,7 @@ export const moveToFolderResolver = authorized< MoveToFolderSuccess, MoveToFolderError, MutationMoveToFolderArgs ->(async (_, { id, folder }, { authTrx, log, pubsub, uid }) => { +>(async (_, { id, folder }, { log, pubsub, uid }) => { analytics.capture({ distinctId: uid, event: 'move_to_folder', @@ -848,13 +860,17 @@ export const moveToFolderResolver = authorized< }, }) - const item = await authTrx((tx) => - tx.getRepository(LibraryItem).findOne({ - where: { - id, - }, - relations: ['user'], - }) + const item = await authTrx( + (tx) => + tx.getRepository(LibraryItem).findOne({ + where: { + id, + }, + relations: ['user'], + }), + { + replicationMode: 'replica', + } ) if (!item) { @@ -913,7 +929,7 @@ export const fetchContentResolver = authorized< FetchContentSuccess, FetchContentError, MutationFetchContentArgs ->(async (_, { id }, { authTrx, uid, log, pubsub }) => { +>(async (_, { id }, { uid, log, pubsub }) => { analytics.capture({ distinctId: uid, event: 'fetch_content', @@ -922,13 +938,17 @@ export const fetchContentResolver = authorized< }, }) - const item = await authTrx((tx) => - tx.getRepository(LibraryItem).findOne({ - where: { - id, - }, - relations: ['user'], - }) + const item = await authTrx( + (tx) => + tx.getRepository(LibraryItem).findOne({ + where: { + id, + }, + relations: ['user'], + }), + { + replicationMode: 'replica', + } ) if (!item) { return { diff --git a/packages/api/src/resolvers/highlight/index.ts b/packages/api/src/resolvers/highlight/index.ts index a52b5d06c..6dcf3cfe9 100644 --- a/packages/api/src/resolvers/highlight/index.ts +++ b/packages/api/src/resolvers/highlight/index.ts @@ -32,6 +32,7 @@ import { UpdateHighlightErrorCode, UpdateHighlightSuccess, } from '../../generated/graphql' +import { authTrx } from '../../repository' import { highlightRepository } from '../../repository/highlight' import { createHighlight, @@ -87,7 +88,7 @@ export const mergeHighlightResolver = authorized< Merge, MergeHighlightError, MutationMergeHighlightArgs ->(async (_, { input }, { authTrx, log, pubsub, uid }) => { +>(async (_, { input }, { log, pubsub, uid }) => { const { overlapHighlightIdList, ...newHighlightInput } = input /* Compute merged annotation form the order of highlights appearing on page */ @@ -96,10 +97,14 @@ export const mergeHighlightResolver = authorized< const mergedColors: string[] = [] try { - const existingHighlights = await authTrx((tx) => - tx - .withRepository(highlightRepository) - .findByLibraryItemId(input.articleId, uid) + const existingHighlights = await authTrx( + (tx) => + tx + .withRepository(highlightRepository) + .findByLibraryItemId(input.articleId, uid), + { + replicationMode: 'replica', + } ) existingHighlights.forEach((highlight) => { diff --git a/packages/api/src/resolvers/labels/index.ts b/packages/api/src/resolvers/labels/index.ts index 2e3b9c6d2..be5ea342a 100644 --- a/packages/api/src/resolvers/labels/index.ts +++ b/packages/api/src/resolvers/labels/index.ts @@ -28,6 +28,7 @@ import { UpdateLabelErrorCode, UpdateLabelSuccess, } from '../../generated/graphql' +import { authTrx } from '../../repository' import { labelRepository } from '../../repository/label' import { userRepository } from '../../repository/user' import { @@ -41,7 +42,7 @@ import { analytics } from '../../utils/analytics' import { authorized } from '../../utils/gql-utils' export const labelsResolver = authorized( - async (_obj, _params, { authTrx, log, uid }) => { + async (_obj, _params, { log, uid }) => { try { const user = await userRepository.findById(uid) if (!user) { @@ -50,16 +51,21 @@ export const labelsResolver = authorized( } } - const labels = await authTrx(async (tx) => { - return tx.withRepository(labelRepository).find({ - where: { - user: { id: uid }, - }, - order: { - name: 'ASC', - }, - }) - }) + const labels = await authTrx( + async (tx) => { + return tx.withRepository(labelRepository).find({ + where: { + user: { id: uid }, + }, + order: { + name: 'ASC', + }, + }) + }, + { + replicationMode: 'replica', + } + ) analytics.capture({ distinctId: uid,