Skip to content

Commit

Permalink
feat(migrations): add support for making db actions
Browse files Browse the repository at this point in the history
this.db will allow to execute database actions using the database provider

Closes #53
  • Loading branch information
thetutlage committed Sep 30, 2016
1 parent 4e128f2 commit 073daa7
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 5 deletions.
22 changes: 20 additions & 2 deletions src/Migrations/Mixins/Migrate.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
const _ = require('lodash')
const CatLog = require('cat-log')
const cf = require('co-functional')
const co = require('co')
const CE = require('../../Exceptions')
const logger = new CatLog('adonis:lucid')

Expand Down Expand Up @@ -55,7 +56,24 @@ Migrate._translateActions = function (schemaInstance, direction) {
*/
Migrate._callSchemaActions = function (defination, connection) {
const builder = this.database.connection(connection).schema
return builder[defination.action](defination.key, this._wrapSchemaCallback(defination.callback))
/**
* Custom check to allow access the database provider and
* do custom stuff with support for co-routines.
*/
if (defination.action === 'db') {
return co.wrap(function * () {
return yield defination.callback(this.database)
}.bind(this))
}

/**
* co.wrap returns a function which returns a promise, so we
* need to wrap schema method inside a function to keep
* the API stable.
*/
return (function () {
return builder[defination.action](defination.key, this._wrapSchemaCallback(defination.callback))
}.bind(this))
}

/**
Expand Down Expand Up @@ -160,7 +178,7 @@ Migrate._executeMigrations = function * (migrations, direction, batchNumber) {
*/
Migrate._executeActions = function * (actions, file, direction, batchNumber) {
yield cf.forEachSerial(function * (action) {
return yield action
return yield action()
}, _.flatten(actions))

/**
Expand Down
20 changes: 20 additions & 0 deletions src/Schema/proxyHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,26 @@ proxyHandler.get = function (target, name) {
if (Object.keys(aliases).indexOf(name) > -1) {
name = aliases[name]
}

/**
* Trying to be more explicit here by adding the if clause
* on the name instead of checking the existence on
* callback and when key is a function but that will not
* be clear that this custom behaviour is required for
* this.db only.
*
* @example
* this.db(function () {})
*
* @alternate-check
* if (!callback && typeof (key) === 'function') {
* // not explicit
* }
*/
if (name === 'db') {
callback = key
key = null
}
target.actions.push({key, callback, action: name})
}
}
70 changes: 67 additions & 3 deletions test/unit/migrations.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,13 @@
*/

/* global describe, it, before,after */
const Migrations = require('../../src/Migrations')
const Database = require('../../src/Database')
const Schema = require('../../src/Schema')
const _ = require('lodash')
const Ioc = require('adonis-fold').Ioc
const chai = require('chai')
const cf = require('co-functional')
const Migrations = require('../../src/Migrations')
const Database = require('../../src/Database')
const Schema = require('../../src/Schema')
const filesFixtures = require('./fixtures/files')
const config = require('./helpers/config')
const expect = chai.expect
Expand Down Expand Up @@ -731,6 +732,7 @@ describe('Migrations', function () {
const migrationsCompleted = yield runner.database.table('adonis_migrations')
expect(migrationsCompleted).to.be.an('array')
expect(migrationsCompleted).to.have.length(0)
yield runner.database.schema.dropTable('adonis_migrations')
})

it('should return the sql output for rollback', function * () {
Expand All @@ -755,5 +757,67 @@ describe('Migrations', function () {
expect(response).to.have.length(1)
expect(response[0].file).to.equal('2015-01-20')
expect(response[0].queries).to.be.an('array')
yield runner.database.schema.dropTable('users')
yield runner.database.schema.dropTable('adonis_migrations')
})

it('should be able to access the database provider using this.db', function * () {
const Runner = new Migrations(Database, Config)
const runner = new Runner()
let db = null
class Users extends Schema {
up () {
this.db(function * (database) {
db = database
})
}
}
const migrations = {'2016-04-20': Users}
yield runner.up(migrations)
expect(db.table).to.be.a('function')
yield runner.database.schema.dropTable('adonis_migrations')
})

it('should be able to migrate a table data to a different column @fun', function * () {
const Runner = new Migrations(Database, Config)
const runner = new Runner()
class Users extends Schema {
up () {
this.create('users', (table) => {
table.increments()
table.string('username')
})

this.db(function * (database) {
yield database.table('users').insert([{username: 'foo'}, {username: 'bar'}])
})
}
}

class UsersMigrate extends Schema {
up () {
this.table('users', (table) => {
table.string('uname')
})

this.db(function * (database) {
const usernames = yield database.table('users').pluck('username')
yield cf.forEach(function * (username) {
yield database.table('users').where('username', username).update('uname', username)
}, usernames)
})

this.table('users', (table) => {
table.dropColumn('username')
})
}
}

const migrations = {'2016-04-20': Users, '2016-10-30': UsersMigrate}
yield runner.up(migrations)
const users = yield Database.table('users').pluck('uname')
expect(users).deep.equal(['foo', 'bar'])
yield runner.database.schema.dropTable('users')
yield runner.database.schema.dropTable('adonis_migrations')
})
})

0 comments on commit 073daa7

Please sign in to comment.