Skip to content

Commit

Permalink
Merge branch 'development' into staging
Browse files Browse the repository at this point in the history
  • Loading branch information
brianloveswords committed Feb 15, 2013
2 parents d37eb60 + 37bd7f0 commit d287bca
Show file tree
Hide file tree
Showing 27 changed files with 1,110 additions and 85 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
*.tar.gz
*.pid

/notes
/docs
/node_modules
/bin/update-docs
Expand Down
2 changes: 1 addition & 1 deletion .puppet-manifests/nodes.pp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

Package { require => Exec['apt-get update'] }

$node_version = "v0.6.20"
$node_version = "v0.8.19"
class { 'nvm':
node_version => $node_version,
}
Expand Down
3 changes: 1 addition & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
language: node_js
node_js:
- 0.6
- 0.8
notifications:
webhooks: http://bjb.io:7076
irc:
- "irc.mozilla.org#badges"
email:
Expand Down
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,8 @@ stop-issuer:
jenkins_build:
echo 'yep'

start:
./bin/db-migrate up
./node_modules/.bin/up -w -n 1 -p 8888 app.js

.PHONY: fakeissuer
33 changes: 32 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ and then back in windows you can fire up your favourite browser and connect to t

4. Run the test suite: `npm test`

5. Start your server: `./node_modules/.bin/up -w -p 8888 app.js`
5. Start your server: `make start`

