From 0a1f960729a99604c3583dcf57635e13689701fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20Bajto=C5=A1?= Date: Fri, 4 May 2018 15:02:22 +0200 Subject: [PATCH] fix: multiple instances of the same repository class Fix DefaultCrudRepository to re-use legacy juggler Models across all instances of the same Repository class. Before this change, each call of DefaultCrudRepository constructor was redefining the backing persisted model. This commit adds a caching mechanism to DefaultCrudRepository: when setting up a backing model, we check datasource's modelBuilder registry to find if the backing model was not already created by an older instance of the repository. --- docs/site/Repositories.md | 4 +++- .../src/repositories/legacy-juggler-bridge.ts | 16 ++++++++++++++-- .../repositories/legacy-juggler-bridge.unit.ts | 7 +++++++ 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/docs/site/Repositories.md b/docs/site/Repositories.md index 7c44ef5862dd..74156c11a528 100644 --- a/docs/site/Repositories.md +++ b/docs/site/Repositories.md @@ -9,7 +9,9 @@ summary: --- A Repository is a type of _Service_ that represents a collection of data within -a DataSource. +a DataSource. A repository class is a lightweight object, its instances can be +created with low runtime overhead. Typically a new repository instance is +created for each incoming request. ## Example Application diff --git a/packages/repository/src/repositories/legacy-juggler-bridge.ts b/packages/repository/src/repositories/legacy-juggler-bridge.ts index d191c14f275d..ecb78a0d009f 100644 --- a/packages/repository/src/repositories/legacy-juggler-bridge.ts +++ b/packages/repository/src/repositories/legacy-juggler-bridge.ts @@ -15,7 +15,7 @@ import { NamedParameters, PositionalParameters, } from '../common-types'; -import {Entity} from '../model'; +import {Entity, ModelDefinition} from '../model'; import {Filter, Where} from '../query'; import {EntityCrudRepository} from './repository'; @@ -88,7 +88,19 @@ export class DefaultCrudRepository `Entity ${entityClass.name} must have at least one id/pk property.`, ); - // Create an internal legacy Model attached to the datasource + this.setupPersistedModel(definition); + } + + // Create an internal legacy Model attached to the datasource + private setupPersistedModel(definition: ModelDefinition) { + const dataSource = this.dataSource; + + const model = dataSource.getModel(definition.name); + if (model) { + // The backing persisted model has been already defined. + this.modelClass = model as typeof juggler.PersistedModel; + return; + } // We need to convert property definitions from PropertyDefinition // to plain data object because of a juggler limitation diff --git a/packages/repository/test/unit/repositories/legacy-juggler-bridge.unit.ts b/packages/repository/test/unit/repositories/legacy-juggler-bridge.unit.ts index e567fee49f73..5249fa5069d5 100644 --- a/packages/repository/test/unit/repositories/legacy-juggler-bridge.unit.ts +++ b/packages/repository/test/unit/repositories/legacy-juggler-bridge.unit.ts @@ -67,6 +67,13 @@ describe('DefaultCrudRepository', () => { await model.deleteAll(); }); + it('shares the backing PersistedModel across repo instances', () => { + const model1 = new DefaultCrudRepository(Note, ds).modelClass; + const model2 = new DefaultCrudRepository(Note, ds).modelClass; + + expect(model1 === model2).to.be.true(); + }); + it('implements Repository.create()', async () => { const repo = new DefaultCrudRepository(Note, ds); const note = await repo.create({title: 't3', content: 'c3'});