Merge pull request #6038 from ErisDS/count-refactor

Move cross-table api counts into plugin
This commit is contained in:
Sebastian Gierlinger 2015-11-03 16:28:58 +01:00
commit d81ddc9310
5 changed files with 58 additions and 29 deletions

View File

@ -0,0 +1,53 @@
var _ = require('lodash');
module.exports = function (Bookshelf) {
var modelProto = Bookshelf.Model.prototype,
Model,
countQueryBuilder;
countQueryBuilder = {
tags: {
posts: function addPostCountToTags(model) {
model.query('columns', 'tags.*', function (qb) {
qb.count('posts_tags.post_id')
.from('posts_tags')
.whereRaw('tag_id = tags.id')
.as('post_count');
});
}
}
};
Model = Bookshelf.Model.extend({
addCounts: function (options) {
if (!options) {
return;
}
var tableName = _.result(this, 'tableName');
if (options.include && options.include.indexOf('post_count') > -1) {
// remove post_count from withRelated and include
options.withRelated = _.pull([].concat(options.withRelated), 'post_count');
options.include = _.pull([].concat(options.include), 'post_count');
// Call the query builder
countQueryBuilder[tableName].posts(this);
}
},
fetch: function () {
this.addCounts.apply(this, arguments);
// Call parent fetch
return modelProto.fetch.apply(this, arguments);
},
fetchAll: function () {
this.addCounts.apply(this, arguments);
// Call parent fetchAll
return modelProto.fetchAll.apply(this, arguments);
}
});
Bookshelf.Model = Model;
};

View File

@ -18,6 +18,7 @@ var _ = require('lodash'),
uuid = require('node-uuid'), uuid = require('node-uuid'),
validation = require('../../data/validation'), validation = require('../../data/validation'),
baseUtils = require('./utils'), baseUtils = require('./utils'),
includeCount = require('./include-count'),
pagination = require('./pagination'), pagination = require('./pagination'),
gql = require('ghost-gql'), gql = require('ghost-gql'),
@ -30,6 +31,9 @@ ghostBookshelf = bookshelf(config.database.knex);
// Load the Bookshelf registry plugin, which helps us avoid circular dependencies // Load the Bookshelf registry plugin, which helps us avoid circular dependencies
ghostBookshelf.plugin('registry'); ghostBookshelf.plugin('registry');
// Load the Ghost include count plugin, which allows for the inclusion of cross-table counts
ghostBookshelf.plugin(includeCount);
// Load the Ghost pagination plugin, which gives us the `fetchPage` method on Models // Load the Ghost pagination plugin, which gives us the `fetchPage` method on Models
ghostBookshelf.plugin(pagination); ghostBookshelf.plugin(pagination);
@ -313,7 +317,7 @@ ghostBookshelf.Model = ghostBookshelf.Model.extend({
data.meta = {pagination: response.pagination}; data.meta = {pagination: response.pagination};
return data; return data;
}).catch(errors.logAndThrowError); });
}, },
/** /**

View File

@ -3,7 +3,6 @@
// Extends Bookshelf.Model with a `fetchPage` method. Handles everything to do with paginated requests. // Extends Bookshelf.Model with a `fetchPage` method. Handles everything to do with paginated requests.
var _ = require('lodash'), var _ = require('lodash'),
Promise = require('bluebird'), Promise = require('bluebird'),
baseUtils = require('./utils'),
defaults, defaults,
paginationUtils, paginationUtils,
@ -173,9 +172,6 @@ pagination = function pagination(bookshelf) {
}); });
} }
// Apply count options if they are present
baseUtils.collectionQuery.count(self, options);
// Setup the promise to do a fetch on our collection, running the specified query // Setup the promise to do a fetch on our collection, running the specified query
// @TODO: ensure option handling is done using an explicit pick elsewhere // @TODO: ensure option handling is done using an explicit pick elsewhere
collectionPromise = self.fetchAll(_.omit(options, ['page', 'limit'])); collectionPromise = self.fetchAll(_.omit(options, ['page', 'limit']));

View File

@ -3,28 +3,9 @@
* Parts of the model code which can be split out and unit tested * Parts of the model code which can be split out and unit tested
*/ */
var _ = require('lodash'), var _ = require('lodash'),
collectionQuery,
processGQLResult, processGQLResult,
addPostCount,
tagUpdate; tagUpdate;
addPostCount = function addPostCount(options, model) {
if (options.include && options.include.indexOf('post_count') > -1) {
model.query('columns', 'tags.*', function (qb) {
qb.count('posts_tags.post_id').from('posts_tags').whereRaw('tag_id = tags.id').as('post_count');
});
options.withRelated = _.pull([].concat(options.withRelated), 'post_count');
options.include = _.pull([].concat(options.include), 'post_count');
}
};
collectionQuery = {
count: function count(model, options) {
addPostCount(options, model);
}
};
processGQLResult = function processGQLResult(itemCollection, options) { processGQLResult = function processGQLResult(itemCollection, options) {
var joinTables = options.filter.joins, var joinTables = options.filter.joins,
tagsHasIn = false; tagsHasIn = false;
@ -126,6 +107,4 @@ tagUpdate = {
}; };
module.exports.processGQLResult = processGQLResult; module.exports.processGQLResult = processGQLResult;
module.exports.collectionQuery = collectionQuery;
module.exports.addPostCount = addPostCount;
module.exports.tagUpdate = tagUpdate; module.exports.tagUpdate = tagUpdate;

View File

@ -1,7 +1,6 @@
var _ = require('lodash'), var _ = require('lodash'),
ghostBookshelf = require('./base'), ghostBookshelf = require('./base'),
events = require('../events'), events = require('../events'),
baseUtils = require('./base/utils'),
Tag, Tag,
Tags; Tags;
@ -101,8 +100,6 @@ Tag = ghostBookshelf.Model.extend({
var tag = this.forge(data); var tag = this.forge(data);
baseUtils.addPostCount(options, tag);
// Add related objects // Add related objects
options.withRelated = _.union(options.withRelated, options.include); options.withRelated = _.union(options.withRelated, options.include);