No matter which way you choose, you should join the
[Open Badges Google Group](https://groups.google.com/forum/#!forum/openbadges). If
Expand All @@ -135,6 +135,37 @@ happen. If you're on OS X, you can also use
[Gas Mask](http://code.google.com/p/gmask/) for temporary hosts file switching
rather than having to manually edit /etc/hosts

### Database Migrations

If you need to modify the database schema, you'll want to create a
migration. You can do this as follows:

1. Come up with an alphanumeric name for your migration, e.g.
`add-issuer-column`.

2. Run `./bin/db-migrate create add-issuer-column`. This will create a new JS
file preixed with a timestamp in the `migrations` directory.
Something like the following should be displayed:

[INFO] Created migration at
migrations/20130213205310-add-issuer-column.js

3. Edit the new JS file as per the [node-db-migrate][] instructions.

4. Try out your migration using `./bin/db-migrate up`.

5. Try rolling back your migration using `./bin/db-migrate down`.

Finally, note that during development, `make start` automatically runs
`./bin/db-migrate up` for you. For production use, you'll need to manually
run this command yourself whenever you deploy changes that involve a
schema change.

If you want to write tests for your migration, check out
`test/migration.test.js` for inspiration.

[node-db-migrate]: https://github.com/nearinfinity/node-db-migrate#creating-migrations

## Related Projects
* https://github.com/lmorchard/django-badger -- Issuing app for Django
* https://github.com/ralphbean/tahrir -- A pyramid (python) app for issuing your own Open Badges
Expand Down
8 changes: 8 additions & 0 deletions app.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,14 @@ app.use(middleware.csrf({
app.use(middleware.cors({ whitelist: ['/_badges.*', '/issuer.*', '/baker', '/displayer/.+/group.*'] }));
app.configure('development', function () {
app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
var gitUtil = require('./lib/git-util');
try {
var sha = gitUtil.findSHA();
app.set('sha', sha);
}
catch (ex) {
logger.warn(ex.message);
}
});
app.configure('production', function () {
app.use(express.errorHandler());
Expand Down
99 changes: 99 additions & 0 deletions bin/db-migrate
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
#!/usr/bin/env node

var assert = require('assert');
var fs = require('fs');
var path = require('path');
var util = require('util');
var optimist = require('optimist');
var migrate = require('db-migrate');
var log = require('db-migrate/lib/log');
var mysql = require('../lib/mysql');
var migrations = require('../lib/migrations');

process.on('uncaughtException', function(err) {
log.error(err.stack);
process.exit(1);
});

var argv = optimist
.default({
verbose: false
})
.usage('Usage: db-migrate [up|down|create] migrationName [options]')

.describe('count', 'Max number of migrations to run.')
.alias('c', 'count')
.string('c')

.describe('dry-run', "Prints the SQL but doesn't run it.")
.boolean('dry-run')

.describe('verbose', 'Verbose mode.')
.alias('v', 'verbose')
.boolean('v')

.alias('h', 'help')
.alias('h', '?')
.boolean('h')
.argv;

if (argv.help || argv._.length == 0) {
optimist.showHelp();
process.exit(1);
}

global.verbose = argv.verbose;
global.dryRun = argv['dry-run'];
if(global.dryRun) {
log.info('dry run');
}

function executeCreate() {
if(argv._.length == 0) {
log.error("'migrationName' is required.");
optimist.showHelp();
process.exit(1);
}

argv.title = argv._.shift();
migrate.createMigration(argv.title, migrations.dir, function(err, migration) {
assert.ifError(err);
log.info(util.format('Created migration at %s', migration.path));
});
}

function onComplete(err) {
assert.ifError(err);
log.info('Done');
}

function run() {
var action = argv._.shift();
switch(action) {
case 'create':
executeCreate();
break;
case 'up':
case 'down':
if(verbose) {
log.info("Using settings:", mysql.getDatabaseConfig());
}
if(argv._.length > 0) {
argv.destination = argv._.shift().toString();
}
if(action == 'up') {
migrations.up(argv, onComplete);
} else {
migrations.down(argv, onComplete);
}
break;

default:
log.error('Invalid Action: Must be [up|down|create].');
optimist.showHelp();
process.exit(1);
break;
}
}

run();
38 changes: 38 additions & 0 deletions lib/git-util.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
var path = require('path');
var fs = require('fs');

function findSHAInHead(file) {
try {
var head = fs.readFileSync(file, 'utf8').trim();
}
catch (ex) {
throw new Error('Could not read HEAD file: ' + file);
}
if(head.indexOf('ref:') === 0){
var ref = head.split(/\s+/)[1].trim();
var gitDir = path.dirname(file);
var refFile = path.join(gitDir, ref);
return findSHAInRef(refFile);
}
else if(/^[0-9a-f]{40}$/m.test(head)) {
return head;
}
else {
throw new Error('Unable to parse HEAD file: ' + file);
}
};

function findSHAInRef(file) {
try {
var sha = fs.readFileSync(file, 'utf8').trim();
}
catch (ex) {
throw new Error('Could not read ref file: ' + file);
}
return sha;
}

exports.findSHA = function(file) {
var file = file || path.join(__dirname, '../.git/HEAD');
return findSHAInHead(file);
};
46 changes: 46 additions & 0 deletions lib/migrations.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
var path = require('path');
var migrate = require('db-migrate');
var mysql = require('./mysql');

module.exports = {
dir: path.resolve(__dirname, '..', 'migrations'),
up: function(options, callback) {
if (arguments.length == 1) {
callback = options;
options = {};
}
options.config = options.config || mysql.getDatabaseConfig();
options.count = options.count || Number.MAX_VALUE;
migrate.connect(options.config, function(err, migrator) {
if (err) throw err;
migrator.migrationsDir = module.exports.dir;
migrator.driver.createMigrationsTable(function(err) {
if (err) throw err;
migrator.up(options, function(err) {
migrator.driver.close();
callback(err);
});
});
});
},
down: function(options, callback) {
if (arguments.length == 1) {
callback = options;
options = {};
}
options.config = options.config || mysql.getDatabaseConfig();
if (!options.destination && !options.count)
options.count = 1;
migrate.connect(options.config, function(err, migrator) {
if (err) throw err;
migrator.migrationsDir = module.exports.dir;
migrator.driver.createMigrationsTable(function(err) {
if (err) throw err;
migrator.down(options, function(err) {
migrator.driver.close();
callback(err);
});
});
});
}
};
62 changes: 6 additions & 56 deletions lib/mysql.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,62 +3,13 @@ var async = require('async');
var conf = require('../lib/configuration').get('database');
var client = mysql.createClient(conf);
var testDb = "`test_" + conf.database + "`";

var usingTestDb = false;
var dbEncoding = 'utf8';

var schemas = [
"CREATE TABLE IF NOT EXISTS `user` ("
+ "id BIGINT AUTO_INCREMENT PRIMARY KEY,"
+ "email VARCHAR(255) UNIQUE NOT NULL,"
+ "last_login INT(13) NULL,"
+ "active BOOLEAN DEFAULT 1,"
+ "passwd VARCHAR(255),"
+ "salt TINYBLOB"
+ ") ENGINE=InnoDB;",

"CREATE TABLE IF NOT EXISTS `badge` ("
+ "id BIGINT AUTO_INCREMENT PRIMARY KEY,"
+ "user_id BIGINT,"
+ "type ENUM('hosted', 'signed') NOT NULL,"
+ "endpoint TINYTEXT,"
+ "public_key TEXT,"
+ "jwt TEXT,"
+ "image_path VARCHAR(255) NOT NULL,"
+ "rejected BOOLEAN DEFAULT 0,"
+ "body MEDIUMBLOB NOT NULL,"
+ "body_hash VARCHAR(255) UNIQUE NOT NULL,"
+ "validated_on TIMESTAMP DEFAULT CURRENT_TIMESTAMP,"
+ "FOREIGN KEY user_fkey (user_id) REFERENCES `user`(id)"
+ ") ENGINE=InnoDB;",

"CREATE TABLE IF NOT EXISTS `group` ("
+ "id BIGINT AUTO_INCREMENT PRIMARY KEY,"
+ "user_id BIGINT NOT NULL,"
+ "name VARCHAR(255),"
+ "url VARCHAR(255) UNIQUE,"
+ "public BOOLEAN DEFAULT 0,"
+ "badges MEDIUMBLOB NOT NULL,"
+ "FOREIGN KEY user_fkey (user_id) REFERENCES `user`(id)"
+ ") ENGINE=InnoDB;",

"CREATE TABLE IF NOT EXISTS `portfolio` ("
+ "`id` bigint AUTO_INCREMENT PRIMARY KEY,"
+ "`group_id` bigint NOT NULL,"
+ "`url` varchar(255) UNIQUE,"
+ "`title` varchar(128),"
+ "`subtitle` varchar(128),"
+ "`preamble` text,"
+ "`stories` mediumblob,"
+ "FOREIGN KEY `group_fkey` (`group_id`) REFERENCES `group`(`id`)"
+ ") ENGINE=InnoDB;"
];

exports.schemas = schemas;

function createSchema(schema, callback) { client.query(schema, callback) }
exports.createTables = function (callback) {
callback = callback || function(){};
async.map(schemas, createSchema, callback);
exports.getDatabaseConfig = function() {
var config = JSON.parse(JSON.stringify(conf));
if (usingTestDb) config.database = testDb.slice(1, -1);
return config;
};

exports.createTestDatabase = function (callback) {
Expand All @@ -67,6 +18,7 @@ exports.createTestDatabase = function (callback) {
};

exports.useTestDatabase = function (callback) {
usingTestDb = true;
client.query("USE " + testDb, callback);
};

Expand Down Expand Up @@ -101,5 +53,3 @@ client._upsert = function (table, fields, callback) {
values.push(fields['id']);
client.query(querystring, values, callback);
};

exports.createTables();
Loading

0 comments on commit d287bca

Please sign in to comment.