Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: nassor/mongoose-auto-increment
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: master
Choose a base ref
...
head repository: Blazemeter/mongoose-auto-increment
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: master
Choose a head ref
Able to merge. These branches can be automatically merged.

Commits on Oct 8, 2013

  1. Fixing bug that caused counter to increment on updates, causing new d…

    …ocuments to skip IDs.
    Alex Ford committed Oct 8, 2013
    Copy the full SHA
    a76d1ce View commit details
  2. 1.1.1

    unknown authored and unknown committed Oct 8, 2013
    Copy the full SHA
    51988ba View commit details
  3. Merge branch 'master' of github.com:Chevex/mongoose-auto-increment

    Conflicts:
    	package.json
    Alex Ford committed Oct 8, 2013
    Copy the full SHA
    3d4549d View commit details
  4. Misplaced variable declaration.

    Alex Ford committed Oct 8, 2013
    Copy the full SHA
    903a196 View commit details
  5. 1.2.2

    unknown authored and unknown committed Oct 8, 2013
    Copy the full SHA
    af78b39 View commit details

Commits on Oct 9, 2013

  1. Merge pull request #2 from rossan/master

    Added Mocha tests with Should assertions.
    Alex Ford authored and Alex Ford committed Oct 9, 2013
    Copy the full SHA
    a35a15c View commit details
  2. Changed counter collection name and removed mongoose from dependencie…

    …s. Added mongoose as a peer dependency.
    Alex Ford committed Oct 9, 2013
    Copy the full SHA
    390a4e7 View commit details
  3. 1.2.3

    unknown authored and unknown committed Oct 9, 2013
    Copy the full SHA
    a61756d View commit details

Commits on Oct 10, 2013

  1. Modified plugin so it requires initialization, passing in a mongoose …

    …connection.
    Alex Ford committed Oct 10, 2013
    Copy the full SHA
    2f6ac1e View commit details
  2. 1.3.0

    unknown authored and unknown committed Oct 10, 2013
    Copy the full SHA
    6607b13 View commit details
  3. Fixing bug with variable scope.

    Alex Ford committed Oct 10, 2013
    Copy the full SHA
    ace1cc0 View commit details
  4. 1.3.1

    unknown authored and unknown committed Oct 10, 2013
    Copy the full SHA
    f0a402e View commit details

Commits on Oct 21, 2013

  1. Added license file.

    Alex Ford committed Oct 21, 2013
    Copy the full SHA
    f8a7d77 View commit details

Commits on Oct 22, 2013

  1. fix example

    Before this change my schema save would never return. Reason:
    Counter.findOne(..)'s callback was never called. I am using mongoose v3.6.20
    mkoryak committed Oct 22, 2013
    Copy the full SHA
    7d61f77 View commit details
  2. Merge pull request #3 from mkoryak/master

    Fixed bug with README example.
    Alex Ford authored and Alex Ford committed Oct 22, 2013
    Copy the full SHA
    c86ed4d View commit details

Commits on Oct 26, 2013

  1. fixed tests; added ability to "npm test"; added mongoose devDep

    Christopher Hiller committed Oct 26, 2013
    Copy the full SHA
    c6fce27 View commit details
  2. added "nextAutoIncrement()" instance function that returns the next n…

    …umber in the sequence.
    Christopher Hiller committed Oct 26, 2013
    Copy the full SHA
    10b1152 View commit details
  3. fixed/improved nextAutoIncrement

    Christopher Hiller committed Oct 26, 2013
    Copy the full SHA
    32b8c16 View commit details
  4. updating docs

    Christopher Hiller committed Oct 26, 2013
    Copy the full SHA
    93c8843 View commit details

