Skip to content

Commit

Permalink
Merge pull request #25 from elhigu/tasks-for-db-create-drop-migrate
Browse files Browse the repository at this point in the history
Tasks for db create drop migrate
  • Loading branch information
elhigu authored Nov 2, 2017
2 parents 201eb22 + adf3f57 commit 878b6f7
Show file tree
Hide file tree
Showing 6 changed files with 208 additions and 11 deletions.
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ node_js:
- '5'
- '6'
- '7'
- '8'

notifications:
email: false
93 changes: 93 additions & 0 deletions features/objection/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ var _ = require('lodash')
, knex = require('knex')
, color = require('cli-color')
, log = require('dodo/logger').getLogger('dodo-objection.feature')
, moment = require('moment')
, path = require('path')
, fs = require('fs')
, createDbManager = require('knex-db-manager').databaseManagerFactory;

/**
Expand Down Expand Up @@ -152,6 +155,96 @@ module.exports = function(app, config) {
}
};

module.exports.tasks = [{
name: 'db-create',
run: function (featureConfig, serviceConfig, servicePath) {
const dbManager = createDbManager(featureConfig);
return dbManager.createDb()
.tap(res => dbManager.closeKnex())
.tap(res => dbManager.close())
.catch(err => {
dbManager.closeKnex();
dbManager.close();
throw err;
});
},
description: 'Creates database for the service (and owner user if necessary)'

}, {
name: 'db-migrate',
run: function (featureConfig, serviceConfig, servicePath) {
const dbManager = createDbManager(featureConfig);
return dbManager.migrateDb()
.tap(res => dbManager.closeKnex())
.tap(res => dbManager.close())
.catch(err => {
dbManager.closeKnex();
dbManager.close();
throw err;
});
},
description: 'Runs migrations of the service'

}, {
name: 'db-drop',
run: function (featureConfig, serviceConfig, servicePath) {
const dbManager = createDbManager(featureConfig);
return dbManager.dropDb()
.tap(res => dbManager.closeKnex())
.tap(res => dbManager.close())
.catch(err => {
dbManager.closeKnex();
dbManager.close();
throw err;
});
},
description: 'Drops database of the service'

}, {
name: 'new-migration',
run: function (featureConfig, serviceConfig, servicePath) {
const migrationName = process.env.MIGRATION_NAME || 'new_migration';
const currentUtc = moment().utc().format("YYYYMMDDHHmmss");

let configuredMigrationDir = featureConfig.knex.migrations.directory || 'migrations';
configuredMigrationDir = configuredMigrationDir.startsWith('/') ?
configuredMigrationDir :
path.join(servicePath, configuredMigrationDir);

// TODO: add migration suffix + template to config
const migrationFileName = path.join(configuredMigrationDir, currentUtc + '_' + migrationName + '.js');

var template = [
"'use strict';",
"//var _ = require('lodash');",
"",
"// see http://knexjs.org/#Schema ",
"exports.up = function (knex) {",
" return knex.schema.table('MyTable', function (table) {",
" table.timestamp('createTime').notNullable().defaultTo(knex.raw('now()'));",
" });",
"};",
"",
"exports.down = function (/* knex */) {",
"};"
];

try {
fs.writeFileSync(migrationFileName, template.join("\n"));
log.debug(`Created new migration script: ${migrationFileName}`);
} catch (err) {
log.error({ error: err }, 'Could not write migration file.');
throw err;
}

return {
createdFile: migrationFileName
};
},
description: 'Creates new migration for the service, pass name is MIGRATION_NAME environment variable'

}];

/**
* @private
*/
Expand Down
6 changes: 1 addition & 5 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,6 @@

var path = require('path');

// TODO: how to export stuff for test helper?

