Skip to content

Commit

Permalink
[Issue #12]
Browse files Browse the repository at this point in the history
[Binary] Implemented the --db namespace for the greppy binary.
[DB-Store] Extended the MySQL backend adapter for the management methods
           which will be called by the greppy binary to perform the
           operations.
  • Loading branch information
Jack12816 committed Aug 21, 2013
1 parent c6f3190 commit ff58cfe
Show file tree
Hide file tree
Showing 7 changed files with 595 additions and 9 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
node_modules
npm-debug.log
310 changes: 310 additions & 0 deletions bin/commands/db.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,310 @@
/**
* List command
*
* @module greppy/cli/list
* @author Hermann Mayer <hermann.mayer92@gmail.com>
*/

var fs = require('fs');
var path = require('path');
var colors = require('colors');
var async = require('async');
var Table = require('tab');

exports.run = function(opts)
{
var printHelp = function()
{
var help = [
' Atomar Operations'.green.bold,
'',
' ' + 'create'.yellow + ' [adapter.connection]',
' Create all|the given connection backend based on the specified adapter.',
'',
' ' + 'drop'.yellow + ' [adapter.connection]',
' Drop all|the given connection(s) backend based on the specified adapter.',
'',
' ' + 'migrate'.yellow + ' [adapter.connection]',
' Run migrations for all|the given connection(s).',
'',
' ' + 'fill'.yellow + ' [adapter.connection]',
' Fill all|the given connection(s) with its fixture data.',
'',
' Combined Operations'.green.bold,
'',
' ' + 'build'.yellow + ' [adapter.connection]',
' Run these operation for all|the given connection(s):',
' * create',
' * migrate',
' * fill',
'',
' ' + 'rebuild'.yellow + ' [adapter.connection]',
' Run these operation for all|the given connection(s):',
' * drop',
' * create',
' * migrate',
' * fill'
].join('\n');

console.log(help);
}

if (opts.options.help) {
return printHelp();
}

var appPath = path.normalize(process.cwd() + '/');

var table = new Table.TableOutputStream({
omitHeader: true,
columns: [
{align: 'right', width: 32},
{align: 'left'}
]
});

var collectConfigs = function()
{
var configPath = appPath + 'app/config/';
var dbConfs = [];

fs.readdirSync(configPath).forEach(function(file) {

if (!file.match(/\.js$|\.json$/gi)) {
return;
}

var config = require(configPath + file);

if (config.database) {
dbConfs.push({
name : file.replace(/\.js$|\.json$/gi, ''),
config : config.database
});
}
});

return dbConfs;
}

var configExists = function(path, configs)
{
var path = path.split('.');
var backend = path[0];
var connection = path[1];

if (!backend || !connection) {
return false;
}

var result = false;

configs.some(function(config) {

config = config.config;

if (config.hasOwnProperty(backend)) {
if (config[backend].hasOwnProperty(connection)) {
result = config[backend][connection];
result.backend = backend;
result.connection = connection;
return true;
}
}
});

return result;
}

var allConfigPaths = function(configs)
{
var paths = [];

configs.forEach(function(config) {

Object.keys(config.config).forEach(function(backend) {

Object.keys(config.config[backend]).forEach(function(connection) {

paths.push(backend + '.' + connection)
});
});
});

return paths;
}

// No operations specified, we print the db-conf list for the cwd project
if (0 === opts.argv.length) {

var contextPath = appPath + 'app/context/';

if (!fs.existsSync(contextPath)) {
console.log(appPath.green.bold + ' is not a Greppy project.');
console.log();
return printHelp();
}

var configPath = appPath + 'app/config/';
var dbConfs = collectConfigs();

if (0 === Object.keys(dbConfs).length) {
console.log('No database configuration found.')
return;
}

dbConfs.forEach(function(config) {

Object.keys(config.config).forEach(function(backend) {

table.writeRow([
config.name.green.bold,
backend.white
]);

Object.keys(config.config[backend]).forEach(function(connection) {

var conConf = config.config[backend][connection];

table.writeRow([
connection.blue.bold,
conConf.username.yellow + '@'.white + conConf.host.cyan + '/'.white + conConf.db.magenta
]);
});

console.log();
});
});

return;
}

var commands = ['create', 'drop', 'migrate', 'fill', 'build', 'rebuild'];
var commandsChain = {};
var commandsToRun = [];
var currentOperation = '';

// Build the command chain
opts.argv.forEach(function(arg) {

if (-1 !== commands.indexOf(arg)) {

currentOperation = arg;
commandsChain[arg] = {
opts: []
};

return;
}

commandsChain[currentOperation].opts.push(arg);
});

var configs = collectConfigs();

Object.keys(commandsChain).forEach(function(command) {

if (0 === commandsChain[command].opts.length) {
commandsChain[command].opts = allConfigPaths(configs);
}

// Dereference combined operation build into atomic ones
if ('build' === command) {

['create', 'migrate', 'fill'].forEach(function(com) {

commandsToRun.push({
command : com,
opts : commandsChain[command].opts
});
});

return;
}

// Dereference combined operation build into atomic ones
if ('rebuild' === command) {

['drop', 'create', 'migrate', 'fill'].forEach(function(com) {

commandsToRun.push({
command : com,
opts : commandsChain[command].opts
});
});

return;
}

// Atomic operation
commandsToRun.push({
command : command,
opts : commandsChain[command].opts
});
});

// Run all operations in series
async.eachSeries(commandsToRun, function(command, callback) {

// Validate each given opt-path
async.map(command.opts, function(path, callback) {

var config = configExists(path, configs);

if (false === config) {
callback && callback('No configuration found for: ' + path.green.bold);
return;
}

callback && callback(undefined, config);

}, function(err, configs) {

if (err) {
callback && callback(err);
return;
}

console.log('Run ' + command.command.yellow + ' for ' + command.opts.join(', '));

// Run operation per config in series
async.eachSeries(configs, function(config, callback) {

global.logger = {
error : console.log,
info : console.log,
warn : console.log,
debug : console.log,
};

// Bootstrap the backend connection and run the operation
var connection = new (
require(__dirname + '/../../lib/db/adapter/' + config.backend)
)(config.connection, config);

console.log();

// Run the actual command
connection[command.command](callback);

}, function(err) {

if (err) {
callback && callback(err);
return;
}

callback && callback();
});
});

}, function(err) {

if (err) {
console.log(err);
return;
}

});
}

6 changes: 6 additions & 0 deletions bin/commands/stop.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@ exports.run = function(contexts, callback)
contexts = require('../helpers/context').getContextsByArgs(contexts);
var appPath = path.normalize(process.cwd() + '/');

if (!contexts) {
console.log(appPath.green.bold + ' is not a Greppy project.');
process.exit(1);
return;
}

var table = new Table.TableOutputStream({
omitHeader: true,
columns: [
Expand Down
Loading

0 comments on commit ff58cfe

Please sign in to comment.