diff --git a/packages/server/modules/core/domain/commits/operations.ts b/packages/server/modules/core/domain/commits/operations.ts index 7c53cc85c..1d460776a 100644 --- a/packages/server/modules/core/domain/commits/operations.ts +++ b/packages/server/modules/core/domain/commits/operations.ts @@ -116,3 +116,36 @@ export type GetAllBranchCommits = (params: { branchIds?: string[] projectId?: string }) => Promise<{ [branchId: string]: Commit[] }> + +export type GetStreamCommitCounts = ( + streamIds: string[], + options?: Partial<{ + ignoreGlobalsBranch: boolean + }> +) => Promise< + { + count: number + streamId: string + }[] +> + +export type GetStreamCommitCount = ( + streamId: string, + options?: Partial<{ + ignoreGlobalsBranch: boolean + }> +) => Promise + +export type GetUserStreamCommitCounts = (params: { + userIds: string[] + publicOnly?: boolean +}) => Promise<{ + [userId: string]: number +}> + +export type GetUserAuthoredCommitCounts = (params: { + userIds: string[] + publicOnly?: boolean +}) => Promise<{ + [userId: string]: number +}> diff --git a/packages/server/modules/core/loaders.ts b/packages/server/modules/core/loaders.ts index 6d099a731..387a31ac5 100644 --- a/packages/server/modules/core/loaders.ts +++ b/packages/server/modules/core/loaders.ts @@ -26,9 +26,9 @@ import { getCommitBranchesFactory, getCommitsFactory, getSpecificBranchCommitsFactory, - getStreamCommitCounts, - getUserAuthoredCommitCounts, - getUserStreamCommitCounts + getStreamCommitCountsFactory, + getUserAuthoredCommitCountsFactory, + getUserStreamCommitCountsFactory } from '@/modules/core/repositories/commits' import { ResourceIdentifier, Scope } from '@/modules/core/graph/generated/graphql' import { @@ -113,6 +113,9 @@ const getBranchCommitCounts = getBranchCommitCountsFactory({ db }) const getCommits = getCommitsFactory({ db }) const getSpecificBranchCommits = getSpecificBranchCommitsFactory({ db }) const getCommitBranches = getCommitBranchesFactory({ db }) +const getStreamCommitCounts = getStreamCommitCountsFactory({ db }) +const getUserStreamCommitCounts = getUserStreamCommitCountsFactory({ db }) +const getUserAuthoredCommitCounts = getUserAuthoredCommitCountsFactory({ db }) /** * TODO: Lazy load DataLoaders to reduce memory usage diff --git a/packages/server/modules/core/repositories/commits.ts b/packages/server/modules/core/repositories/commits.ts index 8d1bccbce..542031c60 100644 --- a/packages/server/modules/core/repositories/commits.ts +++ b/packages/server/modules/core/repositories/commits.ts @@ -11,6 +11,7 @@ import { BranchCommitRecord, BranchRecord, CommitRecord, + StreamAclRecord, StreamCommitRecord } from '@/modules/core/helpers/types' import { clamp, uniq, uniqBy, reduce, keyBy, mapValues } from 'lodash' @@ -35,13 +36,18 @@ import { GetCommitBranch, SwitchCommitBranch, UpdateCommit, - GetAllBranchCommits + GetAllBranchCommits, + GetStreamCommitCounts, + GetStreamCommitCount, + GetUserStreamCommitCounts, + GetUserAuthoredCommitCounts } from '@/modules/core/domain/commits/operations' const tables = { commits: (db: Knex) => db(Commits.name), branchCommits: (db: Knex) => db(BranchCommits.name), - streamCommits: (db: Knex) => db(StreamCommits.name) + streamCommits: (db: Knex) => db(StreamCommits.name), + streamAcl: (db: Knex) => db(StreamAcl.name) } export const generateCommitId = () => crs({ length: 10 }) @@ -181,41 +187,40 @@ export const insertBranchCommitsFactory = return await q } -export async function getStreamCommitCounts( - streamIds: string[], - options?: Partial<{ ignoreGlobalsBranch: boolean }> -) { - if (!streamIds?.length) return [] +export const getStreamCommitCountsFactory = + (deps: { db: Knex }): GetStreamCommitCounts => + async (streamIds: string[], options?: Partial<{ ignoreGlobalsBranch: boolean }>) => { + if (!streamIds?.length) return [] - const { ignoreGlobalsBranch } = options || {} + const { ignoreGlobalsBranch } = options || {} - const q = StreamCommits.knex() - .select(StreamCommits.col.streamId) - .whereIn(StreamCommits.col.streamId, streamIds) - .count() - .groupBy(StreamCommits.col.streamId) + const q = tables + .streamCommits(deps.db) + .select(StreamCommits.col.streamId) + .whereIn(StreamCommits.col.streamId, streamIds) + .count() + .groupBy(StreamCommits.col.streamId) - if (ignoreGlobalsBranch) { - q.innerJoin( - BranchCommits.name, - StreamCommits.col.commitId, - BranchCommits.col.commitId - ) - .innerJoin(Branches.name, Branches.col.id, BranchCommits.col.branchId) - .andWhereNot(Branches.col.name, 'globals') + if (ignoreGlobalsBranch) { + q.innerJoin( + BranchCommits.name, + StreamCommits.col.commitId, + BranchCommits.col.commitId + ) + .innerJoin(Branches.name, Branches.col.id, BranchCommits.col.branchId) + .andWhereNot(Branches.col.name, 'globals') + } + + const results = (await q) as { streamId: string; count: string }[] + return results.map((r) => ({ ...r, count: parseInt(r.count) })) } - const results = (await q) as { streamId: string; count: string }[] - return results.map((r) => ({ ...r, count: parseInt(r.count) })) -} - -export async function getStreamCommitCount( - streamId: string, - options?: Partial<{ ignoreGlobalsBranch: boolean }> -) { - const [res] = await getStreamCommitCounts([streamId], options) - return res?.count || 0 -} +export const getStreamCommitCountFactory = + (deps: { db: Knex }): GetStreamCommitCount => + async (streamId: string, options?: Partial<{ ignoreGlobalsBranch: boolean }>) => { + const [res] = await getStreamCommitCountsFactory(deps)([streamId], options) + return res?.count || 0 + } export async function getCommitsAndTheirBranchIds(commitIds: string[]) { if (!commitIds.length) return [] @@ -457,62 +462,68 @@ export const getAllBranchCommitsFactory = ) } -export async function getUserStreamCommitCounts(params: { - userIds: string[] - /** - * Only include commits from public/discoverable streams - */ - publicOnly?: boolean -}) { - const { userIds, publicOnly } = params - if (!userIds?.length) return {} +export const getUserStreamCommitCountsFactory = + (deps: { db: Knex }): GetUserStreamCommitCounts => + async (params: { + userIds: string[] + /** + * Only include commits from public/discoverable streams + */ + publicOnly?: boolean + }) => { + const { userIds, publicOnly } = params + if (!userIds?.length) return {} - const q = StreamAcl.knex() - .select<{ userId: string; count: string }[]>([ - StreamAcl.col.userId, - knex.raw('COUNT(*)') - ]) - .join(StreamCommits.name, StreamCommits.col.streamId, StreamAcl.col.resourceId) - .whereIn(StreamAcl.col.userId, userIds) - .groupBy(StreamAcl.col.userId) + const q = tables + .streamAcl(deps.db) + .select<{ userId: string; count: string }[]>([ + StreamAcl.col.userId, + knex.raw('COUNT(*)') + ]) + .join(StreamCommits.name, StreamCommits.col.streamId, StreamAcl.col.resourceId) + .whereIn(StreamAcl.col.userId, userIds) + .groupBy(StreamAcl.col.userId) - if (publicOnly) { - q.join(Streams.name, Streams.col.id, StreamAcl.col.resourceId) - q.andWhere((q1) => { - q1.where(Streams.col.isPublic, true).orWhere(Streams.col.isDiscoverable, true) - }) + if (publicOnly) { + q.join(Streams.name, Streams.col.id, StreamAcl.col.resourceId) + q.andWhere((q1) => { + q1.where(Streams.col.isPublic, true).orWhere(Streams.col.isDiscoverable, true) + }) + } + + const res = await q + return mapValues(keyBy(res, 'userId'), (r) => parseInt(r.count)) } - const res = await q - return mapValues(keyBy(res, 'userId'), (r) => parseInt(r.count)) -} +export const getUserAuthoredCommitCountsFactory = + (deps: { db: Knex }): GetUserAuthoredCommitCounts => + async (params: { + userIds: string[] + /** + * Only include commits from public/discoverable streams + */ + publicOnly?: boolean + }) => { + const { userIds, publicOnly } = params + if (!userIds?.length) return {} -export async function getUserAuthoredCommitCounts(params: { - userIds: string[] - /** - * Only include commits from public/discoverable streams - */ - publicOnly?: boolean -}) { - const { userIds, publicOnly } = params - if (!userIds?.length) return {} + const q = tables + .commits(deps.db) + .select<{ authorId: string; count: string }[]>([ + Commits.col.author, + knex.raw('COUNT(*)') + ]) + .whereIn(Commits.col.author, userIds) + .groupBy(Commits.col.author) - const q = Commits.knex() - .select<{ authorId: string; count: string }[]>([ - Commits.col.author, - knex.raw('COUNT(*)') - ]) - .whereIn(Commits.col.author, userIds) - .groupBy(Commits.col.author) + if (publicOnly) { + q.join(StreamCommits.name, StreamCommits.col.commitId, Commits.col.id) + q.join(Streams.name, Streams.col.id, StreamCommits.col.streamId) + q.andWhere((q1) => { + q1.where(Streams.col.isPublic, true).orWhere(Streams.col.isDiscoverable, true) + }) + } - if (publicOnly) { - q.join(StreamCommits.name, StreamCommits.col.commitId, Commits.col.id) - q.join(Streams.name, Streams.col.id, StreamCommits.col.streamId) - q.andWhere((q1) => { - q1.where(Streams.col.isPublic, true).orWhere(Streams.col.isDiscoverable, true) - }) + const res = await q + return mapValues(keyBy(res, 'author'), (r) => parseInt(r.count)) } - - const res = await q - return mapValues(keyBy(res, 'author'), (r) => parseInt(r.count)) -} diff --git a/packages/server/modules/core/services/commit/retrieval.ts b/packages/server/modules/core/services/commit/retrieval.ts index d5c1a1b15..8a2feb22a 100644 --- a/packages/server/modules/core/services/commit/retrieval.ts +++ b/packages/server/modules/core/services/commit/retrieval.ts @@ -7,12 +7,10 @@ import { getBranchCommitsTotalCount, getPaginatedBranchCommits as getPaginatedBranchCommitsDb, getSpecificBranchCommitsFactory, + getStreamCommitCountFactory, PaginatedBranchCommitsParams } from '@/modules/core/repositories/commits' -import { - getCommitsByStreamId, - getCommitsTotalCountByStreamId -} from '@/modules/core/services/commits' +import { getCommitsByStreamId } from '@/modules/core/services/commits' import { BadRequestError } from '@/modules/shared/errors' import { db } from '@/db/knex' @@ -30,8 +28,7 @@ export async function getPaginatedStreamCommits( cursor: params.cursor, ignoreGlobalsBranch: true }) - const totalCount = await getCommitsTotalCountByStreamId({ - streamId, + const totalCount = await getStreamCommitCountFactory({ db })(streamId, { ignoreGlobalsBranch: true }) diff --git a/packages/server/modules/core/services/commits.js b/packages/server/modules/core/services/commits.js index 8044c6281..0847bd6ef 100644 --- a/packages/server/modules/core/services/commits.js +++ b/packages/server/modules/core/services/commits.js @@ -6,7 +6,6 @@ const Commits = () => knex('commits') const StreamCommits = () => knex('stream_commits') const { - getStreamCommitCount, getPaginatedBranchCommits, getBranchCommitsTotalCount } = require('@/modules/core/repositories/commits') @@ -80,10 +79,6 @@ module.exports = { return module.exports.getCommitsByBranchId({ branchId: myBranch.id, limit, cursor }) }, - async getCommitsTotalCountByStreamId({ streamId, ignoreGlobalsBranch }) { - return await getStreamCommitCount(streamId, { ignoreGlobalsBranch }) - }, - /** * @returns {Promise<{ * commits: import('@/modules/core/helpers/types').CommitRecord[], diff --git a/packages/server/modules/core/tests/commits.spec.js b/packages/server/modules/core/tests/commits.spec.js index cdd971340..717ad5506 100644 --- a/packages/server/modules/core/tests/commits.spec.js +++ b/packages/server/modules/core/tests/commits.spec.js @@ -11,7 +11,6 @@ const { getCommitsTotalCountByBranchName, getCommitsByBranchName, getCommitsByStreamId, - getCommitsTotalCountByStreamId, getCommitsByUserId } = require('../services/commits') const { @@ -36,7 +35,8 @@ const { insertBranchCommitsFactory, getCommitBranchFactory, switchCommitBranchFactory, - updateCommitFactory + updateCommitFactory, + getStreamCommitCountFactory } = require('@/modules/core/repositories/commits') const { deleteCommitAndNotifyFactory, @@ -102,6 +102,7 @@ const updateCommitAndNotify = updateCommitAndNotifyFactory({ markCommitStreamUpdated, markCommitBranchUpdated: markCommitBranchUpdatedFactory({ db }) }) +const getStreamCommitCount = getStreamCommitCountFactory({ db }) describe('Commits @core-commits', () => { const user = { @@ -379,7 +380,7 @@ describe('Commits @core-commits', () => { expect(commits.length).to.equal(10) expect(commits2.length).to.equal(5) - const c = await getCommitsTotalCountByStreamId({ streamId }) + const c = await getStreamCommitCount(streamId) expect(c).to.equal(15) })