Commits on Oct 28, 2013

  1. Merge pull request #5 from boneskull/master

    nextAutoIncrement() and tests
    Alex Ford authored and Alex Ford committed Oct 28, 2013
    Copy the full SHA
    9cc5d48 View commit details
  2. Copy the full SHA
    bd4c54d View commit details
  3. Added mongoose as a dev dependency.

    Alex Ford committed Oct 28, 2013
    Copy the full SHA
    e1a9037 View commit details
  4. - Added comments to plugin to make it easy to follow.

    - Updated README to reflect certain changes to the API.
    - Modified plugin to check if counters collection already exists. If so, use it.
    - Modified nextAutoIncrement to nextCount for readability and a more concise API.
    Alex Ford committed Oct 28, 2013
    Copy the full SHA
    32f6506 View commit details
  5. 2.0.0

    unknown authored and unknown committed Oct 28, 2013
    Copy the full SHA
    6dd5736 View commit details
  6. Copy the full SHA
    2440c12 View commit details
  7. 2.0.1

    unknown authored and unknown committed Oct 28, 2013
    Copy the full SHA
    d5ea39e View commit details
  8. Added .travis.yml file for Travis-CI build options.

    Alex Ford committed Oct 28, 2013
    Copy the full SHA
    9e97b68 View commit details
  9. 2.0.2

    unknown authored and unknown committed Oct 28, 2013
    Copy the full SHA
    b8bf2dc View commit details
  10. Copy the full SHA
    1830e44 View commit details
  11. 2.0.3

    unknown authored and unknown committed Oct 28, 2013
    Copy the full SHA
    2a011c1 View commit details
  12. Figured out that travis-ci provides mongodb support. Changed connecti…

    …on string.
    Alex Ford committed Oct 28, 2013
    Copy the full SHA
    6778661 View commit details
  13. 2.0.4

    unknown authored and unknown committed Oct 28, 2013
    Copy the full SHA
    4750700 View commit details
  14. Update README.md

    Alex Ford authored and Alex Ford committed Oct 28, 2013
    Copy the full SHA
    c6f9837 View commit details
  15. Update README.md

    Alex Ford authored and Alex Ford committed Oct 28, 2013
    Copy the full SHA
    a21be13 View commit details
  16. Update README.md

    Alex Ford authored and Alex Ford committed Oct 28, 2013
    Copy the full SHA
    93d1b7a View commit details
  17. Update README.md

    Alex Ford authored and Alex Ford committed Oct 28, 2013
    Copy the full SHA
    a48149b View commit details
  18. Copy the full SHA
    0cd27a7 View commit details
  19. Added a CONTRIBUTING.md file to the root of the project to help other…

    …s figure out how to contribute.
    Alex Ford committed Oct 28, 2013
    Copy the full SHA
    8c8c61f View commit details
  20. Update CONTRIBUTING.md

    Alex Ford authored and Alex Ford committed Oct 28, 2013
    Copy the full SHA
    8740053 View commit details
  21. Update CONTRIBUTING.md

    Alex Ford authored and Alex Ford committed Oct 28, 2013
    Copy the full SHA
    321b552 View commit details

Commits on Nov 8, 2013

  1. Reset function added

    tomaskavka committed Nov 8, 2013
    Copy the full SHA
    e3a608d View commit details
  2. Bug fix: Added static

    tomaskavka committed Nov 8, 2013
    Copy the full SHA
    9bbcadd View commit details
  3. Added pull-request author to contributor list.

    Alex Ford authored and Alex Ford committed Nov 8, 2013
    Copy the full SHA
    f9c2fda View commit details
  4. Added unit test for new resetCount function.

    Alex Ford authored and Alex Ford committed Nov 8, 2013
    Copy the full SHA
    acdccd5 View commit details
  5. Rewriting unit tests for practice with async.

    Alex Ford authored and Alex Ford committed Nov 8, 2013
    Copy the full SHA
    48bfc48 View commit details
  6. Adding test.js to repo.

    Alex Ford authored and Alex Ford committed Nov 8, 2013
    Copy the full SHA
    144add2 View commit details

Commits on Nov 9, 2013

  1. Modified function to do proper calculations. Pull-request author did …

    …not realize that the count is incremented before save, not after. Meaning, in order for the first ID to be equal to startAt we must set the initial count to startAt - incrementBy. Then on save the first ID will be the count + incrementBy ( = startAt).
    Alex Ford authored and Alex Ford committed Nov 9, 2013
    Copy the full SHA
    8e32fcf View commit details
  2. Cleaned up tests using async library. Also added an extra test for th…

    …e new resetCount function.
    Alex Ford authored and Alex Ford committed Nov 9, 2013
    Copy the full SHA
    fda8599 View commit details
  3. Updated README to reflect the updates to the resetCount function.

    Alex Ford authored and Alex Ford committed Nov 9, 2013
    Copy the full SHA
    ec4dcbe View commit details
  4. 2.1.0

    Alex Ford authored and Alex Ford committed Nov 9, 2013
    Copy the full SHA
    6ffc92d View commit details
