Small library that provides a way of implementing multi-tenancy using table prefixes.
It has a very simple API:
var knextancy = require('knextancy');
knextancy.tenant(knex, tenantId).then(function (tenantKnex) {
// the tenantKnex object contains the tenantId as an attribute
console.log(tenantKnex.tenantId);
tenantKnex('$_users').where({
first_name: 'Test',
last_name: 'User'
}).select('id')
});
Its tenant
method expects a knex
instance and a tenantId
and returns Promise for a special tenantKnex
instance that scopes every queries to the particular tenant.
The only requirement is that every query is written using the special $_
prefix for every table name.
Check out this example using knextancy with express and PostgreSQL database
Knextancy assures that all migrations are ran on a tenant's tables before returning its knex
instance.
This special naming convention also applies while writing migrations, for example:
'use strict';
exports.up = function(knex, Promise) {
return knex.schema.createTable('$_users', function (table) {
table.string('name');
});
};
exports.down = function(knex, Promise) {
return knex.schema.dropTable('users');
};
PS: You may have problems creating custom column index. I created a pull request fixing it few months ago. But knex team have not accepted it yet. While that pull request is not accepted is possible to fix it using a custom name for the index:
table.integer('groupId').index('index_$_groupId');
It also provides a handy Connect middleware that automatically creates a knex
instance and attaches it to the request
object for a kiven tetant based on a special HTTP header.
Bellow is a usage example:
var app = express();
app.use(knextancy.middleware(knex, { header: 'x-client-id' }));
app.get('/', function (req, res, next) {
req.knex.select().from('$_users').then(function (users) {
res.send(users);
}, next);
});
The knextancy.middleware
expects two parameters:
knex
instance;options.header
the name of the HTTP header that will contain the tenant id.
Allow execute all migrations/seed for all existing tenants at once.
Bellow is a usage example:
knextancy.setupAllTenants(knex).then(function () {
// done
});
Based in the migration tables in the current database is possible to fetch the existing tenants.
Bellow is a usage example:
knextancy.fetchTenants(knex).then(function (tenants) {
// ['01', '02']
});
To run the tests using Docker Compose:
docker-compose run --rm test bash
npm install # in case you have not installed yet
npm test
Licensed under The MIT License Redistributions of files must retain the above copyright notice.