Skip to content

Commit

Permalink
fix: multiple instances of the same repository class
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
bajtos committed May 10, 2018
1 parent a36e257 commit e18ecf3
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 3 deletions.
4 changes: 3 additions & 1 deletion docs/site/Repositories.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
2 changes: 2 additions & 0 deletions packages/repository/src/loopback-datasource-juggler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,8 @@ export declare namespace juggler {
properties?: AnyObject,
options?: Options,
): T;

modelBuilder: ModelBuilder;
}

/**
Expand Down
16 changes: 14 additions & 2 deletions packages/repository/src/repositories/legacy-juggler-bridge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand Down Expand Up @@ -91,7 +91,19 @@ export class DefaultCrudRepository<T extends Entity, ID>
`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.modelBuilder.models[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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,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'});
Expand Down

0 comments on commit e18ecf3

Please sign in to comment.