Skip to content

Commit

Permalink
fix: old counter records without groupingField
Browse files Browse the repository at this point in the history
  • Loading branch information
nodkz committed Jan 21, 2018
1 parent b82e483 commit fcb0101
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 4 deletions.
46 changes: 45 additions & 1 deletion src/__tests__/index-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
});
Expand All @@ -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: '' },
]);
});
});
27 changes: 24 additions & 3 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -76,20 +80,37 @@ async function createCounterIfNotExist(
settings: AutoIncSettings,
doc: MongooseDocument
): Promise<IdentityCounterDoc> {
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();
}

Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit fcb0101

Please sign in to comment.