Skip to content

Commit

Permalink
fix(schema): fix issue around chaining withSchema
Browse files Browse the repository at this point in the history
fix #282
  • Loading branch information
thetutlage committed Jan 22, 2018
1 parent cf170b4 commit f03c6b7
Show file tree
Hide file tree
Showing 3 changed files with 441 additions and 298 deletions.
329 changes: 329 additions & 0 deletions src/Schema/chain.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,329 @@
'use strict'

/**
* adonis-schema
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

const GE = require('@adonisjs/generic-exceptions')

class SchemaChain {
constructor () {
this._deferredActions = []
this._scheduleFn = null
}

/**
* Select schema to be used with postgreSQL.
*
* @method withSchema
*
* @param {String} schema
*
* @chainable
*/
withSchema (schema) {
this._deferredActions.push({ name: 'withSchema', args: [schema] })
return this
}

/**
* Create a extension.
*
* NOTE: This action is deferred
*
* @method createExtension
*
* @param {String} extensionName
*
* @return {void}
*/
createExtension (extensionName) {
this._deferredActions.push({ name: 'createExtension', args: [extensionName] })
}

/**
* Create a extension if not already exists.
*
* NOTE: This action is deferred
*
* @method createExtensionIfNotExists
*
* @param {String} extensionName
*
* @return {void}
*/
createExtensionIfNotExists (extensionName) {
this._deferredActions.push({ name: 'createExtensionIfNotExists', args: [extensionName] })
}

/**
* Create a new table.
*
* NOTE: This action is deferred
*
* @method createTable
*
* @param {String} tableName
* @param {Function} callback
*
* @return {void}
*/
createTable (tableName, callback) {
this._deferredActions.push({ name: 'createTable', args: [tableName, callback] })
}

/**
* Create a new table if not already exists.
*
* NOTE: This action is deferred
*
* @method createTableIfNotExists
*
* @param {String} tableName
* @param {Function} callback
*
* @return {void}
*/
createTableIfNotExists (tableName, callback) {
this._deferredActions.push({ name: 'createTableIfNotExists', args: [tableName, callback] })
}

/**
* Rename existing table.
*
* NOTE: This action is deferred
*
* @method renameTable
*
* @param {String} fromTable
* @param {String} toTable
*
* @return {void}
*/
renameTable (fromTable, toTable) {
this._deferredActions.push({ name: 'renameTable', args: [fromTable, toTable] })
}

/**
* Drop existing extension.
*
* NOTE: This action is deferred
*
* @method dropExtension
*
* @param {String} extensionName
*
* @return {void}
*/
dropExtension (extensionName) {
this._deferredActions.push({ name: 'dropExtension', args: [extensionName] })
}

/**
* Drop extension only if it exists.
*
* NOTE: This action is deferred
*
* @method dropExtensionIfExists
*
* @param {String} extensionName
*
* @return {void}
*/
dropExtensionIfExists (extensionName) {
this._deferredActions.push({ name: 'dropExtensionIfExists', args: [extensionName] })
}

/**
* Drop existing table.
*
* NOTE: This action is deferred
*
* @method dropTable
*
* @param {String} tableName
*
* @return {void}
*/
dropTable (tableName) {
this._deferredActions.push({ name: 'dropTable', args: [tableName] })
}

/**
* Drop table only if it exists.
*
* NOTE: This action is deferred
*
* @method dropTableIfExists
*
* @param {String} tableName
*
* @return {void}
*/
dropTableIfExists (tableName) {
this._deferredActions.push({ name: 'dropTableIfExists', args: [tableName] })
}

/**
* Select table for altering it.
*
* NOTE: This action is deferred
*
* @method table
*
* @param {String} tableName
* @param {Function} callback
*
* @return {void}
*/
table (tableName, callback) {
this._deferredActions.push({ name: 'table', args: [tableName, callback] })
}

/* istanbul ignore next */
/**
* Run a raw SQL statement
*
* @method raw
*
* @param {String} statement
*
* @return {Object}
*
* @return {void}
*/
raw (statement) {
this._deferredActions.push({ name: 'raw', args: [statement] })
return this
}

/**
* Schedule a method to be executed in sequence with migrations
*
* @method schedule
*
* @param {Function} fn
*
* @return {void}
*/
schedule (fn) {
if (typeof (fn) !== 'function') {
throw GE.InvalidArgumentException.invalidParameter(`this.schedule expects 1st argument to be a function`)
}
this._scheduleFn = fn
}

/**
* Alias for @ref('Schema.table')
*
* @method alter
*/
alter (...args) {
return this.table(...args)
}

/**
* Alias for @ref('Schema.createTable')
*
* @method create
*/
create (...args) {
return this.createTable(...args)
}

/**
* Alias for @ref('Schema.createTableIfNotExists')
*
* @method createIfNotExists
*/
createIfNotExists (...args) {
return this.createTableIfNotExists(...args)
}

/**
* Alias for @ref('Schema.dropTable')
*
* @method drop
*/
drop (...args) {
return this.dropTable(...args)
}

/**
* Alias for @ref('Schema.dropTableIfExists')
*
* @method dropIfExists
*/
dropIfExists (...args) {
return this.dropTableIfExists(...args)
}

/**
* Alias for @ref('Schema.renameTable')
*
* @method rename
*/
rename (...args) {
return this.renameTable(...args)
}

/**
* Returns the SQL query for all the actions.
*
* @method toString
*
* @return {String}
*/
toString (schema) {
this._deferredActions.forEach((action) => (schema[action.name](...action.args)))
return schema.toString()
}

/**
* Executes the deferred actions on a single chain. This method will
* rollback the trx on error.
*
* @method execute
*
* @param {Object} trx
*
* @return {void}
*/
async execute (trx) {
/**
* If schedule fn is defined, then execute it. Within a chain a user
* can never have `schedule` and `deferredActions` together.
*/
if (typeof (this._scheduleFn) === 'function') {
try {
await this._scheduleFn(trx)
} catch (error) {
trx.rollback()
throw error
}
return
}

const schema = trx.schema

/**
* Looping over all the deferred actions
*/
this._deferredActions.forEach((action) => (schema[action.name](...action.args)))

try {
await schema
this._deferredActions = []
} catch (error) {
trx.rollback()
throw error
}
}
}

module.exports = SchemaChain

0 comments on commit f03c6b7

Please sign in to comment.