module.exports = {
featurePath: path.join(__dirname, 'features'),
serviceGulpTasks: null,
globalGulpTasks: null
featurePath: path.join(__dirname, 'features')
};
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "dodo-objection",
"description": "Objection.js ORM plugin for Dodo.js framework",
"version": "0.3.0",
"version": "0.4.0",
"private": false,
"author": {
"name": "Mikael Lepistö",
Expand All @@ -12,7 +12,8 @@
"bluebird": "^3.4.6",
"cli-color": "^1.1.0",
"knex-db-manager": "^0.4.0",
"lodash": "^4.16.2"
"lodash": "^4.16.2",
"moment": "^2.19.1"
},
"peerDependencies": {
"objection": ">=0.8",
Expand Down
114 changes: 110 additions & 4 deletions tests/feature.spec.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
'use strict';

var _ = require('lodash');
var ObjectionFeature = require('../features/objection');
var expect = require('chai').expect;
Expand Down Expand Up @@ -91,7 +93,7 @@ describe('integration', function () {
beforeEach(function () {
mockApp = {};

configFunction = function (req) {
let configFunction = function (req) {
return {
// normal knex config to describe db connection for app
knex: {
Expand Down Expand Up @@ -138,7 +140,7 @@ describe('integration', function () {
it('should be able to run migrations and bind models for 2 databases', function () {
var mockRequest1 = { database: 'dodo-objection-test-1' };
var mockRequest2 = { database: 'dodo-objection-test-2' };

var manager1 = feature.dbManager(mockRequest1);
var manager2 = feature.dbManager(mockRequest2);

Expand Down Expand Up @@ -168,7 +170,7 @@ describe('integration', function () {
})
.then(function () {
return feature.models(mockRequest2).Model2.query().insert({});
})
})
]).then(function () {
var db1Knex = feature.knex(mockRequest1);
var db2Knex = feature.knex(mockRequest2);
Expand All @@ -188,7 +190,7 @@ describe('integration', function () {
}),
]);
});
});
});

it('should close all DB connections', function () {
var mockRequest1 = { database: 'dodo-objection-test-1' };
Expand Down Expand Up @@ -217,6 +219,110 @@ describe('integration', function () {
});
});

describe('running tasks', () => {
let config = opts => {
return {
knex: {
client: 'postgres',
debug: false,
connection: {
host: process.env.POSTGRES_HOST || 'localhost',
port: process.env.POSTGRES_PORT || 5432,
database: opts.dbName || 'dodoobjtestdb',
user: process.env.POSTGRES_USER || 'dodoobjtestuser',
password: process.env.POSTGRES_USER_PW || undefined
},
migrations: {
tableName: 'migrations',
directory: opts.migrationDir || path.join(__dirname, 'migrations')
}
},
dbManager: {
superUser: process.env.POSTGRES_SUPERUSER || 'postgres',
superPassword: process.env.POSTGRES_SUPERUSER_PW || undefined
}
};
};

let tasks;
let dbManager;

before(() => {
tasks = _.keyBy(feature.constructor.tasks, 'name');
console.log(feature.dbManager);
dbManager = feature.dbManager({ database: 'dodomigrationsteaskcreateddb' });
return dbManager.dropDb();
});

it('should create new migration to service relative path', () => {
return Promise.resolve(tasks['new-migration'].run(
config({
migrationDir: './tempMigrations'
}),
{},
__dirname
)).then(res => {
expect(path.dirname(res.createdFile)).to.equal(`${__dirname}/tempMigrations`);
});
});

it('should create new migration to absolute path', () => {
return Promise.resolve(tasks['new-migration'].run(
config({
migrationDir: `${__dirname}/tempMigrations`
}),
{},
'whatever'
)).then(res => {
expect(path.dirname(res.createdFile)).to.equal(`${__dirname}/tempMigrations`);
});
});

it('should call create db', () => {
return Promise.resolve(tasks['db-create'].run(
config({
dbName: 'dodomigrationsteaskcreateddb'
}),
{},
'whatever'
))
.then(res => {
const knex = dbManager.knexInstance();
return dbManager.knexInstance().select(knex.raw('1 as foo'));
})
.then(res => dbManager.closeKnex().return(res)) // tap
.then(res => {
expect(res[0].foo).to.equal(1);
});
});

it('should call migrate db', () => {
return Promise.resolve(tasks['db-migrate'].run(
config({
dbName: 'dodomigrationsteaskcreateddb',
migrationDir: `${__dirname}/migrations`
}),
{},
__dirname
)).then(res => {
expect(res).to.have.length(2);
});
});

it('should call drop db', function () {
this.timeout(100000);
return Promise.resolve(tasks['db-drop'].run(
config({
dbName: 'dodomigrationsteaskcreateddb'
}),
{},
'whatever'
)).then(res => {
expect(res.command).to.equal('DROP');
});
});
});

it.skip('should support mysql!', function () {
expect(false).to.be.ok; // currently initialization code stuff is postrgres only
});
Expand Down
Empty file.

0 comments on commit 878b6f7

Please sign in to comment.