Skip to content

Commit

Permalink
Merge pull request #1 from daniel-slade/feature/S-01094
Browse files Browse the repository at this point in the history
Feature/s 01094
  • Loading branch information
TimBailey-pnk committed Apr 9, 2017
2 parents ec70753 + ef4ccc8 commit 19456ea
Show file tree
Hide file tree
Showing 17 changed files with 524 additions and 444 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ logs
pids
*.pid
*.seed
.git

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
Expand Down
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

Cassandra-migrate is a incremental migration tool for Cassandra.

## Version 1.3.0 update
- Allow migrations folder to be specified using the `--migrations` command-line switch.
- Refactored code to StandardJS.
- Replaced classes with factory functions.
- Allow keyspace to be created when using the `up` command with the `--create` command-line switch.

## Version 1.2.0 update
Just added support for more robust Cassandra client configuration, now you can provide a path to a configuration file that can specify a Cassandra client option object directly as javascript.
Cassandra client options configuration can found [here](http://docs.datastax.com/en/latest-nodejs-driver-api/global.html#ClientOptions). A user
Expand Down
160 changes: 79 additions & 81 deletions app.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
#!/usr/bin/env node
/*jslint node: true */
"use strict";
'use strict'

var program = require('commander');
var Common = require('./util/common');
var fs = require('fs');
var DB = require('./util/database');
const program = require('commander')
const Common = require('./util/common')
const fs = require('fs')
const db = require('./util/database')
const path = require('path')
const keyspace = require('./util/keyspace')

/**
* Usage information.
*/

var usage = [
const usage = [
'',
' example : ',
'',
Expand All @@ -28,116 +29,113 @@ var usage = [
' cassandra-migrate create <migration_name>. (Creates a new cassandra migration)',
'',
' cassandra-migrate create <migration_name> -t <template> (Creates a new cassandra migrate but uses a specified template instead of default).',
'',
''

].join('\n');
].join('\n')

program.on('--help', function () {
console.log(usage);
});
console.log(usage)
})

program
.version(JSON.parse(fs.readFileSync(__dirname + '/package.json', 'utf8')).version)
.option('-k, --keyspace "<keyspace>"', "The name of the keyspace to use.")
.option('-H, --hosts "<host,host>"', "Comma seperated host addresses. Default is [\"localhost\"].")
.option('-u, --username "<username>"', "database username")
.option('-p, --password "<password>"', "database password")
.option('-o, --optionFile "<pathToFile>"', "pass in a javascript option file for the cassandra driver, note that certain option file values can be overridden by provided flags")
.option('-m, --migrations "<pathToFolder>"', "pass in folder to use for migration files")
;
.version(JSON.parse(fs.readFileSync(path.join(__dirname, 'package.json'), 'utf8')).version)
.option('-k, --keyspace "<keyspace>"', 'The name of the keyspace to use.')
.option('-H, --hosts "<host,host>"', 'Comma seperated host addresses. Default is ["localhost"].')
.option('-u, --username "<username>"', 'database username')
.option('-p, --password "<password>"', 'database password')
.option('-o, --optionFile "<pathToFile>"', 'pass in a javascript option file for the cassandra driver, note that certain option file values can be overridden by provided flags')
.option('-m, --migrations "<pathToFolder>"', 'pass in folder to use for migration files')

program.name = 'cassandra-migrate';
program.name = 'cassandra-migrate'

program
.command('create <title>')
.description('initialize a new migration file with title.')
.option('-t, --template "<template>"', "sets the template for create")
.option('-t, --template "<template>"', 'sets the template for create')
.action((title, options) => {
let Create = require('./commands/create');
let create = new Create(fs, options.template, options.parent.migrations);
create.newMigration(title);
process.exit(0);
});
let Create = require('./commands/create')
let create = Create(options.template, options.parent.migrations)
create.newMigration(title)
process.exit(0)
})

program
.command('up')
.description('run pending migrations')
.option('-n, --num "<number>"', 'run migrations up to a specified migration number')
.option('-s, --skip "<number>"', "adds the specified migration to the migration table without actually running it", false)
.option('-s, --skip "<number>"', 'adds the specified migration to the migration table without actually running it', false)
.option('-c, --create', 'Create the keyspace if it doesn\'t exist.')
.action((options) => {
let db = new DB(program);
let common = new Common(fs, db);
common.createMigrationTable()
.then(common.getMigrationFiles(options.parent.migrations || process.cwd()))
.then(() => common.getMigrations())
.then(() => common.getMigrationSet('up', options.num))
const dbConnection = db.getConnection(program)
const common = Common(dbConnection)

// Parallelize Cassandra prep and scanning for migration files to save time.
Promise.all([
keyspace.checkKeyspace(program, options.create)
.then(() => common.createMigrationTable())
.then(() => common.getMigrations()),
common.getMigrationFiles(options.parent.migrations || process.cwd())
])
.then(migrationInfo => common.getMigrationSet(migrationInfo, 'up', options.num))
.then((migrationLists) => {
let Up = require('./commands/up');
let up = new Up(db, migrationLists);
const Up = require('./commands/up')
const up = Up(dbConnection, migrationLists)
if (!options.skip) {
console.log('processing migration lists');
console.log(migrationLists);
console.log('processing migration lists')
console.log(migrationLists)
}
up.runPending(options.skip)
.then(result => {
console.log(result);
process.exit(0);
console.log(result)
process.exit(0)
}, error => {
console.log(error);
process.exit(1);
});
console.log(error)
process.exit(1)
})
})
.catch(error => {
console.log(error);
process.exit(1);
});

});
console.log(error)
process.exit(1)
})
})

