Added transaction support to pagination plugin (#11421)

Adds transaction support to `fetchPage` method. This is needed to be able to count members during the post publish transaction. 

This is the next iteration over initial quick-fix: 90905b0212

* Added transaction support to pagination plugin
    - This support is needed to be able to use `fetchPage` method in transactional context (example usecase was counting members when publishing post for emails)
* Passed transaction related options during email creation
    - Without this SQLite would hang in a transaction and eventually timeout
* Updated parameter name for consistency
This commit is contained in:
Naz Gargol 2019-11-27 17:00:27 +07:00 committed by Kevin Ansfield
parent 628f9179dc
commit 201bef31f0
2 changed files with 11 additions and 9 deletions

View File

@ -144,11 +144,18 @@ pagination = function pagination(bookshelf) {
// Get the table name and idAttribute for this model
var tableName = _.result(this.constructor.prototype, 'tableName'),
idAttribute = _.result(this.constructor.prototype, 'idAttribute'),
self = this,
self = this;
let countPromise;
if (options.transacting) {
countPromise = this.query().clone().transacting(options.transacting).select(
bookshelf.knex.raw('count(distinct ' + tableName + '.' + idAttribute + ') as aggregate')
);
} else {
countPromise = this.query().clone().select(
bookshelf.knex.raw('count(distinct ' + tableName + '.' + idAttribute + ') as aggregate')
);
}
// #### Pre count clauses
// Add any where or join clauses which need to be included with the aggregate query

View File

@ -51,16 +51,11 @@ const sendTestEmail = async (postModel, toEmails) => {
*
* @param {object} postModel Post Model Object
*/
const addEmail = async (postModel, options) => {
const knexOptions = _.pick(options, ['transacting', 'forUpdate']);
// TODO: this is using the Member model directly rather than the members
// service because the service is hardcoded to Member.findPage and our
// pagination plugin does not currently work with transactions
const members = await models.Member
.findAll(Object.assign({filter: 'subscribed:true'}, knexOptions))
.map(member => member.toJSON(options));
const {members} = await membersService.api.members.list(Object.assign(knexOptions, {filter: 'subscribed:true'}, {limit: 'all'}));
const {emailTmpl, emails} = await getEmailData(postModel, members);
// NOTE: don't create email object when there's nobody to send the email to