Showing with 628 additions and 199 deletions.
  1. +2 −0 .gitignore
  2. +9 −0 .travis.yml
  3. +35 −0 CONTRIBUTING.md
  4. +20 −0 LICENSE
  5. +112 −28 README.md
  6. +175 −72 index.js
  7. +35 −9 package.json
  8. +0 −1 test/mocha.opts
  9. +240 −89 test/test.js
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
.idea/
node_modules/
*.swp
*.swo
9 changes: 9 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
language: node_js
services:
- mongodb
node_js:
- "0.10"
before_script:
- npm install
notifications:
email: false
35 changes: 35 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
## Submitting Issues

If you experience any issues with this plugin please feel free to submit them to the [issue tracker](https://github.com/Chevex/mongoose-auto-increment/issues) for this project. One of the projects contributors will eventually take a look at it. Please be patient.

## Guidelines

* Search the issue tracker first! If there is already a question similar to yours then please comment on that issue instead.
* Please include steps to reproduce the issue. It will take us WAY longer to fix the issue (if we even can) if you don't include this information.

## Contributing to Source Code

The source of this plugin is licensed using the MIT license.

> The MIT License
>
> Copyright (C) 2013 Alex Ford and contributors.
>
> Permission is hereby granted, free of charge, to any person obtaining a copy of
> this software and associated documentation files (the "Software"), to deal in
> the Software without restriction, including without limitation the rights to
> use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
> of the Software, and to permit persons to whom the Software is furnished to do
> so, subject to the following conditions:
>
> The above copyright notice and this permission notice shall be included in all
> copies or substantial portions of the Software.
>
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
> FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
> COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
> IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
> CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
To contribute changes to this project please submit them as a [pull request](https://github.com/Chevex/mongoose-auto-increment/pulls). If you don't know how to submit a pull request then see [this article](https://help.github.com/articles/using-pull-requests).
20 changes: 20 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
The MIT License

Copyright (C) 2013 Alex Ford and contributors.

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
140 changes: 112 additions & 28 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,48 +1,132 @@
# mongoose-auto-increment
This plugin allows you to auto-increment any field on any mongoose schema that you wish.

[![Build Status](https://travis-ci.org/codetunnel/mongoose-auto-increment.png?branch=master)](https://travis-ci.org/codetunnel/mongoose-auto-increment)
[![Dependencies Status](https://gemnasium.com/codetunnel/mongoose-auto-increment.png)](https://gemnasium.com/codetunnel/mongoose-auto-increment)
[![NPM version](https://badge.fury.io/js/mongoose-auto-increment.png)](http://badge.fury.io/js/mongoose-auto-increment)

> Mongoose plugin that auto-increments any ID field on your schema every time a document is saved.
---

> This is the module used by [mongoose-simpledb](https://github.com/codetunnel/mongoose-simpledb) to increment Number IDs. You are perfectly able to use this module by itself if you would like. However, if you're looking to make your life easier when using [mongoose](http://mongoosejs.com/) then I highly recommend you check out simpledb. It's a small wrapper around mongoose but it makes it extremely easy to deal with your models and draws a clear path for how to use mongoose in your application.
## Getting Started

> npm install mongoose-auto-increment
Once you have the plugin installed it is very simple to use. Just get reference to it and call the `plugin()` function on your schema.
Once you have the plugin installed it is very simple to use. Just get reference to it, initialize it by passing in your
mongoose connection and pass `autoIncrement.plugin` to the `plugin()` function on your schema.

var mongoose = require('mongoose'),
autoIncrement = require('mongoose-auto-increment');
> Note: You only need to initialize MAI once.
var bookSchema = new mongoose.Schema({
author: { type: Schema.Types.ObjectId, ref: 'Author' },
title: String,
genre: String,
publishDate: Date
});
````js
var mongoose = require('mongoose'),
Schema = mongoose.Schema,
autoIncrement = require('mongoose-auto-increment');

var connection = mongoose.createConnection("mongodb://localhost/myDatabase");

autoIncrement.initialize(connection);

var bookSchema = new Schema({
author: { type: Schema.Types.ObjectId, ref: 'Author' },
title: String,
genre: String,
publishDate: Date
});

bookSchema.plugin(autoIncrement, 'Book');
mongoose.model('Book', bookSchema);
bookSchema.plugin(autoIncrement.plugin, 'Book');
var Book = connection.model('Book', bookSchema);
````

That's it. Now you can create book entities at will and the `_id` field will automatically increment with each new document.
That's it. Now you can create book entities at will and they will have an `_id` field added of type `Number` and will automatically increment with each new document. Even declaring references is easy, just remember to change the reference property's type to `Number` instead of `ObjectId` if the referenced model is also using the plugin.

````js
var authorSchema = new mongoose.Schema({
name: String
});

var bookSchema = new Schema({
author: { type: Number, ref: 'Author' },
title: String,
genre: String,
publishDate: Date
});

bookSchema.plugin(autoIncrement.plugin, 'Book');
authorSchema.plugin(autoIncrement.plugin, 'Author');
````

### Want a field other than `_id`?

bookSchema.plugin(autoIncrement, { model: 'Book', field: 'sequence' });
````js
bookSchema.plugin(autoIncrement.plugin, { model: 'Book', field: 'bookId' });
````

### Want that field to start at a different number than zero or increment by more than one?

bookSchema.plugin(autoIncrement, {
model: 'Book',
field: 'sequence',
startAt: 100,
incrementBy: 100
````js
bookSchema.plugin(autoIncrement.plugin, {
model: 'Book',
field: 'bookId',
startAt: 100,
incrementBy: 100
});
````

Your first book document would have a `bookId` equal to `100`. Your second book document would have a `bookId` equal to `200`, and so on.

### Want to know the next number coming up?

````js
var Book = connection.model('Book', bookSchema);
Book.nextCount(function(err, count) {

// count === 0 -> true

var book = new Book();
book.save(function(err) {

// book._id === 0 -> true

book.nextCount(function(err, count) {

// count === 1 -> true

});
});
});
````

nextCount is both a static method on the model (`Book.nextCount(...)`) and an instance method on the document (`book.nextCount(...)`).

### Want to reset counter back to the start value?

````js
bookSchema.plugin(autoIncrement.plugin, {
model: 'Book',
field: 'bookId',
startAt: 100
});

var Book = connection.model('Book', bookSchema),
book = new Book();

Your first book document would have an `_id` equal to `100`. Your second book document would have an `_id` equal to `200`, and so on.
book.save(function (err) {

### Want your field to increment every time you update it too?
// book._id === 100 -> true

book.nextCount(function(err, count) {

// count === 101 -> true

book.resetCount(function(err, nextCount) {

// nextCount === 100 -> true

});

});

bookSchema.plugin(autoIncrement, {
model: 'Book',
field: 'sequence',
startAt: 100,
incrementBy: 100,
incrementOnUpdate: true
});
});
````
247 changes: 175 additions & 72 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,83 +1,186 @@
// Module Scope
var mongoose = require('mongoose'),
extend = require('extend');
extend = require('extend'),
counterSchema,
IdentityCounter;

var counterSchema = new mongoose.Schema({
model: {
type: String,
require: true
},
field: {
type: String,
require: true
},
c: {
type: Number,
default: 0
// Initialize plugin by creating counter collection in database.
exports.initialize = function (connection) {
try {
IdentityCounter = connection.model('IdentityCounter');
} catch (ex) {
if (ex.name === 'MissingSchemaError') {
// Create new counter schema.
counterSchema = new mongoose.Schema({
model: { type: String, require: true },
field: { type: String, require: true },
count: { type: Number, default: 0 }
});

// Create a unique index using the "field" and "model" fields.
counterSchema.index({ field: 1, model: 1 }, {
unique: true,
required: true,
index: -1,
sparse: true,
});

// Create model using new schema.
IdentityCounter = connection.model('IdentityCounter', counterSchema);
}
});
counterSchema.index({ field: 1, model: 1 }, { unique: true, required: true, index: -1 });
var Counter = mongoose.connection.model('MAIC-Counter', counterSchema);
else
throw ex;
}
};

// The function to use when invoking the plugin on a custom schema.
exports.plugin = async function (schema, options) {

// If we don't have reference to the counterSchema or the IdentityCounter model then the plugin was most likely not
// initialized properly so throw an error.
if (!counterSchema || !IdentityCounter) throw new Error("mongoose-auto-increment has not been initialized");

// Default settings and plugin scope variables.
var settings = {
model: null, // The model to configure the plugin for.
field: '_id', // The field the plugin should track.
startAt: 0, // The number the count should start at.
incrementBy: 1, // The number by which to increment the count each time.
unique: true, // Should we create a unique index for the field,
},
fields = {}, // A hash of fields to add properties to in Mongoose.
ready = false; // True if the counter collection has been updated and the document is ready to be saved.

switch (typeof(options)) {
// If string, the user chose to pass in just the model name.
case 'string':
settings.model = options;
break;
// If object, the user passed in a hash of options.
case 'object':
extend(settings, options);
break;
}

if (settings.model == null)
throw new Error("model must be set");

module.exports = exports = function (schema, options) {
var settings = {
model: null,
field: '_id',
startAt: 0,
incrementBy: 1,
incrementOnUpdate: false
},
fields = {},
ready = false;
// Add properties for field in schema.
fields[settings.field] = {
type: Number,
require: true,
sparse: true,
};
if (settings.field !== '_id')
fields[settings.field].unique = settings.unique
schema.add(fields);

switch (typeof(options)) {
case 'string':
settings.model = options;
break;
case 'object':
extend(settings, options);
break;
// Find the counter for this model and the relevant field.
IdentityCounter.findOne({ model: settings.model, field: settings.field })
.then((counter) => {
if (!counter) {
// If no counter exists then create one and save it.
counter = new IdentityCounter({ model: settings.model, field: settings.field, count: settings.startAt - settings.incrementBy });
return counter.save().then(() => {
ready = true;
});
} else {
ready = true;
}
})
.catch((err) => {
// Handle errors here
console.error(err);
});

fields[settings.field] = {
type: Number,
unique: true,
require: true
};
schema.add(fields);

Counter.findOne(
{ model: settings.model, field: settings.field },
function (err, res) {
if (!res) {
var counter = new Counter({ model: settings.model, field: settings.field, c: settings.startAt });
counter.save(function () {
ready = true;
});
}
else
ready = true;
}
);
// Declare a function to get the next counter for the model/schema.
var nextCount = async function (callback) {
try {
const counter = await IdentityCounter.findOne({
model: settings.model,
field: settings.field
});
return callback(null, counter === null ? settings.startAt : counter.count + settings.incrementBy);
} catch (err){
return callback(err);
}
};

// Add nextCount as both a method on documents and a static on the schema for convenience.
schema.method('nextCount', nextCount);
schema.static('nextCount', nextCount);

schema.pre('save', function (next) {
var doc = this;
(function save() {
if (ready) {
Counter.collection.findAndModify(
{ model: settings.model, field: settings.field },
null,
{ $inc: { c: settings.incrementBy } },
{ new: true, upsert: true },
function (err, res) {
if (err) return next(err);
if (typeof(doc[settings.field]) !== 'number' || settings.incrementOnUpdate)
doc[settings.field] = res.c - 1;
next();
}
);
// Declare a function to reset counter at the start value - increment value.
var resetCount = async function (callback) {
try {
await IdentityCounter.findOneAndUpdate(
{ model: settings.model, field: settings.field },
{ count: settings.startAt - settings.incrementBy },
{ new: true }); // new: true specifies that the callback should get the updated counter.
return callback(null, settings.startAt);
} catch (err) {
return callback(err);
}
};
// Add resetCount as both a method on documents and a static on the schema for convenience.
schema.method('resetCount', resetCount);
schema.static('resetCount', resetCount);

// Every time documents in this schema are saved, run this logic.
schema.pre('save', function (next) {
// Get reference to the document being saved.

var doc = this;
// Only do this if it is a new document (see http://mongoosejs.com/docs/api.html#document_Document-isNew)
if (doc.isNew) {
// Declare self-invoking save function.
(async function save() {
// If ready, run increment logic.
// Note: ready is true when an existing counter collection is found or after it is created for the
// first time.
if (ready) {
// check that a number has already been provided, and update the counter to that number if it is
// greater than the current count
if (typeof doc[settings.field] === 'number') {
try {
await IdentityCounter.findOneAndUpdate(
// IdentityCounter documents are identified by the model and field that the plugin was invoked for.
// Check also that count is less than field value.
{ model: settings.model, field: settings.field, count: { $lt: doc[settings.field] } },
// Change the count of the value found to the new field value.
{ count: doc[settings.field] });
next();
} catch (err) {
return next(err);
}
} else {
try {

// Find the counter collection entry for this model and field and update it.
var updatedIdentityCounter = await IdentityCounter.findOneAndUpdate(
// IdentityCounter documents are identified by the model and field that the plugin was invoked for.
{ model: settings.model, field: settings.field },
// Increment the count by `incrementBy`.
{ $inc: { count: settings.incrementBy } },
// new:true specifies that the callback should get the counter AFTER it is updated (incremented).
{ new: true });
doc[settings.field] = updatedIdentityCounter.count;
return next();
} catch (err) {
return next(err);
}
else
setTimeout(save, 5);
})();
});
}
}
// If not ready then set a 5 millisecond timer and try to save again. It will keep doing this until
// the counter collection is ready.
else
setTimeout(save, 5);
})();
}
// If the document does not have the field we're interested in or that field isn't a number AND the user did
// not specify that we should increment on updates, then just continue the save without any increment logic.
else
next();
});
};
44 changes: 35 additions & 9 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,18 +1,24 @@
{
"name": "mongoose-auto-increment",
"version": "1.2.0",
"version": "5.0.2",
"description": "This plugin allows you to auto-increment any field on any mongoose schema that you wish.",
"repository": {
"type": "git",
"url": "git://github.com/Chevex/mongoose-auto-increment.git"
"url": "git://github.com/codetunnel/mongoose-auto-increment.git"
},
"dependencies": {
"mongoose": "*",
"extend": "*"
"extend": "^3.0.0",
"should": "^13.2.3"
},
"peerDependencies": {
"mongoose": "^8.10.0"
},
"devDependencies": {
"async": "*",
"chai": "*",
"mocha": "*",
"should": "*"
"mongoose": "^8.10.0",
"should": "^13.2.3"
},
"keywords": [
"mongoose",
@@ -29,14 +35,34 @@
"pureautoinc",
"mongoose-pureautoinc"
],
"author": "Chevex",
"author": {
"name": "Alex Ford (Chevex)",
"email": "alex.ford@codetunnel.com",
"url": "http://CodeTunnel.com"
},
"contributors": [
{
"name": "Nassor Paulino da Silva",
"name": "Nassor Paulino da Silva (rossan)",
"email": "nassor@gmail.com"
}
},
{
"name": "Misha Koryak (mkoryak)",
"email": "mkoryak@gmail.com",
"url": "http://ExhibitionNest.com"
},
{
"name": "Christopher Hiller (boneskull)",
"url": "http://boneskull.github.io/"
},
{
"name": "tomaskavka",
"url": "https://github.com/tomaskavka"
}
],
"scripts": {
"test": "node_modules/mocha/bin/_mocha"
},
"bugs": {
"url": "https://github.com/Chevex/mongoose-auto-increment/issues"
"url": "https://github.com/codetunnel/mongoose-auto-increment/issues"
}
}
1 change: 0 additions & 1 deletion test/mocha.opts
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
--require should
-R spec
329 changes: 240 additions & 89 deletions test/test.js
Original file line number Diff line number Diff line change
@@ -1,112 +1,263 @@
var mongoose = require('mongoose')
, should = require('should')
, autoIncrement = require('../index.js');
var async = require('async'),
should = require('should'),
mongoose = require('mongoose'),
autoIncrement = require('..'),
connection;

mongoose.connect('mongodb://localhost/mongoose-auto-increment-test');
before(async function () {
// Use async/await to handle asynchronous operations
connection = await mongoose.createConnection('mongodb://127.0.0.1/mongoose-auto-increment-test');
connection.on('error', console.error.bind(console));
autoIncrement.initialize(connection);
});

after(function(done) {
mongoose.connection.db.executeDbCommand( {dropDatabase:1}, function(err, result) {
done();
});
after(async function () {
// Use async/await to handle asynchronous operations
await connection.db.dropDatabase();
await connection.close();
});

afterEach(async function () {
// Use async/await to handle asynchronous operations
await connection.model('User').collection.drop();
delete connection.models.User;
await connection.model('IdentityCounter').collection.drop();
});

describe('Auto Increment Plugin', function() {

it('should auto-increment in _id', function(done) {

var SomeSchema = new mongoose.Schema({
describe('mongoose-auto-increment', function () {

it('should increment the _id field on save', async function () {

// Arrange
var userSchema = new mongoose.Schema({
name: String,
dept: String
});
SomeSchema.plugin(autoIncrement, 'ai_id');
var User = mongoose.model('ai_id', SomeSchema);
var user = new User({ name: 'Name test', dept: 'Department test' });

user.save(function(err) {
should.not.exists(err);
user._id.should.eql(0)
done();
});
userSchema.plugin(autoIncrement.plugin, 'User');
var User = connection.model('User', userSchema),
user1 = new User({ name: 'Charlie', dept: 'Support' }),
user2 = new User({ name: 'Charlene', dept: 'Marketing' });
// Act
try {
const [result1, result2] = await Promise.all([
user1.save(),
user2.save()
]);

const results = Object.fromEntries([
['user1', result1],
['user2', result2]
]);
// Assert
should.exists(results.user1);
should.exists(results.user2);
should(results.user1).have.property('_id', 0);
should(results.user2).have.property('_id', 1);
} catch (err) {
should.not.exist(err);
}
});

it('should auto-increment in another field', function(done) {
var SomeSchema = new mongoose.Schema({

it('should increment the specified field instead (Test 2)', async function() {

// Arrange
var userSchema = new mongoose.Schema({
name: String,
dept: String,
sequence: Number
});
SomeSchema.plugin(autoIncrement, {model: 'ai_another_field', field: 'sequence'});
var User = mongoose.model('ai_another_field', SomeSchema);

var user = new User({ name: 'Name test', dept: 'Department test' });
user.save(function(err) {
should.not.exists(err);
user.sequence.should.eql(0);
done();
dept: String
});
userSchema.plugin(autoIncrement.plugin, { model: 'User', field: 'userId' });
var User = connection.model('User', userSchema),
user1 = new User({ name: 'Charlie', dept: 'Support' }),
user2 = new User({ name: 'Charlene', dept: 'Marketing' });

try {
const [result1, result2] = await Promise.all([
user1.save(),
user2.save()
]);

const results = Object.fromEntries([
['user1', result1],
['user2', result2]
]);
// Assert
should.exists(results.user1);
should.exists(results.user2);
should(results.user1).have.property('userId', 0);
should(results.user2).have.property('userId', 1);
} catch (err) {
should.not.exist(err);
}
});

it('should start at selected number', function(done) {
var SomeSchema = new mongoose.Schema({


it('should start counting at specified number (Test 3)', async function () {

// Arrange
var userSchema = new mongoose.Schema({
name: String,
dept: String
});
SomeSchema.plugin(autoIncrement, {model: 'ai_start_at', startAt: 3});
var User = mongoose.model('ai_start_at', SomeSchema);

var user = new User({ name: 'Name test', dept: 'Department test' });
user.save(function(err) {
should.not.exists(err);
user._id.should.eql(3);
done();
});
userSchema.plugin(autoIncrement.plugin, { model: 'User', startAt: 3 });
var User = connection.model('User', userSchema),
user1 = new User({ name: 'Charlie', dept: 'Support' }),
user2 = new User({ name: 'Charlene', dept: 'Marketing' });

try {
const [result1, result2] = await Promise.all([
user1.save(),
user2.save()
]);

const results = Object.fromEntries([
['user1', result1],
['user2', result2]
]);
// Assert
should.exists(results.user1);
should.exists(results.user2);
should(results.user1).have.property('_id', 3);
should(results.user2).have.property('_id', 4);
} catch (err) {
should.not.exist(err);
}

});

it('should increment in accordance with the selected number', function(done) {
var SomeSchema = new mongoose.Schema({

it('should increment by the specified amount (Test 4)', async function () {

// Arrange
var userSchema = new mongoose.Schema({
name: String,
dept: String
});
SomeSchema.plugin(autoIncrement, {model: 'incrementBy', incrementBy: 5});
var User = mongoose.model('incrementBy', SomeSchema);

var user = new User({ name: 'Name test', dept: 'Department test' });


user.save(function(err) {
should.not.exists(err);
user._id.should.eql(4);

var user2 = new User({ name: 'Name test 2', dept: 'Department test' });
user2.save(function(err) {
should.not.exists(err);
user2._id.should.eql(9);
done();

userSchema.plugin(autoIncrement.plugin, { model: 'User', incrementBy: 5 });
var User = connection.model('User', userSchema),
user1 = new User({ name: 'Charlie', dept: 'Support' }),
user2 = new User({ name: 'Charlene', dept: 'Marketing' });

try {
const [result1, result2] = await Promise.all([
user1.save(),
user2.save()
]);

const results = Object.fromEntries([
['user1', result1],
['user2', result2]
]);
// Assert
should.exists(results.user1);
should.exists(results.user2);
should(results.user1).have.property('_id', 0);
should(results.user2).have.property('_id', 5);
} catch (err) {
should.not.exist(err);
}

});


describe('helper function', function () {

it('nextCount should return the next count for the model and field (Test 5)', async function () {

// Arrange
var userSchema = new mongoose.Schema({
name: String,
dept: String
});
userSchema.plugin(autoIncrement.plugin, 'User');
var User = connection.model('User', userSchema),
user1 = new User({ name: 'Charlie', dept: 'Support' }),
user2 = new User({ name: 'Charlene', dept: 'Marketing' });;

// Act
result1 = await new Promise((resolve, reject) => {
user1.nextCount((err, result) => {
if (err) {
reject(err);
} else {
resolve(result);
}
});
});

// Can't be made with _id field.
it('should increment on update', function(done) {
var SomeSchema = new mongoose.Schema({
name: String,
dept: String,
sequence: Number
});
SomeSchema.plugin(autoIncrement, {model: 'incrementOnUpdate', field: 'sequence', incrementOnUpdate: true});
var User = mongoose.model('incrementOnUpdate', SomeSchema);
var user = new User({ name: 'Name test', dept: 'Department test' });

user.save(function(err) {
should.not.exists(err);
user.sequence.should.eql(0);
user.name = 'Name change test';
user.save(function(err) {
should.not.exists(err);
user.sequence.should.eql(1);
done();
});
const result2 = await user1.save();
result3 = await new Promise((resolve, reject) => {
user1.nextCount((err, result) => {
if (err) {
reject(err);
} else {
resolve(result);
}
});
});
const result4 = await user2.save();
result5 = await new Promise((resolve, reject) => {
user2.nextCount((err, result) => {
if (err) {
reject(err);
} else {
resolve(result);
}
});
});
should(result2).have.property('_id', 0);
should(result4).have.property('_id', 1);
should(result1).equal(0);
should(result3).equal(1);
should(result5).equal(2);
});

it('resetCount should cause the count to reset as if there were no documents yet.', async function () {

// Arrange
var userSchema = new mongoose.Schema({
name: String,
dept: String
});
userSchema.plugin(autoIncrement.plugin, 'User');
var User = connection.model('User', userSchema),
user = new User({name: 'Charlie', dept: 'Support'});

// Act
var result2, result3, result4;
const result1 = await user.save();
result2 = await new Promise((resolve, reject) => {
user.nextCount((err, result) => {
if (err) {
reject(err);
} else {
resolve(result);
}
});
});
result3 = await new Promise((resolve, reject) => {
user.resetCount((err, result) => {
if (err) {
reject(err);
} else {
resolve(result);
}
});
});

result4 = await new Promise((resolve, reject) => {
user.nextCount((err, result) => {
if (err) {
reject(err);
} else {
resolve(result);
}
});
});
should.exist(result1);
should(result1).have.property('_id', 0);
should(result2).equal(1);
should(result3).equal(0);
should(result4).equal(0);
});

});
});
});