Skip to content

Commit

Permalink
Merge branch 'release-3.0.7'
Browse files Browse the repository at this point in the history
  • Loading branch information
thetutlage committed Oct 4, 2016
2 parents 4e128f2 + 893b9d5 commit 26ea4bd
Show file tree
Hide file tree
Showing 15 changed files with 391 additions and 33 deletions.
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
<a name="3.0.7"></a>
## [3.0.7](https://github.com/adonisjs/adonis-lucid/compare/v3.0.6...v3.0.7) (2016-10-04)


### Features

* **database:** add support for table prefixing ([22399a0](https://github.com/adonisjs/adonis-lucid/commit/22399a0)), closes [#58](https://github.com/adonisjs/adonis-lucid/issues/58)
* **migrations:** add support for making db actions ([073daa7](https://github.com/adonisjs/adonis-lucid/commit/073daa7)), closes [#53](https://github.com/adonisjs/adonis-lucid/issues/53)



<a name="3.0.6"></a>
## [3.0.6](https://github.com/adonisjs/adonis-lucid/compare/v3.0.5...v3.0.6) (2016-09-27)

Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@
In favor of active development we accept contributions from everyone. You can contribute by submitting a bug, creating pull requests or even by improving documentation.

Below is the guide to be followed strictly before submitting your pull requests.
http://adonisjs.com/docs/2.0/contributing
http://adonisjs.com/docs/contributing
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"directories": {
"test": "test"
},
"version": "3.0.6",
"version": "3.0.7",
"scripts": {
"lint": "standard src/**/*.js src/**/**/*.js src/**/**/**/*.js lib/*.js test/**/*.js providers/*.js",
"test:all": "DB=sqlite3 npm run test && DB=mysql npm run test && DB=pg npm run test",
Expand Down
57 changes: 57 additions & 0 deletions src/Database/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,24 @@ Database.connection = function (connection) {
client.client.QueryBuilder.prototype.forPage = Database.forPage
client.client.QueryBuilder.prototype.paginate = Database.paginate
client.client.QueryBuilder.prototype.chunk = Database.chunk
client.client.QueryBuilder.prototype._originalTable = client.client.QueryBuilder.prototype.table
client.client.QueryBuilder.prototype.table = Database.table
client.client.QueryBuilder.prototype.from = Database.table
client.client.QueryBuilder.prototype.into = Database.table
client.client.QueryBuilder.prototype.withPrefix = Database.withPrefix
client.client.QueryBuilder.prototype.withoutPrefix = Database.withoutPrefix

/**
* Adding methods on the client if withoutPrefix or withPrefix
* is called directly it will return the query builder.
*/
client.withoutPrefix = function () {
return new this.client.QueryBuilder(this.client).withoutPrefix()
}
client.withPrefix = function (prefix) {
return new this.client.QueryBuilder(this.client).withPrefix(prefix)
}

connectionPools[connection] = client
}

Expand Down Expand Up @@ -339,6 +357,45 @@ Database.chunk = function * (limit, cb, page) {
}
}

/**
* Overriding the orginal knex.table method to prefix
* the table name based upon the prefix option
* defined in the config
*
* @param {String} tableName
*
* @return {Object}
*/
Database.table = function (tableName) {
const prefix = this._instancePrefix || this.client.config.prefix
const prefixedTableName = (prefix && !this._skipPrefix) ? `${prefix}${tableName}`: tableName
this._originalTable(prefixedTableName)
return this
}

/**
* Skipping the prefix for a single query
*
* @return {Object}
*/
Database.withoutPrefix = function () {
this._skipPrefix = true
return this
}

/**
* Changing the prefix for a given query
*
* @param {String} prefix
*
* @return {Object}
*/
Database.withPrefix = function (prefix) {
this._instancePrefix = prefix
return this
}


/**
* these methods are not proxied and instead actual implementations
* are returned
Expand Down
22 changes: 22 additions & 0 deletions src/Lucid/Model/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,28 @@ class Model {
return util.makeTableName(this)
}

/**
* Returns a custom prefix to be used for selecting the database
* table for a given model
*
* @return {String}
*
* @public
*/
static get prefix () {
return null
}

/**
* A getter defining whether or not to skip
* table prefixing for this model.
*
* @return {Boolean}
*/
static get skipPrefix () {
return false
}

/**
* primary key to be used for given table. Same key is used for fetching
* associations. Defaults to id
Expand Down
11 changes: 10 additions & 1 deletion src/Lucid/QueryBuilder/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,16 @@ class QueryBuilder {
const Database = Ioc.use('Adonis/Src/Database')
this.HostModel = HostModel
this.queryBuilder = Database.connection(this.HostModel.connection)
this.modelQueryBuilder = this.queryBuilder(this.HostModel.table)
this.modelQueryBuilder = null

if (HostModel.prefix && !HostModel.skipPrefix) {
this.modelQueryBuilder = this.queryBuilder.withPrefix(HostModel.prefix).table(this.HostModel.table)
} else if (HostModel.skipPrefix) {
this.modelQueryBuilder = this.queryBuilder.withoutPrefix().table(this.HostModel.table)
} else {
this.modelQueryBuilder = this.queryBuilder.table(this.HostModel.table)
}

this.avoidTrashed = false
this.eagerLoad = new EagerLoad()
return new Proxy(this, proxyHandler)
Expand Down
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})
}
}
65 changes: 65 additions & 0 deletions test/unit/database.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -261,4 +261,69 @@ describe('Database provider', function () {
})
expect(callbackCalledForTimes).to.equal(allUsers.length)
})

it('should be able to prefix the database table using a configuration option', function * () {
Database._setConfigProvider(config.withPrefix)
const query = Database.table('users').toSQL()
expect(queryHelpers.formatQuery(query.sql)).to.equal(queryHelpers.formatQuery('select * from "ad_users"'))
})

it('should be able to prefix the database table when table method is called after other methods', function * () {
const query = Database.where('username', 'foo').table('users').toSQL()
expect(queryHelpers.formatQuery(query.sql)).to.equal(queryHelpers.formatQuery('select * from "ad_users" where "username" = ?'))
})

it('should be able to prefix the database table when from method is used', function * () {
const query = Database.from('users').toSQL()
expect(queryHelpers.formatQuery(query.sql)).to.equal(queryHelpers.formatQuery('select * from "ad_users"'))
})

it('should be able to prefix the database table when from method is called after other methods', function * () {
const query = Database.where('username', 'foo').from('users').toSQL()
expect(queryHelpers.formatQuery(query.sql)).to.equal(queryHelpers.formatQuery('select * from "ad_users" where "username" = ?'))
})

it('should be able to prefix the database table when into method is used', function * () {
const query = Database.into('users').toSQL()
expect(queryHelpers.formatQuery(query.sql)).to.equal(queryHelpers.formatQuery('select * from "ad_users"'))
})

it('should be able to prefix the database table when into method is called after other methods', function * () {
const query = Database.where('username', 'foo').into('users').toSQL()
expect(queryHelpers.formatQuery(query.sql)).to.equal(queryHelpers.formatQuery('select * from "ad_users" where "username" = ?'))
})

it('should be able to remove the prefix using the withoutPrefix method', function * () {
const query = Database.withoutPrefix().table('users').toSQL()
expect(queryHelpers.formatQuery(query.sql)).to.equal(queryHelpers.formatQuery('select * from "users"'))
})

it('should be able to remove the prefix when withoutPrefix method is called after other methods', function * () {
const query = Database.where('username', 'foo').withoutPrefix().table('users').toSQL()
expect(queryHelpers.formatQuery(query.sql)).to.equal(queryHelpers.formatQuery('select * from "users" where "username" = ?'))
})

it('should be able to change the prefix using the withPrefix method', function * () {
const query = Database.withPrefix('k_').table('users').toSQL()
expect(queryHelpers.formatQuery(query.sql)).to.equal(queryHelpers.formatQuery('select * from "k_users"'))
})

it('should be able to remove the prefix when withPrefix method is called after other methods', function * () {
const query = Database.where('username', 'foo').withPrefix('k_').table('users').toSQL()
expect(queryHelpers.formatQuery(query.sql)).to.equal(queryHelpers.formatQuery('select * from "k_users" where "username" = ?'))
})

it('should not mess the query builder instance when withPrefix is called on multiple queries at same time', function * () {
const query = Database.where('username', 'foo').withPrefix('k_').table('users')
const query1 = Database.where('username', 'foo').table('users')
expect(queryHelpers.formatQuery(query.toSQL().sql)).to.equal(queryHelpers.formatQuery('select * from "k_users" where "username" = ?'))
expect(queryHelpers.formatQuery(query1.toSQL().sql)).to.equal(queryHelpers.formatQuery('select * from "ad_users" where "username" = ?'))
})

it('should not mess the query builder instance when withoutPrefix is called on multiple queries at same time', function * () {
const query = Database.where('username', 'foo').withoutPrefix().table('users')
const query1 = Database.where('username', 'foo').table('users')
expect(queryHelpers.formatQuery(query.toSQL().sql)).to.equal(queryHelpers.formatQuery('select * from "users" where "username" = ?'))
expect(queryHelpers.formatQuery(query1.toSQL().sql)).to.equal(queryHelpers.formatQuery('select * from "ad_users" where "username" = ?'))
})
})
59 changes: 34 additions & 25 deletions test/unit/helpers/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,38 +8,47 @@
const mysqlConnections = require('./mysqlConnections')
const postgresConnection = require('./postgresConnection')
const sqliteConnections = require('./sqliteConnections')
const get = function (key, hasPrefix) {
if (key === 'database.migrationsTable') {
return 'adonis_migrations'
}

module.exports = {
get: function (key) {
if (key === 'database.migrationsTable') {
return 'adonis_migrations'
}
if (key === 'database.connection') {
return process.env.DB
}
if (key === 'database.connection') {
return process.env.DB
}

if (key === 'database.sqlite3') {
return sqliteConnections.default
}
if (key === 'database.sqlite3') {
return hasPrefix ? sqliteConnections.defaultPrefix : sqliteConnections.default
}

if (key === 'database.mysql') {
return mysqlConnections.default
}
if (key === 'database.mysql') {
return hasPrefix ? mysqlConnections.defaultPrefix : mysqlConnections.default
}

if (key === 'database.pg') {
return postgresConnection.default
}
if (key === 'database.pg') {
return hasPrefix ? postgresConnection.defaultPrefix : postgresConnection.default
}

if (key === 'database.alternateConnection' && process.env.DB === 'sqlite3') {
return sqliteConnections.alternateConnection
}
if (key === 'database.alternateConnection' && process.env.DB === 'sqlite3') {
return sqliteConnections.alternateConnection
}

if (key === 'database.alternateConnection' && process.env.DB === 'mysql') {
return mysqlConnections.alternateConnection
}
if (key === 'database.alternateConnection' && process.env.DB === 'mysql') {
return mysqlConnections.alternateConnection
}

if (key === 'database.alternateConnection' && process.env.DB === 'pg') {
return postgresConnection.alternateConnection
if (key === 'database.alternateConnection' && process.env.DB === 'pg') {
return postgresConnection.alternateConnection
}
}

module.exports = {
get: function (key) {
return get(key, false)
},
withPrefix: {
get: function (key) {
return get(key, true)
}
}
}
10 changes: 10 additions & 0 deletions test/unit/helpers/mysqlConnections.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,15 @@ module.exports = {
password : '',
database : 'alternate'
}
},

defaultPrefix : {
client: 'mysql',
connection: {
user : 'root',
password : '',
database : 'default'
},
prefix: 'ad_'
}
}
10 changes: 10 additions & 0 deletions test/unit/helpers/postgresConnection.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,15 @@ module.exports = {
password : '',
database : 'alternate'
}
},

defaultPrefix : {
client: 'pg',
connection: {
user: '',
password : '',
database : 'default'
},
prefix: 'ad_'
}
}
Loading

0 comments on commit 26ea4bd

Please sign in to comment.