Skip to content

Commit 85347fa

Browse files
Nguyen Truong Minhbajtos
authored andcommitted
feat(repository): add datasource method in repository mixin
The repository now support multiple datasource. Each datasource can be injected with the key `datasource.${name}`. The loopback-datasource-juggler version is 3.15.2 to have datasource name via setting option.
1 parent b710c1b commit 85347fa

File tree

7 files changed

+78
-7
lines changed

7 files changed

+78
-7
lines changed
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"name": "ds",
2+
"name": "db",
33
"connector": "memory",
44
"file": "./data/db.json"
55
}

packages/example-getting-started/src/application.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import {
1818
Repository,
1919
DataSourceConstructor,
2020
RepositoryMixin,
21+
juggler,
2122
} from '@loopback/repository';
2223
/* tslint:enable:no-unused-variable */
2324

@@ -38,10 +39,7 @@ export class TodoApplication extends BootMixin(
3839
this.options && this.options.datasource
3940
? new DataSourceConstructor(this.options.datasource)
4041
: db;
41-
// TODO(bajtos) use app.dataSource() from @loopback/repository mixin
42-
// (app.dataSource() is not implemented there yet)
43-
// See https://github.com/strongloop/loopback-next/issues/743
44-
this.bind('datasource').to(datasource);
42+
this.dataSource(datasource);
4543
this.repository(TodoRepository);
4644
}
4745
}

packages/example-getting-started/src/repositories/todo.repository.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ export class TodoRepository extends DefaultCrudRepository<
1111
Todo,
1212
typeof Todo.prototype.id
1313
> {
14-
constructor(@inject('datasource') protected datasource: DataSourceType) {
14+
constructor(@inject('datasources.db') protected datasource: DataSourceType) {
1515
super(Todo, datasource);
1616
}
1717
}

packages/example-getting-started/test/acceptance/application.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ describe('Application', () => {
105105
port: 0,
106106
},
107107
datasource: {
108+
name: 'db',
108109
connector: 'memory',
109110
},
110111
});

packages/repository/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
},
2828
"dependencies": {
2929
"@loopback/context": "^0.1.1",
30-
"loopback-datasource-juggler": "^3.9.2"
30+
"loopback-datasource-juggler": "^3.15.2"
3131
},
3232
"files": [
3333
"README.md",

packages/repository/src/repository-mixin.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
import {Class} from './common-types';
77
import {Repository} from './repository';
8+
import {juggler} from './loopback-datasource-juggler';
89

910
// tslint:disable:no-any
1011

@@ -57,6 +58,32 @@ export function RepositoryMixin<T extends Class<any>>(superClass: T) {
5758
this.bind(repoKey).toClass(repo);
5859
}
5960

61+
/**
62+
* Add the dataSource to this application.
63+
*
64+
* @param dataSource The dataSource to add.
65+
* @param name The binding name of the datasource; defaults to dataSource.name
66+
*
67+
* ```ts
68+
*
69+
* const ds: juggler.DataSource = new DataSourceConstructor({
70+
* name: 'db',
71+
* connector: 'memory',
72+
* });
73+
*
74+
* app.dataSource(ds);
75+
*
76+
* // The datasource can be injected with
77+
* constructor(@inject('datasources.db') protected datasource: DataSourceType) {
78+
*
79+
* }
80+
* ```
81+
*/
82+
dataSource(dataSource: juggler.DataSource, name?: string) {
83+
const dataSourceKey = `datasources.${name || dataSource.name}`;
84+
this.bind(dataSourceKey).to(dataSource);
85+
}
86+
6087
/**
6188
* Add a component to this application. Also mounts
6289
* all the components repositories.

packages/repository/test/unit/repository-mixin/repository-mixin.test.ts

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,3 +111,48 @@ describe('RepositoryMixin', () => {
111111
expect(componentInstance).to.be.instanceOf(component);
112112
}
113113
});
114+
115+
describe('RepositoryMixin dataSource', () => {
116+
it('mixes into the target class', () => {
117+
const myApp = new AppWithRepoMixin();
118+
expect(typeof myApp.dataSource).to.be.eql('function');
119+
});
120+
121+
it('does not conflict with previous binding keys', () => {
122+
const myApp = new AppWithRepoMixin();
123+
const withoutDataSource = myApp.find('datasources.*');
124+
expect(withoutDataSource).to.be.empty();
125+
});
126+
127+
it('binds dataSource to a binding key using the dataSource name property', () => {
128+
const myApp = new AppWithRepoMixin();
129+
const fooDataSource: juggler.DataSource = new DataSourceConstructor({
130+
name: 'foo',
131+
connector: 'memory',
132+
});
133+
myApp.dataSource(fooDataSource);
134+
expectDataSourceToBeBound(myApp, fooDataSource, 'foo');
135+
});
136+
137+
it('binds dataSource to a binding key using the given name', () => {
138+
const myApp = new AppWithRepoMixin();
139+
const barDataSource: juggler.DataSource = new DataSourceConstructor({
140+
connector: 'memory',
141+
});
142+
myApp.dataSource(barDataSource, 'bar');
143+
expectDataSourceToBeBound(myApp, barDataSource, 'bar');
144+
});
145+
146+
const expectDataSourceToBeBound = (
147+
app: AppWithRepoMixin,
148+
ds: juggler.DataSource,
149+
name: string,
150+
) => {
151+
expect(app.find('datasources.*').map(d => d.key)).to.containEql(
152+
`datasources.${name}`,
153+
);
154+
expect(app.getSync(`datasources.${name}`)).to.be.eql(ds);
155+
};
156+
157+
class AppWithRepoMixin extends RepositoryMixin(Application) {}
158+
});

0 commit comments

Comments
 (0)