I have defined several models that use a Datasource \"db\" (mysql) for my environment.
Is there any way to have several datasources attached to those models, so I wo
For anyone still looking for a working answer to this, the solution for switching databases on the fly was to write a middleware script that examined the request path and then created a new DataSource connector, passing in a variable based on the req.path variable. For example, if the request path is /orders, then "orders" as a string would be saved in a variable, then we attached a new Datasource, passing in that variable for "orders". Here's the complete working code.
'use strict';
const DataSource = require('loopback-datasource-juggler').DataSource;
const app = require('../server.js');
module.exports = function() {
return function datasourceSelector(req, res, next) {
// Check if the API request path contains one of our models.
// We could use app.models() here, but that would also include
// models we don't want.
let $models = ['offers', 'orders', 'prducts'];
// $path expects to be 'offers', 'orders', 'prducts'.
let $path = req.path.toLowerCase().split("/")[1];
// Run our function if the request path is equal to one of
// our models, but not if it also includes 'count'. We don't
// want to run this twice unnecessarily.
if (($models.includes($path, 0)) && !(req.path.includes('count'))) {
// The angular customer-select form adds a true value
// to the selected property of only one customer model.
// So we search the customers for that 'selected' = true.
let customers = app.models.Customer;
// Customers.find() returns a Promise, so we need to get
// our selected customer from the results.
customers.find({"where": {"selected": true}}).then(function(result){
// Called if the operation succeeds.
let customerDb = result[0].name;
// Log the selected customer and the timestamp
// it was selected. Needed for debugging and optimization.
let date = new Date;
console.log(customerDb, $path+req.path, date);
// Use the existing veracore datasource config
// since we can use its environment variables.
let settings = app.dataSources.Veracore.settings;
// Clear out the veracore options array since that
// prevents us from changing databases.
settings.options = null;
// Add the selected customer to the new database value.
settings.database = customerDb;
try {
let dataSource = new DataSource(settings);
// Attach our models to the new database selection.
app.models.Offer.attachTo(dataSource);
app.models.Order.attachTo(dataSource);
app.models.Prduct.attachTo(dataSource);
} catch(err) {
console.error(err);
}
})
// Called if the customers.find() promise fails.
.catch(function(err){
console.error(err);
});
}
else {
// We need a better solution for paths like '/orders/count'.
console.log(req.path + ' was passed to datasourceSelector().');
}
next();
};
};