-
Notifications
You must be signed in to change notification settings - Fork 3
/
switch-datasource-mixin.js
86 lines (68 loc) · 2.91 KB
/
switch-datasource-mixin.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
var loopback = require('loopback');
module.exports = function(model, debug, dynamic_ds_mixin)
{
model.beforeRemote('**', function(remoteCtx, unused, next)
{
if (remoteCtx)
{
var ds_name = remoteCtx.req.headers.datasource;
if (ds_name)
{
var include = null;
// TODO: handle complex/hierarchical include
if (remoteCtx.args && remoteCtx.args.filter && remoteCtx.args.filter.include)
include = remoteCtx.args.filter.include;
// TODO generic
model.switchDataSource(ds_name, include);
}
}
next();
});
// NOTE: this method attaches all required models to a requested datasource
model.switchDataSource = function(ds_name, include)
{
if (!ds_name)
{
if (debug)
console.log(model.modelName, "getDS: no datasource");
throw new Error("DataSource: no datasource name defined for request");
}
var ds = model.app.dataSources[ds_name];
// if the data-source is invalid
if (!ds)
{
// see if we can inject a dynamically created data-source
if (dynamic_ds_mixin)
ds = dynamic_ds_mixin(model, ds_name);
// otherwise just return an error
if (!ds)
throw new Error("DataSource: " + ds_name + " not available");
}
// NOTE: this is to work arround a bug in the MS SQL connector which does not pass the request context when querying model relations
// NOTE: this is only working right now for the most simple 'include' case, when a single relation property is included in the query
if (typeof include === 'string')
{
// find relation that should be included
var relation = model.relations[include];
// it is a valid relation of the model
if (relation && relation.modelTo && relation.modelTo.modelName)
{
var target_mdl_name = relation.modelTo.modelName;
var target_mdl = model.app.models[target_mdl_name];
// also attach the relation target model to the correct data-source
if (target_mdl.dataSource.settings.name !== ds.settings.name)
target_mdl.attachTo(ds);
}
}
if (model.dataSource.settings.name === ds.settings.name)
{
if (debug)
console.log(model.modelName, "getDS: correct datasource is active -> " + ds_name);
return this.dataSource;
}
model.attachTo(ds);
if (debug)
console.log(model.modelName, "getDS: switched datasource -> " + ds_name);
return ds;
}
}