From fcb0101cf63372df1cdf08aee2228f091921cd47 Mon Sep 17 00:00:00 2001 From: nodkz Date: Sun, 21 Jan 2018 21:10:58 +0600 Subject: [PATCH] fix: old counter records without `groupingField` --- src/__tests__/index-test.js | 46 ++++++++++++++++++++++++++++++++++++- src/index.js | 27 +++++++++++++++++++--- 2 files changed, 69 insertions(+), 4 deletions(-) diff --git a/src/__tests__/index-test.js b/src/__tests__/index-test.js index 8f3d1da..d4dbb68 100644 --- a/src/__tests__/index-test.js +++ b/src/__tests__/index-test.js @@ -352,7 +352,7 @@ describe('mongoose-auto-increment', () => { it('with string field and output filter increment the counter value only once', async () => { const userSchema = new mongoose.Schema({ - orderNumber: String, + orderNumber: Number, name: String, dept: String, }); @@ -372,4 +372,48 @@ describe('mongoose-auto-increment', () => { await user1.save(); expect(user1.orderNumber).toBe(initialId); }); + + it('should fix old counter record without `groupingField`', async () => { + const _id = new mongoose.Types.ObjectId('100000000000000000000000'); + const icCollectoion = connection.collection('identitycounters'); + await icCollectoion.ensureIndex( + { + field: 1, + groupingField: 1, + model: 1, + }, + { + unique: true, + } + ); + await icCollectoion.insert({ + _id, + model: 'User', + field: 'orderNumber', + count: 79, + }); + + expect(await icCollectoion.find().toArray()).toEqual([ + { _id, count: 79, field: 'orderNumber', model: 'User' }, + ]); + + const userSchema = new mongoose.Schema({ + orderNumber: Number, + name: String, + dept: String, + }); + userSchema.plugin(autoIncrement, { + model: 'User', + field: 'orderNumber', + }); + const User = connection.model('User', userSchema); + await User.ensureIndexes(); + + const user1 = new User({ name: 'Charlie', dept: 'Support' }); + await user1.save(); + + expect(await icCollectoion.find().toArray()).toEqual([ + { _id, count: 80, field: 'orderNumber', model: 'User', groupingField: '' }, + ]); + }); }); diff --git a/src/index.js b/src/index.js index c096145..07218b4 100644 --- a/src/index.js +++ b/src/index.js @@ -54,6 +54,10 @@ export function initialize(): void { ); } +function isMongoDuplicateError(e: any): boolean { + return e.name === 'MongoError' && e.code === 11000; +} + // Initialize plugin by creating counter collection in database. function initIdentityCounter(connection: MongooseConnection): IdentityCounterModel { let identityCounter; @@ -76,20 +80,37 @@ async function createCounterIfNotExist( settings: AutoIncSettings, doc: MongooseDocument ): Promise { + const groupingField = doc.get(settings.groupingField) || ''; + let existedCounter: IdentityCounterDoc = (await IC.findOne({ model: settings.model, field: settings.field, - groupingField: doc.get(settings.groupingField) || '', + groupingField, }).exec(): any); + // Check old record without `groupingField`, + // so let fix this record by adding this field + if (!existedCounter) { + existedCounter = (await IC.findOne({ + model: settings.model, + field: settings.field, + groupingField: { $exists: false }, + }): any); + if (existedCounter) { + existedCounter.groupingField = ''; + await existedCounter.save(); + } + } + if (!existedCounter) { // If no counter exists then create one and save it. existedCounter = (new IC({ model: settings.model, field: settings.field, - groupingField: doc.get(settings.groupingField) || '', + groupingField, count: settings.startAt - settings.incrementBy, }): any); + await existedCounter.save(); } @@ -158,7 +179,7 @@ async function preSave( next(); } catch (err) { - if (err.name === 'MongoError' && err.code === 11000) { + if (isMongoDuplicateError(err)) { setTimeout(() => preSave(IC, settings, doc, next), 5); } else { next(err);