Files
bigcapital/server/bin/bigcapital.js
Ahmed Bouhuolia a22c8395f3 feat: remove path alias.
feat: remove Webpack and depend on nodemon.
feat: refactoring expenses.
feat: optimize system users with caching.
feat: architecture tenant optimize.
2020-09-15 00:51:39 +02:00

203 lines
6.4 KiB
JavaScript

import commander from 'commander';
import color from 'colorette';
import argv from 'getopts'
import config from '../src/config';
import {
initSystemKnex,
getAllSystemTenants,
initTenantKnex,
exit,
success,
log,
} from './utils';
// - bigcapital system:migrate:latest
// - bigcapital system:migrate:rollback
// - bigcapital tenants:migrate:latest
// - bigcapital tenants:migrate:latest --tenant_id=XXX
// - bigcapital tenants:migrate:rollback
// - bigcapital tenants:migrate:rollback --tenant_id=XXX
// - bigcapital tenants:migrate:make
// - bigcapital system:migrate:make
// - bigcapital tenants:list
commander
.command('system:migrate:rollback')
.description('Migrate the system database of the application.')
.action(async () => {
try {
const sysKnex = await initSystemKnex();
const [batchNo, _log] = await sysKnex.migrate.rollback();
if (_log.length === 0) {
success(color.cyan('Already at the base migration'));
}
success(
color.green(
`Batch ${batchNo} rolled back: ${_log.length} migrations`
) + (argv.verbose ? `\n${color.cyan(_log.join('\n'))}` : '')
);
} catch(error) {
exit(error);
}
});
commander
.command('system:migrate:latest')
.description('Rollback latest mgiration of the system database.')
.action(async () => {
try {
const sysKnex = await initSystemKnex();
const [batchNo, log] = await sysKnex.migrate.latest();
if (log.length === 0) {
success(color.cyan('Already up to date'));
}
success(
color.green(`Batch ${batchNo} run: ${log.length} migrations`) +
(argv.verbose ? `\n${color.cyan(log.join('\n'))}` : '')
);
} catch(error) {
exit(error);
}
});
commander
.command('system:migrate:make <name>')
.description('Created a named migration file to the system database.')
.action(async (name) => {
const sysKnex = await initSystemKnex();
sysKnex.migrate.make(name).then((name) => {
success(color.green(`Created Migration: ${name}`));
}).catch(exit)
});
commander
.command('tenants:migrate:make <name>')
.description('Created a name migration file to the tenants databases.')
.action(async (name) => {
const sysKnex = await initTenantKnex();
sysKnex.migrate.make(name).then((name) => {
success(color.green(`Created Migration: ${name}`));
}).catch(exit)
});
commander
.command('tenants:list')
.description('Retrieve a list of all system tenants databases.')
.action(async (cmd) => {
try{
const sysKnex = await initSystemKnex();
const tenants = await getAllSystemTenants(sysKnex);
tenants.forEach((tenant) => {
const dbName = `${config.tenant.db_name_prefix}${tenant.organizationId}`;
console.log(`ID: ${tenant.id} | Organization ID: ${tenant.organizationId} | DB Name: ${dbName}`);
});
} catch(error) { exit(error); };
success('---');
});
commander
.command('tenants:migrate:rollback')
.description('Rollback the last batch of tenants migrations.')
.option('-t, --tenant_id [tenant_id]', 'Which tenant id do you migrate.')
.action(async (cmd) => {
try {
const sysKnex = await initSystemKnex();
const tenants = await getAllSystemTenants(sysKnex);
const tenantsOrgsIds = tenants.map((tenant) => tenant.organizationId);
if (cmd.tenant_id && tenantsOrgsIds.indexOf(cmd.tenant_id) === -1) {
exit(`The given tenant id ${cmd.tenant_id} is not exists.`);
}
const migrateOpers = [];
const migrateTenant = async (organizationId) => {
try {
const tenantKnex = await initTenantKnex(organizationId);
const [batchNo, _log] = await tenantKnex.migrate.rollback();
const tenantDb = `${config.tenant.db_name_prefix}${organizationId}`;
if (_log.length === 0) {
log(color.cyan('Already at the base migration'));
}
log(
color.green(
`Tenant: ${tenantDb} > Batch ${batchNo} rolled back: ${_log.length} migrations`
) + (argv.verbose ? `\n${color.cyan(_log.join('\n'))}` : '')
);
log('---------------');
} catch (error) { exit(error); }
};
if (!cmd.tenant_id) {
tenants.forEach((tenant) => {
const oper = migrateTenant(tenant.organizationId);
migrateOpers.push(oper);
});
} else {
const oper = migrateTenant(cmd.tenant_id);
migrateOpers.push(oper);
}
Promise.all(migrateOpers).then(() => {
success('All tenants are rollbacked.');
});
} catch (error) { exit(error); }
});
commander
.command('tenants:migrate:latest')
.description('Migrate all tenants or the given tenant id.')
.option('-t, --tenant_id [tenant_id]', 'Which tenant id do you migrate.')
.action(async (cmd) => {
try {
const sysKnex = await initSystemKnex();
const tenants = await getAllSystemTenants(sysKnex);
const tenantsOrgsIds = tenants.map(tenant => tenant.organizationId);
if (cmd.tenant_id && tenantsOrgsIds.indexOf(cmd.tenant_id) === -1) {
exit(`The given tenant id ${cmd.tenant_id} is not exists.`);
}
// Validate the tenant id exist first of all.
const migrateOpers = [];
const migrateTenant = async (organizationId) => {
try {
const tenantKnex = await initTenantKnex(organizationId);
const [batchNo, _log] = await tenantKnex.migrate.latest();
const tenantDb = `${config.tenant.db_name_prefix}${organizationId}`;
if (_log.length === 0) {
log(color.cyan('Already up to date'));
}
log(
color.green(`Tenant ${tenantDb} > Batch ${batchNo} run: ${_log.length} migrations`) +
(argv.verbose ? `\n${color.cyan(log.join('\n'))}` : '')
);
log('-------------------');
} catch (error) {
log(error);
}
}
if (!cmd.tenant_id) {
tenants.forEach((tenant) => {
const oper = migrateTenant(tenant.organizationId);
migrateOpers.push(oper);
});
} else {
const oper = migrateTenant(cmd.tenant_id);
migrateOpers.push(oper);
}
Promise.all(migrateOpers).then(() => {
success('All tenants are migrated.');
});
} catch (error) {
exit(error);
}
});
commander.parse(process.argv);