program
.command('down')
.description('roll back already run migrations')
.option('-n, --num "<number>"', 'rollback migrations down to a specified migration number')
.option('-s, --skip "<number>"', "removes the specified migration from the migration table without actually running it", false)
.option('-s, --skip "<number>"', 'removes the specified migration from the migration table without actually running it', false)
.action((options) => {
let db = new DB(program);
let common = new Common(fs, db);
common.createMigrationTable()
.then(common.getMigrationFiles(options.parent.migrations || process.cwd()))
.then(() => common.getMigrations())
.then(() => common.getMigrationSet('down', options.num))
const dbConnection = db.getConnection(program)
const common = Common(dbConnection)

// Parallelize Cassandra prep and scanning for migration files to save time.
Promise.all([
common.createMigrationTable()
.then(() => common.getMigrations()),
common.getMigrationFiles(options.parent.migrations || process.cwd())
])
.then(migrationInfo => common.getMigrationSet(migrationInfo, 'down', options.num))
.then((migrationLists) => {
console.log('processing migration lists');
let Down = require('./commands/down');
let down = new Down(db, migrationLists);
console.log('processing migration lists')
const Down = require('./commands/down')
const down = Down(dbConnection, migrationLists)
if (!options.skip) {
console.log('processing migration lists');
console.log(migrationLists);
console.log('processing migration lists')
console.log(migrationLists)
}
down.runPending(options.skip)
.then(result => {
console.log(result);
process.exit(0);
console.log(result)
process.exit(0)
}, error => {
console.log(error);
process.exit(1);
});
console.log(error)
process.exit(1)
})
})
.catch(error => {
console.log(error);
process.exit(1);
});
});
/*
//@TODO: add this functionality so that a cql client isn't directly required
program
.command('run')
.description('run cql directly')
.option('-f, --files', 'run cql commands from file', true)
.action(function(options){
var Run = new require('../commands/run')(options);
Run.cql();
process.exit(0);
});
*/
program.parse(process.argv);
console.log(error)
process.exit(1)
})
})

program.parse(process.argv)
52 changes: 26 additions & 26 deletions commands/create.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
'use strict';
'use strict'

/**
* A method to create incremental new migrations
Expand All @@ -7,15 +7,13 @@
* @param path
*/

class Create {
const create = (templateFile, folder, fsOverride) => {
const dateString = Math.floor(Date.now() / 1000) + ''
const migrationsFolder = folder || process.cwd()
const fs = fsOverride || require('fs')

constructor(fs, templateFile, migrationsFolder) {
this.fs = fs;
this.dateString = Math.floor(Date.now() / 1000) + '';
this.migrationsFolder = migrationsFolder || process.cwd()

var template = `
var migration${this.dateString} = {
let template = `
const migration${dateString} = {
up: function (db, handler) {
return Promise.resolve()
.then(() => {
Expand All @@ -35,27 +33,29 @@ var migration${this.dateString} = {
}
}
module.exports = migration${this.dateString}`;
module.exports = migration${dateString}`

if (templateFile) {
template = this.fs.readFileSync(templateFile);
let tpl = new Function("return `" + template + "`;");
template = tpl.call(this);
}
this.template = template;
if (templateFile) {
template = fs.readFileSync(templateFile)
/* eslint no-new-func: 0 */
let tpl = new Function('dateString', 'return `' + template + '`;')
template = tpl(dateString)
}

newMigration(title) {
var reTitle = /^[a-z0-9\_]*$/i;
if (!reTitle.test(title)) {
console.log("Invalid title. Only alphanumeric and '_' title is accepted.");
process.exit(1);
return {
newMigration: (title) => {
/* eslint no-useless-escape: 0 */
const reTitle = /^[a-z0-9\_]*$/i
if (!reTitle.test(title)) {
console.log("Invalid title. Only alphanumeric and '_' title is accepted.")
process.exit(1)
}

const fileName = `${dateString}_${title}.js`
fs.writeFileSync(`${migrationsFolder}/${fileName}`, template)
console.log(`Created a new migration file with name ${fileName}`)
}

var fileName = `${this.dateString}_${title}.js`;
this.fs.writeFileSync(`${this.migrationsFolder}/${fileName}`, this.template);
console.log(`Created a new migration file with name ${fileName}`);
}
}

module.exports = Create;
module.exports = create
Loading

0 comments on commit 19456ea

Please sign in to comment.