From 35ddd6501e7d7dcdf17f15330c1f4802231babf0 Mon Sep 17 00:00:00 2001 From: Kristaps Fabians Geikins Date: Fri, 18 Oct 2024 16:43:02 +0300 Subject: [PATCH] chore(server): core IoC #93 - getObjectChildrenStreamFactory --- .../modules/core/domain/objects/operations.ts | 6 +++ .../modules/core/repositories/objects.ts | 37 ++++++++++++++++++- packages/server/modules/core/rest/download.js | 7 +++- .../server/modules/core/services/objects.js | 32 ---------------- .../server/modules/core/tests/objects.spec.js | 7 ++-- 5 files changed, 51 insertions(+), 38 deletions(-) diff --git a/packages/server/modules/core/domain/objects/operations.ts b/packages/server/modules/core/domain/objects/operations.ts index 9cef76281..3a118546b 100644 --- a/packages/server/modules/core/domain/objects/operations.ts +++ b/packages/server/modules/core/domain/objects/operations.ts @@ -8,6 +8,7 @@ import { import { BatchedSelectOptions } from '@/modules/shared/helpers/dbHelper' import { Nullable, Optional } from '@speckle/shared' import { Knex } from 'knex' +import type stream from 'node:stream' export type GetStreamObjects = ( streamId: string, @@ -48,6 +49,11 @@ export type StoreClosuresIfNotFound = ( closures: SpeckleObjectClosureEntry[] ) => Promise +export type GetObjectChildrenStream = (params: { + streamId: string + objectId: string +}) => Promise> + export type CreateObject = (params: { streamId: string object: RawSpeckleObject diff --git a/packages/server/modules/core/repositories/objects.ts b/packages/server/modules/core/repositories/objects.ts index 7750fde7a..09b2b6611 100644 --- a/packages/server/modules/core/repositories/objects.ts +++ b/packages/server/modules/core/repositories/objects.ts @@ -1,5 +1,5 @@ import { Optional } from '@speckle/shared' -import { buildTableHelper, Objects } from '@/modules/core/dbSchema' +import { buildTableHelper, knex, Objects } from '@/modules/core/dbSchema' import { ObjectChildrenClosureRecord, ObjectRecord } from '@/modules/core/helpers/types' import { BatchedSelectOptions, @@ -10,6 +10,7 @@ import { GetBatchedStreamObjects, GetFormattedObject, GetObject, + GetObjectChildrenStream, GetStreamObjects, StoreClosuresIfNotFound, StoreObjects, @@ -128,3 +129,37 @@ export const storeClosuresIfNotFoundFactory = .onConflict() .ignore() } + +export const getObjectChildrenStreamFactory = + (deps: { db: Knex }): GetObjectChildrenStream => + async ({ streamId, objectId }) => { + const q = deps.db.with( + 'object_children_closure', + knex.raw( + `SELECT objects.id as parent, d.key as child, d.value as mindepth, ? as "streamId" + FROM objects + JOIN jsonb_each_text(objects.data->'__closure') d ON true + where objects.id = ?`, + [streamId, objectId] + ) + ) + q.select('id') + q.select(knex.raw('data::text as "dataText"')) + q.from('object_children_closure') + + q.rightJoin('objects', function () { + this.on('objects.streamId', '=', 'object_children_closure.streamId').andOn( + 'objects.id', + '=', + 'object_children_closure.child' + ) + }) + .where( + knex.raw('object_children_closure."streamId" = ? AND parent = ?', [ + streamId, + objectId + ]) + ) + .orderBy('objects.id') + return q.stream({ highWaterMark: 500 }) + } diff --git a/packages/server/modules/core/rest/download.js b/packages/server/modules/core/rest/download.js index a26191b01..bb0589091 100644 --- a/packages/server/modules/core/rest/download.js +++ b/packages/server/modules/core/rest/download.js @@ -4,14 +4,17 @@ const { corsMiddleware } = require('@/modules/core/configs/cors') const { validatePermissionsReadStream } = require('./authUtils') -const { getObjectChildrenStream } = require('../services/objects') const { SpeckleObjectsStream } = require('./speckleObjectsStream') const { pipeline, PassThrough } = require('stream') const { logger } = require('@/logging/logging') -const { getFormattedObjectFactory } = require('@/modules/core/repositories/objects') +const { + getFormattedObjectFactory, + getObjectChildrenStreamFactory +} = require('@/modules/core/repositories/objects') const { db } = require('@/db/knex') const getObject = getFormattedObjectFactory({ db }) +const getObjectChildrenStream = getObjectChildrenStreamFactory({ db }) module.exports = (app) => { app.options('/objects/:streamId/:objectId', corsMiddleware()) diff --git a/packages/server/modules/core/services/objects.js b/packages/server/modules/core/services/objects.js index 08db8dac9..0cdabf4c4 100644 --- a/packages/server/modules/core/services/objects.js +++ b/packages/server/modules/core/services/objects.js @@ -5,38 +5,6 @@ const knex = require(`@/db/knex`) const Objects = () => knex('objects') module.exports = { - async getObjectChildrenStream({ streamId, objectId }) { - const q = knex.with( - 'object_children_closure', - knex.raw( - `SELECT objects.id as parent, d.key as child, d.value as mindepth, ? as "streamId" - FROM objects - JOIN jsonb_each_text(objects.data->'__closure') d ON true - where objects.id = ?`, - [streamId, objectId] - ) - ) - q.select('id') - q.select(knex.raw('data::text as "dataText"')) - q.from('object_children_closure') - - q.rightJoin('objects', function () { - this.on('objects.streamId', '=', 'object_children_closure.streamId').andOn( - 'objects.id', - '=', - 'object_children_closure.child' - ) - }) - .where( - knex.raw('object_children_closure."streamId" = ? AND parent = ?', [ - streamId, - objectId - ]) - ) - .orderBy('objects.id') - return q.stream({ highWaterMark: 500 }) - }, - /** * @returns {Promise<{objects: import('@/modules/core/helpers/types').ObjectRecord[], cursor: string | null}>} */ diff --git a/packages/server/modules/core/tests/objects.spec.js b/packages/server/modules/core/tests/objects.spec.js index e4ed4587f..5480b679e 100644 --- a/packages/server/modules/core/tests/objects.spec.js +++ b/packages/server/modules/core/tests/objects.spec.js @@ -10,8 +10,7 @@ const { getAnIdForThisOnePlease } = require('@/test/helpers') const { getObjects, getObjectChildren, - getObjectChildrenQuery, - getObjectChildrenStream + getObjectChildrenQuery } = require('../services/objects') const { getStreamFactory, @@ -86,7 +85,8 @@ const { storeSingleObjectIfNotFoundFactory, storeClosuresIfNotFoundFactory, storeObjectsIfNotFoundFactory, - getFormattedObjectFactory + getFormattedObjectFactory, + getObjectChildrenStreamFactory } = require('@/modules/core/repositories/objects') const sampleCommit = JSON.parse(`{ @@ -189,6 +189,7 @@ const createObjects = createObjectsFactory({ storeClosuresIfNotFound: storeClosuresIfNotFoundFactory({ db }) }) const getObject = getFormattedObjectFactory({ db }) +const getObjectChildrenStream = getObjectChildrenStreamFactory({ db }) describe('Objects @core-objects', () => { const userOne = {