Skip to content

Instantly share code, notes, and snippets.

@myndzi
Created January 13, 2014 16:41
Show Gist options
  • Save myndzi/8403458 to your computer and use it in GitHub Desktop.
Save myndzi/8403458 to your computer and use it in GitHub Desktop.
var prompt = require('promised-prompt'),
Promise = prompt.Promise;
prompt({
required: true
}).ask('db type?', {
key: 'db',
type: 'multi',
default: 'pg',
validator: [ 'pg' ]
}).ask({
key: 'rootUser',
question: 'root user?'
}).ask({
key: 'rootPass',
type: 'password',
question: 'root password?'
}).ask({
key: 'user',
question: 'client username?'
}).ask({
key: 'host',
question: 'host?',
default: 'localhost'
}).ask({
key: 'dbName',
question: 'database name?',
default: 'twitchbot'
}).ask({
key: 'port',
type: 'integer',
question: 'port?',
default: '5432'
}).then(function () {
switch (this.db) {
case 'pg':
var pg = this.pg = require('pg');
Promise.promisifyAll(pg);
var conString = [
'postgres', '://',
encodeURIComponent(this.rootUser), ':',
encodeURIComponent(this.rootPass), '@',
encodeURIComponent(this.host), ':',
encodeURIComponent(this.port), '/'
].join('');
console.log('OPENING DB CONNECTION');
return pg.connectAsync(conString).spread(function (client, done) {
Promise.promisifyAll(client);
this.client = client;
this.query = client.queryAsync.bind(client);
this.pgDone = done;
}.bind(this));
break;
default:
return Promise.reject('Unsupported database: ' + this.db);
break;
}
}).then(function () {
var self = this, client = self.client;
return self.query(
'SELECT 1 FROM pg_database WHERE datname = $1',
[ self.dbName ]
).then(function (res) {
if (res.rowCount === 0) {
var query = 'CREATE DATABASE ' + self.client.escapeIdentifier(self.dbName);
return self.query(query).then(function () {
console.log(query);
});
}
});
}).then(function () {
return this.query('BEGIN TRANSACTION');
}).then(function (res) {
var self = this, client = this.client;
return self.query(
'SELECT 1 FROM pg_roles WHERE rolname = $1',
[ self.user ]
).then(function (res) {
if (res.rowCount > 0) return;
return getRandomPass(24).then(function (password) {
self.pass = password;
var query = 'CREATE ROLE ' + client.escapeIdentifier(self.user) +
' WITH ENCRYPTED password ' + client.escapeLiteral(self.pass);
return self.query(query).then(function () {
console.log(query.replace(/(ENCRYPTED password).*?$/, '$1 *****'));
});
});
});
}).then(function () {
var self = this, client = this.client;
var query = 'GRANT ALL PRIVILEGES ON DATABASE ' + client.escapeIdentifier(self.dbName) +
' TO ' + client.escapeIdentifier(self.user);
return self.query(query).then(function () {
console.log(query)
});
}).ask('write configuration?', {
type: 'boolean',
default: 'N'
}).then(function (res) {
var config = {
user: this.user,
pass: this.pass,
host: this.host,
port: this.port,
database: this.dbName
};
if (res) {
return prompt().ask('filename?', {
default: 'config.json'
}).then(function (res) {
console.log('WRITING CONFIGURATION');
console.log('filename: ', res);
console.log(config);
})
}
}).then(function () {
console.log('DONE');
}).catch(function (err) {
console.log(err);
}).finally(function () {
this.pgDone();
console.log('CLOSING DB CONNECTION');
this.pg.end();
});
var ie = require('int-encoder'),
crypto = require('crypto');
var alpha = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ`~!@#$%^&*()[{]}/?=+\\|-_\'",<.>;:';
function getRandomPass(len) {
var deferred = Promise.defer();
var bytes = Math.ceil(Math.log(alpha.length)/Math.log(256)*len);
crypto.randomBytes(bytes, function (ex, buf) {
ie.alphabet(alpha);
var hex = buf.toString('hex'),
num = ie.encode(hex, 16);
// cut off the MSB, it won't have the full range available
deferred.resolve(num.slice(1));
});
return deferred.promise;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment