1
0
mirror of https://github.com/mgerb/mywebsite synced 2026-01-12 02:42:48 +00:00

updated bunch of file paths and changed the way posts are loaded

This commit is contained in:
2016-01-05 12:28:04 -06:00
parent 4bb8cae81e
commit 6ab45fe935
13249 changed files with 317868 additions and 2101398 deletions

3
node_modules/mongoose/.eslintignore generated vendored Normal file
View File

@@ -0,0 +1,3 @@
docs/
bin/
test/triage/

31
node_modules/mongoose/.eslintrc.yml generated vendored Normal file
View File

@@ -0,0 +1,31 @@
extends: 'eslint:recommended'
env:
node: true
mocha: true
rules:
comma-style: 2
consistent-this:
- 1
- _this
indent:
- 2
- 2
- SwitchCase: 1
VariableDeclarator: 2
key-spacing: 1
no-console: 0
no-multi-spaces: 1
no-spaced-func: 2
no-trailing-spaces: 2
semi: 2
space-after-keywords: 2
space-before-blocks: 2
space-before-function-paren:
- 2
- never
space-before-keywords: 2
space-infix-ops: 2
space-return-throw-case: 2
space-unary-ops: 1

3
node_modules/mongoose/.travis.yml generated vendored
View File

@@ -1,5 +1,8 @@
language: node_js
sudo: false
node_js:
- "5"
- "4"
- "0.12"
- "0.10"
- "iojs"

View File

@@ -37,7 +37,7 @@ If you have a question about Mongoose (not a bug report) please post it to eithe
### Running the tests
- Open a terminal and navigate to the root of the project
- execute `npm install` to install the necessary dependencies
- execute `make test` to run the tests (we're using [mocha](http://visionmedia.github.com/mocha/))
- execute `make test` to run the tests (we're using [mocha](http://mochajs.org/))
- or to execute a single test `T="-g 'some regexp that matches the test description'" make test`
- any mocha flags can be specified with `T="..."`
@@ -47,7 +47,7 @@ To contribute to the [API documentation](http://mongoosejs.com/docs/api.html) ju
To contribute to the [guide](http://mongoosejs.com/docs/guide.html) or [quick start](http://mongoosejs.com/docs/index.html) docs, make your changes to the appropriate `.jade` files in the [docs](https://github.com/LearnBoost/mongoose/tree/master/docs) directory of the master branch and submit a pull request. Again, the [Edit](https://github.com/blog/844-forking-with-the-edit-button) button might work for you here.
If you'd like to preview your documentation changes, first commit your changes to your local 3.8.x branch, then execute `make docs` from the project root, which switches to the gh-pages branch, merges from the 3.8.x branch and builds all the static pages for you. Now execute `node static.js` from the project root which will launch a local webserver where you can browse the documentation site locally. If all looks good, submit a [pull request](https://help.github.com/articles/using-pull-requests/) to the 3.8.x branch with your changes.
If you'd like to preview your documentation changes, first commit your changes to your local master branch, then execute `make docs` from the project root, which switches to the gh-pages branch, merges from the master branch and builds all the static pages for you. Now execute `node static.js` from the project root which will launch a local webserver where you can browse the documentation site locally. If all looks good, submit a [pull request](https://help.github.com/articles/using-pull-requests/) to the master branch with your changes.
### Plugins website

350
node_modules/mongoose/History.md generated vendored
View File

@@ -1,3 +1,353 @@
4.3.4 / 2015-12-23
==================
* fix: upgrade mongodb driver to 2.1.2 for repl set error #3712 [sansmischevia](https://github.com/sansmischevia)
* docs: validation docs typo #3709 [ivanmaeder](https://github.com/ivanmaeder)
* style: remove unused variables #3708 [ChristianMurphy](https://github.com/ChristianMurphy)
* fix(schema): duck-typing for schemas #3703 [mgcrea](https://github.com/mgcrea)
* docs: connection sample code issue #3697
* fix(schema): duck-typing for schemas #3693 [mgcrea](https://github.com/mgcrea)
* docs: clarify id schema option #3638
4.3.3 / 2015-12-18
==================
* fix(connection): properly support 'replSet' as well as 'replset' #3688 [taxilian](https://github.com/taxilian)
* fix(document): single nested doc pre hooks called before nested doc array #3687 [aliatsis](https://github.com/aliatsis)
4.3.2 / 2015-12-17
==================
* fix(document): .set() into single nested schemas #3686
* fix(connection): support 'replSet' as well as 'replset' option #3685
* fix(document): bluebird unhandled rejection when validating doc arrays #3681
* fix(document): hooks for doc arrays in single nested schemas #3680
* fix(document): post hooks for single nested schemas #3679
* fix: remove unused npm module #3674 [sybarite](https://github.com/sybarite)
* fix(model): don't swallow exceptions in nested doc save callback #3671
* docs: update keepAlive info #3667 [ChrisZieba](https://github.com/ChrisZieba)
* fix(document): strict 'throw' throws a specific mongoose error #3662
* fix: flakey test #3332
* fix(query): more robust check for RegExp #2969
4.3.1 / 2015-12-11
==================
* feat(aggregate): `.sample()` helper #3665
* fix(query): bitwise query operators with buffers #3663
* docs(migration): clarify `new` option and findByIdAndUpdate #3661
4.3.0 / 2015-12-09
==================
* feat(query): support for mongodb 3.2 bitwise query operators #3660
* style: use comma-last style consistently #3657 [ChristianMurphy](https://github.com/ChristianMurphy)
* feat: upgrade mongodb driver to 2.1.0 for full MongoDB 3.2 support #3656
* feat(aggregate): `.lookup()` helper #3532
4.2.10 / 2015-12-08
===================
* fixed; upgraded marked #3653 [ChristianMurphy](https://github.com/ChristianMurphy)
* docs; cross-db populate #3648
* docs; update mocha URL #3646 [ojhaujjwal](https://github.com/ojhaujjwal)
* fixed; call close callback asynchronously #3645
* docs; virtuals.html issue #3644 [Psarna94](https://github.com/Psarna94)
* fixed; single embedded doc casting on init #3642
* docs; validation docs improvements #3640
4.2.9 / 2015-12-02
==================
* docs; defaults docs #3625
* fix; nested numeric keys causing an embedded document crash #3623
* fix; apply path getters before virtual getters #3618
* fix; casting for arrays in single nested schemas #3616
4.2.8 / 2015-11-25
==================
* docs; clean up README links #3612 [ReadmeCritic](https://github.com/ReadmeCritic)
* fix; ESLint improvements #3605 [ChristianMurphy](https://github.com/ChristianMurphy)
* fix; assigning single nested subdocs #3601
* docs; describe custom logging functions in `mongoose.set()` docs #3557
4.2.7 / 2015-11-20
==================
* fixed; readPreference connection string option #3600
* fixed; pulling from manually populated arrays #3598 #3579
* docs; FAQ about OverwriteModelError #3597 [stcruy](https://github.com/stcruy)
* fixed; setting single embedded schemas to null #3596
* fixed; indexes for single embedded schemas #3594
* docs; clarify projection for `findOne()` #3593 [gunar](https://github.com/gunar)
* fixed; .ownerDocument() method on single embedded schemas #3589
* fixed; properly throw casterror for query on single embedded schema #3580
* upgraded; mongodb driver -> 2.0.49 for reconnect issue fix #3481
4.2.6 / 2015-11-16
==================
* fixed; ability to manually populate an array #3575
* docs; clarify `isAsync` parameter to hooks #3573
* fixed; use captureStackTrace if possible instead #3571
* fixed; crash with buffer and update validators #3565 [johnpeb](https://github.com/johnpeb)
* fixed; update casting with operators overwrite: true #3564
* fixed; validation with single embedded docs #3562
* fixed; inline docs inherit parents $type key #3560
* docs; bad grammar in populate docs #3559 [amaurymedeiros](https://github.com/amaurymedeiros)
* fixed; properly handle populate option for find() #2321
3.8.37 / 2015-11-16
===================
* fixed; use retainKeyOrder for cloning update op #3572
4.2.5 / 2015-11-09
==================
* fixed; handle setting fields in pre update hooks with exec #3549
* upgraded; ESLint #3547 [ChristianMurphy](https://github.com/ChristianMurphy)
* fixed; bluebird unhandled rejections with cast errors and .exec #3543
* fixed; min/max validators handling undefined #3539
* fixed; standalone mongos connections #3537
* fixed; call `.toObject()` when setting a single nested doc #3535
* fixed; single nested docs now have methods #3534
* fixed; single nested docs with .create() #3533 #3521 [tusbar](https://github.com/tusbar)
* docs; deep populate docs #3528
* fixed; deep populate schema ref handling #3507
* upgraded; mongodb driver -> 2.0.48 for sort overflow issue #3493
* docs; clarify default ids for discriminators #3482
* fixed; properly support .update(doc) #3221
4.2.4 / 2015-11-02
==================
* fixed; upgraded `ms` package for security vulnerability #3254 [fhemberger](https://github.com/fhemberger)
* fixed; ESlint rules #3517 [ChristianMurphy](https://github.com/ChristianMurphy)
* docs; typo in aggregation docs #3513 [rafakato](https://github.com/rafakato)
* fixed; add `dontThrowCastError` option to .update() for promises #3512
* fixed; don't double-cast buffers in node 4.x #3510 #3496
* fixed; population with single embedded schemas #3501
* fixed; pre('set') hooks work properly #3479
* docs; promises guide #3441
4.2.3 / 2015-10-26
==================
* docs; remove unreferenced function in middleware.jade #3506
* fixed; handling auth with no username/password #3500 #3498 #3484 [mleanos](https://github.com/mleanos)
* fixed; more ESlint rules #3491 [ChristianMurphy](https://github.com/ChristianMurphy)
* fixed; swallowing exceptions in save callback #3478
* docs; fixed broken links in subdocs guide #3477
* fixed; casting booleans to numbers #3475
* fixed; report CastError for subdoc arrays in findOneAndUpdate #3468
* fixed; geoNear returns ES6 promise #3458
4.2.2 / 2015-10-22
==================
* fixed; go back to old pluralization code #3490
4.2.1 / 2015-10-22
==================
* fixed; pluralization issues #3492 [ChristianMurphy](https://github.com/ChristianMurphy)
4.2.0 / 2015-10-22
==================
* added; support for skipVersioning for document arrays #3467 [chazmo03](https://github.com/chazmo03)
* added; ability to customize schema 'type' key #3459 #3245
* fixed; writeConcern for index builds #3455
* added; emit event when individual index build starts #3440 [objectiveSee](https://github.com/objectiveSee)
* added; 'context' option for update validators #3430
* refactor; pluralization now in separate pluralize-mongoose npm module #3415 [ChristianMurphy](https://github.com/ChristianMurphy)
* added; customizable error validation messages #3406 [geronime](https://github.com/geronime)
* added; support for passing 'minimize' option to update #3381
* added; ability to customize debug logging format #3261
* added; baseModelName property for discriminator models #3202
* added; 'emitIndexErrors' option #3174
* added; 'async' option for aggregation cursor to support buffering #3160
* added; ability to skip validation for individual save() calls #2981
* added; single embedded schema support #2689 #585
* added; depopulate function #2509
4.1.12 / 2015-10-19
===================
* docs; use readPreference instead of slaveOk for Query.setOptions docs #3471 [buunguyen](https://github.com/buunguyen)
* fixed; more helpful error when regexp contains null bytes #3456
* fixed; x509 auth issue #3454 [NoxHarmonium](https://github.com/NoxHarmonium)
3.8.36 / 2015-10-18
===================
* fixed; Make array props non-enumerable #3461 [boblauer](https://github.com/boblauer)
4.1.11 / 2015-10-12
===================
* fixed; update timestamps for update() if they're enabled #3450 [isayme](https://github.com/isayme)
* fixed; unit test error on node 0.10 #3449 [isayme](https://github.com/isayme)
* docs; timestamp option docs #3448 [isayme](https://github.com/isayme)
* docs; fix unexpected indent #3443 [isayme](https://github.com/isayme)
* fixed; use ES6 promises for Model.prototype.remove() #3442
* fixed; don't use unused 'safe' option for index builds #3439
* fixed; elemMatch casting bug #3437 #3435 [DefinitelyCarter](https://github.com/DefinitelyCarter)
* docs; schema.index docs #3434
* fixed; exceptions in save() callback getting swallowed on mongodb 2.4 #3371
4.1.10 / 2015-10-05
===================
* docs; improve virtuals docs to explain virtuals schema option #3433 [zoyaH](https://github.com/zoyaH)
* docs; MongoDB server version compatibility guide #3427
* docs; clarify that findById and findByIdAndUpdate fire hooks #3422
* docs; clean up Model.save() docs #3420
* fixed; properly handle projection with just id #3407 #3412
* fixed; infinite loop when database document is corrupted #3405
* docs; clarify remove middleware #3388
4.1.9 / 2015-09-28
==================
* docs; minlength and maxlength string validation docs #3368 #3413 [cosmosgenius](https://github.com/cosmosgenius)
* fixed; linting for infix operators #3397 [ChristianMurphy](https://github.com/ChristianMurphy)
* fixed; proper casting for $all #3394
* fixed; unhandled rejection warnings with .create() #3391
* docs; clarify update validators on paths that aren't explicitly set #3386
* docs; custom validator examples #2778
4.1.8 / 2015-09-21
==================
* docs; fixed typo in example #3390 [kmctown](https://github.com/kmctown)
* fixed; error in toObject() #3387 [guumaster](https://github.com/guumaster)
* fixed; handling for casting null dates #3383 [alexmingoia](https://github.com/alexmingoia)
* fixed; passing composite ids to `findByIdAndUpdate` #3380
* fixed; linting #3376 #3375 [ChristianMurphy](https://github.com/ChristianMurphy)
* fixed; added NodeJS v4 to Travis #3374 [ChristianMurphy](https://github.com/ChristianMurphy)
* fixed; casting $elemMatch inside of $not #3373 [gaguirre](https://github.com/gaguirre)
* fixed; handle case where $slice is 0 #3369
* fixed; avoid running getters if path is populated #3357
* fixed; cast documents to objects when setting to a nested path #3346
4.1.7 / 2015-09-14
==================
* docs; typos in SchemaType documentation #3367 [jasson15](https://github.com/jasson15)
* fixed; MONGOOSE_DRIVER_PATH env variable again #3360
* docs; added validateSync docs #3353
* fixed; set findOne op synchronously in query #3344
* fixed; handling for `.pull()` on a documentarray without an id #3341
* fixed; use natural order for cloning update conditions #3338
* fixed; issue with strict mode casting for mixed type updates #3337
4.1.6 / 2015-09-08
==================
* fixed; MONGOOSE_DRIVER_PATH env variable #3345 [g13013](https://github.com/g13013)
* docs; global autoIndex option #3335 [albertorestifo](https://github.com/albertorestifo)
* docs; model documentation typos #3330
* fixed; report reason for CastError #3320
* fixed; .populate() no longer returns true after re-assigning #3308
* fixed; discriminators with aggregation geoNear #3304
* docs; discriminator docs #2743
4.1.5 / 2015-09-01
==================
* fixed; document.remove() removing all docs #3326 #3325
* fixed; connect() checks for rs_name in options #3299
* docs; examples for schema.set() #3288
* fixed; checkKeys issue with bluebird #3286 [gregthegeek](https://github.com/gregthegeek)
4.1.4 / 2015-08-31
==================
* fixed; ability to set strict: false for update #3305
* fixed; .create() properly uses ES6 promises #3297
* fixed; pre hooks on nested subdocs #3291 #3284 [aliatsis](https://github.com/aliatsis)
* docs; remove unclear text in .remove() docs #3282
* fixed; pre hooks called twice for 3rd-level nested doc #3281
* fixed; nested transforms #3279
* upgraded; mquery -> 1.6.3 #3278 #3272
* fixed; don't swallow callback errors by default #3273 #3222
* fixed; properly get nested paths from nested schemas #3265
* fixed; remove() with id undefined deleting all docs #3260 [thanpolas](https://github.com/thanpolas)
* fixed; handling for non-numeric projections #3256
* fixed; findById with id undefined returning first doc #3255
* fixed; use retainKeyOrder for update #3215
* added; passRawResult option to findOneAndUpdate for backwards compat #3173
4.1.3 / 2015-08-16
==================
* fixed; getUpdate() in pre update hooks #3520 [gregthegeek](https://github.com/gregthegeek)
* fixed; handleArray() ensures arg is an array #3238 [jloveridge](https://github.com/jloveridge)
* fixed; refresh required path cache when recreating docs #3199
* fixed; $ operator on unwind aggregation helper #3197
* fixed; findOneAndUpdate() properly returns raw result as third arg to callback #3173
* fixed; querystream with dynamic refs #3108
3.8.35 / 2015-08-14
===================
* fixed; handling for minimize on nested objects #2930
* fixed; don't crash when schema.path.options undefined #1824
4.1.2 / 2015-08-10
==================
* fixed; better handling for Jade templates #3241 [kbadk](https://github.com/kbadk)
* added; ESlint trailing spaces #3234 [ChristianMurphy](https://github.com/ChristianMurphy)
* added; ESlint #3191 [ChristianMurphy](https://github.com/ChristianMurphy)
* fixed; properly emit event on disconnect #3183
* fixed; copy options properly using Query.toConstructor() #3176
* fixed; setMaxListeners() issue in browser build #3170
* fixed; node driver -> 2.0.40 to not store undefined keys as null #3169
* fixed; update validators handle positional operator #3167
* fixed; handle $all + $elemMatch query casting #3163
* fixed; post save hooks don't swallow extra args #3155
* docs; spelling mistake in index.jade #3154
* fixed; don't crash when toObject() has no fields #3130
* fixed; apply toObject() recursively for find and update queries #3086 [naoina](https://github.com/naoina)
4.1.1 / 2015-08-03
==================
* fixed; aggregate exec() crash with no callback #3212 #3198 [jpgarcia](https://github.com/jpgarcia)
* fixed; pre init hooks now properly synchronous #3207 [burtonjc](https://github.com/burtonjc)
* fixed; updateValidators doesn't flatten dates #3206 #3194 [victorkohl](https://github.com/victorkohl)
* fixed; default fields don't make document dirty between saves #3205 [burtonjc](https://github.com/burtonjc)
* fixed; save passes 0 as numAffected rather than undefined when no change #3195 [burtonjc](https://github.com/burtonjc)
* fixed; better handling for positional operator in update #3185
* fixed; use Travis containers #3181 [ChristianMurphy](https://github.com/ChristianMurphy)
* fixed; leaked variable #3180 [ChristianMurphy](https://github.com/ChristianMurphy)
4.1.0 / 2015-07-24
==================
* added; `schema.queue()` now public #3193
* added; raw result as third parameter to findOneAndX callback #3173
* added; ability to run validateSync() on only certain fields #3153
* added; subPopulate #3103 [timbur](https://github.com/timbur)
* added; $isDefault function on documents #3077
* added; additional properties for built-in validator messages #3063 [KLicheR](https://github.com/KLicheR)
* added; getQuery() and getUpdate() functions for Query #3013
* added; export DocumentProvider #2996
* added; ability to remove path from schema #2993 [JohnnyEstilles](https://github.com/JohnnyEstilles)
* added; .explain() helper for aggregate #2714
* added; ability to specify which ES6-compatible promises library mongoose uses #2688
* added; export Aggregate #1910
4.0.8 / 2015-07-20
==================
* fixed; assignment with document arrays #3178 [rosston](https://github.com/rosston)
* docs; remove duplicate paragraph #3164 [rhmeeuwisse](https://github.com/rhmeeuwisse)
* docs; improve findOneAndXYZ parameter descriptions #3159 [rhmeeuwisse](https://github.com/rhmeeuwisse)
* docs; add findOneAndRemove to list of supported middleware #3158
* docs; clarify ensureIndex #3156
* fixed; refuse to save/remove document without id #3118
* fixed; hooks next() no longer accidentally returns promise #3104
* fixed; strict mode for findOneAndUpdate #2947
* added; .min.js.gz file for browser component #2806
3.8.34 / 2015-07-20
===================
* fixed; allow using $rename #3171
* fixed; no longer modifies update arguments #3008
4.0.7 / 2015-07-11
==================
* fixed; documentarray id method when using object id #3157 [siboulet](https://github.com/siboulet)
* docs; improve findById docs #3147
* fixed; update validators handle null properly #3136 [odeke-em](https://github.com/odeke-em)
* docs; jsdoc syntax errors #3128 [rhmeeuwisse](https://github.com/rhmeeuwisse)
* docs; fix typo #3126 [rhmeeuwisse](https://github.com/rhmeeuwisse)
* docs; proper formatting in queries.jade #3121 [rhmeeuwisse](https://github.com/rhmeeuwisse)
* docs; correct example for string maxlength validator #3111 [rhmeeuwisse](https://github.com/rhmeeuwisse)
* fixed; setDefaultsOnInsert with arrays #3107
* docs; LearnBoost -> Automattic in package.json #3099
* docs; pre update hook example #3094 [danpe](https://github.com/danpe)
* docs; clarify query middleware example #3051
* fixed; ValidationErrors in strict mode #3046
* fixed; set findOneAndUpdate properties before hooks run #3024
3.8.33 / 2015-07-10
===================
* upgraded; node driver -> 1.4.38
* fixed; dont crash when `match` validator undefined
4.0.6 / 2015-06-21
==================
* upgraded; node driver -> 2.0.34 #3087

72
node_modules/mongoose/README.md generated vendored
View File

@@ -1,6 +1,6 @@
# Mongoose
Mongoose is a [MongoDB](http://www.mongodb.org/) object modeling tool designed to work in an asynchronous environment.
Mongoose is a [MongoDB](https://www.mongodb.org/) object modeling tool designed to work in an asynchronous environment.
[![Build Status](https://api.travis-ci.org/Automattic/mongoose.png?branch=master)](https://travis-ci.org/Automattic/mongoose)
[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/Automattic/mongoose?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
@@ -15,7 +15,7 @@ Mongoose is a [MongoDB](http://www.mongodb.org/) object modeling tool designed t
- [Stack Overflow](http://stackoverflow.com/questions/tagged/mongoose)
- [bug reports](https://github.com/Automattic/mongoose/issues/)
- [help forum](http://groups.google.com/group/mongoose-orm)
- [MongoDB support](http://www.mongodb.org/display/DOCS/Technical+Support)
- [MongoDB support](https://docs.mongodb.org/manual/support/)
- (irc) #mongoosejs on freenode
## Plugins
@@ -29,11 +29,11 @@ Build your own Mongoose plugin through [generator-mongoose-plugin](https://githu
View all 100+ [contributors](https://github.com/Automattic/mongoose/graphs/contributors). Stand up and be counted as a [contributor](https://github.com/Automattic/mongoose/blob/master/CONTRIBUTING.md) too!
## Live Examples
<a href="http://runnable.com/mongoose" target="_blank"><img src="http://runnable.com/external/styles/assets/runnablebtn.png" style="width:67px;height:25px;"></a>
<a href="http://code.runnable.com/mongoose" target="_blank"><img src="http://runnable.com/external/styles/assets/runnablebtn.png" style="width:67px;height:25px;"></a>
## Installation
First install [node.js](http://nodejs.org/) and [mongodb](http://www.mongodb.org/downloads). Then:
First install [node.js](http://nodejs.org/) and [mongodb](https://www.mongodb.org/downloads). Then:
```sh
$ npm install mongoose
@@ -41,7 +41,7 @@ $ npm install mongoose
## Stability
The current stable branch is [master](https://github.com/Automattic/mongoose/tree/master). The [3.8.x](https://github.com/Automattic/mongoose/tree/3.8.x) branch contains legacy support for the 3.x release series, which will continue to be actively maintained until September 1, 2015.
The current stable branch is [master](https://github.com/Automattic/mongoose/tree/master). The [3.8.x](https://github.com/Automattic/mongoose/tree/3.8.x) branch contains legacy support for the 3.x release series, which is no longer under active development as of September 2015. The [3.8.x docs](http://mongoosejs.com/docs/3.8.x/) are still available.
## Overview
@@ -57,7 +57,7 @@ var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/my_database');
```
Once connected, the `open` event is fired on the `Connection` instance. If you're using `mongoose.connect`, the `Connection` is `mongoose.connection`. Otherwise, `mongoose.createConnection` return value is a `Connection`.
Once connected, the `open` event is fired on the `Connection` instance. If you're using `mongoose.connect`, the `Connection` is `mongoose.connection`. Otherwise, `mongoose.createConnection` return value is a `Connection`.
**Note:** _If the local connection fails then try using 127.0.0.1 instead of localhost. Sometimes issues may arise when the local hostname has been changed._
@@ -68,14 +68,14 @@ Once connected, the `open` event is fired on the `Connection` instance. If you'r
Models are defined through the `Schema` interface.
```js
var Schema = mongoose.Schema
, ObjectId = Schema.ObjectId;
var Schema = mongoose.Schema,
ObjectId = Schema.ObjectId;
var BlogPost = new Schema({
author : ObjectId
, title : String
, body : String
, date : Date
author : ObjectId,
title : String,
body : String,
date : Date
});
```
@@ -96,11 +96,11 @@ The following example shows some of these features:
```js
var Comment = new Schema({
name : { type: String, default: 'hahaha' }
, age : { type: Number, min: 18, index: true }
, bio : { type: String, match: /[a-z]/ }
, date : { type: Date, default: Date.now }
, buff : Buffer
name: { type: String, default: 'hahaha' },
age: { type: Number, min: 18, index: true },
bio: { type: String, match: /[a-z]/ },
date: { type: Date, default: Date.now },
buff: Buffer
});
// a setter
@@ -162,18 +162,18 @@ You can also `findOne`, `findById`, `update`, etc. For more details check out [t
**Important!** If you opened a separate connection using `mongoose.createConnection()` but attempt to access the model through `mongoose.model('ModelName')` it will not work as expected since it is not hooked up to an active db connection. In this case access your model through the connection you created:
```js
var conn = mongoose.createConnection('your connection string')
, MyModel = conn.model('ModelName', schema)
, m = new MyModel;
var conn = mongoose.createConnection('your connection string'),
MyModel = conn.model('ModelName', schema),
m = new MyModel;
m.save(); // works
```
vs
```js
var conn = mongoose.createConnection('your connection string')
, MyModel = mongoose.model('ModelName', schema)
, m = new MyModel;
var conn = mongoose.createConnection('your connection string'),
MyModel = mongoose.model('ModelName', schema),
m = new MyModel;
m.save(); // does not work b/c the default connection object was never connected
```
@@ -182,10 +182,10 @@ m.save(); // does not work b/c the default connection object was never connected
In the first example snippet, we defined a key in the Schema that looks like:
```
comments: [Comments]
comments: [Comment]
```
Where `Comments` is a `Schema` we created. This means that creating embedded documents is as simple as:
Where `Comment` is a `Schema` we created. This means that creating embedded documents is as simple as:
```js
// retrieve my model
@@ -269,19 +269,19 @@ Moreover, you can mutate the incoming `method` arguments so that subsequent midd
```js
new Schema({
broken: { type: Boolean }
, asset : {
name: String
, type: String // uh oh, it broke. asset will be interpreted as String
broken: { type: Boolean },
asset : {
name: String,
type: String // uh oh, it broke. asset will be interpreted as String
}
});
new Schema({
works: { type: Boolean }
, asset : {
name: String
, type: { type: String } // works. asset is an object with a type property
}
works: { type: Boolean },
asset: {
name: String,
type: { type: String } // works. asset is an object with a type property
}
});
```
@@ -291,8 +291,8 @@ The driver being used defaults to [node-mongodb-native](https://github.com/mongo
## API Docs
Find the API docs [here](http://mongoosejs.com/docs/api.html), generated using [dox](http://github.com/visionmedia/dox)
and [acquit](http://github.com/vkarpov15/acquit).
Find the API docs [here](http://mongoosejs.com/docs/api.html), generated using [dox](https://github.com/tj/dox)
and [acquit](https://github.com/vkarpov15/acquit).
## License

10
node_modules/mongoose/contRun.sh generated vendored
View File

@@ -1,10 +0,0 @@
#!/bin/bash
make test
ret=$?
while [ $ret == 0 ]; do
make test
ret=$?
done

View File

@@ -11,32 +11,55 @@ var Person = mongoose.model('Person');
// define some dummy data
var data = [
{ name : 'bill', age : 25, birthday : new Date().setFullYear((new
Date().getFullYear() - 25)), gender : "Male",
likes : ['movies', 'games', 'dogs']},
{ name : 'mary', age : 30, birthday : new Date().setFullYear((new
Date().getFullYear() - 30)), gender : "Female",
likes : ['movies', 'birds', 'cats']},
{ name : 'bob', age : 21, birthday : new Date().setFullYear((new
Date().getFullYear() - 21)), gender : "Male",
likes : ['tv', 'games', 'rabbits']},
{ name : 'lilly', age : 26, birthday : new Date().setFullYear((new
Date().getFullYear() - 26)), gender : "Female",
likes : ['books', 'cats', 'dogs']},
{ name : 'alucard', age : 1000, birthday : new Date().setFullYear((new
Date().getFullYear() - 1000)), gender : "Male",
likes : ['glasses', 'wine', 'the night']},
{
name: 'bill',
age: 25,
birthday: new Date().setFullYear((new Date().getFullYear() - 25)),
gender: "Male",
likes: ['movies', 'games', 'dogs']
},
{
name: 'mary',
age: 30,
birthday: new Date().setFullYear((new Date().getFullYear() - 30)),
gender: "Female",
likes: ['movies', 'birds', 'cats']
},
{
name: 'bob',
age: 21,
birthday: new Date().setFullYear((new Date().getFullYear() - 21)),
gender: "Male",
likes: ['tv', 'games', 'rabbits']
},
{
name: 'lilly',
age: 26,
birthday: new Date().setFullYear((new Date().getFullYear() - 26)),
gender: "Female",
likes: ['books', 'cats', 'dogs']
},
{
name: 'alucard',
age: 1000,
birthday : new Date().setFullYear((new Date().getFullYear() - 1000)),
gender : "Male",
likes : ['glasses', 'wine', 'the night']
}
];
mongoose.connect('mongodb://localhost/persons', function (err) {
mongoose.connect('mongodb://localhost/persons', function(err) {
if (err) throw err;
// create all of the dummy people
async.each(data, function (item, cb) {
async.each(data, function(item, cb) {
Person.create(item, cb);
}, function (err) {
}, function(err) {
if (err) {
// handle error
}
// run an aggregate query that will get all of the people who like a given
// item. To see the full documentation on ways to use the aggregate
// framework, see http://docs.mongodb.org/manual/core/aggregation/
@@ -51,7 +74,7 @@ mongoose.connect('mongodb://localhost/persons', function (err) {
_id : { likes : "$likes" },
likers : { $addToSet : "$name" }
} },
function (err, result) {
function(err, result) {
if (err) throw err;
console.log(result);
//[ { _id: { likes: 'the night' }, likers: [ 'alucard' ] },
@@ -67,7 +90,7 @@ mongoose.connect('mongodb://localhost/persons', function (err) {
//{ _id: { likes: 'movies' }, likers: [ 'mary', 'bill' ] } ]
cleanup();
});
});
});
});

View File

@@ -7,9 +7,9 @@ var Schema = mongoose.Schema;
module.exports = function() {
// define schema
var PersonSchema = new Schema({
name : String,
age : Number,
birthday : Date,
name: String,
age: Number,
birthday: Date,
gender: String,
likes: [String]
});

View File

@@ -1,5 +1,5 @@
var mongoose = require('mongoose')
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
console.log('Running mongoose version %s', mongoose.version);
@@ -9,17 +9,24 @@ console.log('Running mongoose version %s', mongoose.version);
*/
var CharacterSchema = Schema({
name: { type: String, required: true }
, health: { type: Number, min: 0, max: 100 }
})
name: {
type: String,
required: true
},
health: {
type: Number,
min: 0,
max: 100
}
});
/**
* Methods
*/
CharacterSchema.methods.attack = function () {
CharacterSchema.methods.attack = function() {
console.log('%s is attacking', this.name);
}
};
/**
* Character model
@@ -32,39 +39,39 @@ var Character = mongoose.model('Character', CharacterSchema);
* the default port (27017)
*/
var dbname = 'mongoose-example-doc-methods-' + ((Math.random()*10000)|0);
var dbname = 'mongoose-example-doc-methods-' + ((Math.random() * 10000) | 0);
var uri = 'mongodb://localhost/' + dbname;
console.log('connecting to %s', uri);
mongoose.connect(uri, function (err) {
mongoose.connect(uri, function(err) {
// if we failed to connect, abort
if (err) throw err;
// we connected ok
example();
})
});
/**
* Use case
*/
function example () {
Character.create({ name: 'Link', health: 100 }, function (err, link) {
function example() {
Character.create({ name: 'Link', health: 100 }, function(err, link) {
if (err) return done(err);
console.log('found', link);
link.attack(); // 'Link is attacking'
done();
})
});
}
/**
* Clean up
*/
function done (err) {
function done(err) {
if (err) console.error(err);
mongoose.connection.db.dropDatabase(function () {
mongoose.connection.db.dropDatabase(function() {
mongoose.disconnect();
})
});
}

View File

@@ -1,18 +1,17 @@
var express = require('express')
var mongoose = require('../../../lib')
var express = require('express');
var mongoose = require('../../../lib');
var uri = 'mongodb://localhost/mongoose-shared-connection';
global.db = mongoose.createConnection(uri);
var routes = require('./routes')
var routes = require('./routes');
var app = express();
app.get('/', routes.home);
app.get('/insert', routes.insert);
app.get('/name', routes.modelName);
app.listen(8000, function () {
app.listen(8000, function() {
console.log('listening on http://localhost:8000');
})
});

View File

@@ -1,6 +1,5 @@
var Schema = require('../../../lib').Schema;
var mySchema = Schema({ name: String });
// db is global
/* global db */
module.exports = db.model('MyModel', mySchema);

View File

@@ -1,20 +1,20 @@
var model = require('./modelA')
var model = require('./modelA');
exports.home = function (req, res, next) {
model.find(function (err, docs) {
exports.home = function(req, res, next) {
model.find(function(err, docs) {
if (err) return next(err);
res.send(docs);
})
}
});
};
exports.modelName = function (req, res) {
exports.modelName = function(req, res) {
res.send('my model name is ' + model.modelName);
}
};
exports.insert = function (req, res, next) {
model.create({ name: 'inserting ' + Date.now() }, function (err, doc) {
exports.insert = function(req, res, next) {
model.create({ name: 'inserting ' + Date.now() }, function(err, doc) {
if (err) return next(err);
res.send(doc);
})
}
});
};

View File

@@ -11,7 +11,7 @@ module.exports = function() {
// MUST BE VANILLA
var LocationObject = new Schema({
loc: {
type: { type: String },
type: { type: String },
coordinates: []
}
});

View File

@@ -20,15 +20,15 @@ var data = [
];
mongoose.connect('mongodb://localhost/locations', function (err) {
mongoose.connect('mongodb://localhost/locations', function(err) {
if (err) throw err;
Location.on('index', function(err) {
if (err) throw err;
// create all of the dummy locations
async.each(data, function (item, cb) {
async.each(data, function(item, cb) {
Location.create(item, cb);
}, function (err) {
}, function(err) {
if (err) throw err;
// create the location we want to search for
var coords = { type : 'Point', coordinates : [-5, 5] };

View File

@@ -11,41 +11,69 @@ var Person = mongoose.model('Person');
// define some dummy data
var data = [
{ name : 'bill', age : 25, birthday : new Date().setFullYear((new
Date().getFullYear() - 25)), gender : "Male",
likes : ['movies', 'games', 'dogs'], loc : [0, 0]},
{ name : 'mary', age : 30, birthday : new Date().setFullYear((new
Date().getFullYear() - 30)), gender : "Female",
likes : ['movies', 'birds', 'cats'], loc : [1, 1]},
{ name : 'bob', age : 21, birthday : new Date().setFullYear((new
Date().getFullYear() - 21)), gender : "Male",
likes : ['tv', 'games', 'rabbits'], loc : [3, 3]},
{ name : 'lilly', age : 26, birthday : new Date().setFullYear((new
Date().getFullYear() - 26)), gender : "Female",
likes : ['books', 'cats', 'dogs'], loc : [6, 6]},
{ name : 'alucard', age : 1000, birthday : new Date().setFullYear((new
Date().getFullYear() - 1000)), gender : "Male",
likes : ['glasses', 'wine', 'the night'], loc : [10, 10]},
{
name: 'bill',
age: 25,
birthday: new Date().setFullYear((new Date().getFullYear() - 25)),
gender: "Male",
likes: ['movies', 'games', 'dogs'],
loc: [0, 0]
},
{
name: 'mary',
age: 30,
birthday: new Date().setFullYear((new Date().getFullYear() - 30)),
gender: "Female",
likes: ['movies', 'birds', 'cats'],
loc: [1, 1]
},
{
name: 'bob',
age: 21,
birthday: new Date().setFullYear((new Date().getFullYear() - 21)),
gender: "Male",
likes: ['tv', 'games', 'rabbits'],
loc: [3, 3]
},
{
name: 'lilly',
age: 26,
birthday: new Date().setFullYear((new Date().getFullYear() - 26)),
gender: "Female",
likes: ['books', 'cats', 'dogs'],
loc: [6, 6]
},
{
name: 'alucard',
age: 1000,
birthday: new Date().setFullYear((new Date().getFullYear() - 1000)),
gender: "Male",
likes: ['glasses', 'wine', 'the night'],
loc: [10, 10]
}
];
mongoose.connect('mongodb://localhost/persons', function (err) {
mongoose.connect('mongodb://localhost/persons', function(err) {
if (err) throw err;
// create all of the dummy people
async.each(data, function (item, cb) {
async.each(data, function(item, cb) {
Person.create(item, cb);
}, function (err) {
}, function(err) {
if (err) {
// handler error
}
// let's find the closest person to bob
Person.find({ name : 'bob' }, function (err, res) {
Person.find({ name : 'bob' }, function(err, res) {
if (err) throw err;
res[0].findClosest(function (err, closest) {
res[0].findClosest(function(err, closest) {
if (err) throw err;
console.log("%s is closest to %s", res[0].name, closest);
// we can also just query straight off of the model. For more
// information about geospatial queries and indexes, see

View File

@@ -18,10 +18,10 @@ module.exports = function() {
// define a method to find the closest person
PersonSchema.methods.findClosest = function(cb) {
return this.model('Person').find({
loc : { $nearSphere : this.loc },
name : { $ne : this.name }
}).limit(1).exec(cb);
return this.model('Person').find({
loc : { $nearSphere : this.loc },
name : { $ne : this.name }
}).limit(1).exec(cb);
};
mongoose.model('Person', PersonSchema);

View File

@@ -17,7 +17,7 @@ mongoose.connect('mongodb://localhost/persons', function(err) {
name : 'bill',
age : 25,
birthday : new Date().setFullYear((new Date().getFullYear() - 25))
}, function (err, bill) {
}, function(err, bill) {
if (err) throw err;
console.log("People added to db: %s", bill.toString());
Person.find({}, function(err, people) {
@@ -28,7 +28,7 @@ mongoose.connect('mongodb://localhost/persons', function(err) {
});
// make sure to clean things up after we're done
setTimeout(function () { cleanup(); }, 2000);
setTimeout(function() { cleanup(); }, 2000);
});
});
});

View File

@@ -11,40 +11,63 @@ var Person = mongoose.model('Person');
// define some dummy data
var data = [
{ name : 'bill', age : 25, birthday : new Date().setFullYear((new
Date().getFullYear() - 25)), gender : "Male",
likes : ['movies', 'games', 'dogs']},
{ name : 'mary', age : 30, birthday : new Date().setFullYear((new
Date().getFullYear() - 30)), gender : "Female",
likes : ['movies', 'birds', 'cats']},
{ name : 'bob', age : 21, birthday : new Date().setFullYear((new
Date().getFullYear() - 21)), gender : "Male",
likes : ['tv', 'games', 'rabbits']},
{ name : 'lilly', age : 26, birthday : new Date().setFullYear((new
Date().getFullYear() - 26)), gender : "Female",
likes : ['books', 'cats', 'dogs']},
{ name : 'alucard', age : 1000, birthday : new Date().setFullYear((new
Date().getFullYear() - 1000)), gender : "Male",
likes : ['glasses', 'wine', 'the night']},
{
name: 'bill',
age: 25,
birthday: new Date().setFullYear((new Date().getFullYear() - 25)),
gender: "Male",
likes: ['movies', 'games', 'dogs']
},
{
name: 'mary',
age: 30,
birthday : new Date().setFullYear((new Date().getFullYear() - 30)),
gender: "Female",
likes: ['movies', 'birds', 'cats']
},
{
name: 'bob',
age: 21,
birthday: new Date().setFullYear((new Date().getFullYear() - 21)),
gender: "Male",
likes: ['tv', 'games', 'rabbits']
},
{
name: 'lilly',
age: 26,
birthday: new Date().setFullYear((new Date().getFullYear() - 26)),
gender: "Female",
likes: ['books', 'cats', 'dogs']
},
{
name: 'alucard',
age: 1000,
birthday: new Date().setFullYear((new Date().getFullYear() - 1000)),
gender: "Male",
likes: ['glasses', 'wine', 'the night']
}
];
mongoose.connect('mongodb://localhost/persons', function (err) {
mongoose.connect('mongodb://localhost/persons', function(err) {
if (err) throw err;
// create all of the dummy people
async.each(data, function (item, cb) {
async.each(data, function(item, cb) {
Person.create(item, cb);
}, function (err) {
}, function(err) {
if (err) {
// handle error
}
// lean queries return just plain javascript objects, not
// MongooseDocuments. This makes them good for high performance read
// situations
// when using .lean() the default is true, but you can explicitly set the
// value by passing in a boolean value. IE. .lean(false)
var q = Person.find({ age : { $lt : 1000 }}).sort('age').limit(2).lean();
q.exec(function (err, results) {
q.exec(function(err, results) {
if (err) throw err;
console.log("Are the results MongooseDocuments?: %s", results[0] instanceof mongoose.Document);

View File

@@ -1,4 +1,3 @@
// import async to make control flow simplier
var async = require('async');
@@ -11,42 +10,66 @@ var Person = mongoose.model('Person');
// define some dummy data
var data = [
{ name : 'bill', age : 25, birthday : new Date().setFullYear((new
Date().getFullYear() - 25)), gender : "Male" },
{ name : 'mary', age : 30, birthday : new Date().setFullYear((new
Date().getFullYear() - 30)), gender : "Female" },
{ name : 'bob', age : 21, birthday : new Date().setFullYear((new
Date().getFullYear() - 21)), gender : "Male" },
{ name : 'lilly', age : 26, birthday : new Date().setFullYear((new
Date().getFullYear() - 26)), gender : "Female" },
{ name : 'alucard', age : 1000, birthday : new Date().setFullYear((new
Date().getFullYear() - 1000)), gender : "Male" },
{
name: 'bill',
age: 25,
birthday: new Date().setFullYear((new Date().getFullYear() - 25)),
gender : "Male"
},
{
name: 'mary',
age: 30,
birthday: new Date().setFullYear((new Date().getFullYear() - 30)),
gender: "Female"
},
{
name: 'bob',
age: 21,
birthday : new Date().setFullYear((new Date().getFullYear() - 21)),
gender: "Male"
},
{
name: 'lilly',
age: 26,
birthday: new Date().setFullYear((new Date().getFullYear() - 26)),
gender: "Female"
},
{
name: 'alucard',
age: 1000,
birthday: new Date().setFullYear((new Date().getFullYear() - 1000)),
gender : "Male"
}
];
mongoose.connect('mongodb://localhost/persons', function (err) {
mongoose.connect('mongodb://localhost/persons', function(err) {
if (err) throw err;
// create all of the dummy people
async.each(data, function (item, cb) {
async.each(data, function(item, cb) {
Person.create(item, cb);
}, function (err) {
}, function(err) {
if (err) {
// handle error
}
// alright, simple map reduce example. We will find the total ages of each
// gender
// create the options object
var o = {};
o.map = function () {
o.map = function() {
// in this function, 'this' refers to the current document being
// processed. Return the (gender, age) tuple using emit()
// processed. Return the (gender, age) tuple using
/* global emit */
emit(this.gender, this.age);
};
// the reduce function receives the array of ages that are grouped by the
// id, which in this case is the gender
o.reduce = function (id, ages) {
o.reduce = function(id, ages) {
return Array.sum(ages);
};
@@ -62,7 +85,7 @@ mongoose.connect('mongodb://localhost/persons', function (err) {
// o.out = {}; // objects to specify where output goes, by default is
// returned, but can also be stored in a new collection
// see: http://mongoosejs.com/docs/api.html#model_Model.mapReduce
Person.mapReduce(o, function (err, results, stats) {
Person.mapReduce(o, function(err, results, stats) {
console.log("map reduce took %d ms", stats.processtime);
console.log(results);
cleanup();

View File

@@ -1,5 +1,5 @@
var assert = require('assert')
var assert = require('assert');
var mongoose = require('../../lib');
var Schema = mongoose.Schema;
var ObjectId = mongoose.Types.ObjectId;
@@ -8,7 +8,7 @@ var ObjectId = mongoose.Types.ObjectId;
* Connect to the db
*/
var dbname = 'testing_populateAdInfinitum_' + require('../../lib/utils').random()
var dbname = 'testing_populateAdInfinitum_' + require('../../lib/utils').random();
mongoose.connect('localhost', dbname);
mongoose.connection.on('error', function() {
console.error('connection error', arguments);
@@ -34,7 +34,7 @@ var blogpost = Schema({
type: Schema.ObjectId,
ref: 'User'
}
})
});
var BlogPost = mongoose.model('BlogPost', blogpost);
/**
@@ -71,7 +71,7 @@ mongoose.connection.on('open', function() {
friends: [userIds[0], userIds[1], userIds[2]]
});
User.create(users, function(err, docs) {
User.create(users, function(err) {
assert.ifError(err);
var blogposts = [];
@@ -79,19 +79,19 @@ mongoose.connection.on('open', function() {
title: 'blog 1',
tags: ['fun', 'cool'],
author: userIds[3]
})
});
blogposts.push({
title: 'blog 2',
tags: ['cool'],
author: userIds[1]
})
});
blogposts.push({
title: 'blog 3',
tags: ['fun', 'odd'],
author: userIds[2]
})
});
BlogPost.create(blogposts, function(err, docs) {
BlogPost.create(blogposts, function(err) {
assert.ifError(err);
/**
@@ -113,18 +113,18 @@ mongoose.connection.on('open', function() {
path: 'author.friends',
select: 'name',
options: { limit: 2 }
}
};
BlogPost.populate(docs, opts, function(err, docs) {
assert.ifError(err);
console.log('populated');
var s = require('util').inspect(docs, { depth: null })
var s = require('util').inspect(docs, { depth: null });
console.log(s);
done();
})
})
})
})
});
});
});
});
});
function done(err) {

View File

@@ -1,5 +1,5 @@
var mongoose = require('../../lib')
var mongoose = require('../../lib');
var Schema = mongoose.Schema;
console.log('Running mongoose version %s', mongoose.version);
@@ -9,10 +9,10 @@ console.log('Running mongoose version %s', mongoose.version);
*/
var consoleSchema = Schema({
name: String
, manufacturer: String
, released: Date
})
name: String,
manufacturer: String,
released: Date
});
var Console = mongoose.model('Console', consoleSchema);
/**
@@ -20,11 +20,14 @@ var Console = mongoose.model('Console', consoleSchema);
*/
var gameSchema = Schema({
name: String
, developer: String
, released: Date
, consoles: [{ type: Schema.Types.ObjectId, ref: 'Console' }]
})
name: String,
developer: String,
released: Date,
consoles: [{
type: Schema.Types.ObjectId,
ref: 'Console'
}]
});
var Game = mongoose.model('Game', gameSchema);
/**
@@ -32,64 +35,69 @@ var Game = mongoose.model('Game', gameSchema);
* the default port (27017)
*/
mongoose.connect('mongodb://localhost/console', function (err) {
mongoose.connect('mongodb://localhost/console', function(err) {
// if we failed to connect, abort
if (err) throw err;
// we connected ok
createData();
})
});
/**
* Data generation
*/
function createData () {
Console.create({
name: 'Nintendo 64'
, manufacturer: 'Nintendo'
, released: 'September 29, 1996'
}, function (err, nintendo64) {
if (err) return done(err);
Game.create({
name: 'Legend of Zelda: Ocarina of Time'
, developer: 'Nintendo'
, released: new Date('November 21, 1998')
, consoles: [nintendo64]
}, function (err) {
function createData() {
Console.create(
{
name: 'Nintendo 64',
manufacturer: 'Nintendo',
released: 'September 29, 1996'
},
function(err, nintendo64) {
if (err) return done(err);
example();
})
})
Game.create({
name: 'Legend of Zelda: Ocarina of Time',
developer: 'Nintendo',
released: new Date('November 21, 1998'),
consoles: [nintendo64]
},
function(err) {
if (err) return done(err);
example();
});
}
);
}
/**
* Population
*/
function example () {
function example() {
Game
.findOne({ name: /^Legend of Zelda/ })
.populate('consoles')
.exec(function (err, ocinara) {
.exec(function(err, ocinara) {
if (err) return done(err);
console.log(
'"%s" was released for the %s on %s'
, ocinara.name
, ocinara.consoles[0].name
, ocinara.released.toLocaleDateString());
'"%s" was released for the %s on %s',
ocinara.name,
ocinara.consoles[0].name,
ocinara.released.toLocaleDateString()
);
done();
})
});
}
function done (err) {
function done(err) {
if (err) console.error(err);
Console.remove(function () {
Game.remove(function () {
Console.remove(function() {
Game.remove(function() {
mongoose.disconnect();
})
})
});
});
}

View File

@@ -1,5 +1,5 @@
var mongoose = require('../../lib')
var mongoose = require('../../lib');
var Schema = mongoose.Schema;
console.log('Running mongoose version %s', mongoose.version);
@@ -9,10 +9,10 @@ console.log('Running mongoose version %s', mongoose.version);
*/
var consoleSchema = Schema({
name: String
, manufacturer: String
, released: Date
})
name: String,
manufacturer: String,
released: Date
});
var Console = mongoose.model('Console', consoleSchema);
/**
@@ -20,11 +20,14 @@ var Console = mongoose.model('Console', consoleSchema);
*/
var gameSchema = Schema({
name: String
, developer: String
, released: Date
, consoles: [{ type: Schema.Types.ObjectId, ref: 'Console' }]
})
name: String,
developer: String,
released: Date,
consoles: [{
type: Schema.Types.ObjectId,
ref: 'Console'
}]
});
var Game = mongoose.model('Game', gameSchema);
/**
@@ -32,70 +35,75 @@ var Game = mongoose.model('Game', gameSchema);
* the default port (27017)
*/
mongoose.connect('mongodb://localhost/console', function (err) {
mongoose.connect('mongodb://localhost/console', function(err) {
// if we failed to connect, abort
if (err) throw err;
// we connected ok
createData();
})
});
/**
* Data generation
*/
function createData () {
Console.create({
name: 'Nintendo 64'
, manufacturer: 'Nintendo'
, released: 'September 29, 1996'
}, function (err, nintendo64) {
if (err) return done(err);
Game.create({
name: 'Legend of Zelda: Ocarina of Time'
, developer: 'Nintendo'
, released: new Date('November 21, 1998')
, consoles: [nintendo64]
}, function (err) {
function createData() {
Console.create(
{
name: 'Nintendo 64',
manufacturer: 'Nintendo',
released: 'September 29, 1996'
},
function(err, nintendo64) {
if (err) return done(err);
example();
})
})
Game.create({
name: 'Legend of Zelda: Ocarina of Time',
developer: 'Nintendo',
released: new Date('November 21, 1998'),
consoles: [nintendo64]
},
function(err) {
if (err) return done(err);
example();
});
}
);
}
/**
* Population
*/
function example () {
function example() {
Game
.findOne({ name: /^Legend of Zelda/ })
.exec(function (err, ocinara) {
.exec(function(err, ocinara) {
if (err) return done(err);
console.log('"%s" console _id: %s', ocinara.name, ocinara.consoles[0]);
// population of existing document
ocinara.populate('consoles', function (err) {
ocinara.populate('consoles', function(err) {
if (err) return done(err);
console.log(
'"%s" was released for the %s on %s'
, ocinara.name
, ocinara.consoles[0].name
, ocinara.released.toLocaleDateString());
'"%s" was released for the %s on %s',
ocinara.name,
ocinara.consoles[0].name,
ocinara.released.toLocaleDateString()
);
done();
})
})
});
});
}
function done (err) {
function done(err) {
if (err) console.error(err);
Console.remove(function () {
Game.remove(function () {
Console.remove(function() {
Game.remove(function() {
mongoose.disconnect();
})
})
});
});
}

View File

@@ -1,5 +1,5 @@
var mongoose = require('../../lib')
var mongoose = require('../../lib');
var Schema = mongoose.Schema;
console.log('Running mongoose version %s', mongoose.version);
@@ -9,10 +9,10 @@ console.log('Running mongoose version %s', mongoose.version);
*/
var consoleSchema = Schema({
name: String
, manufacturer: String
, released: Date
})
name: String,
manufacturer: String,
released: Date
});
var Console = mongoose.model('Console', consoleSchema);
/**
@@ -20,11 +20,14 @@ var Console = mongoose.model('Console', consoleSchema);
*/
var gameSchema = Schema({
name: String
, developer: String
, released: Date
, consoles: [{ type: Schema.Types.ObjectId, ref: 'Console' }]
})
name: String,
developer: String,
released: Date,
consoles: [{
type: Schema.Types.ObjectId,
ref: 'Console'
}]
});
var Game = mongoose.model('Game', gameSchema);
/**
@@ -32,81 +35,90 @@ var Game = mongoose.model('Game', gameSchema);
* the default port (27017)
*/
mongoose.connect('mongodb://localhost/console', function (err) {
mongoose.connect('mongodb://localhost/console', function(err) {
// if we failed to connect, abort
if (err) throw err;
// we connected ok
createData();
})
});
/**
* Data generation
*/
function createData () {
Console.create({
name: 'Nintendo 64'
, manufacturer: 'Nintendo'
, released: 'September 29, 1996'
}, {
name: 'Super Nintendo'
, manufacturer: 'Nintendo'
, released: 'August 23, 1991'
}, function (err, nintendo64, superNintendo) {
if (err) return done(err);
Game.create({
name: 'Legend of Zelda: Ocarina of Time'
, developer: 'Nintendo'
, released: new Date('November 21, 1998')
, consoles: [nintendo64]
}, {
name: 'Mario Kart'
, developer: 'Nintendo'
, released: 'September 1, 1992'
, consoles: [superNintendo]
}, function (err) {
function createData() {
Console.create(
{
name: 'Nintendo 64',
manufacturer: 'Nintendo',
released: 'September 29, 1996'
},
{
name: 'Super Nintendo',
manufacturer: 'Nintendo',
released: 'August 23, 1991'
},
function(err, nintendo64, superNintendo) {
if (err) return done(err);
example();
})
})
Game.create(
{
name: 'Legend of Zelda: Ocarina of Time',
developer: 'Nintendo',
released: new Date('November 21, 1998'),
consoles: [nintendo64]
},
{
name: 'Mario Kart',
developer: 'Nintendo',
released: 'September 1, 1992',
consoles: [superNintendo]
},
function(err) {
if (err) return done(err);
example();
}
);
}
);
}
/**
* Population
*/
function example () {
function example() {
Game
.find({})
.exec(function (err, games) {
.exec(function(err, games) {
if (err) return done(err);
console.log('found %d games', games.length);
var options = { path: 'consoles', select: 'name released -_id' };
Game.populate(games, options, function (err, games) {
Game.populate(games, options, function(err, games) {
if (err) return done(err);
games.forEach(function (game) {
games.forEach(function(game) {
console.log(
'"%s" was released for the %s on %s'
, game.name
, game.consoles[0].name
, game.released.toLocaleDateString());
})
'"%s" was released for the %s on %s',
game.name,
game.consoles[0].name,
game.released.toLocaleDateString()
);
});
done()
})
})
done();
});
});
}
function done (err) {
function done(err) {
if (err) console.error(err);
Console.remove(function () {
Game.remove(function () {
Console.remove(function() {
Game.remove(function() {
mongoose.disconnect();
})
})
});
});
}

View File

@@ -1,5 +1,5 @@
var mongoose = require('../../lib')
var mongoose = require('../../lib');
var Schema = mongoose.Schema;
console.log('Running mongoose version %s', mongoose.version);
@@ -9,10 +9,10 @@ console.log('Running mongoose version %s', mongoose.version);
*/
var consoleSchema = Schema({
name: String
, manufacturer: String
, released: Date
})
name: String,
manufacturer: String,
released: Date
});
var Console = mongoose.model('Console', consoleSchema);
/**
@@ -20,11 +20,14 @@ var Console = mongoose.model('Console', consoleSchema);
*/
var gameSchema = Schema({
name: String
, developer: String
, released: Date
, consoles: [{ type: Schema.Types.ObjectId, ref: 'Console' }]
})
name: String,
developer: String,
released: Date,
consoles: [{
type: Schema.Types.ObjectId,
ref: 'Console'
}]
});
var Game = mongoose.model('Game', gameSchema);
/**
@@ -32,93 +35,104 @@ var Game = mongoose.model('Game', gameSchema);
* the default port (27017)
*/
mongoose.connect('mongodb://localhost/console', function (err) {
mongoose.connect('mongodb://localhost/console', function(err) {
// if we failed to connect, abort
if (err) throw err;
// we connected ok
createData();
})
});
/**
* Data generation
*/
function createData () {
Console.create({
name: 'Nintendo 64'
, manufacturer: 'Nintendo'
, released: 'September 29, 1996'
}, {
name: 'Super Nintendo'
, manufacturer: 'Nintendo'
, released: 'August 23, 1991'
}, {
name: 'XBOX 360'
, manufacturer: 'Microsoft'
, released: 'November 22, 2005'
}, function (err, nintendo64, superNintendo, xbox360) {
if (err) return done(err);
Game.create({
name: 'Legend of Zelda: Ocarina of Time'
, developer: 'Nintendo'
, released: new Date('November 21, 1998')
, consoles: [nintendo64]
}, {
name: 'Mario Kart'
, developer: 'Nintendo'
, released: 'September 1, 1992'
, consoles: [superNintendo]
}, {
name: 'Perfect Dark Zero'
, developer: 'Rare'
, released: 'November 17, 2005'
, consoles: [xbox360]
}, function (err) {
function createData() {
Console.create(
{
name: 'Nintendo 64',
manufacturer: 'Nintendo',
released: 'September 29, 1996'
},
{
name: 'Super Nintendo',
manufacturer: 'Nintendo',
released: 'August 23, 1991'
},
{
name: 'XBOX 360',
manufacturer: 'Microsoft',
released: 'November 22, 2005'
},
function(err, nintendo64, superNintendo, xbox360) {
if (err) return done(err);
example();
})
})
Game.create(
{
name: 'Legend of Zelda: Ocarina of Time',
developer: 'Nintendo',
released: new Date('November 21, 1998'),
consoles: [nintendo64]
},
{
name: 'Mario Kart',
developer: 'Nintendo',
released: 'September 1, 1992',
consoles: [superNintendo]
},
{
name: 'Perfect Dark Zero',
developer: 'Rare',
released: 'November 17, 2005',
consoles: [xbox360]
},
function(err) {
if (err) return done(err);
example();
}
);
}
);
}
/**
* Population
*/
function example () {
function example() {
Game
.find({})
.populate({
path: 'consoles'
, match: { manufacturer: 'Nintendo' }
, select: 'name'
, options: { comment: 'population' }
path: 'consoles',
match: { manufacturer: 'Nintendo' },
select: 'name',
options: { comment: 'population' }
})
.exec(function (err, games) {
.exec(function(err, games) {
if (err) return done(err);
games.forEach(function (game) {
games.forEach(function(game) {
console.log(
'"%s" was released for the %s on %s'
, game.name
, game.consoles.length ? game.consoles[0].name : '??'
, game.released.toLocaleDateString());
})
'"%s" was released for the %s on %s',
game.name,
game.consoles.length ? game.consoles[0].name : '??',
game.released.toLocaleDateString()
);
});
return done();
})
});
}
/**
* Clean up
*/
function done (err) {
function done(err) {
if (err) console.error(err);
Console.remove(function () {
Game.remove(function () {
Console.remove(function() {
Game.remove(function() {
mongoose.disconnect();
})
})
});
});
}

View File

@@ -1,5 +1,5 @@
var mongoose = require('../../lib')
var mongoose = require('../../lib');
var Schema = mongoose.Schema;
console.log('Running mongoose version %s', mongoose.version);
@@ -9,10 +9,10 @@ console.log('Running mongoose version %s', mongoose.version);
*/
var consoleSchema = Schema({
name: String
, manufacturer: String
, released: Date
})
name: String,
manufacturer: String,
released: Date
});
var Console = mongoose.model('Console', consoleSchema);
/**
@@ -20,11 +20,14 @@ var Console = mongoose.model('Console', consoleSchema);
*/
var gameSchema = Schema({
name: String
, developer: String
, released: Date
, consoles: [{ type: Schema.Types.ObjectId, ref: 'Console' }]
})
name: String,
developer: String,
released: Date,
consoles: [{
type: Schema.Types.ObjectId,
ref: 'Console'
}]
});
var Game = mongoose.model('Game', gameSchema);
/**
@@ -32,65 +35,72 @@ var Game = mongoose.model('Game', gameSchema);
* the default port (27017)
*/
mongoose.connect('mongodb://localhost/console', function (err) {
mongoose.connect('mongodb://localhost/console', function(err) {
// if we failed to connect, abort
if (err) throw err;
// we connected ok
createData();
})
});
/**
* Data generation
*/
function createData () {
Console.create({
name: 'Nintendo 64'
, manufacturer: 'Nintendo'
, released: 'September 29, 1996'
}, function (err, nintendo64) {
if (err) return done(err);
Game.create({
name: 'Legend of Zelda: Ocarina of Time'
, developer: 'Nintendo'
, released: new Date('November 21, 1998')
, consoles: [nintendo64]
}, function (err) {
function createData() {
Console.create(
{
name: 'Nintendo 64',
manufacturer: 'Nintendo',
released: 'September 29, 1996'
},
function(err, nintendo64) {
if (err) return done(err);
example();
})
})
Game.create(
{
name: 'Legend of Zelda: Ocarina of Time',
developer: 'Nintendo',
released: new Date('November 21, 1998'),
consoles: [nintendo64]
},
function(err) {
if (err) return done(err);
example();
}
);
}
);
}
/**
* Population
*/
function example () {
function example() {
Game
.findOne({ name: /^Legend of Zelda/ })
.populate('consoles')
.lean() // just return plain objects, not documents wrapped by mongoose
.exec(function (err, ocinara) {
.exec(function(err, ocinara) {
if (err) return done(err);
console.log(
'"%s" was released for the %s on %s'
, ocinara.name
, ocinara.consoles[0].name
, ocinara.released.toLocaleDateString());
'"%s" was released for the %s on %s',
ocinara.name,
ocinara.consoles[0].name,
ocinara.released.toLocaleDateString()
);
done();
})
});
}
function done (err) {
function done(err) {
if (err) console.error(err);
Console.remove(function () {
Game.remove(function () {
Console.remove(function() {
Game.remove(function() {
mongoose.disconnect();
})
})
});
});
}

View File

@@ -7,9 +7,9 @@ var Schema = mongoose.Schema;
module.exports = function() {
// define schema
var PersonSchema = new Schema({
name : String,
age : Number,
birthday : Date
name: String,
age: Number,
birthday: Date
});
mongoose.model('Person', PersonSchema);
};

View File

@@ -11,55 +11,73 @@ var Person = mongoose.model('Person');
// define some dummy data
var data = [
{ name : 'bill', age : 25, birthday : new Date().setFullYear((new
Date().getFullYear() - 25)) },
{ name : 'mary', age : 30, birthday : new Date().setFullYear((new
Date().getFullYear() - 30)) },
{ name : 'bob', age : 21, birthday : new Date().setFullYear((new
Date().getFullYear() - 21)) },
{ name : 'lilly', age : 26, birthday : new Date().setFullYear((new
Date().getFullYear() - 26)) },
{ name : 'alucard', age : 1000, birthday : new Date().setFullYear((new
Date().getFullYear() - 1000)) },
{
name: 'bill',
age: 25,
birthday : new Date().setFullYear((new Date().getFullYear() - 25))
},
{
name: 'mary',
age: 30,
birthday: new Date().setFullYear((new Date().getFullYear() - 30))
},
{
name: 'bob',
age: 21,
birthday : new Date().setFullYear((new Date().getFullYear() - 21))
},
{
name: 'lilly',
age: 26,
birthday: new Date().setFullYear((new Date().getFullYear() - 26))
},
{
name: 'alucard',
age: 1000,
birthday: new Date().setFullYear((new Date().getFullYear() - 1000))
}
];
mongoose.connect('mongodb://localhost/persons', function (err) {
mongoose.connect('mongodb://localhost/persons', function(err) {
if (err) throw err;
// create all of the dummy people
async.each(data, function (item, cb) {
Person.create(item, cb);
}, function (err) {
async.each(data, function(item, cb) {
Person.create(item, cb);
}, function(err) {
if (err) {
// handle error
}
// create a promise (get one from the query builder)
var prom = Person.find({age : { $lt : 1000 }}).exec();
var prom = Person.find({age : { $lt : 1000 }}).exec();
// add a callback on the promise. This will be called on both error and
// complete
prom.addBack(function () { console.log("completed"); });
prom.addBack(function() { console.log("completed"); });
// add a callback that is only called on complete (success) events
prom.addCallback(function () { console.log("Successful Completion!"); });
prom.addCallback(function() { console.log("Successful Completion!"); });
// add a callback that is only called on err (rejected) events
prom.addErrback(function () { console.log("Fail Boat"); });
prom.addErrback(function() { console.log("Fail Boat"); });
// you can chain things just like in the promise/A+ spec
// note: each then() is returning a new promise, so the above methods
// that we defined will all fire after the initial promise is fulfilled
prom.then(function (people) {
prom.then(function(people) {
// just getting the stuff for the next query
var ids = people.map(function (p) {
return p._id;
});
var ids = people.map(function(p) {
return p._id;
});
// return the next promise
return Person.find({ _id : { $nin : ids }}).exec();
}).then(function (oldest) {
console.log("Oldest person is: %s", oldest);
}).then(cleanup);
return Person.find({ _id : { $nin : ids }}).exec();
}).then(function(oldest) {
console.log("Oldest person is: %s", oldest);
}).then(cleanup);
});
});

View File

@@ -7,9 +7,9 @@ var Schema = mongoose.Schema;
module.exports = function() {
// define schema
var PersonSchema = new Schema({
name : String,
age : Number,
birthday : Date
name: String,
age: Number,
birthday: Date
});
mongoose.model('Person', PersonSchema);
};

View File

@@ -11,26 +11,41 @@ var Person = mongoose.model('Person');
// define some dummy data
var data = [
{ name : 'bill', age : 25, birthday : new Date().setFullYear((new
Date().getFullYear() - 25)) },
{ name : 'mary', age : 30, birthday : new Date().setFullYear((new
Date().getFullYear() - 30)) },
{ name : 'bob', age : 21, birthday : new Date().setFullYear((new
Date().getFullYear() - 21)) },
{ name : 'lilly', age : 26, birthday : new Date().setFullYear((new
Date().getFullYear() - 26)) },
{ name : 'alucard', age : 1000, birthday : new Date().setFullYear((new
Date().getFullYear() - 1000)) },
{
name: 'bill',
age: 25,
birthday : new Date().setFullYear((new Date().getFullYear() - 25))
},
{
name: 'mary',
age: 30,
birthday: new Date().setFullYear((new Date().getFullYear() - 30))
},
{
name: 'bob',
age: 21,
birthday : new Date().setFullYear((new Date().getFullYear() - 21))
},
{
name: 'lilly',
age: 26,
birthday: new Date().setFullYear((new Date().getFullYear() - 26))
},
{
name: 'alucard',
age: 1000,
birthday: new Date().setFullYear((new Date().getFullYear() - 1000))
}
];
mongoose.connect('mongodb://localhost/persons', function (err) {
mongoose.connect('mongodb://localhost/persons', function(err) {
if (err) throw err;
// create all of the dummy people
async.each(data, function (item, cb) {
Person.create(item, cb);
}, function (err) {
async.each(data, function(item, cb) {
Person.create(item, cb);
}, function(err) {
if (err) throw err;
// when querying data, instead of providing a callback, you can instead
@@ -40,21 +55,21 @@ mongoose.connect('mongodb://localhost/persons', function (err) {
// this allows you to continue applying modifiers to it
query.sort('birthday');
query.select('name');
// you can chain them together as well
// a full list of methods can be found:
// http://mongoosejs.com/docs/api.html#query-js
query.where('age').gt(21);
// finally, when ready to execute the query, call the exec() function
query.exec(function (err, results) {
query.exec(function(err, results) {
if (err) throw err;
console.log(results);
cleanup();
});
});
});

View File

@@ -7,9 +7,9 @@ var Schema = mongoose.Schema;
module.exports = function() {
// define schema
var PersonSchema = new Schema({
name : String,
age : Number,
birthday : Date
name: String,
age: Number,
birthday: Date
});
mongoose.model('Person', PersonSchema);
};

View File

@@ -11,16 +11,31 @@ var Person = mongoose.model('Person');
// define some dummy data
var data = [
{ name : 'bill', age : 25, birthday : new Date().setFullYear((new
Date().getFullYear() - 25)) },
{ name : 'mary', age : 30, birthday : new Date().setFullYear((new
Date().getFullYear() - 30)) },
{ name : 'bob', age : 21, birthday : new Date().setFullYear((new
Date().getFullYear() - 21)) },
{ name : 'lilly', age : 26, birthday : new Date().setFullYear((new
Date().getFullYear() - 26)) },
{ name : 'alucard', age : 1000, birthday : new Date().setFullYear((new
Date().getFullYear() - 1000)) },
{
name: 'bill',
age: 25,
birthday : new Date().setFullYear((new Date().getFullYear() - 25))
},
{
name: 'mary',
age: 30,
birthday: new Date().setFullYear((new Date().getFullYear() - 30))
},
{
name: 'bob',
age: 21,
birthday : new Date().setFullYear((new Date().getFullYear() - 21))
},
{
name: 'lilly',
age: 26,
birthday: new Date().setFullYear((new Date().getFullYear() - 26))
},
{
name: 'alucard',
age: 1000,
birthday: new Date().setFullYear((new Date().getFullYear() - 1000))
}
];
@@ -29,20 +44,23 @@ var data = [
var opts = {
replSet : { rs_name : "rs0" }
};
mongoose.connect('mongodb://localhost:27018/persons,localhost:27019,localhost:27020', opts, function (err) {
mongoose.connect('mongodb://localhost:27018/persons,localhost:27019,localhost:27020', opts, function(err) {
if (err) throw err;
// create all of the dummy people
async.each(data, function (item, cb) {
Person.create(item, cb);
}, function (err) {
async.each(data, function(item, cb) {
Person.create(item, cb);
}, function(err) {
if (err) {
// handle error
}
// create and delete some data
var prom = Person.find({age : { $lt : 1000 }}).exec();
var prom = Person.find({age : { $lt : 1000 }}).exec();
prom.then(function (people) {
console.log("young people: %s", people);
}).then(cleanup);
prom.then(function(people) {
console.log("young people: %s", people);
}).then(cleanup);
});
});

View File

@@ -3,8 +3,8 @@
* Module dependencies.
*/
var mongoose = require('../../lib')
, Schema = mongoose.Schema;
var mongoose = require('../../lib'),
Schema = mongoose.Schema;
/**
* Schema definition
@@ -15,28 +15,45 @@ var mongoose = require('../../lib')
var Comment = new Schema();
Comment.add({
title : { type: String, index: true }
, date : Date
, body : String
, comments : [Comment]
title: {
type: String,
index: true
},
date: Date,
body: String,
comments: [Comment]
});
var BlogPost = new Schema({
title : { type: String, index: true }
, slug : { type: String, lowercase: true, trim: true }
, date : Date
, buf : Buffer
, comments : [Comment]
, creator : Schema.ObjectId
title: {
type: String,
index: true
},
slug: {
type: String,
lowercase: true,
trim: true
},
date: Date,
buf: Buffer,
comments: [Comment],
creator: Schema.ObjectId
});
var Person = new Schema({
name: {
first: String
, last : String
name: {
first: String,
last : String
},
email: {
type: String,
required: true,
index: {
unique: true,
sparse: true
}
, email: { type: String, required: true, index: { unique: true, sparse: true } }
, alive: Boolean
},
alive: Boolean
});
/**
@@ -44,18 +61,19 @@ var Person = new Schema({
*/
BlogPost.path('date')
.default(function(){
return new Date()
})
.set(function(v){
return v == 'now' ? new Date() : v;
});
.default(function() {
return new Date();
})
.set(function(v) {
return v == 'now' ? new Date() : v;
});
/**
* Pre hook.
*/
BlogPost.pre('save', function(next, done){
BlogPost.pre('save', function(next, done) {
/* global emailAuthor */
emailAuthor(done); // some async function
next();
});
@@ -64,33 +82,33 @@ BlogPost.pre('save', function(next, done){
* Methods
*/
BlogPost.methods.findCreator = function (callback) {
BlogPost.methods.findCreator = function(callback) {
return this.db.model('Person').findById(this.creator, callback);
}
};
BlogPost.statics.findByTitle = function (title, callback) {
BlogPost.statics.findByTitle = function(title, callback) {
return this.find({ title: title }, callback);
}
};
BlogPost.methods.expressiveQuery = function (creator, date, callback) {
BlogPost.methods.expressiveQuery = function(creator, date, callback) {
return this.find('creator', creator).where('date').gte(date).run(callback);
}
};
/**
* Plugins
*/
function slugGenerator (options){
function slugGenerator(options) {
options = options || {};
var key = options.key || 'title';
return function slugGenerator(schema){
schema.path(key).set(function(v){
return function slugGenerator(schema) {
schema.path(key).set(function(v) {
this.slug = v.toLowerCase().replace(/[^a-z0-9]/g, '').replace(/-+/g, '');
return v;
});
};
};
}
BlogPost.plugin(slugGenerator());

View File

@@ -1,6 +1,6 @@
// modules
var mongoose = require('../../../lib')
var mongoose = require('../../../lib');
var Schema = mongoose.Schema;
// parse json
@@ -14,14 +14,14 @@ var TimeSignature = mongoose.model('TimeSignatures', timeSignatureSchema);
// create a TimeSignature document
var threeFour = new TimeSignature({
count: 3
, unit: 4
, description: "3/4"
, additive: false
, created: new Date
, links: ["http://en.wikipedia.org/wiki/Time_signature"]
, user_id: "518d31a0ef32bbfa853a9814"
count: 3,
unit: 4,
description: "3/4",
additive: false,
created: new Date,
links: ["http://en.wikipedia.org/wiki/Time_signature"],
user_id: "518d31a0ef32bbfa853a9814"
});
// print its description
console.log(threeFour)
console.log(threeFour);

View File

@@ -7,13 +7,13 @@ var Schema = mongoose.Schema;
module.exports = function() {
// define schema
var PersonSchema = new Schema({
name : String,
age : Number,
birthday : Date
name: String,
age: Number,
birthday: Date
});
// define a static
PersonSchema.statics.findPersonByName = function (name, cb) {
PersonSchema.statics.findPersonByName = function(name, cb) {
this.find({ name : new RegExp(name, 'i') }, cb);
};

View File

@@ -13,22 +13,25 @@ var Person = mongoose.model("Person");
mongoose.connect('mongodb://localhost/persons', function(err) {
if (err) throw err;
Person.create({
name : 'bill',
age : 25,
birthday : new Date().setFullYear((new Date().getFullYear() - 25))
}, function (err, bill) {
if (err) throw err;
console.log("People added to db: %s", bill.toString());
// using the static
Person.findPersonByName('bill', function(err, result) {
Person.create(
{
name : 'bill',
age : 25,
birthday : new Date().setFullYear((new Date().getFullYear() - 25))
},
function(err, bill) {
if (err) throw err;
console.log(result);
cleanup();
});
});
console.log("People added to db: %s", bill.toString());
// using the static
Person.findPersonByName('bill', function(err, result) {
if (err) throw err;
console.log(result);
cleanup();
});
}
);
});
function cleanup() {

28
node_modules/mongoose/lib/ES6Promise.js generated vendored Normal file
View File

@@ -0,0 +1,28 @@
/* eslint no-unused-vars: 1 */
/**
* ES6 Promise wrapper constructor.
*
* Promises are returned from executed queries. Example:
*
* var query = Candy.find({ bar: true });
* var promise = query.exec();
*
* DEPRECATED. Mongoose 5.0 will use native promises by default (or bluebird,
* if native promises are not present) but still
* support plugging in your own ES6-compatible promises library. Mongoose 5.0
* will **not** support mpromise.
*
* @param {Function} fn a function which will be called when the promise is resolved that accepts `fn(err, ...){}` as signature
* @api public
*/
function ES6Promise(fn) {
throw 'Can\'t use ES6 promise with mpromise style constructor';
}
ES6Promise.use = function(Promise) {
ES6Promise.ES6 = Promise;
};
module.exports = ES6Promise;

View File

@@ -1,12 +1,14 @@
/* eslint no-unused-vars: 1 */
/*!
* Module dependencies
*/
var Promise = require('./promise')
, util = require('util')
, utils = require('./utils')
, Query = require('./query')
, read = Query.prototype.read
var util = require('util');
var utils = require('./utils');
var PromiseProvider = require('./promise_provider');
var Query = require('./query');
var read = Query.prototype.read;
/**
* Aggregate constructor used for building aggregation pipelines.
@@ -31,6 +33,7 @@ var Promise = require('./promise')
*
* - The documents returned are plain javascript objects, not mongoose documents (since any shape of document can be returned).
* - Requires MongoDB >= 2.1
* - Mongoose does **not** cast pipeline stages. `new Aggregate({ $match: { _id: '00000000000000000000000a' } });` will not work unless `_id` is a string in the database. Use `new Aggregate({ $match: { _id: mongoose.Types.ObjectId('00000000000000000000000a') } });` instead.
*
* @see MongoDB http://docs.mongodb.org/manual/applications/aggregation/
* @see driver http://mongodb.github.com/node-mongodb-native/api-generated/collection.html#aggregate
@@ -38,7 +41,7 @@ var Promise = require('./promise')
* @api public
*/
function Aggregate () {
function Aggregate() {
this._pipeline = [];
this._model = undefined;
this.options = undefined;
@@ -55,13 +58,13 @@ function Aggregate () {
*
* @param {Model} model the model to which the aggregate is to be bound
* @return {Aggregate}
* @api private
* @api public
*/
Aggregate.prototype.bind = function (model) {
Aggregate.prototype.model = function(model) {
this._model = model;
return this;
}
};
/**
* Appends new operators to this aggregate pipeline
@@ -79,9 +82,8 @@ Aggregate.prototype.bind = function (model) {
* @api public
*/
Aggregate.prototype.append = function () {
var args = utils.args(arguments)
, arg;
Aggregate.prototype.append = function() {
var args = utils.args(arguments);
if (!args.every(isOperator)) {
throw new Error("Arguments must be aggregate pipeline operators");
@@ -90,7 +92,7 @@ Aggregate.prototype.append = function () {
this._pipeline = this._pipeline.concat(args);
return this;
}
};
/**
* Appends a new $project operator to this aggregate pipeline.
@@ -124,15 +126,15 @@ Aggregate.prototype.append = function () {
* @api public
*/
Aggregate.prototype.project = function (arg) {
Aggregate.prototype.project = function(arg) {
var fields = {};
if ('object' === typeof arg && !util.isArray(arg)) {
Object.keys(arg).forEach(function (field) {
Object.keys(arg).forEach(function(field) {
fields[field] = arg[field];
});
} else if (1 === arguments.length && 'string' === typeof arg) {
arg.split(/\s+/).forEach(function (field) {
arg.split(/\s+/).forEach(function(field) {
if (!field) return;
var include = '-' == field[0] ? 0 : 1;
if (include === 0) field = field.substring(1);
@@ -143,7 +145,7 @@ Aggregate.prototype.project = function (arg) {
}
return this.append({ $project: fields });
}
};
/**
* Appends a new custom $group operator to this aggregate pipeline.
@@ -232,7 +234,7 @@ Aggregate.prototype.project = function (arg) {
* @api public
*/
Aggregate.prototype.near = function (arg) {
Aggregate.prototype.near = function(arg) {
var op = {};
op.$geoNear = arg;
return this.append(op);
@@ -242,8 +244,8 @@ Aggregate.prototype.near = function (arg) {
* define methods
*/
'group match skip limit out'.split(' ').forEach(function ($operator) {
Aggregate.prototype[$operator] = function (arg) {
'group match skip limit out'.split(' ').forEach(function($operator) {
Aggregate.prototype[$operator] = function(arg) {
var op = {};
op['$' + $operator] = arg;
return this.append(op);
@@ -253,6 +255,9 @@ Aggregate.prototype.near = function (arg) {
/**
* Appends new custom $unwind operator(s) to this aggregate pipeline.
*
* Note that the `$unwind` operator requires the path name to start with '$'.
* Mongoose will prepend '$' if the specified field doesn't start '$'.
*
* ####Examples:
*
* aggregate.unwind("tags");
@@ -264,13 +269,47 @@ Aggregate.prototype.near = function (arg) {
* @api public
*/
Aggregate.prototype.unwind = function () {
Aggregate.prototype.unwind = function() {
var args = utils.args(arguments);
return this.append.apply(this, args.map(function (arg) {
return { $unwind: '$' + arg };
return this.append.apply(this, args.map(function(arg) {
return { $unwind: (arg && arg.charAt(0) === '$') ? arg : '$' + arg };
}));
}
};
/**
* Appends new custom $lookup operator(s) to this aggregate pipeline.
*
* ####Examples:
*
* aggregate.lookup({ from: 'users', localField: 'userId', foreignField: '_id', as: 'users' });
*
* @see $lookup https://docs.mongodb.org/manual/reference/operator/aggregation/lookup/#pipe._S_lookup
* @param {Object} options to $lookup as described in the above link
* @return {Aggregate}
* @api public
*/
Aggregate.prototype.lookup = function(options) {
return this.append({ $lookup: options });
};
/**
* Appends new custom $sample operator(s) to this aggregate pipeline.
*
* ####Examples:
*
* aggregate.sample(3); // Add a pipeline that picks 3 random documents
*
* @see $sample https://docs.mongodb.org/manual/reference/operator/aggregation/sample/#pipe._S_sample
* @param {Number} size number of random documents to pick
* @return {Aggregate}
* @api public
*/
Aggregate.prototype.sample = function(size) {
return this.append({ $sample: { size: size } });
};
/**
* Appends a new $sort operator to this aggregate pipeline.
@@ -291,18 +330,18 @@ Aggregate.prototype.unwind = function () {
* @api public
*/
Aggregate.prototype.sort = function (arg) {
Aggregate.prototype.sort = function(arg) {
// TODO refactor to reuse the query builder logic
var sort = {};
if ('Object' === arg.constructor.name) {
var desc = ['desc', 'descending', -1];
Object.keys(arg).forEach(function (field) {
Object.keys(arg).forEach(function(field) {
sort[field] = desc.indexOf(arg[field]) === -1 ? 1 : -1;
});
} else if (1 === arguments.length && 'string' == typeof arg) {
arg.split(/\s+/).forEach(function (field) {
arg.split(/\s+/).forEach(function(field) {
if (!field) return;
var ascend = '-' == field[0] ? -1 : 1;
if (ascend === -1) field = field.substring(1);
@@ -313,7 +352,7 @@ Aggregate.prototype.sort = function (arg) {
}
return this.append({ $sort: sort });
}
};
/**
* Sets the readPreference option for the aggregation query.
@@ -328,12 +367,58 @@ Aggregate.prototype.sort = function (arg) {
* @see driver http://mongodb.github.com/node-mongodb-native/driver-articles/anintroductionto1_1and2_2.html#read-preferences
*/
Aggregate.prototype.read = function (pref) {
Aggregate.prototype.read = function(pref) {
if (!this.options) this.options = {};
read.apply(this, arguments);
return this;
};
/**
* Execute the aggregation with explain
*
* ####Example:
*
* Model.aggregate(..).explain(callback)
*
* @param {Function} callback
* @return {Promise}
*/
Aggregate.prototype.explain = function(callback) {
var _this = this;
var Promise = PromiseProvider.get();
return new Promise.ES6(function(resolve, reject) {
if (!_this._pipeline.length) {
var err = new Error('Aggregate has empty pipeline');
if (callback) {
callback(err);
}
reject(err);
return;
}
prepareDiscriminatorPipeline(_this);
_this._model
.collection
.aggregate(_this._pipeline, _this.options || {})
.explain(function(error, result) {
if (error) {
if (callback) {
callback(error);
}
reject(error);
return;
}
if (callback) {
callback(null, result);
}
resolve(result);
});
});
};
/**
* Sets the allowDiskUse option for the aggregation query (ignored for < 2.6.0)
*
@@ -391,34 +476,68 @@ Aggregate.prototype.cursor = function(options) {
* @api public
*/
Aggregate.prototype.exec = function (callback) {
var promise = new Promise();
if (callback) {
promise.addBack(callback);
}
if (!this._pipeline.length) {
promise.error(new Error("Aggregate has empty pipeline"));
return promise;
}
Aggregate.prototype.exec = function(callback) {
if (!this._model) {
promise.error(new Error("Aggregate not bound to any Model"));
return promise;
throw new Error("Aggregate not bound to any Model");
}
prepareDiscriminatorPipeline(this);
var _this = this;
var Promise = PromiseProvider.get();
if (this.options && this.options.cursor) {
return this._model.collection.aggregate(this._pipeline, this.options || {});
if (this.options.cursor.async) {
return new Promise.ES6(function(resolve, reject) {
if (!_this._model.collection.buffer) {
process.nextTick(function() {
var cursor = _this._model.collection.
aggregate(_this._pipeline, _this.options || {});
resolve(cursor);
callback && callback(cursor);
});
return;
} else {
_this._model.collection.emitter.once('queue', function() {
var cursor = _this._model.collection.
aggregate(_this._pipeline, _this.options || {});
resolve(cursor);
callback && callback(null, cursor);
});
}
});
} else {
return this._model.collection.
aggregate(this._pipeline, this.options || {});
}
}
this._model
.collection
.aggregate(this._pipeline, this.options || {}, promise.resolve.bind(promise));
return new Promise.ES6(function(resolve, reject) {
if (!_this._pipeline.length) {
var err = new Error('Aggregate has empty pipeline');
if (callback) {
callback(err);
}
reject(err);
return;
}
return promise;
prepareDiscriminatorPipeline(_this);
_this._model
.collection
.aggregate(_this._pipeline, _this.options || {}, function(error, result) {
if (error) {
if (callback) {
callback(error);
}
reject(error);
return;
}
if (callback) {
callback(null, result);
}
resolve(result);
});
});
};
/*!
@@ -433,7 +552,7 @@ Aggregate.prototype.exec = function (callback) {
* @api private
*/
function isOperator (obj) {
function isOperator(obj) {
var k;
if ('object' !== typeof obj) {
@@ -442,7 +561,7 @@ function isOperator (obj) {
k = Object.keys(obj);
return 1 === k.length && k.some(function (key) {
return 1 === k.length && k.some(function(key) {
return '$' === key[0];
});
}
@@ -455,7 +574,7 @@ function isOperator (obj) {
* @param {Aggregate} aggregate Aggregate to prepare
*/
function prepareDiscriminatorPipeline (aggregate) {
function prepareDiscriminatorPipeline(aggregate) {
var schema = aggregate._model.schema,
discriminatorMapping = schema && schema.discriminatorMapping;
@@ -472,6 +591,10 @@ function prepareDiscriminatorPipeline (aggregate) {
originalPipeline[0].$match[discriminatorKey] = discriminatorValue;
// `originalPipeline` is a ref, so there's no need for
// aggregate._pipeline = originalPipeline
} else if (originalPipeline[0] && originalPipeline[0].$geoNear) {
originalPipeline[0].$geoNear.query =
originalPipeline[0].$geoNear.query || {};
originalPipeline[0].$geoNear.query[discriminatorKey] = discriminatorValue;
} else {
var match = {};
match[discriminatorKey] = discriminatorValue;

View File

@@ -2,26 +2,14 @@
* Module dependencies.
*/
var NodeJSDocument = require('./document')
, EventEmitter = require('events').EventEmitter
, setMaxListeners = EventEmitter.prototype.setMaxListeners
, MongooseError = require('./error')
, MixedSchema = require('./schema/mixed')
, Schema = require('./schema')
, ObjectId = require('./types/objectid')
, ValidatorError = require('./schematype').ValidatorError
, utils = require('./utils')
, clone = utils.clone
, isMongooseObject = utils.isMongooseObject
, inspect = require('util').inspect
, ValidationError = MongooseError.ValidationError
, InternalCache = require('./internal')
, deepEqual = utils.deepEqual
, hooks = require('hooks-fixed')
, Promise = require('./promise')
, DocumentArray
, MongooseArray
, Embedded
var NodeJSDocument = require('./document'),
EventEmitter = require('events').EventEmitter,
MongooseError = require('./error'),
Schema = require('./schema'),
ObjectId = require('./types/objectid'),
utils = require('./utils'),
ValidationError = MongooseError.ValidationError,
InternalCache = require('./internal');
/**
* Document constructor.
@@ -30,17 +18,17 @@ var NodeJSDocument = require('./document')
* @param {Object} [fields] optional object containing the fields which were selected in the query returning this document and any populated paths data
* @param {Boolean} [skipId] bool, should we auto create an ObjectId _id
* @inherits NodeJS EventEmitter http://nodejs.org/api/events.html#events_class_events_eventemitter
* @event `init`: Emitted on a document after it has was retreived from the db and fully hydrated by Mongoose.
* @event `init`: Emitted on a document after it has was retrieved from the db and fully hydrated by Mongoose.
* @event `save`: Emitted when the document is successfully saved
* @api private
*/
function Document (obj, schema, fields, skipId, skipInit) {
function Document(obj, schema, fields, skipId, skipInit) {
if ( !(this instanceof Document) )
return new Document( obj, schema, fields, skipId, skipInit );
if (utils.isObject(schema) && !(schema instanceof Schema)) {
if (utils.isObject(schema) && !schema.instanceOfSchema) {
schema = new Schema(schema);
}
@@ -48,15 +36,15 @@ function Document (obj, schema, fields, skipId, skipInit) {
schema = this.schema || schema;
// Generate ObjectId if it is missing, but it requires a scheme
if ( !this.schema && schema.options._id ){
if ( !this.schema && schema.options._id ) {
obj = obj || {};
if ( obj._id === undefined ){
if ( obj._id === undefined ) {
obj._id = new ObjectId();
}
}
if ( !schema ){
if ( !schema ) {
throw new MongooseError.MissingSchemaError();
}
@@ -82,21 +70,21 @@ function Document (obj, schema, fields, skipId, skipInit) {
this.$__.activePaths.require(required[i]);
}
setMaxListeners.call(this, 0);
this.$__.emitter.setMaxListeners(0);
this._doc = this.$__buildDoc(obj, fields, skipId);
if ( !skipInit && obj ){
if ( !skipInit && obj ) {
this.init( obj );
}
this.$__registerHooksFromSchema();
// apply methods
for ( var m in schema.methods ){
for ( var m in schema.methods ) {
this[ m ] = schema.methods[ m ];
}
// apply statics
for ( var s in schema.statics ){
for ( var s in schema.statics ) {
this[ s ] = schema.statics[ s ];
}
}

52
node_modules/mongoose/lib/cast.js generated vendored
View File

@@ -14,14 +14,14 @@ var Types = require('./schema/index');
*/
var cast = module.exports = function(schema, obj) {
var paths = Object.keys(obj)
, i = paths.length
, any$conditionals
, schematype
, nested
, path
, type
, val;
var paths = Object.keys(obj),
i = paths.length,
any$conditionals,
schematype,
nested,
path,
type,
val;
while (i--) {
path = paths[i];
@@ -29,7 +29,6 @@ var cast = module.exports = function(schema, obj) {
if ('$or' === path || '$nor' === path || '$and' === path) {
var k = val.length;
var orComponentQuery;
while (k--) {
val[k] = cast(schema, val[k]);
@@ -48,6 +47,10 @@ var cast = module.exports = function(schema, obj) {
continue;
} else if (path === '$elemMatch') {
val = cast(schema, val);
} else {
if (!schema) {
@@ -59,12 +62,11 @@ var cast = module.exports = function(schema, obj) {
if (!schematype) {
// Handle potential embedded array queries
var split = path.split('.')
, j = split.length
, pathFirstHalf
, pathLastHalf
, remainingConds
, castingQuery;
var split = path.split('.'),
j = split.length,
pathFirstHalf,
pathLastHalf,
remainingConds;
// Find the part of the var path that is a path of the Schema
while (j--) {
@@ -100,7 +102,7 @@ var cast = module.exports = function(schema, obj) {
continue;
}
var numbertype = new Types.Number('__QueryCasting__')
var numbertype = new Types.Number('__QueryCasting__');
var value = val[geo];
if (val.$maxDistance) {
@@ -131,16 +133,16 @@ var cast = module.exports = function(schema, obj) {
value = value.$geometry.coordinates;
}
;(function _cast (val) {
(function _cast(val) {
if (Array.isArray(val)) {
val.forEach(function (item, i) {
val.forEach(function(item, i) {
if (Array.isArray(item) || utils.isObject(item)) {
return _cast(item);
}
val[i] = numbertype.castForQuery(item);
});
} else {
var nearKeys= Object.keys(val);
var nearKeys = Object.keys(val);
var nearLen = nearKeys.length;
while (nearLen--) {
var nkey = nearKeys[nearLen];
@@ -157,10 +159,11 @@ var cast = module.exports = function(schema, obj) {
}
} else if (val === null || val === undefined) {
obj[path] = null;
continue;
} else if ('Object' === val.constructor.name) {
any$conditionals = Object.keys(val).some(function (k) {
any$conditionals = Object.keys(val).some(function(k) {
return k.charAt(0) === '$' && k !== '$id' && k !== '$ref';
});
@@ -168,9 +171,10 @@ var cast = module.exports = function(schema, obj) {
obj[path] = schematype.castForQuery(val);
} else {
var ks = Object.keys(val)
, k = ks.length
, $cond;
var ks = Object.keys(val),
$cond;
k = ks.length;
while (k--) {
$cond = ks[k];
@@ -204,4 +208,4 @@ var cast = module.exports = function(schema, obj) {
}
return obj;
}
};

View File

@@ -3,7 +3,8 @@
* Module dependencies.
*/
var STATES = require('./connectionstate')
var EventEmitter = require('events').EventEmitter;
var STATES = require('./connectionstate');
/**
* Abstract Collection constructor
@@ -16,7 +17,7 @@ var STATES = require('./connectionstate')
* @api public
*/
function Collection (name, conn, opts) {
function Collection(name, conn, opts) {
if (undefined === opts) opts = {};
if (undefined === opts.capped) opts.capped = {};
@@ -34,11 +35,12 @@ function Collection (name, conn, opts) {
this.conn = conn;
this.queue = [];
this.buffer = this.opts.bufferCommands;
this.emitter = new EventEmitter();
if (STATES.connected == this.conn.readyState) {
this.onOpen();
}
};
}
/**
* The collection name
@@ -73,7 +75,7 @@ Collection.prototype.conn;
* @api private
*/
Collection.prototype.onOpen = function () {
Collection.prototype.onOpen = function() {
var self = this;
this.buffer = false;
self.doQueue();
@@ -85,7 +87,7 @@ Collection.prototype.onOpen = function () {
* @api private
*/
Collection.prototype.onClose = function () {
Collection.prototype.onClose = function() {
if (this.opts.bufferCommands) {
this.buffer = true;
}
@@ -100,7 +102,7 @@ Collection.prototype.onClose = function () {
* @api private
*/
Collection.prototype.addQueue = function (name, args) {
Collection.prototype.addQueue = function(name, args) {
this.queue.push([name, args]);
return this;
};
@@ -111,11 +113,15 @@ Collection.prototype.addQueue = function (name, args) {
* @api private
*/
Collection.prototype.doQueue = function () {
for (var i = 0, l = this.queue.length; i < l; i++){
Collection.prototype.doQueue = function() {
for (var i = 0, l = this.queue.length; i < l; i++) {
this[this.queue[i][0]].apply(this, this.queue[i][1]);
}
this.queue = [];
var _this = this;
process.nextTick(function() {
_this.emitter.emit('queue');
});
return this;
};
@@ -123,7 +129,7 @@ Collection.prototype.doQueue = function () {
* Abstract method that drivers must implement.
*/
Collection.prototype.ensureIndex = function(){
Collection.prototype.ensureIndex = function() {
throw new Error('Collection#ensureIndex unimplemented by driver');
};
@@ -131,7 +137,7 @@ Collection.prototype.ensureIndex = function(){
* Abstract method that drivers must implement.
*/
Collection.prototype.findAndModify = function(){
Collection.prototype.findAndModify = function() {
throw new Error('Collection#findAndModify unimplemented by driver');
};
@@ -139,7 +145,7 @@ Collection.prototype.findAndModify = function(){
* Abstract method that drivers must implement.
*/
Collection.prototype.findOne = function(){
Collection.prototype.findOne = function() {
throw new Error('Collection#findOne unimplemented by driver');
};
@@ -147,7 +153,7 @@ Collection.prototype.findOne = function(){
* Abstract method that drivers must implement.
*/
Collection.prototype.find = function(){
Collection.prototype.find = function() {
throw new Error('Collection#find unimplemented by driver');
};
@@ -155,7 +161,7 @@ Collection.prototype.find = function(){
* Abstract method that drivers must implement.
*/
Collection.prototype.insert = function(){
Collection.prototype.insert = function() {
throw new Error('Collection#insert unimplemented by driver');
};
@@ -163,7 +169,7 @@ Collection.prototype.insert = function(){
* Abstract method that drivers must implement.
*/
Collection.prototype.save = function(){
Collection.prototype.save = function() {
throw new Error('Collection#save unimplemented by driver');
};
@@ -171,7 +177,7 @@ Collection.prototype.save = function(){
* Abstract method that drivers must implement.
*/
Collection.prototype.update = function(){
Collection.prototype.update = function() {
throw new Error('Collection#update unimplemented by driver');
};
@@ -179,7 +185,7 @@ Collection.prototype.update = function(){
* Abstract method that drivers must implement.
*/
Collection.prototype.getIndexes = function(){
Collection.prototype.getIndexes = function() {
throw new Error('Collection#getIndexes unimplemented by driver');
};
@@ -187,7 +193,7 @@ Collection.prototype.getIndexes = function(){
* Abstract method that drivers must implement.
*/
Collection.prototype.mapReduce = function(){
Collection.prototype.mapReduce = function() {
throw new Error('Collection#mapReduce unimplemented by driver');
};

View File

@@ -2,17 +2,14 @@
* Module dependencies.
*/
var url = require('url')
, utils = require('./utils')
, EventEmitter = require('events').EventEmitter
, driver = global.MONGOOSE_DRIVER_PATH || 'node-mongodb-native'
, Model = require('./model')
, Schema = require('./schema')
, Collection = require('./drivers/' + driver + '/collection')
, STATES = require('./connectionstate')
, MongooseError = require('./error')
, assert =require('assert')
, muri = require('muri')
var utils = require('./utils'),
EventEmitter = require('events').EventEmitter,
driver = global.MONGOOSE_DRIVER_PATH || './drivers/node-mongodb-native',
Schema = require('./schema'),
Collection = require(driver + '/collection'),
STATES = require('./connectionstate'),
MongooseError = require('./error'),
muri = require('muri');
/*!
* Protocol prefix regexp.
@@ -22,6 +19,16 @@ var url = require('url')
var rgxProtocol = /^(?:.)+:\/\//;
/*!
* A list of authentication mechanisms that don't require a password for authentication.
* This is used by the authMechanismDoesNotRequirePassword method.
*
* @api private
*/
var authMechanismsWhichDontRequirePassword = [
'MONGODB-X509'
];
/**
* Connection constructor
*
@@ -41,7 +48,7 @@ var rgxProtocol = /^(?:.)+:\/\//;
* @api public
*/
function Connection (base) {
function Connection(base) {
this.base = base;
this.collections = {};
this.models = {};
@@ -58,7 +65,7 @@ function Connection (base) {
this._readyState = STATES.disconnected;
this._closeCalled = false;
this._hasOpened = false;
};
}
/*!
* Inherit from EventEmitter
@@ -86,25 +93,25 @@ Connection.prototype.__proto__ = EventEmitter.prototype;
*/
Object.defineProperty(Connection.prototype, 'readyState', {
get: function(){ return this._readyState; }
, set: function (val) {
if (!(val in STATES)) {
throw new Error('Invalid connection state: ' + val);
}
if (this._readyState !== val) {
this._readyState = val;
// loop over the otherDbs on this connection and change their state
for (var i=0; i < this.otherDbs.length; i++) {
this.otherDbs[i].readyState = val;
}
if (STATES.connected === val)
this._hasOpened = true;
this.emit(STATES[val]);
}
get: function() { return this._readyState; },
set: function(val) {
if (!(val in STATES)) {
throw new Error('Invalid connection state: ' + val);
}
if (this._readyState !== val) {
this._readyState = val;
// loop over the otherDbs on this connection and change their state
for (var i = 0; i < this.otherDbs.length; i++) {
this.otherDbs[i].readyState = val;
}
if (STATES.connected === val)
this._hasOpened = true;
this.emit(STATES[val]);
}
}
});
/**
@@ -162,15 +169,14 @@ Connection.prototype.config;
* @api public
*/
Connection.prototype.open = function (host, database, port, options, callback) {
var self = this
, parsed
, uri;
Connection.prototype.open = function(host, database, port, options, callback) {
var parsed;
if ('string' === typeof database) {
switch (arguments.length) {
case 2:
port = 27017;
break;
case 3:
switch (typeof port) {
case 'function':
@@ -234,7 +240,7 @@ Connection.prototype.open = function (host, database, port, options, callback) {
}
// authentication
if (options && options.user && options.pass) {
if (this.optionsProvideAuthenticationData(options)) {
this.user = options.user;
this.pass = options.pass;
@@ -256,7 +262,7 @@ Connection.prototype.open = function (host, database, port, options, callback) {
// global configuration options
if (options && options.config) {
if (options.config.autoIndex === false){
if (options.config.autoIndex === false) {
this.config.autoIndex = false;
}
else {
@@ -317,13 +323,11 @@ Connection.prototype.open = function (host, database, port, options, callback) {
* @api public
*/
Connection.prototype.openSet = function (uris, database, options, callback) {
Connection.prototype.openSet = function(uris, database, options, callback) {
if (!rgxProtocol.test(uris)) {
uris = 'mongodb://' + uris;
}
var self = this;
switch (arguments.length) {
case 3:
switch (typeof database) {
@@ -378,7 +382,7 @@ Connection.prototype.openSet = function (uris, database, options, callback) {
}
// authentication
if (options && options.user && options.pass) {
if (this.optionsProvideAuthenticationData(options)) {
this.user = options.user;
this.pass = options.pass;
@@ -392,7 +396,7 @@ Connection.prototype.openSet = function (uris, database, options, callback) {
// global configuration options
if (options && options.config) {
if (options.config.autoIndex === false){
if (options.config.autoIndex === false) {
this.config.autoIndex = false;
}
else {
@@ -416,10 +420,10 @@ Connection.prototype.openSet = function (uris, database, options, callback) {
* @api private
*/
Connection.prototype.error = function (err, callback) {
Connection.prototype.error = function(err, callback) {
if (callback) return callback(err);
this.emit('error', err);
}
};
/**
* Handles opening the connection with the appropriate method based on connection type.
@@ -428,7 +432,7 @@ Connection.prototype.error = function (err, callback) {
* @api private
*/
Connection.prototype._open = function (callback) {
Connection.prototype._open = function(callback) {
this.readyState = STATES.connecting;
this._closeCalled = false;
@@ -439,7 +443,7 @@ Connection.prototype._open = function (callback) {
: 'doOpen';
// open connection
this[method](function (err) {
this[method](function(err) {
if (err) {
self.readyState = STATES.disconnected;
if (self._hasOpened) {
@@ -452,7 +456,7 @@ Connection.prototype._open = function (callback) {
self.onOpen(callback);
});
}
};
/**
* Called when the connection is opened
@@ -460,7 +464,7 @@ Connection.prototype._open = function (callback) {
* @api private
*/
Connection.prototype.onOpen = function (callback) {
Connection.prototype.onOpen = function(callback) {
var self = this;
function open(err, isAuth) {
@@ -483,10 +487,10 @@ Connection.prototype.onOpen = function (callback) {
callback && callback();
self.emit('open');
};
}
// re-authenticate
if (self.user && self.pass) {
if (this.shouldAuthenticate()) {
self.db.authenticate(self.user, self.pass, self.options.auth, function(err) {
open(err, true);
});
@@ -503,11 +507,11 @@ Connection.prototype.onOpen = function (callback) {
* @api public
*/
Connection.prototype.close = function (callback) {
Connection.prototype.close = function(callback) {
var self = this;
this._closeCalled = true;
switch (this.readyState){
switch (this.readyState) {
case 0: // disconnected
callback && callback();
break;
@@ -515,8 +519,8 @@ Connection.prototype.close = function (callback) {
case 1: // connected
case 4: // unauthorized
this.readyState = STATES.disconnecting;
this.doClose(function(err){
if (err){
this.doClose(function(err) {
if (err) {
self.error(err, callback);
} else {
self.onClose();
@@ -526,14 +530,14 @@ Connection.prototype.close = function (callback) {
break;
case 2: // connecting
this.once('open', function(){
this.once('open', function() {
self.close(callback);
});
break;
case 3: // disconnecting
if (!callback) break;
this.once('close', function () {
this.once('close', function() {
callback();
});
break;
@@ -548,7 +552,7 @@ Connection.prototype.close = function (callback) {
* @api private
*/
Connection.prototype.onClose = function () {
Connection.prototype.onClose = function() {
this.readyState = STATES.disconnected;
// avoid having the collection subscribe to our event emitter
@@ -570,7 +574,7 @@ Connection.prototype.onClose = function () {
* @api public
*/
Connection.prototype.collection = function (name, options) {
Connection.prototype.collection = function(name, options) {
if (!(name in this.collections))
this.collections[name] = new Collection(name, this, options);
return this.collections[name];
@@ -608,31 +612,31 @@ Connection.prototype.collection = function (name, options) {
* @api public
*/
Connection.prototype.model = function (name, schema, collection) {
Connection.prototype.model = function(name, schema, collection) {
// collection name discovery
if ('string' == typeof schema) {
collection = schema;
schema = false;
}
if (utils.isObject(schema) && !(schema instanceof Schema)) {
if (utils.isObject(schema) && !schema.instanceOfSchema) {
schema = new Schema(schema);
}
if (this.models[name] && !collection) {
// model exists but we are not subclassing with custom collection
if (schema instanceof Schema && schema != this.models[name].schema) {
if (schema && schema.instanceOfSchema && schema != this.models[name].schema) {
throw new MongooseError.OverwriteModelError(name);
}
return this.models[name];
}
var opts = { cache: false, connection: this }
var opts = { cache: false, connection: this };
var model;
if (schema instanceof Schema) {
if (schema && schema.instanceOfSchema) {
// compile a model
model = this.base.model(name, schema, collection, opts)
model = this.base.model(name, schema, collection, opts);
// only the first model with this name is cached to allow
// for one-offs with custom collection names etc.
@@ -682,15 +686,51 @@ Connection.prototype.model = function (name, schema, collection) {
* @return {Array}
*/
Connection.prototype.modelNames = function () {
Connection.prototype.modelNames = function() {
return Object.keys(this.models);
};
/*!
* Noop.
/**
* @brief Returns if the connection requires authentication after it is opened. Generally if a
* username and password are both provided than authentication is needed, but in some cases a
* password is not required.
* @api private
* @return {Boolean} true if the connection should be authenticated after it is opened, otherwise false.
*/
Connection.prototype.shouldAuthenticate = function() {
return (this.user != null) &&
((this.pass != null) || this.authMechanismDoesNotRequirePassword());
};
function noop () {}
/**
* @brief Returns a boolean value that specifies if the current authentication mechanism needs a
* password to authenticate according to the auth objects passed into the open/openSet methods.
* @api private
* @return {Boolean} true if the authentication mechanism specified in the options object requires
* a password, otherwise false.
*/
Connection.prototype.authMechanismDoesNotRequirePassword = function() {
if (this.options && this.options.auth) {
return authMechanismsWhichDontRequirePassword.indexOf(this.options.auth.authMechanism) >= 0;
}
return true;
};
/**
* @brief Returns a boolean value that specifies if the provided objects object provides enough
* data to authenticate with. Generally this is true if the username and password are both specified
* but in some authentication methods, a password is not required for authentication so only a username
* is required.
* @param {Object} [options] the options object passed into the open/openSet methods.
* @api private
* @return {Boolean} true if the provided options object provides enough data to authenticate with,
* otherwise false.
*/
Connection.prototype.optionsProvideAuthenticationData = function(options) {
return (options) &&
(options.user) &&
((options.pass) || this.authMechanismDoesNotRequirePassword());
};
/*!
* Module exports.

798
node_modules/mongoose/lib/document.js generated vendored

File diff suppressed because it is too large Load Diff

View File

@@ -5,8 +5,7 @@
var driver;
if (typeof window === 'undefined') {
driver = require('./' +
(global.MONGOOSE_DRIVER_PATH || 'node-mongodb-native'));
driver = require(global.MONGOOSE_DRIVER_PATH || './node-mongodb-native');
} else {
driver = require('./browser');
}

View File

@@ -13,7 +13,7 @@ var ReadPref = mongodb.ReadPreference;
* @param {Array} [tags]
*/
module.exports = function readPref (pref, tags) {
module.exports = function readPref(pref, tags) {
if (Array.isArray(pref)) {
tags = pref[1];
pref = pref[0];
@@ -42,4 +42,4 @@ module.exports = function readPref (pref, tags) {
}
return new ReadPref(pref, tags);
}
};

View File

@@ -3,10 +3,9 @@
* Module dependencies.
*/
var MongooseCollection = require('../../collection')
, Collection = require('mongodb').Collection
, STATES = require('../../connectionstate')
, utils = require('../../utils')
var MongooseCollection = require('../../collection'),
Collection = require('mongodb').Collection,
utils = require('../../utils');
/**
* A [node-mongodb-native](https://github.com/mongodb/node-mongodb-native) collection implementation.
@@ -17,7 +16,7 @@ var MongooseCollection = require('../../collection')
* @api private
*/
function NativeCollection () {
function NativeCollection() {
this.collection = null;
MongooseCollection.apply(this, arguments);
}
@@ -34,7 +33,7 @@ NativeCollection.prototype.__proto__ = MongooseCollection.prototype;
* @api private
*/
NativeCollection.prototype.onOpen = function () {
NativeCollection.prototype.onOpen = function() {
var self = this;
// always get a new collection in case the user changed host:port
@@ -46,7 +45,7 @@ NativeCollection.prototype.onOpen = function () {
}
// capped
return self.conn.db.collection(self.name, function (err, c) {
return self.conn.db.collection(self.name, function(err, c) {
if (err) return callback(err);
// discover if this collection exists and if it is capped
@@ -61,10 +60,10 @@ NativeCollection.prototype.onOpen = function () {
if (doc.options && doc.options.capped) {
callback(null, c);
} else {
var msg = 'A non-capped collection exists with the name: '+ self.name +'\n\n'
var msg = 'A non-capped collection exists with the name: ' + self.name + '\n\n'
+ ' To use this collection as a capped collection, please '
+ 'first convert it.\n'
+ ' http://www.mongodb.org/display/DOCS/Capped+Collections#CappedCollections-Convertingacollectiontocapped'
+ ' http://www.mongodb.org/display/DOCS/Capped+Collections#CappedCollections-Convertingacollectiontocapped';
err = new Error(msg);
callback(err);
}
@@ -77,7 +76,7 @@ NativeCollection.prototype.onOpen = function () {
});
});
function callback (err, collection) {
function callback(err, collection) {
if (err) {
// likely a strict mode error
self.conn.emit('error', err);
@@ -85,7 +84,7 @@ NativeCollection.prototype.onOpen = function () {
self.collection = collection;
MongooseCollection.prototype.onOpen.call(self);
}
};
}
};
/**
@@ -94,7 +93,7 @@ NativeCollection.prototype.onOpen = function () {
* @api private
*/
NativeCollection.prototype.onClose = function () {
NativeCollection.prototype.onClose = function() {
MongooseCollection.prototype.onClose.call(this);
};
@@ -109,34 +108,28 @@ for (var i in Collection.prototype) {
if (typeof Collection.prototype[i] !== 'function') {
continue;
}
} catch(e) {
} catch (e) {
continue;
}
(function(i){
NativeCollection.prototype[i] = function () {
(function(i) {
NativeCollection.prototype[i] = function() {
if (this.buffer) {
this.addQueue(i, arguments);
return;
}
var collection = this.collection
, args = arguments
, self = this
, debug = self.conn.base.options.debug;
var collection = this.collection,
args = arguments,
self = this,
debug = self.conn.base.options.debug;
if (debug) {
if ('function' === typeof debug) {
debug.apply(debug
, [self.name, i].concat(utils.args(args, 0, args.length-1)));
, [self.name, i].concat(utils.args(args, 0, args.length - 1)));
} else {
console.error('\x1B[0;36mMongoose:\x1B[0m %s.%s(%s) %s %s %s'
, self.name
, i
, print(args[0])
, print(args[1])
, print(args[2])
, print(args[3]))
this.$print(self.name, i, args);
}
}
@@ -145,30 +138,50 @@ for (var i in Collection.prototype) {
})(i);
}
/*!
/**
* Debug print helper
*
* @api public
*/
function print (arg) {
NativeCollection.prototype.$print = function(name, i, args) {
console.error(
'\x1B[0;36mMongoose:\x1B[0m %s.%s(%s) %s %s %s',
name,
i,
this.$format(args[0]),
this.$format(args[1]),
this.$format(args[2]),
this.$format(args[3]));
};
/**
* Formatter for debug print args
*
* @api public
*/
NativeCollection.prototype.$format = function(arg) {
var type = typeof arg;
if ('function' === type || 'undefined' === type) return '';
return format(arg);
}
};
/*!
* Debug print helper
*/
function format (obj, sub) {
function format(obj, sub) {
var x = utils.clone(obj, { retainKeyOrder: 1 });
var representation;
if (x) {
if ('Binary' === x.constructor.name) {
x = '[object Buffer]';
} else if ('ObjectID' === x.constructor.name) {
var representation = 'ObjectId("' + x.toHexString() + '")';
representation = 'ObjectId("' + x.toHexString() + '")';
x = { inspect: function() { return representation; } };
} else if ('Date' === x.constructor.name) {
var representation = 'new Date("' + x.toUTCString() + '")';
representation = 'new Date("' + x.toUTCString() + '")';
x = { inspect: function() { return representation; } };
} else if ('Object' === x.constructor.name) {
var keys = Object.keys(x);
@@ -182,18 +195,18 @@ function format (obj, sub) {
} else if ('Object' === x[key].constructor.name) {
x[key] = format(x[key], true);
} else if ('ObjectID' === x[key].constructor.name) {
;(function(x){
(function(x) {
var representation = 'ObjectId("' + x[key].toHexString() + '")';
x[key] = { inspect: function() { return representation; } };
})(x)
})(x);
} else if ('Date' === x[key].constructor.name) {
;(function(x){
(function(x) {
var representation = 'new Date("' + x[key].toUTCString() + '")';
x[key] = { inspect: function() { return representation; } };
})(x)
})(x);
} else if (Array.isArray(x[key])) {
x[key] = x[key].map(function (o) {
return format(o, true)
x[key] = x[key].map(function(o) {
return format(o, true);
});
}
}
@@ -205,7 +218,7 @@ function format (obj, sub) {
return require('util')
.inspect(x, false, 10, true)
.replace(/\n/g, '')
.replace(/\s{2,}/g, ' ')
.replace(/\s{2,}/g, ' ');
}
/**

View File

@@ -2,14 +2,13 @@
* Module dependencies.
*/
var MongooseConnection = require('../../connection')
, mongo = require('mongodb')
, Db = mongo.Db
, Server = mongo.Server
, Mongos = mongo.Mongos
, STATES = require('../../connectionstate')
, ReplSetServers = mongo.ReplSet
, utils = require('../../utils');
var MongooseConnection = require('../../connection'),
mongo = require('mongodb'),
Db = mongo.Db,
Server = mongo.Server,
Mongos = mongo.Mongos,
STATES = require('../../connectionstate'),
ReplSetServers = mongo.ReplSet;
/**
* A [node-mongodb-native](https://github.com/mongodb/node-mongodb-native) connection implementation.
@@ -21,7 +20,7 @@ var MongooseConnection = require('../../connection')
function NativeConnection() {
MongooseConnection.apply(this, arguments);
this._listening = false;
};
}
/**
* Expose the possible connection states.
@@ -44,16 +43,18 @@ NativeConnection.prototype.__proto__ = MongooseConnection.prototype;
* @api private
*/
NativeConnection.prototype.doOpen = function (fn) {
if (this.db) {
mute(this);
NativeConnection.prototype.doOpen = function(fn) {
var server = new Server(this.host, this.port, this.options.server);
if (this.options && this.options.mongos) {
var mongos = new Mongos([server], this.options.mongos);
this.db = new Db(this.name, mongos, this.options.db);
} else {
this.db = new Db(this.name, server, this.options.db);
}
var server = new Server(this.host, this.port, this.options.server);
this.db = new Db(this.name, server, this.options.db);
var self = this;
this.db.open(function (err) {
this.db.open(function(err) {
if (err) return fn(err);
listen(self);
fn();
@@ -72,7 +73,7 @@ NativeConnection.prototype.doOpen = function (fn) {
* @api public
*/
NativeConnection.prototype.useDb = function (name) {
NativeConnection.prototype.useDb = function(name) {
// we have to manually copy all of the attributes...
var newConn = new this.constructor();
newConn.name = name;
@@ -106,7 +107,7 @@ NativeConnection.prototype.useDb = function (name) {
this.once('connected', wireup);
}
function wireup () {
function wireup() {
newConn.db = self.db.db(name);
newConn.onOpen();
// setup the events appropriately
@@ -126,11 +127,11 @@ NativeConnection.prototype.useDb = function (name) {
* Register listeners for important events and bubble appropriately.
*/
function listen (conn) {
function listen(conn) {
if (conn._listening) return;
conn._listening = true;
conn.db.on('close', function(){
conn.db.on('close', function() {
if (conn._closeCalled) return;
// the driver never emits an `open` event. auto_reconnect still
@@ -143,18 +144,18 @@ function listen (conn) {
}
conn.onClose();
});
conn.db.on('error', function(err){
conn.db.on('error', function(err) {
conn.emit('error', err);
});
conn.db.on('reconnect', function() {
conn.readyState = STATES.connected;
conn.emit('reconnected');
});
conn.db.on('timeout', function(err){
conn.db.on('timeout', function(err) {
var error = new Error(err && err.err || 'connection timeout');
conn.emit('error', error);
});
conn.db.on('open', function (err, db) {
conn.db.on('open', function(err, db) {
if (STATES.disconnected === conn.readyState && db && db.databaseName) {
conn.readyState = STATES.connected;
conn.emit('reconnected');
@@ -165,20 +166,6 @@ function listen (conn) {
});
}
/*!
* Remove listeners registered in `listen`
*/
function mute (conn) {
if (!conn.db) throw new Error('missing db');
conn.db.removeAllListeners("close");
conn.db.removeAllListeners("error");
conn.db.removeAllListeners("timeout");
conn.db.removeAllListeners("open");
conn.db.removeAllListeners("fullsetup");
conn._listening = false;
}
/**
* Opens a connection to a MongoDB ReplicaSet.
*
@@ -189,30 +176,26 @@ function mute (conn) {
* @return {Connection} this
*/
NativeConnection.prototype.doOpenSet = function (fn) {
if (this.db) {
mute(this);
}
NativeConnection.prototype.doOpenSet = function(fn) {
var servers = [],
self = this;
var servers = []
, self = this;
this.hosts.forEach(function (server) {
this.hosts.forEach(function(server) {
var host = server.host || server.ipc;
var port = server.port || 27017;
servers.push(new Server(host, port, self.options.server));
})
});
var server = this.options.mongos
? new Mongos(servers, this.options.mongos)
: new ReplSetServers(servers, this.options.replset);
: new ReplSetServers(servers, this.options.replset || this.options.replSet);
this.db = new Db(this.name, server, this.options.db);
this.db.on('fullsetup', function () {
self.emit('fullsetup')
this.db.on('fullsetup', function() {
self.emit('fullsetup');
});
this.db.open(function (err) {
this.db.open(function(err) {
if (err) return fn(err);
fn();
listen(self);
@@ -229,11 +212,10 @@ NativeConnection.prototype.doOpenSet = function (fn) {
* @api private
*/
NativeConnection.prototype.doClose = function (fn) {
this.db.close();
if (fn) fn();
NativeConnection.prototype.doClose = function(fn) {
this.db.close(fn);
return this;
}
};
/**
* Prepares default connection options for the node-mongodb-native driver.
@@ -245,17 +227,17 @@ NativeConnection.prototype.doClose = function (fn) {
* @api private
*/
NativeConnection.prototype.parseOptions = function (passed, connStrOpts) {
NativeConnection.prototype.parseOptions = function(passed, connStrOpts) {
var o = passed || {};
o.db || (o.db = {});
o.auth || (o.auth = {});
o.server || (o.server = {});
o.replset || (o.replset = {});
o.replset || (o.replset = o.replSet) || (o.replset = {});
o.server.socketOptions || (o.server.socketOptions = {});
o.replset.socketOptions || (o.replset.socketOptions = {});
var opts = connStrOpts || {};
Object.keys(opts).forEach(function (name) {
Object.keys(opts).forEach(function(name) {
switch (name) {
case 'ssl':
case 'poolSize':
@@ -321,8 +303,8 @@ NativeConnection.prototype.parseOptions = function (passed, connStrOpts) {
}
break;
case 'readPreference':
if ('undefined' == typeof o.db.read_preference) {
o.db.read_preference = opts[name];
if ('undefined' == typeof o.db.readPreference) {
o.db.readPreference = opts[name];
}
break;
case 'readPreferenceTags':
@@ -331,17 +313,12 @@ NativeConnection.prototype.parseOptions = function (passed, connStrOpts) {
}
break;
}
})
});
if (!('auto_reconnect' in o.server)) {
o.server.auto_reconnect = true;
}
if (!o.db.read_preference) {
// read from primaries by default
o.db.read_preference = 'primary';
}
// mongoose creates its own ObjectIds
o.db.forceServerObjectId = false;
@@ -353,7 +330,7 @@ NativeConnection.prototype.parseOptions = function (passed, connStrOpts) {
validate(o);
return o;
}
};
/*!
* Validates the driver db options.
@@ -361,7 +338,7 @@ NativeConnection.prototype.parseOptions = function (passed, connStrOpts) {
* @param {Object} o
*/
function validate (o) {
function validate(o) {
if (-1 === o.db.w || 0 === o.db.w) {
if (o.db.journal || o.db.fsync || o.db.safe) {
throw new Error(

22
node_modules/mongoose/lib/error.js generated vendored
View File

@@ -6,12 +6,16 @@
* @inherits Error https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error
*/
function MongooseError (msg) {
function MongooseError(msg) {
Error.call(this);
this.stack = new Error().stack;
if (Error.captureStackTrace) {
Error.captureStackTrace(this);
} else {
this.stack = new Error().stack;
}
this.message = msg;
this.name = 'MongooseError';
};
}
/*!
* Inherits from Error.
@@ -43,9 +47,9 @@ MongooseError.Messages = MongooseError.messages;
*/
MongooseError.CastError = require('./error/cast');
MongooseError.ValidationError = require('./error/validation')
MongooseError.ValidatorError = require('./error/validator')
MongooseError.VersionError =require('./error/version')
MongooseError.OverwriteModelError = require('./error/overwriteModel')
MongooseError.MissingSchemaError = require('./error/missingSchema')
MongooseError.DivergentArrayError = require('./error/divergentArray')
MongooseError.ValidationError = require('./error/validation');
MongooseError.ValidatorError = require('./error/validator');
MongooseError.VersionError = require('./error/version');
MongooseError.OverwriteModelError = require('./error/overwriteModel');
MongooseError.MissingSchemaError = require('./error/missingSchema');
MongooseError.DivergentArrayError = require('./error/divergentArray');

View File

@@ -1,4 +1,4 @@
/* eslint no-unused-vars: 1 */
/*!
* Module dependencies.
*/
@@ -11,7 +11,7 @@ var MongooseError = require('../error.js');
* @inherits MongooseError
*/
function MissingSchemaError (name) {
function MissingSchemaError(name) {
var msg = 'Schema hasn\'t been registered for document.\n'
+ 'Use mongoose.Document(name, schema)';
MongooseError.call(this, msg);

View File

@@ -13,14 +13,19 @@ var MongooseError = require('../error.js');
* @api private
*/
function CastError (type, value, path) {
function CastError(type, value, path, reason) {
MongooseError.call(this, 'Cast to ' + type + ' failed for value "' + value + '" at path "' + path + '"');
Error.captureStackTrace && Error.captureStackTrace(this, arguments.callee);
if (Error.captureStackTrace) {
Error.captureStackTrace(this);
} else {
this.stack = new Error().stack;
}
this.name = 'CastError';
this.kind = type;
this.value = value;
this.path = path;
};
this.reason = reason;
}
/*!
* Inherits from MongooseError.

View File

@@ -11,7 +11,7 @@ var MongooseError = require('../error.js');
* @inherits MongooseError
*/
function DivergentArrayError (paths) {
function DivergentArrayError(paths) {
var msg = 'For your own good, using `document.save()` to update an array '
+ 'which was selected using an $elemMatch projection OR '
+ 'populated using skip, limit, query conditions, or exclusion of '
@@ -19,13 +19,13 @@ function DivergentArrayError (paths) {
+ 'the entire array is not supported. The following '
+ 'path(s) would have been modified unsafely:\n'
+ ' ' + paths.join('\n ') + '\n'
+ 'Use Model.update() to update these arrays instead.'
+ 'Use Model.update() to update these arrays instead.';
// TODO write up a docs page (FAQ) and link to it
MongooseError.call(this, msg);
Error.captureStackTrace && Error.captureStackTrace(this, arguments.callee);
this.name = 'DivergentArrayError';
};
}
/*!
* Inherits from MongooseError.

View File

@@ -11,7 +11,7 @@ var MongooseError = require('../error.js');
* @inherits MongooseError
*/
function MissingSchemaError (name) {
function MissingSchemaError(name) {
var msg = 'Schema hasn\'t been registered for model "' + name + '".\n'
+ 'Use mongoose.model(name, schema)';
MongooseError.call(this, msg);

View File

@@ -11,11 +11,11 @@ var MongooseError = require('../error.js');
* @inherits MongooseError
*/
function OverwriteModelError (name) {
function OverwriteModelError(name) {
MongooseError.call(this, 'Cannot overwrite `' + name + '` model once compiled.');
Error.captureStackTrace && Error.captureStackTrace(this, arguments.callee);
this.name = 'OverwriteModelError';
};
}
/*!
* Inherits from MongooseError.

35
node_modules/mongoose/lib/error/strict.js generated vendored Normal file
View File

@@ -0,0 +1,35 @@
/*!
* Module dependencies.
*/
var MongooseError = require('../error.js');
/**
* Strict mode error constructor
*
* @param {String} type
* @param {String} value
* @inherits MongooseError
* @api private
*/
function StrictModeError(path) {
MongooseError.call(this, 'Field `' + path + '` is not in schema and strict ' +
'mode is set to throw.');
if (Error.captureStackTrace) {
Error.captureStackTrace(this);
} else {
this.stack = new Error().stack;
}
this.name = 'StrictModeError';
this.path = path;
}
/*!
* Inherits from MongooseError.
*/
StrictModeError.prototype = Object.create(MongooseError.prototype);
StrictModeError.prototype.constructor = MongooseError;
module.exports = StrictModeError;

View File

@@ -13,13 +13,17 @@ var MongooseError = require('../error.js');
* @inherits MongooseError
*/
function ValidationError (instance) {
function ValidationError(instance) {
if (instance && instance.constructor.name === 'model') {
MongooseError.call(this, instance.constructor.modelName + " validation failed");
} else {
MongooseError.call(this, "Validation failed");
}
this.stack = new Error().stack;
if (Error.captureStackTrace) {
Error.captureStackTrace(this);
} else {
this.stack = new Error().stack;
}
this.name = 'ValidationError';
this.errors = {};
if (instance) {
@@ -39,11 +43,11 @@ ValidationError.prototype.constructor = MongooseError;
* Console.log helper
*/
ValidationError.prototype.toString = function () {
ValidationError.prototype.toString = function() {
var ret = this.name + ': ';
var msgs = [];
Object.keys(this.errors).forEach(function (key) {
Object.keys(this.errors).forEach(function(key) {
if (this == this.errors[key]) return;
msgs.push(String(this.errors[key]));
}, this);

View File

@@ -13,7 +13,7 @@ var errorMessages = MongooseError.messages;
* @api private
*/
function ValidatorError (properties) {
function ValidatorError(properties) {
var msg = properties.message;
if (!msg) {
msg = errorMessages.general.default;
@@ -22,12 +22,16 @@ function ValidatorError (properties) {
this.properties = properties;
var message = this.formatMessage(msg, properties);
MongooseError.call(this, message);
this.stack = new Error().stack;
if (Error.captureStackTrace) {
Error.captureStackTrace(this);
} else {
this.stack = new Error().stack;
}
this.name = 'ValidatorError';
this.kind = properties.type;
this.path = properties.path;
this.value = properties.value;
};
}
/*!
* Inherits from MongooseError
@@ -40,7 +44,7 @@ ValidatorError.prototype.constructor = MongooseError;
* Formats error messages
*/
ValidatorError.prototype.formatMessage = function (msg, properties) {
ValidatorError.prototype.formatMessage = function(msg, properties) {
var propertyNames = Object.keys(properties);
for (var i = 0; i < propertyNames.length; ++i) {
var propertyName = propertyNames[i];
@@ -56,9 +60,9 @@ ValidatorError.prototype.formatMessage = function (msg, properties) {
* toString helper
*/
ValidatorError.prototype.toString = function () {
ValidatorError.prototype.toString = function() {
return this.message;
}
};
/*!
* exports

View File

@@ -12,11 +12,11 @@ var MongooseError = require('../error.js');
* @api private
*/
function VersionError () {
function VersionError() {
MongooseError.call(this, 'No matching document found.');
Error.captureStackTrace && Error.captureStackTrace(this, arguments.callee);
this.name = 'VersionError';
};
}
/*!
* Inherits from MongooseError.

118
node_modules/mongoose/lib/index.js generated vendored
View File

@@ -4,22 +4,23 @@
* Module dependencies.
*/
var Schema = require('./schema')
, SchemaType = require('./schematype')
, VirtualType = require('./virtualtype')
, STATES = require('./connectionstate')
, Types = require('./types')
, Query = require('./query')
, Promise = require('./promise')
, Model = require('./model')
, Document = require('./document')
, utils = require('./utils')
, format = utils.toCollectionName
, mongodb = require('mongodb')
, pkg = require('../package.json')
var Schema = require('./schema'),
SchemaType = require('./schematype'),
VirtualType = require('./virtualtype'),
STATES = require('./connectionstate'),
Types = require('./types'),
Query = require('./query'),
Model = require('./model'),
Document = require('./document'),
utils = require('./utils'),
format = utils.toCollectionName,
pkg = require('../package.json');
var querystring = require('querystring');
var Aggregate = require('./aggregate');
var PromiseProvider = require('./promise_provider');
/**
* Mongoose constructor.
*
@@ -29,7 +30,7 @@ var querystring = require('querystring');
* @api public
*/
function Mongoose () {
function Mongoose() {
this.connections = [];
this.plugins = [];
this.models = {};
@@ -40,7 +41,7 @@ function Mongoose () {
};
var conn = this.createConnection(); // default connection
conn.models = this.models;
};
}
/**
* Expose connection states for user-land
@@ -57,12 +58,14 @@ Mongoose.prototype.STATES = STATES;
*
* mongoose.set('debug', true) // enable logging collection methods + arguments to the console
*
* mongoose.set('debug', function(collectionName, methodName, arg1, arg2...) {}); // use custom function to log collection methods + arguments
*
* @param {String} key
* @param {String} value
* @param {String|Function} value
* @api public
*/
Mongoose.prototype.set = function (key, value) {
Mongoose.prototype.set = function(key, value) {
if (arguments.length == 1) {
return this.options[key];
}
@@ -116,7 +119,7 @@ var checkReplicaSetInUri = function(uri) {
if (obj && obj.replicaSet) {
isReplicaSet = true;
}
} catch(e) {
} catch (e) {
return false;
}
}
@@ -168,13 +171,16 @@ var checkReplicaSetInUri = function(uri) {
* @api public
*/
Mongoose.prototype.createConnection = function () {
Mongoose.prototype.createConnection = function(uri, options) {
var conn = new Connection(this);
this.connections.push(conn);
if (arguments.length) {
if (rgxReplSet.test(arguments[0]) || checkReplicaSetInUri(arguments[0])) {
conn.openSet.apply(conn, arguments);
} else if (options && options.replset &&
(options.replset.replicaSet || options.replset.rs_name)) {
conn.openSet.apply(conn, arguments);
} else {
conn.open.apply(conn, arguments);
}
@@ -195,7 +201,7 @@ Mongoose.prototype.createConnection = function () {
* mongoose.connect('mongodb://user:pass@localhost:port/database');
*
* // replica sets
* var uri = 'mongodb://user:pass@localhost:port/database,mongodb://anotherhost:port,mongodb://yetanother:port';
* var uri = 'mongodb://user:pass@localhost:port,anotherhost:port,yetanother:port/mydatabase';
* mongoose.connect(uri);
*
* // with options
@@ -234,12 +240,12 @@ Mongoose.prototype.connect = function() {
* @api public
*/
Mongoose.prototype.disconnect = function (fn) {
var count = this.connections.length
, error
Mongoose.prototype.disconnect = function(fn) {
var count = this.connections.length,
error;
this.connections.forEach(function(conn){
conn.close(function(err){
this.connections.forEach(function(conn) {
conn.close(function(err) {
if (error) return;
if (err) {
@@ -295,13 +301,13 @@ Mongoose.prototype.disconnect = function (fn) {
* @api public
*/
Mongoose.prototype.model = function (name, schema, collection, skipInit) {
Mongoose.prototype.model = function(name, schema, collection, skipInit) {
if ('string' == typeof schema) {
collection = schema;
schema = false;
}
if (utils.isObject(schema) && !(schema instanceof Schema)) {
if (utils.isObject(schema) && !(schema.instanceOfSchema)) {
schema = new Schema(schema);
}
@@ -336,7 +342,7 @@ Mongoose.prototype.model = function (name, schema, collection, skipInit) {
// connection.model() may be passing a different schema for
// an existing model name. in this case don't read from cache.
if (this.models[name] && false !== options.cache) {
if (schema instanceof Schema && schema != this.models[name].schema) {
if (schema && schema.instanceOfSchema && schema != this.models[name].schema) {
throw new mongoose.Error.OverwriteModelError(name);
}
@@ -380,7 +386,7 @@ Mongoose.prototype.model = function (name, schema, collection, skipInit) {
}
return this.models[name] = model;
}
};
/**
* Returns an array of model names created on this instance of Mongoose.
@@ -393,10 +399,10 @@ Mongoose.prototype.model = function (name, schema, collection, skipInit) {
* @return {Array}
*/
Mongoose.prototype.modelNames = function () {
Mongoose.prototype.modelNames = function() {
var names = Object.keys(this.models);
return names;
}
};
/**
* Applies global plugins to `schema`.
@@ -405,11 +411,11 @@ Mongoose.prototype.modelNames = function () {
* @api private
*/
Mongoose.prototype._applyPlugins = function (schema) {
Mongoose.prototype._applyPlugins = function(schema) {
for (var i = 0, l = this.plugins.length; i < l; i++) {
schema.plugin(this.plugins[i][0], this.plugins[i][1]);
}
}
};
/**
* Declares a global plugin executed on all Schemas.
@@ -423,7 +429,7 @@ Mongoose.prototype._applyPlugins = function (schema) {
* @api public
*/
Mongoose.prototype.plugin = function (fn, opts) {
Mongoose.prototype.plugin = function(fn, opts) {
this.plugins.push([fn, opts]);
return this;
};
@@ -444,7 +450,7 @@ Mongoose.prototype.plugin = function (fn, opts) {
* @api public
*/
Mongoose.prototype.__defineGetter__('connection', function(){
Mongoose.prototype.__defineGetter__('connection', function() {
return this.connections[0];
});
@@ -452,19 +458,28 @@ Mongoose.prototype.__defineGetter__('connection', function(){
* Driver depentend APIs
*/
var driver = global.MONGOOSE_DRIVER_PATH || 'node-mongodb-native';
var driver = global.MONGOOSE_DRIVER_PATH || './drivers/node-mongodb-native';
/*!
* Connection
*/
var Connection = require('./drivers/' + driver + '/connection');
var Connection = require(driver + '/connection');
/*!
* Collection
*/
var Collection = require('./drivers/' + driver + '/collection');
var Collection = require(driver + '/collection');
/**
* The Mongoose Aggregate constructor
*
* @method Aggregate
* @api public
*/
Mongoose.prototype.Aggregate = Aggregate;
/**
* The Mongoose Collection constructor
@@ -599,7 +614,23 @@ Mongoose.prototype.Query = Query;
* @api public
*/
Mongoose.prototype.Promise = Promise;
Object.defineProperty(Mongoose.prototype, 'Promise', {
get: function() {
return PromiseProvider.get();
},
set: function(lib) {
PromiseProvider.set(lib);
}
});
/**
* Storage layer for mongoose promises
*
* @method PromiseProvider
* @api public
*/
Mongoose.prototype.PromiseProvider = PromiseProvider;
/**
* The Mongoose [Model](#model_Model) constructor.
@@ -619,6 +650,15 @@ Mongoose.prototype.Model = Model;
Mongoose.prototype.Document = Document;
/**
* The Mongoose DocumentProvider constructor.
*
* @method DocumentProvider
* @api public
*/
Mongoose.prototype.DocumentProvider = require('./document_provider');
/**
* The [MongooseError](#error_MongooseError) constructor.
*

View File

@@ -2,12 +2,12 @@
* Dependencies
*/
var StateMachine = require('./statemachine')
var StateMachine = require('./statemachine');
var ActiveRoster = StateMachine.ctor('require', 'modify', 'init', 'default', 'ignore');
module.exports = exports = InternalCache;
function InternalCache () {
function InternalCache() {
this.strictMode = undefined;
this.selected = undefined;
this.shardval = undefined;

1088
node_modules/mongoose/lib/model.js generated vendored

File diff suppressed because it is too large Load Diff

52
node_modules/mongoose/lib/promise.js generated vendored
View File

@@ -13,29 +13,57 @@ var util = require('util');
* var query = Candy.find({ bar: true });
* var promise = query.exec();
*
* DEPRECATED. Mongoose 5.0 will use native promises by default (or bluebird,
* if native promises are not present) but still
* support plugging in your own ES6-compatible promises library. Mongoose 5.0
* will **not** support mpromise.
*
* @param {Function} fn a function which will be called when the promise is resolved that accepts `fn(err, ...){}` as signature
* @inherits mpromise https://github.com/aheckmann/mpromise
* @inherits NodeJS EventEmitter http://nodejs.org/api/events.html#events_class_events_eventemitter
* @event `err`: Emits when the promise is rejected
* @event `complete`: Emits when the promise is fulfilled
* @api public
* @deprecated
*/
function Promise (fn) {
function Promise(fn) {
MPromise.call(this, fn);
}
/**
* ES6-style promise constructor wrapper around mpromise.
*
* @param {Function} resolver
* @return {Promise} new promise
* @api public
*/
Promise.ES6 = function(resolver) {
var promise = new Promise();
// No try/catch for backwards compatibility
resolver(
function() {
promise.complete.apply(promise, arguments);
},
function(e) {
promise.error(e);
});
return promise;
};
/*!
* Inherit from mpromise
*/
Promise.prototype = Object.create(MPromise.prototype, {
constructor: {
value: Promise
, enumerable: false
, writable: true
, configurable: true
}
constructor: {
value: Promise,
enumerable: false,
writable: true,
configurable: true
}
});
/*!
@@ -84,7 +112,7 @@ Promise.FAILURE = 'err';
* @return {Promise} this
*/
Promise.prototype.error = function (err) {
Promise.prototype.error = function(err) {
if (!(err instanceof Error)) {
if (err instanceof Object) {
err = util.inspect(err);
@@ -92,7 +120,7 @@ Promise.prototype.error = function (err) {
err = new Error(err);
}
return this.reject(err);
}
};
/**
* Resolves this promise to a rejected state if `err` is passed or a fulfilled state if no `err` is passed.
@@ -106,9 +134,10 @@ Promise.prototype.error = function (err) {
* @param {Error} [err] error or null
* @param {Object} [val] value to fulfill the promise with
* @api public
* @deprecated
*/
Promise.prototype.resolve = function (err) {
Promise.prototype.resolve = function(err) {
if (err) return this.error(err);
return this.fulfill.apply(this, Array.prototype.slice.call(arguments, 1));
};
@@ -143,6 +172,7 @@ Promise.prototype.addBack = Promise.prototype.onResolve;
* @see https://github.com/aheckmann/mpromise#fulfill
* @param {any} args
* @api public
* @deprecated
*/
/**
@@ -223,6 +253,7 @@ Promise.prototype.addErrback = Promise.prototype.onReject;
* @param {Function} onFulFill
* @param {Function} onReject
* @return {Promise} newPromise
* @deprecated
*/
/**
@@ -250,6 +281,7 @@ Promise.prototype.addErrback = Promise.prototype.onReject;
* @see mpromise#end https://github.com/aheckmann/mpromise#end
* @method end
* @memberOf Promise
* @deprecated
*/
/*!

51
node_modules/mongoose/lib/promise_provider.js generated vendored Normal file
View File

@@ -0,0 +1,51 @@
/*!
* Module dependencies.
*/
var MPromise = require('./promise');
/**
* Helper for multiplexing promise implementations
*
* @api private
*/
var Promise = {
_promise: MPromise
};
/**
* Get the current promise constructor
*
* @api private
*/
Promise.get = function() {
return Promise._promise;
};
/**
* Set the current promise constructor
*
* @api private
*/
Promise.set = function(lib) {
if (lib === MPromise) {
return Promise.reset();
}
Promise._promise = require('./ES6Promise');
Promise._promise.use(lib);
require('mquery').Promise = Promise._promise.ES6;
};
/**
* Resets to using mpromise
*
* @api private
*/
Promise.reset = function() {
Promise._promise = MPromise;
};
module.exports = Promise;

869
node_modules/mongoose/lib/query.js generated vendored

File diff suppressed because it is too large Load Diff

View File

@@ -3,7 +3,7 @@
* Module dependencies
*/
var utils = require('./utils')
var utils = require('./utils');
/*!
* Prepare a set of path options for query population.
@@ -13,14 +13,14 @@ var utils = require('./utils')
* @return {Array}
*/
exports.preparePopulationOptions = function preparePopulationOptions (query, options) {
exports.preparePopulationOptions = function preparePopulationOptions(query, options) {
var pop = utils.object.vals(query.options.populate);
// lean options should trickle through all queries
if (options.lean) pop.forEach(makeLean);
return pop;
}
};
/*!
* Prepare a set of path options for query population. This is the MongooseQuery
@@ -31,14 +31,14 @@ exports.preparePopulationOptions = function preparePopulationOptions (query, opt
* @return {Array}
*/
exports.preparePopulationOptionsMQ = function preparePopulationOptionsMQ (query, options) {
exports.preparePopulationOptionsMQ = function preparePopulationOptionsMQ(query, options) {
var pop = utils.object.vals(query._mongooseOptions.populate);
// lean options should trickle through all queries
if (options.lean) pop.forEach(makeLean);
return pop;
}
};
/*!
* If the document is a mapped discriminator type, it returns a model instance for that type, otherwise,
@@ -64,7 +64,7 @@ exports.createModel = function createModel(model, doc, fields) {
}
return new model(undefined, fields, true);
}
};
/*!
* Set each path query option to lean
@@ -72,8 +72,7 @@ exports.createModel = function createModel(model, doc, fields) {
* @param {Object} option
*/
function makeLean (option) {
function makeLean(option) {
option.options || (option.options = {});
option.options.lean = true;
}

View File

@@ -1,12 +1,13 @@
/* eslint no-empty: 1 */
/*!
* Module dependencies.
*/
var Stream = require('stream').Stream
var utils = require('./utils')
var helpers = require('./queryhelpers')
var K = function(k){ return k }
var Stream = require('stream').Stream;
var utils = require('./utils');
var helpers = require('./queryhelpers');
var K = function(k) { return k; };
/**
* Provides a Node.js 0.8 style [ReadStream](http://nodejs.org/docs/v0.8.21/api/stream.html#stream_readable_stream) interface for Queries.
@@ -49,7 +50,7 @@ var K = function(k){ return k }
* @api public
*/
function QueryStream (query, options) {
function QueryStream(query, options) {
Stream.call(this);
this.query = query;
@@ -67,7 +68,7 @@ function QueryStream (query, options) {
// give time to hook up events
var self = this;
process.nextTick(function () {
process.nextTick(function() {
self._init();
});
}
@@ -107,13 +108,13 @@ var T_CONT = 2;
* @api private
*/
QueryStream.prototype._init = function () {
QueryStream.prototype._init = function() {
if (this._destroyed) return;
var query = this.query
, model = query.model
, options = query._optionsForExec(model)
, self = this
var query = this.query,
model = query.model,
options = query._optionsForExec(model),
self = this;
try {
query.cast(model);
@@ -124,12 +125,12 @@ QueryStream.prototype._init = function () {
self._fields = utils.clone(query._fields);
options.fields = query._castFields(self._fields);
model.collection.find(query._conditions, options, function (err, cursor) {
model.collection.find(query._conditions, options, function(err, cursor) {
if (err) return self.destroy(err);
self._cursor = cursor;
self._next();
});
}
};
/**
* Trampoline for pulling the next doc from cursor.
@@ -138,7 +139,7 @@ QueryStream.prototype._init = function () {
* @api private
*/
QueryStream.prototype._next = function _next () {
QueryStream.prototype._next = function _next() {
if (this.paused || this._destroyed) {
return this._running = false;
}
@@ -155,7 +156,7 @@ QueryStream.prototype._next = function _next () {
// avoid stack overflows with large result sets.
// trampoline instead of recursion.
while (this.__next()) {}
}
};
/**
* Pulls the next doc from the cursor.
@@ -164,14 +165,14 @@ QueryStream.prototype._next = function _next () {
* @api private
*/
QueryStream.prototype.__next = function () {
QueryStream.prototype.__next = function() {
if (this.paused || this._destroyed)
return this._running = false;
var self = this;
self._inline = T_INIT;
self._cursor.nextObject(function cursorcb (err, doc) {
self._cursor.nextObject(function cursorcb(err, doc) {
self._onNextObject(err, doc);
});
@@ -185,7 +186,7 @@ QueryStream.prototype.__next = function () {
// the trampoline anymore.
this._inline = T_IDLE;
}
}
};
/**
* Transforms raw `doc`s returned from the cursor into a model instance.
@@ -195,7 +196,7 @@ QueryStream.prototype.__next = function () {
* @api private
*/
QueryStream.prototype._onNextObject = function _onNextObject (err, doc) {
QueryStream.prototype._onNextObject = function _onNextObject(err, doc) {
if (this._destroyed) return;
if (this.paused) {
@@ -223,21 +224,26 @@ QueryStream.prototype._onNextObject = function _onNextObject (err, doc) {
var self = this;
var pop = helpers.preparePopulationOptionsMQ(self.query, self.query._mongooseOptions);
self.query.model.populate(doc, pop, function (err, doc) {
// Hack to work around gh-3108
pop.forEach(function(option) {
delete option.model;
});
self.query.model.populate(doc, pop, function(err, doc) {
if (err) return self.destroy(err);
return true === opts.lean ?
emit(self, doc) :
createAndEmit(self, pop, doc);
});
}
};
function createAndEmit (self, populatedIds, doc) {
function createAndEmit(self, populatedIds, doc) {
var instance = helpers.createModel(self.query.model, doc, self._fields);
var opts = populatedIds ?
{ populated: populatedIds } :
undefined;
instance.init(doc, opts, function (err) {
instance.init(doc, opts, function(err) {
if (err) return self.destroy(err);
emit(self, instance);
});
@@ -247,7 +253,7 @@ function createAndEmit (self, populatedIds, doc) {
* Emit a data event and manage the trampoline state
*/
function emit (self, doc) {
function emit(self, doc) {
self.emit('data', self._transform(doc));
// trampoline management
@@ -267,9 +273,9 @@ function emit (self, doc) {
* @api public
*/
QueryStream.prototype.pause = function () {
QueryStream.prototype.pause = function() {
this.paused = true;
}
};
/**
* Resumes this stream.
@@ -277,7 +283,7 @@ QueryStream.prototype.pause = function () {
* @api public
*/
QueryStream.prototype.resume = function () {
QueryStream.prototype.resume = function() {
this.paused = false;
if (!this._cursor) {
@@ -294,7 +300,7 @@ QueryStream.prototype.resume = function () {
// outside QueryStream control, need manual restart
return this._next();
}
}
};
/**
* Destroys the stream, closing the underlying cursor. No more events will be emitted.
@@ -303,7 +309,7 @@ QueryStream.prototype.resume = function () {
* @api public
*/
QueryStream.prototype.destroy = function (err) {
QueryStream.prototype.destroy = function(err) {
if (this._destroyed) return;
this._destroyed = true;
this._running = false;
@@ -318,7 +324,7 @@ QueryStream.prototype.destroy = function (err) {
}
this.emit('close');
}
};
/**
* Pipes this query stream into another stream. This method is inherited from NodeJS Streams.

459
node_modules/mongoose/lib/schema.js generated vendored
View File

@@ -8,6 +8,7 @@ var VirtualType = require('./virtualtype');
var utils = require('./utils');
var MongooseTypes;
var Kareem = require('kareem');
var async = require('async');
var IS_QUERY_HOOK = {
count: true,
@@ -36,6 +37,7 @@ var IS_QUERY_HOOK = {
* - [bufferCommands](/docs/guide.html#bufferCommands): bool - defaults to true
* - [capped](/docs/guide.html#capped): bool - defaults to false
* - [collection](/docs/guide.html#collection): string - no default
* - [emitIndexErrors](/docs/guide.html#emitIndexErrors): bool - defaults to false.
* - [id](/docs/guide.html#id): bool - defaults to true
* - [_id](/docs/guide.html#_id): bool - defaults to true
* - `minimize`: bool - controls [document#toObject](#document_Document-toObject) behavior when called manually - defaults to true
@@ -45,6 +47,7 @@ var IS_QUERY_HOOK = {
* - [strict](/docs/guide.html#strict): bool - defaults to true
* - [toJSON](/docs/guide.html#toJSON) - object - no default
* - [toObject](/docs/guide.html#toObject) - object - no default
* - [typeKey](/docs/guide.html#typeKey) - string - defaults to 'type'
* - [validateBeforeSave](/docs/guide.html#validateBeforeSave) - bool - defaults to `true`
* - [versionKey](/docs/guide.html#versionKey): bool - defaults to "__v"
*
@@ -58,13 +61,14 @@ var IS_QUERY_HOOK = {
* @api public
*/
function Schema (obj, options) {
function Schema(obj, options) {
if (!(this instanceof Schema))
return new Schema(obj, options);
this.paths = {};
this.subpaths = {};
this.virtuals = {};
this.singleNestedPaths = {};
this.nested = {};
this.inherits = {};
this.callQueue = [];
@@ -92,29 +96,33 @@ function Schema (obj, options) {
var _idSubDoc = obj && obj._id && utils.isObject(obj._id);
// ensure the documents get an auto _id unless disabled
var auto_id = !this.paths['_id'] && (!this.options.noId && this.options._id) && !_idSubDoc;
var auto_id = !this.paths['_id'] &&
(!this.options.noId && this.options._id) && !_idSubDoc;
if (auto_id) {
this.add({ _id: {type: Schema.ObjectId, auto: true} });
obj = { _id: { auto: true } };
obj._id[this.options.typeKey] = Schema.ObjectId;
this.add(obj);
}
// ensure the documents receive an id getter unless disabled
var autoid = !this.paths['id'] && (!this.options.noVirtualId && this.options.id);
var autoid = !this.paths['id'] &&
(!this.options.noVirtualId && this.options.id);
if (autoid) {
this.virtual('id').get(idGetter);
}
for (var i = 0; i < this._defaultMiddleware.length; ++i) {
var m = this._defaultMiddleware[i];
this[m.kind](m.hook, m.fn);
this[m.kind](m.hook, !!m.isAsync, m.fn);
}
// adds updatedAt and createdAt timestamps to documents if enabled
var timestamps = this.options.timestamps;
if (timestamps) {
var createdAt = timestamps.createdAt || 'createdAt'
, updatedAt = timestamps.updatedAt || 'updatedAt'
, schemaAdditions = {};
var createdAt = timestamps.createdAt || 'createdAt',
updatedAt = timestamps.updatedAt || 'updatedAt',
schemaAdditions = {};
schemaAdditions[updatedAt] = Date;
@@ -124,10 +132,10 @@ function Schema (obj, options) {
this.add(schemaAdditions);
this.pre('save', function (next) {
this.pre('save', function(next) {
var defaultTimestamp = new Date();
if (!this[createdAt]){
if (!this[createdAt]) {
this[createdAt] = auto_id ? this._id.getTimestamp() : defaultTimestamp;
}
@@ -135,6 +143,25 @@ function Schema (obj, options) {
next();
});
var genUpdates = function() {
var now = new Date();
var updates = {$set: {}, $setOnInsert: {}};
updates.$set[updatedAt] = now;
updates.$setOnInsert[createdAt] = now;
return updates;
};
this.pre('findOneAndUpdate', function(next) {
this.findOneAndUpdate({}, genUpdates());
next();
});
this.pre('update', function(next) {
this.update({}, genUpdates());
next();
});
}
}
@@ -143,7 +170,7 @@ function Schema (obj, options) {
* Returns this documents _id cast to a string.
*/
function idGetter () {
function idGetter() {
if (this.$__._id) {
return this.$__._id;
}
@@ -158,6 +185,7 @@ function idGetter () {
*/
Schema.prototype = Object.create( EventEmitter.prototype );
Schema.prototype.constructor = Schema;
Schema.prototype.instanceOfSchema = true;
/**
* Default middleware attached to a schema. Cannot be changed.
@@ -173,25 +201,74 @@ Object.defineProperty(Schema.prototype, '_defaultMiddleware', {
configurable: false,
enumerable: false,
writable: false,
value: [
{
kind: 'pre',
hook: 'save',
fn: function(next) {
// Nested docs have their own presave
if (this.ownerDocument) {
return next();
}
value: [{
kind: 'pre',
hook: 'save',
fn: function(next, options) {
// Nested docs have their own presave
if (this.ownerDocument) {
return next();
}
// Validate
if (this.schema.options.validateBeforeSave) {
this.validate(next);
var hasValidateBeforeSaveOption = options &&
(typeof options === 'object') &&
('validateBeforeSave' in options);
var shouldValidate;
if (hasValidateBeforeSaveOption) {
shouldValidate = !!options.validateBeforeSave;
} else {
shouldValidate = this.schema.options.validateBeforeSave;
}
// Validate
if (shouldValidate) {
// HACK: use $__original_validate to avoid promises so bluebird doesn't
// complain
if (this.$__original_validate) {
this.$__original_validate({ __noPromise: true }, function(error) {
next(error);
});
} else {
next();
this.validate({ __noPromise: true }, function(error) {
next(error);
});
}
} else {
next();
}
}
]
}, {
kind: 'pre',
hook: 'save',
isAsync: true,
fn: function(next, done) {
var subdocs = this.$__getAllSubdocs();
if (!subdocs.length || this.$__preSavingFromParent) {
done();
next();
return;
}
async.each(subdocs, function(subdoc, cb) {
subdoc.$__preSavingFromParent = true;
subdoc.save(function(err) {
cb(err);
});
}, function(error) {
for (var i = 0; i < subdocs.length; ++i) {
delete subdocs[i].$__preSavingFromParent;
}
if (error) {
done(error);
return;
}
next();
done();
});
}
}]
});
/**
@@ -234,7 +311,7 @@ Schema.prototype.tree;
* @api private
*/
Schema.prototype.defaultOptions = function (options) {
Schema.prototype.defaultOptions = function(options) {
if (options && false === options.safe) {
options.safe = { w: 0 };
}
@@ -245,22 +322,22 @@ Schema.prototype.defaultOptions = function (options) {
}
options = utils.options({
strict: true
, bufferCommands: true
, capped: false // { size, max, autoIndexId }
, versionKey: '__v'
, discriminatorKey: '__t'
, minimize: true
, autoIndex: null
, shardKey: null
, read: null
, validateBeforeSave: true
strict: true,
bufferCommands: true,
capped: false, // { size, max, autoIndexId }
versionKey: '__v',
discriminatorKey: '__t',
minimize: true,
autoIndex: null,
shardKey: null,
read: null,
validateBeforeSave: true,
// the following are only applied at construction time
, noId: false // deprecated, use { _id: false }
, _id: true
, noVirtualId: false // deprecated, use { id: false }
, id: true
// , pluralization: true // only set this to override the global option
noId: false, // deprecated, use { _id: false }
_id: true,
noVirtualId: false, // deprecated, use { id: false }
id: true,
typeKey: 'type'
}, options);
if (options.read) {
@@ -268,7 +345,7 @@ Schema.prototype.defaultOptions = function (options) {
}
return options;
}
};
/**
* Adds key path / schema type pairs to this schema.
@@ -283,7 +360,7 @@ Schema.prototype.defaultOptions = function (options) {
* @api public
*/
Schema.prototype.add = function add (obj, prefix) {
Schema.prototype.add = function add(obj, prefix) {
prefix = prefix || '';
var keys = Object.keys(obj);
@@ -291,14 +368,16 @@ Schema.prototype.add = function add (obj, prefix) {
var key = keys[i];
if (null == obj[key]) {
throw new TypeError('Invalid value for schema path `'+ prefix + key +'`');
throw new TypeError('Invalid value for schema path `' + prefix + key + '`');
}
if (Array.isArray(obj[key]) && obj[key].length === 1 && null == obj[key][0]) {
throw new TypeError('Invalid value for schema Array path `'+ prefix + key +'`');
throw new TypeError('Invalid value for schema Array path `' + prefix + key + '`');
}
if (utils.isObject(obj[key]) && (!obj[key].constructor || 'Object' == utils.getFunctionName(obj[key].constructor)) && (!obj[key].type || obj[key].type.type)) {
if (utils.isObject(obj[key]) &&
(!obj[key].constructor || 'Object' == utils.getFunctionName(obj[key].constructor)) &&
(!obj[key][this.options.typeKey] || (this.options.typeKey === 'type' && obj[key].type.type))) {
if (Object.keys(obj[key]).length) {
// nested object { last: { name: String }}
this.nested[prefix + key] = true;
@@ -372,10 +451,13 @@ warnings.increment = '`increment` should not be used as a schema path name ' +
* @api public
*/
Schema.prototype.path = function (path, obj) {
Schema.prototype.path = function(path, obj) {
if (obj == undefined) {
if (this.paths[path]) return this.paths[path];
if (this.subpaths[path]) return this.subpaths[path];
if (this.singleNestedPaths[path]) {
return this.singleNestedPaths[path];
}
// subpaths?
return /\.\d+\.?.*$/.test(path)
@@ -393,9 +475,9 @@ Schema.prototype.path = function (path, obj) {
}
// update the tree
var subpaths = path.split(/\./)
, last = subpaths.pop()
, branch = this.tree;
var subpaths = path.split(/\./),
last = subpaths.pop(),
branch = this.tree;
subpaths.forEach(function(sub, i) {
if (!branch[sub]) branch[sub] = {};
@@ -412,7 +494,13 @@ Schema.prototype.path = function (path, obj) {
branch[last] = utils.clone(obj);
this.paths[path] = Schema.interpretAsType(path, obj);
this.paths[path] = Schema.interpretAsType(path, obj, this.options);
if (this.paths[path].$isSingleNested) {
for (var key in this.paths[path].schema.paths) {
this.singleNestedPaths[path + '.' + key] =
this.paths[path].schema.paths[key];
}
}
return this;
};
@@ -424,19 +512,21 @@ Schema.prototype.path = function (path, obj) {
* @api private
*/
Schema.interpretAsType = function (path, obj) {
Schema.interpretAsType = function(path, obj, options) {
if (obj.constructor) {
var constructorName = utils.getFunctionName(obj.constructor);
if (constructorName != 'Object') {
obj = { type: obj };
var oldObj = obj;
obj = {};
obj[options.typeKey] = oldObj;
}
}
// Get the type making sure to allow keys named "type"
// and default to mixed if not specified.
// { type: { type: String, default: 'freshcut' } }
var type = obj.type && !obj.type.type
? obj.type
var type = obj[options.typeKey] && (options.typeKey !== 'type' || !obj.type.type)
? obj[options.typeKey]
: {};
if ('Object' == utils.getFunctionName(type.constructor) || 'mixed' == type) {
@@ -449,21 +539,34 @@ Schema.interpretAsType = function (path, obj) {
? obj.cast
: type[0];
if (cast instanceof Schema) {
if (cast && cast.instanceOfSchema) {
return new MongooseTypes.DocumentArray(path, cast, obj);
}
if ('string' == typeof cast) {
cast = MongooseTypes[cast.charAt(0).toUpperCase() + cast.substring(1)];
} else if (cast && (!cast.type || cast.type.type)
} else if (cast && (!cast[options.typeKey] || (options.typeKey === 'type' && cast.type.type))
&& 'Object' == utils.getFunctionName(cast.constructor)
&& Object.keys(cast).length) {
return new MongooseTypes.DocumentArray(path, new Schema(cast), obj);
// The `minimize` and `typeKey` options propagate to child schemas
// declared inline, like `{ arr: [{ val: { $type: String } }] }`.
// See gh-3560
var childSchemaOptions = { minimize: options.minimize };
if (options.typeKey) {
childSchemaOptions.typeKey = options.typeKey;
}
var childSchema = new Schema(cast, childSchemaOptions);
return new MongooseTypes.DocumentArray(path, childSchema, obj);
}
return new MongooseTypes.Array(path, cast || MongooseTypes.Mixed, obj);
}
if (type && type.instanceOfSchema) {
return new MongooseTypes.Embedded(type, path, obj);
}
var name;
if (Buffer.isBuffer(type)) {
name = 'Buffer';
@@ -498,9 +601,9 @@ Schema.interpretAsType = function (path, obj) {
* @api public
*/
Schema.prototype.eachPath = function (fn) {
var keys = Object.keys(this.paths)
, len = keys.length;
Schema.prototype.eachPath = function(fn) {
var keys = Object.keys(this.paths),
len = keys.length;
for (var i = 0; i < len; ++i) {
fn(keys[i], this.paths[keys[i]]);
@@ -513,15 +616,16 @@ Schema.prototype.eachPath = function (fn) {
* Returns an Array of path strings that are required by this schema.
*
* @api public
* @param {Boolean} invalidate refresh the cache
* @return {Array}
*/
Schema.prototype.requiredPaths = function requiredPaths () {
if (this._requiredpaths) return this._requiredpaths;
Schema.prototype.requiredPaths = function requiredPaths(invalidate) {
if (this._requiredpaths && !invalidate) return this._requiredpaths;
var paths = Object.keys(this.paths)
, i = paths.length
, ret = [];
var paths = Object.keys(this.paths),
i = paths.length,
ret = [];
while (i--) {
var path = paths[i];
@@ -529,7 +633,7 @@ Schema.prototype.requiredPaths = function requiredPaths () {
}
return this._requiredpaths = ret;
}
};
/**
* Returns indexes from fields and schema-level indexes (cached).
@@ -538,11 +642,11 @@ Schema.prototype.requiredPaths = function requiredPaths () {
* @return {Array}
*/
Schema.prototype.indexedPaths = function indexedPaths () {
Schema.prototype.indexedPaths = function indexedPaths() {
if (this._indexedpaths) return this._indexedpaths;
return this._indexedpaths = this.indexes();
}
};
/**
* Returns the pathType of `path` for this schema.
@@ -554,37 +658,64 @@ Schema.prototype.indexedPaths = function indexedPaths () {
* @api public
*/
Schema.prototype.pathType = function (path) {
Schema.prototype.pathType = function(path) {
if (path in this.paths) return 'real';
if (path in this.virtuals) return 'virtual';
if (path in this.nested) return 'nested';
if (path in this.subpaths) return 'real';
if (/\.\d+\.|\.\d+$/.test(path) && getPositionalPath(this, path)) {
if (path in this.singleNestedPaths) {
return 'real';
} else {
return 'adhocOrUndefined'
}
if (/\.\d+\.|\.\d+$/.test(path)) {
return getPositionalPathType(this, path);
} else {
return 'adhocOrUndefined';
}
};
/**
* Returns true iff this path is a child of a mixed schema.
*
* @param {String} path
* @return {Boolean}
* @api private
*/
Schema.prototype.hasMixedParent = function(path) {
var subpaths = path.split(/\./g);
path = '';
for (var i = 0; i < subpaths.length; ++i) {
path = i > 0 ? path + '.' + subpaths[i] : subpaths[i];
if (path in this.paths &&
this.paths[path] instanceof MongooseTypes.Mixed) {
return true;
}
}
return false;
};
/*!
* ignore
*/
function getPositionalPath (self, path) {
function getPositionalPathType(self, path) {
var subpaths = path.split(/\.(\d+)\.|\.(\d+)$/).filter(Boolean);
if (subpaths.length < 2) {
return self.paths[subpaths[0]];
}
var val = self.path(subpaths[0]);
var isNested = false;
if (!val) return val;
var last = subpaths.length - 1
, subpath
, i = 1;
var last = subpaths.length - 1,
subpath,
i = 1;
for (; i < subpaths.length; ++i) {
isNested = false;
subpath = subpaths[i];
if (i === last && val && !val.schema && !/\D/.test(subpath)) {
@@ -605,10 +736,29 @@ function getPositionalPath (self, path) {
break;
}
var type = val.schema.pathType(subpath);
isNested = (type === 'nested');
val = val.schema.path(subpath);
}
return self.subpaths[path] = val;
self.subpaths[path] = val;
if (val) {
return 'real';
}
if (isNested) {
return 'nested';
}
return 'adhocOrUndefined';
}
/*!
* ignore
*/
function getPositionalPath(self, path) {
getPositionalPathType(self, path);
return self.subpaths[path];
}
/**
@@ -616,10 +766,10 @@ function getPositionalPath (self, path) {
*
* @param {String} name name of the document method to call later
* @param {Array} args arguments to pass to the method
* @api private
* @api public
*/
Schema.prototype.queue = function(name, args){
Schema.prototype.queue = function(name, args) {
this.callQueue.push([name, args]);
return this;
};
@@ -691,12 +841,13 @@ Schema.prototype.post = function(method, fn) {
}]);
}
return this.queue('post', [arguments[0], function(next){
return this.queue('post', [arguments[0], function(next) {
// wrap original function so that the callback goes last,
// for compatibility with old code that is using synchronous post hooks
var self = this;
fn.call(this, this, function(err, result) {
return next(err, result || self);
var args = Array.prototype.slice.call(arguments, 1);
fn.call(this, this, function(err) {
return next.apply(self, [err].concat(args));
});
}]);
};
@@ -710,7 +861,7 @@ Schema.prototype.post = function(method, fn) {
* @api public
*/
Schema.prototype.plugin = function (fn, opts) {
Schema.prototype.plugin = function(fn, opts) {
fn(this, opts);
return this;
};
@@ -747,7 +898,7 @@ Schema.prototype.plugin = function (fn, opts) {
* @api public
*/
Schema.prototype.method = function (name, fn) {
Schema.prototype.method = function(name, fn) {
if ('string' != typeof name)
for (var i in name)
this.methods[i] = name[i];
@@ -795,11 +946,12 @@ Schema.prototype.static = function(name, fn) {
* schema.index({ first: 1, last: -1 })
*
* @param {Object} fields
* @param {Object} [options]
* @param {Object} [options] Options to pass to [MongoDB driver's `createIndex()` function](http://mongodb.github.io/node-mongodb-native/2.0/api/Collection.html#createIndex)
* @param {String} [options.expires=null] Mongoose-specific syntactic sugar, uses [ms](https://www.npmjs.com/package/ms) to convert `expires` option into seconds for the `expireAfterSeconds` in the above link.
* @api public
*/
Schema.prototype.index = function (fields, options) {
Schema.prototype.index = function(fields, options) {
options || (options = {});
if (options.expires)
@@ -812,12 +964,19 @@ Schema.prototype.index = function (fields, options) {
/**
* Sets/gets a schema option.
*
* ####Example
*
* schema.set('strict'); // 'true' by default
* schema.set('strict', false); // Sets 'strict' to false
* schema.set('strict'); // 'false'
*
* @param {String} key option name
* @param {Object} [value] if not passed, the current option value is returned
* @see Schema ./
* @api public
*/
Schema.prototype.set = function (key, value, _tags) {
Schema.prototype.set = function(key, value, _tags) {
if (1 === arguments.length) {
return this.options[key];
}
@@ -829,14 +988,14 @@ Schema.prototype.set = function (key, value, _tags) {
case 'safe':
this.options[key] = false === value
? { w: 0 }
: value
: value;
break;
default:
this.options[key] = value;
}
return this;
}
};
/**
* Gets a schema option.
@@ -845,9 +1004,9 @@ Schema.prototype.set = function (key, value, _tags) {
* @api public
*/
Schema.prototype.get = function (key) {
Schema.prototype.get = function(key) {
return this.options[key];
}
};
/**
* The allowed index types
@@ -860,9 +1019,9 @@ Schema.prototype.get = function (key) {
var indexTypes = '2d 2dsphere hashed text'.split(' ');
Object.defineProperty(Schema, 'indexTypes', {
get: function () { return indexTypes }
, set: function () { throw new Error('Cannot overwrite Schema.indexTypes') }
})
get: function() { return indexTypes; },
set: function() { throw new Error('Cannot overwrite Schema.indexTypes'); }
});
/**
* Compiles indexes from fields and schema-level indexes
@@ -870,7 +1029,7 @@ Object.defineProperty(Schema, 'indexTypes', {
* @api public
*/
Schema.prototype.indexes = function () {
Schema.prototype.indexes = function() {
'use strict';
var indexes = [];
@@ -892,6 +1051,8 @@ Schema.prototype.indexes = function () {
if (path instanceof MongooseTypes.DocumentArray) {
collectIndexes(path.schema, key + '.');
} else if (path.$isSingleNested) {
collectIndexes(path.schema, key + '.');
} else {
index = path._index;
@@ -922,7 +1083,7 @@ Schema.prototype.indexes = function () {
if (prefix) {
fixSubIndexPaths(schema, prefix);
} else {
schema._indexes.forEach(function (index) {
schema._indexes.forEach(function(index) {
if (!('background' in index[1])) index[1].background = true;
});
indexes = indexes.concat(schema._indexes);
@@ -940,16 +1101,16 @@ Schema.prototype.indexes = function () {
* schema._indexes = [ [indexObj, options], [indexObj, options] ..]
*/
function fixSubIndexPaths (schema, prefix) {
var subindexes = schema._indexes
, len = subindexes.length
, indexObj
, newindex
, klen
, keys
, key
, i = 0
, j
function fixSubIndexPaths(schema, prefix) {
var subindexes = schema._indexes,
len = subindexes.length,
indexObj,
newindex,
klen,
keys,
key,
i = 0,
j;
for (i = 0; i < len; ++i) {
indexObj = subindexes[i][0];
@@ -966,7 +1127,7 @@ Schema.prototype.indexes = function () {
indexes.push([newindex, subindexes[i][1]]);
}
}
}
};
/**
* Creates a virtual type with the given name.
@@ -976,11 +1137,11 @@ Schema.prototype.indexes = function () {
* @return {VirtualType}
*/
Schema.prototype.virtual = function (name, options) {
Schema.prototype.virtual = function(name, options) {
var virtuals = this.virtuals;
var parts = name.split('.');
return virtuals[name] = parts.reduce(function (mem, part, i) {
mem[part] || (mem[part] = (i === parts.length-1)
return virtuals[name] = parts.reduce(function(mem, part, i) {
mem[part] || (mem[part] = (i === parts.length - 1)
? new VirtualType(options, name)
: {});
return mem[part];
@@ -994,10 +1155,80 @@ Schema.prototype.virtual = function (name, options) {
* @return {VirtualType}
*/
Schema.prototype.virtualpath = function (name) {
Schema.prototype.virtualpath = function(name) {
return this.virtuals[name];
};
/**
* Removes the given `path` (or [`paths`]).
*
* @param {String|Array} path
*
* @api public
*/
Schema.prototype.remove = function(path) {
if (typeof path === 'string') {
path = [path];
}
if (Array.isArray(path)) {
path.forEach(function(name) {
if (this.path(name)) {
delete this.paths[name];
}
}, this);
}
};
/*!
* ignore
*/
Schema.prototype._getSchema = function(path) {
var schema = this;
var pathschema = schema.path(path);
if (pathschema) {
return pathschema;
}
// look for arrays
return (function search(parts, schema) {
var p = parts.length + 1,
foundschema,
trypath;
while (p--) {
trypath = parts.slice(0, p).join('.');
foundschema = schema.path(trypath);
if (foundschema) {
if (foundschema.caster) {
// array of Mixed?
if (foundschema.caster instanceof MongooseTypes.Mixed) {
return foundschema.caster;
}
// Now that we found the array, we need to check if there
// are remaining document paths to look up for casting.
// Also we need to handle array.$.path since schema.path
// doesn't work for that.
// If there is no foundschema.schema we are dealing with
// a path like array.$
if (p !== parts.length && foundschema.schema) {
if ('$' === parts[p]) {
// comments.$.comments.$.title
return search(parts.slice(p + 1), foundschema.schema);
} else {
// this is the last path of the selector
return search(parts.slice(p), foundschema.schema);
}
}
}
return foundschema;
}
}
})(path.split('.'), schema);
};
/*!
* Module exports.
*/
@@ -1039,4 +1270,4 @@ Schema.Types = MongooseTypes = require('./schema/index');
* ignore
*/
var ObjectId = exports.ObjectId = MongooseTypes.ObjectId;
exports.ObjectId = MongooseTypes.ObjectId;

View File

@@ -2,23 +2,22 @@
* Module dependencies.
*/
var SchemaType = require('../schematype')
, CastError = SchemaType.CastError
, NumberSchema = require('./number')
, Types = {
Boolean: require('./boolean')
, Date: require('./date')
, Number: require('./number')
, String: require('./string')
, ObjectId: require('./objectid')
, Buffer: require('./buffer')
}
, MongooseArray = require('../types').Array
, EmbeddedDoc = require('../types').Embedded
, Mixed = require('./mixed')
, cast = require('../cast')
, utils = require('../utils')
, isMongooseObject = utils.isMongooseObject
var SchemaType = require('../schematype'),
CastError = SchemaType.CastError,
Types = {
Boolean: require('./boolean'),
Date: require('./date'),
Number: require('./number'),
String: require('./string'),
ObjectId: require('./objectid'),
Buffer: require('./buffer')
},
MongooseArray = require('../types').Array,
EmbeddedDoc = require('../types').Embedded,
Mixed = require('./mixed'),
cast = require('../cast'),
utils = require('../utils'),
isMongooseObject = utils.isMongooseObject;
/**
* Array SchemaType constructor
@@ -30,7 +29,7 @@ var SchemaType = require('../schematype')
* @api private
*/
function SchemaArray (key, cast, options) {
function SchemaArray(key, cast, options) {
if (cast) {
var castOptions = {};
@@ -63,16 +62,16 @@ function SchemaArray (key, cast, options) {
SchemaType.call(this, key, options, 'Array');
var self = this
, defaultArr
, fn;
var self = this,
defaultArr,
fn;
if (this.defaultValue) {
defaultArr = this.defaultValue;
fn = 'function' == typeof defaultArr;
}
this.default(function(){
this.default(function() {
var arr = fn ? defaultArr() : defaultArr || [];
return new MongooseArray(arr, self.path, this);
});
@@ -99,7 +98,7 @@ SchemaArray.prototype.constructor = SchemaArray;
* @api private
*/
SchemaArray.prototype.checkRequired = function (value) {
SchemaArray.prototype.checkRequired = function(value) {
return !!(value && value.length);
};
@@ -111,7 +110,7 @@ SchemaArray.prototype.checkRequired = function (value) {
* @api private
*/
SchemaArray.prototype.applyGetters = function (value, scope) {
SchemaArray.prototype.applyGetters = function(value, scope) {
if (this.caster.options && this.caster.options.ref) {
// means the object id was populated
return value;
@@ -129,7 +128,7 @@ SchemaArray.prototype.applyGetters = function (value, scope) {
* @api private
*/
SchemaArray.prototype.cast = function (value, doc, init) {
SchemaArray.prototype.cast = function(value, doc, init) {
if (Array.isArray(value)) {
if (!value.length && doc) {
@@ -149,7 +148,7 @@ SchemaArray.prototype.cast = function (value, doc, init) {
if (this.caster) {
try {
for (var i = 0, l = value.length; i < l; i++) {
for (i = 0, l = value.length; i < l; i++) {
value[i] = this.caster.cast(value[i], doc, init);
}
} catch (e) {
@@ -177,9 +176,9 @@ SchemaArray.prototype.cast = function (value, doc, init) {
* @api private
*/
SchemaArray.prototype.castForQuery = function ($conditional, value) {
var handler
, val;
SchemaArray.prototype.castForQuery = function($conditional, value) {
var handler,
val;
if (arguments.length === 2) {
handler = this.$conditionalHandlers[$conditional];
@@ -198,7 +197,10 @@ SchemaArray.prototype.castForQuery = function ($conditional, value) {
var caster = this.caster;
if (Array.isArray(val)) {
val = val.map(function (v) {
val = val.map(function(v) {
if (utils.isObject(v) && v.$elemMatch) {
return v;
}
if (method) v = method.call(caster, v);
return isMongooseObject(v) ?
v.toObject({ virtuals: false }) :
@@ -221,14 +223,14 @@ SchemaArray.prototype.castForQuery = function ($conditional, value) {
* $atomic cast helpers
*/
function castToNumber (val) {
function castToNumber(val) {
return Types.Number.prototype.cast.call(this, val);
}
function castArraysOfNumbers (arr, self) {
function castArraysOfNumbers(arr, self) {
self || (self = this);
arr.forEach(function (v, i) {
arr.forEach(function(v, i) {
if (Array.isArray(v)) {
castArraysOfNumbers(v, self);
} else {
@@ -237,7 +239,7 @@ function castArraysOfNumbers (arr, self) {
});
}
function cast$near (val) {
function cast$near(val) {
if (Array.isArray(val)) {
castArraysOfNumbers(val, this);
return val;
@@ -250,7 +252,7 @@ function cast$near (val) {
return SchemaArray.prototype.castForQuery.call(this, val);
}
function cast$geometry (val, self) {
function cast$geometry(val, self) {
switch (val.$geometry.type) {
case 'Polygon':
case 'LineString':
@@ -269,7 +271,7 @@ function cast$geometry (val, self) {
return val;
}
function cast$within (val) {
function cast$within(val) {
var self = this;
if (val.$maxDistance) {
@@ -278,27 +280,27 @@ function cast$within (val) {
if (val.$box || val.$polygon) {
var type = val.$box ? '$box' : '$polygon';
val[type].forEach(function (arr) {
val[type].forEach(function(arr) {
if (!Array.isArray(arr)) {
var msg = 'Invalid $within $box argument. '
+ 'Expected an array, received ' + arr;
throw new TypeError(msg);
}
arr.forEach(function (v, i) {
arr.forEach(function(v, i) {
arr[i] = castToNumber.call(this, v);
});
})
});
} else if (val.$center || val.$centerSphere) {
var type = val.$center ? '$center' : '$centerSphere';
val[type].forEach(function (item, i) {
type = val.$center ? '$center' : '$centerSphere';
val[type].forEach(function(item, i) {
if (Array.isArray(item)) {
item.forEach(function (v, j) {
item.forEach(function(v, j) {
item[j] = castToNumber.call(this, v);
});
} else {
val[type][i] = castToNumber.call(this, item);
}
})
});
} else if (val.$geometry) {
cast$geometry(val, this);
}
@@ -306,12 +308,12 @@ function cast$within (val) {
return val;
}
function cast$all (val) {
function cast$all(val) {
if (!Array.isArray(val)) {
val = [val];
}
val = val.map(function (v) {
val = val.map(function(v) {
if (utils.isObject(v)) {
var o = {};
o[this.path] = v;
@@ -323,28 +325,23 @@ function cast$all (val) {
return this.castForQuery(val);
}
function cast$elemMatch (val) {
var hasDollarKey = false;
function cast$elemMatch(val) {
var keys = Object.keys(val);
var numKeys = keys.length;
var key;
var value;
for (var i = 0; i < numKeys; ++i) {
var key = keys[i];
var value = val[key];
key = keys[i];
value = val[key];
if (key.indexOf('$') === 0 && value) {
val[key] = this.castForQuery(key, value);
hasDollarKey = true;
}
}
if (hasDollarKey) {
return val;
}
return cast(this.casterConstructor.schema, val);
}
function cast$geoIntersects (val) {
function cast$geoIntersects(val) {
var geo = val.$geometry;
if (!geo) return;

View File

@@ -5,7 +5,6 @@
var utils = require('../utils');
var SchemaType = require('../schematype');
var utils = require('../utils');
/**
* Boolean SchemaType constructor.
@@ -16,7 +15,7 @@ var utils = require('../utils');
* @api private
*/
function SchemaBoolean (path, options) {
function SchemaBoolean(path, options) {
SchemaType.call(this, path, options, 'Boolean');
}
@@ -40,7 +39,7 @@ SchemaBoolean.prototype.constructor = SchemaBoolean;
* @api private
*/
SchemaBoolean.prototype.checkRequired = function (value) {
SchemaBoolean.prototype.checkRequired = function(value) {
return value === true || value === false;
};
@@ -51,29 +50,16 @@ SchemaBoolean.prototype.checkRequired = function (value) {
* @api private
*/
SchemaBoolean.prototype.cast = function (value) {
SchemaBoolean.prototype.cast = function(value) {
if (null === value) return value;
if ('0' === value) return false;
if ('true' === value) return true;
if ('false' === value) return false;
return !! value;
}
/*!
* ignore
*/
function handleArray (val) {
var self = this;
return val.map(function (m) {
return self.cast(m);
});
}
return !!value;
};
SchemaBoolean.$conditionalHandlers =
utils.options(SchemaType.prototype.$conditionalHandlers, {
'$in': handleArray
});
utils.options(SchemaType.prototype.$conditionalHandlers, {});
/**
* Casts contents for queries.
@@ -83,7 +69,7 @@ SchemaBoolean.$conditionalHandlers =
* @api private
*/
SchemaBoolean.prototype.castForQuery = function ($conditional, val) {
SchemaBoolean.prototype.castForQuery = function($conditional, val) {
var handler;
if (2 === arguments.length) {
handler = SchemaBoolean.$conditionalHandlers[$conditional];

View File

@@ -2,6 +2,7 @@
* Module dependencies.
*/
var handleBitwiseOperator = require('./operators/bitwise');
var utils = require('../utils');
var MongooseBuffer = require('../types').Buffer;
@@ -20,7 +21,7 @@ var Document;
* @api private
*/
function SchemaBuffer (key, options) {
function SchemaBuffer(key, options) {
SchemaType.call(this, key, options, 'Buffer');
}
@@ -44,7 +45,7 @@ SchemaBuffer.prototype.constructor = SchemaBuffer;
* @api private
*/
SchemaBuffer.prototype.checkRequired = function (value, doc) {
SchemaBuffer.prototype.checkRequired = function(value, doc) {
if (SchemaType._isRef(this, value, doc, true)) {
return null != value;
} else {
@@ -61,7 +62,8 @@ SchemaBuffer.prototype.checkRequired = function (value, doc) {
* @api private
*/
SchemaBuffer.prototype.cast = function (value, doc, init) {
SchemaBuffer.prototype.cast = function(value, doc, init) {
var ret;
if (SchemaType._isRef(this, value, doc, init)) {
// wait! we may need to cast this to a document
@@ -90,7 +92,7 @@ SchemaBuffer.prototype.cast = function (value, doc, init) {
var path = doc.$__fullPath(this.path);
var owner = doc.ownerDocument ? doc.ownerDocument() : doc;
var pop = owner.populated(path, true);
var ret = new pop.options.model(value);
ret = new pop.options.model(value);
ret.$__.wasPopulated = true;
return ret;
}
@@ -111,7 +113,7 @@ SchemaBuffer.prototype.cast = function (value, doc, init) {
return value;
} else if (value instanceof Binary) {
var ret = new MongooseBuffer(value.value(true), [this.path, doc]);
ret = new MongooseBuffer(value.value(true), [this.path, doc]);
if (typeof value.sub_type !== 'number') {
throw new CastError('buffer', value, this.path);
}
@@ -123,7 +125,7 @@ SchemaBuffer.prototype.cast = function (value, doc, init) {
var type = typeof value;
if ('string' == type || 'number' == type || Array.isArray(value)) {
var ret = new MongooseBuffer(value, [this.path, doc]);
ret = new MongooseBuffer(value, [this.path, doc]);
return ret;
}
@@ -133,26 +135,20 @@ SchemaBuffer.prototype.cast = function (value, doc, init) {
/*!
* ignore
*/
function handleSingle (val) {
function handleSingle(val) {
return this.castForQuery(val);
}
function handleArray (val) {
var self = this;
return val.map( function (m) {
return self.castForQuery(m);
});
}
SchemaBuffer.prototype.$conditionalHandlers =
utils.options(SchemaType.prototype.$conditionalHandlers, {
'$bitsAllClear': handleBitwiseOperator,
'$bitsAnyClear': handleBitwiseOperator,
'$bitsAllSet': handleBitwiseOperator,
'$bitsAnySet': handleBitwiseOperator,
'$gt' : handleSingle,
'$gte': handleSingle,
'$in' : handleArray,
'$lt' : handleSingle,
'$lte': handleSingle,
'$ne' : handleSingle,
'$nin': handleArray
'$lte': handleSingle
});
/**
@@ -163,7 +159,7 @@ SchemaBuffer.prototype.$conditionalHandlers =
* @api private
*/
SchemaBuffer.prototype.castForQuery = function ($conditional, val) {
SchemaBuffer.prototype.castForQuery = function($conditional, val) {
var handler;
if (arguments.length === 2) {
handler = this.$conditionalHandlers[$conditional];

View File

@@ -2,7 +2,7 @@
* Module requirements.
*/
var errorMessages = require('../error').messages
var errorMessages = require('../error').messages;
var utils = require('../utils');
var SchemaType = require('../schematype');
@@ -18,7 +18,7 @@ var CastError = SchemaType.CastError;
* @api private
*/
function SchemaDate (key, options) {
function SchemaDate(key, options) {
SchemaType.call(this, key, options, 'Date');
}
@@ -67,7 +67,7 @@ SchemaDate.prototype.constructor = SchemaDate;
* @api public
*/
SchemaDate.prototype.expires = function (when) {
SchemaDate.prototype.expires = function(when) {
if (!this._index || 'Object' !== this._index.constructor.name) {
this._index = {};
}
@@ -83,7 +83,7 @@ SchemaDate.prototype.expires = function (when) {
* @api private
*/
SchemaDate.prototype.checkRequired = function (value) {
SchemaDate.prototype.checkRequired = function(value) {
return value instanceof Date;
};
@@ -118,9 +118,9 @@ SchemaDate.prototype.checkRequired = function (value) {
* @api public
*/
SchemaDate.prototype.min = function (value, message) {
SchemaDate.prototype.min = function(value, message) {
if (this.minValidator) {
this.validators = this.validators.filter(function (v) {
this.validators = this.validators.filter(function(v) {
return v.validator != this.minValidator;
}, this);
}
@@ -130,12 +130,13 @@ SchemaDate.prototype.min = function (value, message) {
msg = msg.replace(/{MIN}/, (value === Date.now ? 'Date.now()' : this.cast(value).toString()));
var self = this;
this.validators.push({
validator: this.minValidator = function (val) {
validator: this.minValidator = function(val) {
var min = (value === Date.now ? value() : self.cast(value));
return val === null || val.valueOf() >= min.valueOf();
},
message: msg,
type: 'min'
type: 'min',
min: value
});
}
@@ -173,9 +174,9 @@ SchemaDate.prototype.min = function (value, message) {
* @api public
*/
SchemaDate.prototype.max = function (value, message) {
SchemaDate.prototype.max = function(value, message) {
if (this.maxValidator) {
this.validators = this.validators.filter(function(v){
this.validators = this.validators.filter(function(v) {
return v.validator != this.maxValidator;
}, this);
}
@@ -190,7 +191,8 @@ SchemaDate.prototype.max = function (value, message) {
return val === null || val.valueOf() <= max.valueOf();
},
message: msg,
type: 'max'
type: 'max',
max: value
});
}
@@ -204,10 +206,10 @@ SchemaDate.prototype.max = function (value, message) {
* @api private
*/
SchemaDate.prototype.cast = function (value) {
SchemaDate.prototype.cast = function(value) {
// If null or undefined
if (value == null || value === '')
return value;
return null;
if (value instanceof Date)
return value;
@@ -238,27 +240,16 @@ SchemaDate.prototype.cast = function (value) {
* @api private
*/
function handleSingle (val) {
function handleSingle(val) {
return this.cast(val);
}
function handleArray (val) {
var self = this;
return val.map( function (m) {
return self.cast(m);
});
}
SchemaDate.prototype.$conditionalHandlers =
utils.options(SchemaType.prototype.$conditionalHandlers, {
'$all': handleArray,
'$gt': handleSingle,
'$gte': handleSingle,
'$in': handleArray,
'$lt': handleSingle,
'$lte': handleSingle,
'$ne': handleSingle,
'$nin': handleArray
'$lte': handleSingle
});
@@ -270,7 +261,7 @@ SchemaDate.prototype.$conditionalHandlers =
* @api private
*/
SchemaDate.prototype.castForQuery = function ($conditional, val) {
SchemaDate.prototype.castForQuery = function($conditional, val) {
var handler;
if (2 !== arguments.length) {

View File

@@ -1,10 +1,11 @@
/* eslint no-empty: 1 */
/*!
* Module dependencies.
*/
var ArrayType = require('./array');
var Document = require('../document');
var CastError = require('../error/cast');
var MongooseDocumentArray = require('../types/documentarray');
var SchemaType = require('../schematype');
var Subdocument = require('../types/embedded');
@@ -19,10 +20,9 @@ var Subdocument = require('../types/embedded');
* @api private
*/
function DocumentArray (key, schema, options) {
function DocumentArray(key, schema, options) {
// compile an embedded document for this schema
function EmbeddedDocument () {
function EmbeddedDocument() {
Subdocument.apply(this, arguments);
}
@@ -35,7 +35,7 @@ function DocumentArray (key, schema, options) {
EmbeddedDocument.prototype[i] = schema.methods[i];
// apply statics
for (var i in schema.statics)
for (i in schema.statics)
EmbeddedDocument[i] = schema.statics[i];
EmbeddedDocument.options = options;
@@ -47,7 +47,7 @@ function DocumentArray (key, schema, options) {
var path = this.path;
var fn = this.defaultValue;
this.default(function(){
this.default(function() {
var arr = fn.call(this);
if (!Array.isArray(arr)) arr = [arr];
return new MongooseDocumentArray(arr, path, this);
@@ -74,8 +74,8 @@ DocumentArray.prototype.constructor = DocumentArray;
* @api private
*/
DocumentArray.prototype.doValidate = function (array, fn, scope) {
SchemaType.prototype.doValidate.call(this, array, function (err) {
DocumentArray.prototype.doValidate = function(array, fn, scope) {
SchemaType.prototype.doValidate.call(this, array, function(err) {
if (err) {
return fn(err);
}
@@ -97,7 +97,7 @@ DocumentArray.prototype.doValidate = function (array, fn, scope) {
continue;
}
doc.validate(function (err) {
doc.validate({ __noPromise: true }, function(err) {
if (err) {
error = err;
}
@@ -118,12 +118,12 @@ DocumentArray.prototype.doValidate = function (array, fn, scope) {
* @api private
*/
DocumentArray.prototype.doValidateSync = function (array, scope) {
DocumentArray.prototype.doValidateSync = function(array, scope) {
var schemaTypeError = SchemaType.prototype.doValidateSync.call(this, array, scope);
if (schemaTypeError) return schemaTypeError;
var count = array && array.length
, resultError = null;
var count = array && array.length,
resultError = null;
if (!count) return;
@@ -156,10 +156,10 @@ DocumentArray.prototype.doValidateSync = function (array, scope) {
* @api private
*/
DocumentArray.prototype.cast = function (value, doc, init, prev) {
var selected
, subdoc
, i
DocumentArray.prototype.cast = function(value, doc, init, prev) {
var selected,
subdoc,
i;
if (!Array.isArray(value)) {
// gh-2442 mark whole array as modified if we're initializing a doc from
@@ -190,7 +190,7 @@ DocumentArray.prototype.cast = function (value, doc, init, prev) {
} else {
try {
subdoc = prev.id(value[i]._id);
} catch(e) {}
} catch (e) {}
if (prev && subdoc) {
// handle resetting doc with existing id but differing data
@@ -200,17 +200,22 @@ DocumentArray.prototype.cast = function (value, doc, init, prev) {
// see gh-746
value[i] = subdoc;
} else {
subdoc = new this.casterConstructor(value[i], value, undefined, undefined, i);
// if set() is hooked it will have no return value
// see gh-746
value[i] = subdoc;
try {
subdoc = new this.casterConstructor(value[i], value, undefined,
undefined, i);
// if set() is hooked it will have no return value
// see gh-746
value[i] = subdoc;
} catch (error) {
throw new CastError('embedded', value[i], value._path);
}
}
}
}
}
return value;
}
};
/*!
* Scopes paths selected in a query to this array.
@@ -221,15 +226,15 @@ DocumentArray.prototype.cast = function (value, doc, init, prev) {
* @param {Boolean|undefined} init - if we are being created part of a query result
*/
function scopePaths (array, fields, init) {
function scopePaths(array, fields, init) {
if (!(init && fields)) return undefined;
var path = array.path + '.'
, keys = Object.keys(fields)
, i = keys.length
, selected = {}
, hasKeys
, key
var path = array.path + '.',
keys = Object.keys(fields),
i = keys.length,
selected = {},
hasKeys,
key;
while (i--) {
key = keys[i];

137
node_modules/mongoose/lib/schema/embedded.js generated vendored Normal file
View File

@@ -0,0 +1,137 @@
var SchemaType = require('../schematype');
var Subdocument = require('../types/subdocument');
module.exports = Embedded;
/**
* Sub-schema schematype constructor
*
* @param {Schema} schema
* @param {String} key
* @param {Object} options
* @inherits SchemaType
* @api private
*/
function Embedded(schema, path, options) {
var _embedded = function(value, path, parent) {
var _this = this;
Subdocument.apply(this, arguments);
this.$parent = parent;
if (parent) {
parent.on('save', function() {
_this.emit('save', _this);
});
}
};
_embedded.prototype = Object.create(Subdocument.prototype);
_embedded.prototype.$__setSchema(schema);
_embedded.schema = schema;
_embedded.$isSingleNested = true;
_embedded.prototype.$basePath = path;
// apply methods
for (var i in schema.methods) {
_embedded.prototype[i] = schema.methods[i];
}
// apply statics
for (i in schema.statics) {
_embedded[i] = schema.statics[i];
}
this.caster = _embedded;
this.schema = schema;
this.$isSingleNested = true;
SchemaType.call(this, path, options, 'Embedded');
}
Embedded.prototype = Object.create(SchemaType.prototype);
/**
* Casts contents
*
* @param {Object} value
* @api private
*/
Embedded.prototype.cast = function(val, doc, init) {
if (val && val.$isSingleNested) {
return val;
}
var subdoc = new this.caster(undefined, undefined, doc);
if (init) {
subdoc.init(val);
} else {
subdoc.set(val, undefined, true);
}
return subdoc;
};
/**
* Casts contents for query
*
* @param {string} [$conditional] optional query operator (like `$eq` or `$in`)
* @param {any} value
* @api private
*/
Embedded.prototype.castForQuery = function($conditional, val) {
var handler;
if (arguments.length === 2) {
handler = this.$conditionalHandlers[$conditional];
if (!handler) {
throw new Error('Can\'t use ' + $conditional);
}
return handler.call(this, val);
} else {
val = $conditional;
return new this.caster(val).
toObject({ virtuals: false });
}
};
/**
* Async validation on this single nested doc.
*
* @api private
*/
Embedded.prototype.doValidate = function(value, fn) {
SchemaType.prototype.doValidate.call(this, value, function(error) {
if (error) {
return fn(error);
}
if (!value) {
return fn(null);
}
value.validate(fn, { __noPromise: true });
});
};
/**
* Synchronously validate this single nested doc
*
* @api private
*/
Embedded.prototype.doValidateSync = function(value) {
var schemaTypeError = SchemaType.prototype.doValidateSync.call(this, value);
if (schemaTypeError) {
return schemaTypeError;
}
if (!value) {
return;
}
return value.validateSync();
};
/**
* Required validator for single nested docs
*
* @api private
*/
Embedded.prototype.checkRequired = function(value) {
return !!value && value.$isSingleNested;
};

View File

@@ -11,6 +11,8 @@ exports.Boolean = require('./boolean');
exports.DocumentArray = require('./documentarray');
exports.Embedded = require('./embedded');
exports.Array = require('./array');
exports.Buffer = require('./buffer');

View File

@@ -15,7 +15,7 @@ var utils = require('../utils');
* @api private
*/
function Mixed (path, options) {
function Mixed(path, options) {
if (options && options.default) {
var def = options.default;
if (Array.isArray(def) && 0 === def.length) {
@@ -25,9 +25,9 @@ function Mixed (path, options) {
utils.isObject(def) &&
0 === Object.keys(def).length) {
// prevent odd "shared" objects between documents
options.default = function () {
return {}
}
options.default = function() {
return {};
};
}
}
@@ -54,7 +54,7 @@ Mixed.prototype.constructor = Mixed;
* @api private
*/
Mixed.prototype.checkRequired = function (val) {
Mixed.prototype.checkRequired = function(val) {
return (val !== undefined) && (val !== null);
};
@@ -67,7 +67,7 @@ Mixed.prototype.checkRequired = function (val) {
* @api private
*/
Mixed.prototype.cast = function (val) {
Mixed.prototype.cast = function(val) {
return val;
};
@@ -79,7 +79,7 @@ Mixed.prototype.cast = function (val) {
* @api private
*/
Mixed.prototype.castForQuery = function ($cond, val) {
Mixed.prototype.castForQuery = function($cond, val) {
if (arguments.length === 2) return val;
return $cond;
};

View File

@@ -2,11 +2,12 @@
* Module requirements.
*/
var SchemaType = require('../schematype')
, CastError = SchemaType.CastError
, errorMessages = require('../error').messages
, utils = require('../utils')
, Document
var SchemaType = require('../schematype');
var CastError = SchemaType.CastError;
var handleBitwiseOperator = require('./operators/bitwise');
var errorMessages = require('../error').messages;
var utils = require('../utils');
var Document;
/**
* Number SchemaType constructor.
@@ -17,7 +18,7 @@ var SchemaType = require('../schematype')
* @api private
*/
function SchemaNumber (key, options) {
function SchemaNumber(key, options) {
SchemaType.call(this, key, options, 'Number');
}
@@ -41,7 +42,7 @@ SchemaNumber.prototype.constructor = SchemaNumber;
* @api private
*/
SchemaNumber.prototype.checkRequired = function checkRequired (value, doc) {
SchemaNumber.prototype.checkRequired = function checkRequired(value, doc) {
if (SchemaType._isRef(this, value, doc, true)) {
return null != value;
} else {
@@ -80,9 +81,9 @@ SchemaNumber.prototype.checkRequired = function checkRequired (value, doc) {
* @api public
*/
SchemaNumber.prototype.min = function (value, message) {
SchemaNumber.prototype.min = function(value, message) {
if (this.minValidator) {
this.validators = this.validators.filter(function (v) {
this.validators = this.validators.filter(function(v) {
return v.validator != this.minValidator;
}, this);
}
@@ -91,11 +92,12 @@ SchemaNumber.prototype.min = function (value, message) {
var msg = message || errorMessages.Number.min;
msg = msg.replace(/{MIN}/, value);
this.validators.push({
validator: this.minValidator = function (v) {
return v === null || v >= value;
validator: this.minValidator = function(v) {
return v == null || v >= value;
},
message: msg,
type: 'min'
type: 'min',
min: value
});
}
@@ -133,9 +135,9 @@ SchemaNumber.prototype.min = function (value, message) {
* @api public
*/
SchemaNumber.prototype.max = function (value, message) {
SchemaNumber.prototype.max = function(value, message) {
if (this.maxValidator) {
this.validators = this.validators.filter(function(v){
this.validators = this.validators.filter(function(v) {
return v.validator != this.maxValidator;
}, this);
}
@@ -145,10 +147,11 @@ SchemaNumber.prototype.max = function (value, message) {
msg = msg.replace(/{MAX}/, value);
this.validators.push({
validator: this.maxValidator = function(v) {
return v === null || v <= value;
return v == null || v <= value;
},
message: msg,
type: 'max'
type: 'max',
max: value
});
}
@@ -164,7 +167,7 @@ SchemaNumber.prototype.max = function (value, message) {
* @api private
*/
SchemaNumber.prototype.cast = function (value, doc, init) {
SchemaNumber.prototype.cast = function(value, doc, init) {
if (SchemaType._isRef(this, value, doc, init)) {
// wait! we may need to cast this to a document
@@ -202,15 +205,17 @@ SchemaNumber.prototype.cast = function (value, doc, init) {
? value._id // documents
: value;
if (!isNaN(val)){
if (!isNaN(val)) {
if (null === val) return val;
if ('' === val) return null;
if ('string' == typeof val) val = Number(val);
if (val instanceof Number) return val
if (typeof val === 'string' || typeof val === 'boolean') {
val = Number(val);
}
if (val instanceof Number) return val;
if ('number' == typeof val) return val;
if (val.toString && !Array.isArray(val) &&
val.toString() == Number(val)) {
return new Number(val)
return new Number(val);
}
}
@@ -221,28 +226,31 @@ SchemaNumber.prototype.cast = function (value, doc, init) {
* ignore
*/
function handleSingle (val) {
return this.cast(val)
function handleSingle(val) {
return this.cast(val);
}
function handleArray (val) {
function handleArray(val) {
var self = this;
return val.map(function (m) {
return self.cast(m)
if (!Array.isArray(val)) {
return [this.cast(val)];
}
return val.map(function(m) {
return self.cast(m);
});
}
SchemaNumber.prototype.$conditionalHandlers =
utils.options(SchemaType.prototype.$conditionalHandlers, {
'$all': handleArray,
'$bitsAllClear': handleBitwiseOperator,
'$bitsAnyClear': handleBitwiseOperator,
'$bitsAllSet': handleBitwiseOperator,
'$bitsAnySet': handleBitwiseOperator,
'$gt' : handleSingle,
'$gte': handleSingle,
'$in' : handleArray,
'$lt' : handleSingle,
'$lte': handleSingle,
'$ne' : handleSingle,
'$mod': handleArray,
'$nin': handleArray
'$mod': handleArray
});
/**
@@ -253,7 +261,7 @@ SchemaNumber.prototype.$conditionalHandlers =
* @api private
*/
SchemaNumber.prototype.castForQuery = function ($conditional, val) {
SchemaNumber.prototype.castForQuery = function($conditional, val) {
var handler;
if (arguments.length === 2) {
handler = this.$conditionalHandlers[$conditional];
@@ -262,7 +270,7 @@ SchemaNumber.prototype.castForQuery = function ($conditional, val) {
return handler.call(this, val);
} else {
val = this.cast($conditional);
return val == null ? val : val
return val == null ? val : val;
}
};

View File

@@ -1,12 +1,14 @@
/* eslint no-empty: 1 */
/*!
* Module dependencies.
*/
var SchemaType = require('../schematype')
, CastError = SchemaType.CastError
, oid = require('../types/objectid')
, utils = require('../utils')
, Document
var SchemaType = require('../schematype'),
CastError = SchemaType.CastError,
oid = require('../types/objectid'),
utils = require('../utils'),
Document;
/**
* ObjectId SchemaType constructor.
@@ -17,7 +19,7 @@ var SchemaType = require('../schematype')
* @api private
*/
function ObjectId (key, options) {
function ObjectId(key, options) {
SchemaType.call(this, key, options, 'ObjectID');
}
@@ -42,10 +44,10 @@ ObjectId.prototype.constructor = ObjectId;
* @return {SchemaType} this
*/
ObjectId.prototype.auto = function (turnOn) {
ObjectId.prototype.auto = function(turnOn) {
if (turnOn) {
this.default(defaultId);
this.set(resetId)
this.set(resetId);
}
return this;
@@ -57,7 +59,7 @@ ObjectId.prototype.auto = function (turnOn) {
* @api private
*/
ObjectId.prototype.checkRequired = function checkRequired (value, doc) {
ObjectId.prototype.checkRequired = function checkRequired(value, doc) {
if (SchemaType._isRef(this, value, doc, true)) {
return null != value;
} else {
@@ -74,7 +76,7 @@ ObjectId.prototype.checkRequired = function checkRequired (value, doc) {
* @api private
*/
ObjectId.prototype.cast = function (value, doc, init) {
ObjectId.prototype.cast = function(value, doc, init) {
if (SchemaType._isRef(this, value, doc, init)) {
// wait! we may need to cast this to a document
@@ -121,7 +123,7 @@ ObjectId.prototype.cast = function (value, doc, init) {
if (value._id.toString instanceof Function) {
try {
return oid.createFromHexString(value._id.toString());
} catch(e) {}
} catch (e) {}
}
}
@@ -140,27 +142,16 @@ ObjectId.prototype.cast = function (value, doc, init) {
* ignore
*/
function handleSingle (val) {
function handleSingle(val) {
return this.cast(val);
}
function handleArray (val) {
var self = this;
return val.map(function (m) {
return self.cast(m);
});
}
ObjectId.prototype.$conditionalHandlers =
utils.options(SchemaType.prototype.$conditionalHandlers, {
'$all': handleArray,
'$gt': handleSingle,
'$gte': handleSingle,
'$in': handleArray,
'$lt': handleSingle,
'$lte': handleSingle,
'$ne': handleSingle,
'$nin': handleArray
'$lte': handleSingle
});
/**
@@ -171,7 +162,7 @@ ObjectId.prototype.$conditionalHandlers =
* @api private
*/
ObjectId.prototype.castForQuery = function ($conditional, val) {
ObjectId.prototype.castForQuery = function($conditional, val) {
var handler;
if (arguments.length === 2) {
handler = this.$conditionalHandlers[$conditional];
@@ -187,11 +178,11 @@ ObjectId.prototype.castForQuery = function ($conditional, val) {
* ignore
*/
function defaultId () {
function defaultId() {
return new oid();
};
}
function resetId (v) {
function resetId(v) {
this.$__._id = null;
return v;
}

37
node_modules/mongoose/lib/schema/operators/bitwise.js generated vendored Normal file
View File

@@ -0,0 +1,37 @@
/*!
* Module requirements.
*/
var CastError = require('../../error/cast');
/*!
* ignore
*/
function handleBitwiseOperator(val) {
var _this = this;
if (Array.isArray(val)) {
return val.map(function(v) {
return _castNumber(_this, v);
});
} else if (Buffer.isBuffer(val)) {
return val;
} else {
// Assume trying to cast to number
return _castNumber(_this, val);
}
}
/*!
* ignore
*/
function _castNumber(_this, num) {
var v = Number(num);
if (isNaN(v)) {
throw new CastError('number', num, _this.path);
}
return v;
}
module.exports = handleBitwiseOperator;

View File

@@ -3,11 +3,11 @@
* Module dependencies.
*/
var SchemaType = require('../schematype')
, CastError = SchemaType.CastError
, errorMessages = require('../error').messages
, utils = require('../utils')
, Document
var SchemaType = require('../schematype');
var CastError = SchemaType.CastError;
var errorMessages = require('../error').messages;
var utils = require('../utils');
var Document;
/**
* String SchemaType constructor.
@@ -18,11 +18,11 @@ var SchemaType = require('../schematype')
* @api private
*/
function SchemaString (key, options) {
function SchemaString(key, options) {
this.enumValues = [];
this.regExp = null;
SchemaType.call(this, key, options, 'String');
};
}
/**
* This schema type's name, to defend against minifiers that mangle
@@ -73,7 +73,7 @@ SchemaString.prototype.constructor = SchemaString;
* @api public
*/
SchemaString.prototype.enum = function () {
SchemaString.prototype.enum = function() {
if (this.enumValidator) {
this.validators = this.validators.filter(function(v) {
return v.validator != this.enumValidator;
@@ -103,13 +103,14 @@ SchemaString.prototype.enum = function () {
}
var vals = this.enumValues;
this.enumValidator = function (v) {
this.enumValidator = function(v) {
return undefined === v || ~vals.indexOf(v);
};
this.validators.push({
validator: this.enumValidator,
message: errorMessage,
type: 'enum'
type: 'enum',
enumValues: vals
});
return this;
@@ -129,9 +130,9 @@ SchemaString.prototype.enum = function () {
* @return {SchemaType} this
*/
SchemaString.prototype.lowercase = function () {
return this.set(function (v, self) {
if ('string' != typeof v) v = self.cast(v)
SchemaString.prototype.lowercase = function() {
return this.set(function(v, self) {
if ('string' != typeof v) v = self.cast(v);
if (v) return v.toLowerCase();
return v;
});
@@ -151,9 +152,9 @@ SchemaString.prototype.lowercase = function () {
* @return {SchemaType} this
*/
SchemaString.prototype.uppercase = function () {
return this.set(function (v, self) {
if ('string' != typeof v) v = self.cast(v)
SchemaString.prototype.uppercase = function() {
return this.set(function(v, self) {
if ('string' != typeof v) v = self.cast(v);
if (v) return v.toUpperCase();
return v;
});
@@ -177,9 +178,9 @@ SchemaString.prototype.uppercase = function () {
* @return {SchemaType} this
*/
SchemaString.prototype.trim = function () {
return this.set(function (v, self) {
if ('string' != typeof v) v = self.cast(v)
SchemaString.prototype.trim = function() {
return this.set(function(v, self) {
if ('string' != typeof v) v = self.cast(v);
if (v) return v.trim();
return v;
});
@@ -200,12 +201,12 @@ SchemaString.prototype.trim = function () {
* })
*
* // custom error messages
* // We can also use the special {MINLENGTH} token which will be replaced with the invalid value
* var minlength = [10, 'The value of path `{PATH}` (`{VALUE}`) is shorter than the minimum length ({MINLENGTH}).'];
* // We can also use the special {MINLENGTH} token which will be replaced with the minimum allowed length
* var minlength = [5, 'The value of path `{PATH}` (`{VALUE}`) is shorter than the minimum allowed length ({MINLENGTH}).'];
* var schema = new Schema({ postalCode: { type: String, minlength: minlength })
* var Address = mongoose.model('Address', schema);
* var address = new Address({ postalCode: '9512' });
* s.validate(function (err) {
* address.validate(function (err) {
* console.log(String(err)) // ValidationError: The value of path `postalCode` (`9512`) is shorter than the minimum length (5).
* })
*
@@ -216,9 +217,9 @@ SchemaString.prototype.trim = function () {
* @api public
*/
SchemaString.prototype.minlength = function (value, message) {
SchemaString.prototype.minlength = function(value, message) {
if (this.minlengthValidator) {
this.validators = this.validators.filter(function (v) {
this.validators = this.validators.filter(function(v) {
return v.validator != this.minlengthValidator;
}, this);
}
@@ -227,11 +228,12 @@ SchemaString.prototype.minlength = function (value, message) {
var msg = message || errorMessages.String.minlength;
msg = msg.replace(/{MINLENGTH}/, value);
this.validators.push({
validator: this.minlengthValidator = function (v) {
validator: this.minlengthValidator = function(v) {
return v === null || v.length >= value;
},
message: msg,
type: 'minlength'
type: 'minlength',
minlength: value
});
}
@@ -253,13 +255,13 @@ SchemaString.prototype.minlength = function (value, message) {
* })
*
* // custom error messages
* // We can also use the special {MAXLENGTH} token which will be replaced with the invalid value
* var maxlength = [10, 'The value of path `{PATH}` (`{VALUE}`) exceeds the maximum allowed length ({MAXLENGTH}).'];
* // We can also use the special {MAXLENGTH} token which will be replaced with the maximum allowed length
* var maxlength = [9, 'The value of path `{PATH}` (`{VALUE}`) exceeds the maximum allowed length ({MAXLENGTH}).'];
* var schema = new Schema({ postalCode: { type: String, maxlength: maxlength })
* var Address = mongoose.model('Address', schema);
* var address = new Address({ postalCode: '9512512345' });
* address.validate(function (err) {
* console.log(String(err)) // ValidationError: The value of path `postalCode` (`9512512345`) exceeds the maximum allowed length (10).
* console.log(String(err)) // ValidationError: The value of path `postalCode` (`9512512345`) exceeds the maximum allowed length (9).
* })
*
* @param {Number} value maximum string length
@@ -269,9 +271,9 @@ SchemaString.prototype.minlength = function (value, message) {
* @api public
*/
SchemaString.prototype.maxlength = function (value, message) {
SchemaString.prototype.maxlength = function(value, message) {
if (this.maxlengthValidator) {
this.validators = this.validators.filter(function(v){
this.validators = this.validators.filter(function(v) {
return v.validator != this.maxlengthValidator;
}, this);
}
@@ -284,7 +286,8 @@ SchemaString.prototype.maxlength = function (value, message) {
return v === null || v.length <= value;
},
message: msg,
type: 'maxlength'
type: 'maxlength',
maxlength: value
});
}
@@ -329,19 +332,28 @@ SchemaString.prototype.maxlength = function (value, message) {
* @api public
*/
SchemaString.prototype.match = function match (regExp, message) {
SchemaString.prototype.match = function match(regExp, message) {
// yes, we allow multiple match validators
var msg = message || errorMessages.String.match;
var matchValidator = function(v) {
if (!regExp) {
return false;
}
var ret = ((null != v && '' !== v)
? regExp.test(v)
: true);
return ret;
};
this.validators.push({ validator: matchValidator, message: msg, type: 'regexp' });
this.validators.push({
validator: matchValidator,
message: msg,
type: 'regexp',
regexp: regExp
});
return this;
};
@@ -352,7 +364,7 @@ SchemaString.prototype.match = function match (regExp, message) {
* @api private
*/
SchemaString.prototype.checkRequired = function checkRequired (value, doc) {
SchemaString.prototype.checkRequired = function checkRequired(value, doc) {
if (SchemaType._isRef(this, value, doc, true)) {
return null != value;
} else {
@@ -366,7 +378,7 @@ SchemaString.prototype.checkRequired = function checkRequired (value, doc) {
* @api private
*/
SchemaString.prototype.cast = function (value, doc, init) {
SchemaString.prototype.cast = function(value, doc, init) {
if (SchemaType._isRef(this, value, doc, init)) {
// wait! we may need to cast this to a document
@@ -426,13 +438,16 @@ SchemaString.prototype.cast = function (value, doc, init) {
* ignore
*/
function handleSingle (val) {
function handleSingle(val) {
return this.castForQuery(val);
}
function handleArray (val) {
function handleArray(val) {
var self = this;
return val.map(function (m) {
if (!Array.isArray(val)) {
return [this.castForQuery(val)];
}
return val.map(function(m) {
return self.castForQuery(m);
});
}
@@ -442,11 +457,8 @@ SchemaString.prototype.$conditionalHandlers =
'$all': handleArray,
'$gt' : handleSingle,
'$gte': handleSingle,
'$in' : handleArray,
'$lt' : handleSingle,
'$lte': handleSingle,
'$ne' : handleSingle,
'$nin': handleArray,
'$options': handleSingle,
'$regex': handleSingle
});
@@ -459,7 +471,7 @@ SchemaString.prototype.$conditionalHandlers =
* @api private
*/
SchemaString.prototype.castForQuery = function ($conditional, val) {
SchemaString.prototype.castForQuery = function($conditional, val) {
var handler;
if (arguments.length === 2) {
handler = this.$conditionalHandlers[$conditional];
@@ -468,7 +480,9 @@ SchemaString.prototype.castForQuery = function ($conditional, val) {
return handler.call(this, val);
} else {
val = $conditional;
if (val instanceof RegExp) return val;
if (Object.prototype.toString.call(val) === '[object RegExp]') {
return val;
}
return this.cast(val);
}
};

View File

@@ -17,7 +17,7 @@ var ValidatorError = error.ValidatorError;
* @api public
*/
function SchemaType (path, options, instance) {
function SchemaType(path, options, instance) {
this.path = path;
this.instance = instance;
this.validators = [];
@@ -27,17 +27,19 @@ function SchemaType (path, options, instance) {
this._index = null;
this.selected;
for (var i in options) if (this[i] && 'function' == typeof this[i]) {
// { unique: true, index: true }
if ('index' == i && this._index) continue;
for (var i in options) {
if (this[i] && 'function' == typeof this[i]) {
// { unique: true, index: true }
if ('index' == i && this._index) continue;
var opts = Array.isArray(options[i])
? options[i]
: [options[i]];
var opts = Array.isArray(options[i])
? options[i]
: [options[i]];
this[i].apply(this, opts);
this[i].apply(this, opts);
}
}
};
}
/**
* Sets a default value for this SchemaType.
@@ -82,7 +84,7 @@ function SchemaType (path, options, instance) {
* @api public
*/
SchemaType.prototype.default = function (val) {
SchemaType.prototype.default = function(val) {
if (1 === arguments.length) {
this.defaultValue = typeof val === 'function'
? val
@@ -119,7 +121,7 @@ SchemaType.prototype.default = function (val) {
* @api public
*/
SchemaType.prototype.index = function (options) {
SchemaType.prototype.index = function(options) {
this._index = options;
utils.expires(this._index);
return this;
@@ -130,7 +132,7 @@ SchemaType.prototype.index = function (options) {
*
* ####Example:
*
* var s = new Schema({ name: { type: String, unique: true })
* var s = new Schema({ name: { type: String, unique: true }});
* Schema.path('name').index({ unique: true });
*
* _NOTE: violating the constraint returns an `E11000` error from MongoDB when saving, not a Mongoose validation error._
@@ -140,7 +142,7 @@ SchemaType.prototype.index = function (options) {
* @api public
*/
SchemaType.prototype.unique = function (bool) {
SchemaType.prototype.unique = function(bool) {
if (null == this._index || 'boolean' == typeof this._index) {
this._index = {};
} else if ('string' == typeof this._index) {
@@ -187,7 +189,7 @@ SchemaType.prototype.text = function(bool) {
* @api public
*/
SchemaType.prototype.sparse = function (bool) {
SchemaType.prototype.sparse = function(bool) {
if (null == this._index || 'boolean' == typeof this._index) {
this._index = {};
} else if ('string' == typeof this._index) {
@@ -271,7 +273,7 @@ SchemaType.prototype.sparse = function (bool) {
* @api public
*/
SchemaType.prototype.set = function (fn) {
SchemaType.prototype.set = function(fn) {
if ('function' != typeof fn)
throw new TypeError('A setter must be a function.');
this.setters.push(fn);
@@ -340,7 +342,7 @@ SchemaType.prototype.set = function (fn) {
* @api public
*/
SchemaType.prototype.get = function (fn) {
SchemaType.prototype.get = function(fn) {
if ('function' != typeof fn)
throw new TypeError('A getter must be a function.');
this.getters.push(fn);
@@ -393,8 +395,17 @@ SchemaType.prototype.get = function (fn) {
* ...
* respond(false); // validation failed
* })
* }, '{PATH} failed validation.');
*
* }, '{PATH} failed validation.');
*
* // or with dynamic message
*
* schema.path('name').validate(function (value, respond) {
* doStuff(value, function () {
* ...
* respond(false, 'this message gets to the validation error');
* });
* }, 'this message does not matter');
*
* You might use asynchronous validators to retreive other documents from the database to validate against or to meet other I/O bound validation needs.
*
* Validation occurs `pre('save')` or whenever you manually execute [document#validate](#document_Document-validate).
@@ -420,7 +431,7 @@ SchemaType.prototype.get = function (fn) {
* @api public
*/
SchemaType.prototype.validate = function (obj, message, type) {
SchemaType.prototype.validate = function(obj, message, type) {
if ('function' == typeof obj || obj && 'RegExp' === utils.getFunctionName(obj.constructor)) {
var properties;
if (message instanceof Object && !type) {
@@ -439,11 +450,11 @@ SchemaType.prototype.validate = function (obj, message, type) {
return this;
}
var i
, length
, arg;
var i,
length,
arg;
for (i=0, length=arguments.length; i<length; i++) {
for (i = 0, length = arguments.length; i < length; i++) {
arg = arguments[i];
if (!(arg && 'Object' === utils.getFunctionName(arg.constructor))) {
var msg = 'Invalid validator. Received (' + typeof arg + ') '
@@ -486,9 +497,9 @@ SchemaType.prototype.validate = function (obj, message, type) {
* @api public
*/
SchemaType.prototype.required = function (required, message) {
SchemaType.prototype.required = function(required, message) {
if (false === required) {
this.validators = this.validators.filter(function (v) {
this.validators = this.validators.filter(function(v) {
return v.validator != this.requiredValidator;
}, this);
@@ -499,7 +510,7 @@ SchemaType.prototype.required = function (required, message) {
var self = this;
this.isRequired = true;
this.requiredValidator = function (v) {
this.requiredValidator = function(v) {
// in here, `this` refers to the validating document.
// no validation when this path wasn't selected in the query.
if ('isSelected' in this &&
@@ -508,7 +519,7 @@ SchemaType.prototype.required = function (required, message) {
return (('function' === typeof required) && !required.apply(this)) ||
self.checkRequired(v, this);
}
};
if ('string' == typeof required) {
message = required;
@@ -533,7 +544,7 @@ SchemaType.prototype.required = function (required, message) {
* @api private
*/
SchemaType.prototype.getDefault = function (scope, init) {
SchemaType.prototype.getDefault = function(scope, init) {
var ret = 'function' === typeof this.defaultValue
? this.defaultValue.call(scope)
: this.defaultValue;
@@ -554,11 +565,11 @@ SchemaType.prototype.getDefault = function (scope, init) {
* @api private
*/
SchemaType.prototype.applySetters = function (value, scope, init, priorVal) {
var v = value
, setters = this.setters
, len = setters.length
, caster = this.caster;
SchemaType.prototype.applySetters = function(value, scope, init, priorVal) {
var v = value,
setters = this.setters,
len = setters.length,
caster = this.caster;
while (len--) {
v = setters[len].call(scope, v, this);
@@ -588,10 +599,10 @@ SchemaType.prototype.applySetters = function (value, scope, init, priorVal) {
* @api private
*/
SchemaType.prototype.applyGetters = function (value, scope) {
var v = value
, getters = this.getters
, len = getters.length;
SchemaType.prototype.applyGetters = function(value, scope) {
var v = value,
getters = this.getters,
len = getters.length;
if (!len) {
return v;
@@ -621,8 +632,8 @@ SchemaType.prototype.applyGetters = function (value, scope) {
* @api public
*/
SchemaType.prototype.select = function select (val) {
this.selected = !! val;
SchemaType.prototype.select = function select(val) {
this.selected = !!val;
return this;
};
@@ -635,10 +646,10 @@ SchemaType.prototype.select = function select (val) {
* @api private
*/
SchemaType.prototype.doValidate = function (value, fn, scope) {
var err = false
, path = this.path
, count = this.validators.length;
SchemaType.prototype.doValidate = function(value, fn, scope) {
var err = false,
path = this.path,
count = this.validators.length;
if (!count) return fn(null);
@@ -653,7 +664,7 @@ SchemaType.prototype.doValidate = function (value, fn, scope) {
};
var self = this;
this.validators.forEach(function (v) {
this.validators.forEach(function(v) {
if (err) {
return;
}
@@ -672,7 +683,10 @@ SchemaType.prototype.doValidate = function (value, fn, scope) {
return;
}
if (2 === validator.length) {
validator.call(scope, value, function (ok) {
validator.call(scope, value, function(ok, customMsg) {
if (customMsg) {
validatorProperties.message = customMsg;
}
validate(ok, validatorProperties);
});
} else {
@@ -695,18 +709,16 @@ SchemaType.prototype.doValidate = function (value, fn, scope) {
* @api private
*/
SchemaType.prototype.doValidateSync = function (value, scope) {
var err = null
, path = this.path
, count = this.validators.length;
SchemaType.prototype.doValidateSync = function(value, scope) {
var err = null,
path = this.path,
count = this.validators.length;
if (!count) return null;
var validate = function(ok, validatorProperties) {
if (err) return;
if (ok === undefined || ok) {
} else {
if (ok !== undefined && !ok) {
err = new ValidatorError(validatorProperties);
}
};
@@ -716,11 +728,11 @@ SchemaType.prototype.doValidateSync = function (value, scope) {
return null;
}
this.validators.forEach(function (v) {
this.validators.forEach(function(v) {
if (err) {
return;
}
var validator = v.validator;
var validatorProperties = utils.clone(v);
validatorProperties.path = path;
@@ -750,7 +762,7 @@ SchemaType.prototype.doValidateSync = function (value, scope) {
* @api private
*/
SchemaType._isRef = function (self, value, doc, init) {
SchemaType._isRef = function(self, value, doc, init) {
// fast path
var ref = init && self.options && self.options.ref;
@@ -781,12 +793,55 @@ SchemaType._isRef = function (self, value, doc, init) {
*/
function handleSingle(val) {
return this.cast(val);
return this.castForQuery(val);
}
// Default conditional handlers for all schema types
/*!
* ignore
*/
function handleArray(val) {
var _this = this;
if (!Array.isArray(val)) {
return [this.castForQuery(val)];
}
return val.map(function(m) {
return _this.castForQuery(m);
});
}
/*!
* ignore
*/
SchemaType.prototype.$conditionalHandlers = {
'$eq': handleSingle
'$all': handleArray,
'$eq': handleSingle,
'$in' : handleArray,
'$ne' : handleSingle,
'$nin': handleArray
};
/**
* Cast the given value with the given optional query operator.
*
* @param {String} [$conditional] query operator, like `$eq` or `$in`
* @param {any} val
* @api private
*/
SchemaType.prototype.castForQuery = function($conditional, val) {
var handler;
if (arguments.length === 2) {
handler = this.$conditionalHandlers[$conditional];
if (!handler) {
throw new Error('Can\'t use ' + $conditional);
}
return handler.call(this, val);
} else {
val = $conditional;
return this.cast(val);
}
};
/*!

View File

@@ -7,7 +7,7 @@ var ValidationError = require('../error/validation.js');
var ObjectId = require('../types/objectid');
/**
* Applies validators and defaults to update and fineOneAndUpdate operations,
* Applies validators and defaults to update and findOneAndUpdate operations,
* specifically passing a null doc as `this` to validators and defaults
*
* @param {Query} query
@@ -24,25 +24,30 @@ module.exports = function(query, schema, castedDoc, options) {
var updatedValues = {};
var numKeys = keys.length;
var hasDollarUpdate = false;
var modified = {};
for (var i = 0; i < numKeys; ++i) {
if (keys[i].charAt(0) === '$') {
modifiedPaths(castedDoc[keys[i]], '', modified);
var flat = flatten(castedDoc[keys[i]]);
var paths = Object.keys(flat);
var numPaths = paths.length;
for (var j = 0; j < numPaths; ++j) {
var updatedPath = paths[j].replace('.$.', '.0.');
updatedPath = updatedPath.replace(/\.\$$/, '.0');
if (keys[i] === '$set' || keys[i] === '$setOnInsert') {
updatedValues[paths[j]] = flat[paths[j]];
updatedValues[updatedPath] = flat[paths[j]];
} else if (keys[i] === '$unset') {
updatedValues[paths[j]] = undefined;
updatedValues[updatedPath] = undefined;
}
updatedKeys[paths[j]] = true;
updatedKeys[updatedPath] = true;
}
hasDollarUpdate = true;
}
}
if (!hasDollarUpdate) {
modifiedPaths(castedDoc, '', modified);
updatedValues = flatten(castedDoc);
updatedKeys = Object.keys(updatedValues);
}
@@ -50,12 +55,14 @@ module.exports = function(query, schema, castedDoc, options) {
if (options && options.upsert) {
paths = Object.keys(query._conditions);
numPaths = keys.length;
for (var i = 0; i < numPaths; ++i) {
if (typeof query._conditions[paths[i]] === 'object') {
var conditionKeys = Object.keys(query._conditions[paths[i]]);
for (i = 0; i < numPaths; ++i) {
var path = paths[i];
var condition = query._conditions[path];
if (condition && typeof condition === 'object') {
var conditionKeys = Object.keys(condition);
var numConditionKeys = conditionKeys.length;
var hasDollarKey = false;
for (var j = 0; j < numConditionKeys; ++j) {
for (j = 0; j < numConditionKeys; ++j) {
if (conditionKeys[j].charAt(0) === '$') {
hasDollarKey = true;
break;
@@ -65,7 +72,8 @@ module.exports = function(query, schema, castedDoc, options) {
continue;
}
}
updatedKeys[paths[i]] = true;
updatedKeys[path] = true;
modified[path] = true;
}
if (options.setDefaultsOnInsert) {
@@ -74,11 +82,29 @@ module.exports = function(query, schema, castedDoc, options) {
// Ignore _id for now because it causes bugs in 2.4
return;
}
var def = schemaType.getDefault(null, true);
if (!updatedKeys[path] && typeof def !== 'undefined') {
castedDoc.$setOnInsert = castedDoc.$setOnInsert || {};
castedDoc.$setOnInsert[path] = def;
updatedValues[path] = def;
if (schemaType.$isSingleNested) {
// Only handle nested schemas 1-level deep to avoid infinite
// recursion re: https://github.com/mongodb-js/mongoose-autopopulate/issues/11
schemaType.schema.eachPath(function(_path, _schemaType) {
if (path === '_id') {
// Ignore _id for now because it causes bugs in 2.4
return;
}
var def = _schemaType.getDefault(null, true);
if (!modified[path + '.' + _path] && typeof def !== 'undefined') {
castedDoc.$setOnInsert = castedDoc.$setOnInsert || {};
castedDoc.$setOnInsert[path + '.' + _path] = def;
updatedValues[path + '.' + _path] = def;
}
});
} else {
var def = schemaType.getDefault(null, true);
if (!modified[path] && typeof def !== 'undefined') {
castedDoc.$setOnInsert = castedDoc.$setOnInsert || {};
castedDoc.$setOnInsert[path] = def;
updatedValues[path] = def;
}
}
});
}
@@ -88,19 +114,21 @@ module.exports = function(query, schema, castedDoc, options) {
var numUpdates = updates.length;
var validatorsToExecute = [];
var validationErrors = [];
for (var i = 0; i < numUpdates; ++i) {
for (i = 0; i < numUpdates; ++i) {
(function(i) {
if (schema.path(updates[i])) {
var schemaPath = schema._getSchema(updates[i]);
if (schemaPath) {
validatorsToExecute.push(function(callback) {
schema.path(updates[i]).doValidate(
schemaPath.doValidate(
updatedValues[updates[i]],
function(err) {
if (err) {
err.path = updates[i];
validationErrors.push(err);
}
callback(null);
},
null);
options && options.context === 'query' ? query : null);
});
}
})(i);
@@ -120,6 +148,25 @@ module.exports = function(query, schema, castedDoc, options) {
};
};
function modifiedPaths(update, path, result) {
var keys = Object.keys(update);
var numKeys = keys.length;
result = result || {};
path = path ? path + '.' : '';
for (var i = 0; i < numKeys; ++i) {
var key = keys[i];
var val = update[key];
result[path + key] = true;
if (shouldFlatten(val)) {
modifiedPaths(val, path + key, result);
}
}
return result;
}
function flatten(update, path) {
var keys = Object.keys(update);
var numKeys = keys.length;
@@ -143,5 +190,10 @@ function flatten(update, path) {
}
function shouldFlatten(val) {
return val && typeof val === 'object' && !(val instanceof ObjectId);
return val &&
typeof val === 'object' &&
!(val instanceof Date) &&
!(val instanceof ObjectId) &&
(!Array.isArray(val) || val.length > 0) &&
!(val instanceof Buffer);
}

View File

@@ -12,8 +12,8 @@ var utils = require('./utils');
* @api private
*/
var StateMachine = module.exports = exports = function StateMachine () {
}
var StateMachine = module.exports = exports = function StateMachine() {
};
/*!
* StateMachine.ctor('state1', 'state2', ...)
@@ -29,17 +29,17 @@ var StateMachine = module.exports = exports = function StateMachine () {
* @private
*/
StateMachine.ctor = function () {
StateMachine.ctor = function() {
var states = utils.args(arguments);
var ctor = function () {
var ctor = function() {
StateMachine.apply(this, arguments);
this.paths = {};
this.states = {};
this.stateNames = states;
var i = states.length
, state;
var i = states.length,
state;
while (i--) {
state = states[i];
@@ -49,11 +49,11 @@ StateMachine.ctor = function () {
ctor.prototype = new StateMachine();
states.forEach(function (state) {
states.forEach(function(state) {
// Changes the `path`'s state to `state`.
ctor.prototype[state] = function (path) {
ctor.prototype[state] = function(path) {
this._changeState(path, state);
}
};
});
return ctor;
@@ -69,29 +69,29 @@ StateMachine.ctor = function () {
* @api private
*/
StateMachine.prototype._changeState = function _changeState (path, nextState) {
StateMachine.prototype._changeState = function _changeState(path, nextState) {
var prevBucket = this.states[this.paths[path]];
if (prevBucket) delete prevBucket[path];
this.paths[path] = nextState;
this.states[nextState][path] = true;
}
};
/*!
* ignore
*/
StateMachine.prototype.clear = function clear (state) {
var keys = Object.keys(this.states[state])
, i = keys.length
, path
StateMachine.prototype.clear = function clear(state) {
var keys = Object.keys(this.states[state]),
i = keys.length,
path;
while (i--) {
path = keys[i];
delete this.states[state][path];
delete this.paths[path];
}
}
};
/*!
* Checks to see if at least one path is in the states passed in via `arguments`
@@ -101,13 +101,13 @@ StateMachine.prototype.clear = function clear (state) {
* @private
*/
StateMachine.prototype.some = function some () {
StateMachine.prototype.some = function some() {
var self = this;
var what = arguments.length ? arguments : this.stateNames;
return Array.prototype.some.call(what, function (state) {
return Array.prototype.some.call(what, function(state) {
return Object.keys(self.states[state]).length;
});
}
};
/*!
* This function builds the functions that get assigned to `forEach` and `map`,
@@ -118,25 +118,25 @@ StateMachine.prototype.some = function some () {
* @api private
*/
StateMachine.prototype._iter = function _iter (iterMethod) {
return function () {
var numArgs = arguments.length
, states = utils.args(arguments, 0, numArgs-1)
, callback = arguments[numArgs-1];
StateMachine.prototype._iter = function _iter(iterMethod) {
return function() {
var numArgs = arguments.length,
states = utils.args(arguments, 0, numArgs - 1),
callback = arguments[numArgs - 1];
if (!states.length) states = this.stateNames;
var self = this;
var paths = states.reduce(function (paths, state) {
var paths = states.reduce(function(paths, state) {
return paths.concat(Object.keys(self.states[state]));
}, []);
return paths[iterMethod](function (path, i, paths) {
return paths[iterMethod](function(path, i, paths) {
return callback(path, i, paths);
});
};
}
};
/*!
* Iterates over the paths that belong to one of the parameter states.
@@ -152,10 +152,10 @@ StateMachine.prototype._iter = function _iter (iterMethod) {
* @private
*/
StateMachine.prototype.forEach = function forEach () {
StateMachine.prototype.forEach = function forEach() {
this.forEach = this._iter('forEach');
return this.forEach.apply(this, arguments);
}
};
/*!
* Maps over the paths that belong to one of the parameter states.
@@ -172,8 +172,7 @@ StateMachine.prototype.forEach = function forEach () {
* @private
*/
StateMachine.prototype.map = function map () {
StateMachine.prototype.map = function map() {
this.map = this._iter('map');
return this.map.apply(this, arguments);
}
};

View File

@@ -23,12 +23,19 @@ var isMongooseObject = utils.isMongooseObject;
* @see http://bit.ly/f6CnZU
*/
function MongooseArray (values, path, doc) {
function MongooseArray(values, path, doc) {
var arr = [].concat(values);
utils.decorate( arr, MongooseArray.mixin );
arr.isMongooseArray = true;
var _options = { enumerable: false, configurable: true, writable: true };
var keys = Object.keys(MongooseArray.mixin).
concat(['isMongooseArray', 'validators', '_path']);
for (var i = 0; i < keys.length; ++i) {
Object.defineProperty(arr, keys[i], _options);
}
arr._atomics = {};
arr.validators = [];
arr._path = path;
@@ -76,7 +83,7 @@ MongooseArray.mixin = {
* @receiver MongooseArray
*/
_cast: function (value) {
_cast: function(value) {
var owner = this._owner;
var populated = false;
var Model;
@@ -111,10 +118,10 @@ MongooseArray.mixin = {
if (!isDisc) {
value = new Model(value);
}
return this._schema.caster.cast(value, this._parent, true)
return this._schema.caster.cast(value, this._parent, true);
}
return this._schema.caster.cast(value, this._parent, false)
return this._schema.caster.cast(value, this._parent, false);
},
/**
@@ -129,9 +136,9 @@ MongooseArray.mixin = {
* @receiver MongooseArray
*/
_markModified: function (elem, embeddedPath) {
var parent = this._parent
, dirtyPath;
_markModified: function(elem, embeddedPath) {
var parent = this._parent,
dirtyPath;
if (parent) {
dirtyPath = this._path;
@@ -145,6 +152,7 @@ MongooseArray.mixin = {
dirtyPath = dirtyPath + '.' + elem;
}
}
parent.markModified(dirtyPath);
}
@@ -161,7 +169,7 @@ MongooseArray.mixin = {
* @receiver MongooseArray
*/
_registerAtomic: function (op, val) {
_registerAtomic: function(op, val) {
if ('$set' == op) {
// $set takes precedence over all other ops.
// mark entire array modified.
@@ -174,7 +182,7 @@ MongooseArray.mixin = {
// reset pop/shift after save
if ('$pop' == op && !('$pop' in atomics)) {
var self = this;
this._parent.once('save', function () {
this._parent.once('save', function() {
self._popped = self._shifted = null;
});
}
@@ -189,13 +197,22 @@ MongooseArray.mixin = {
return this;
}
var selector;
if (op === '$pullAll' || op === '$pushAll' || op === '$addToSet') {
atomics[op] || (atomics[op] = []);
atomics[op] = atomics[op].concat(val);
} else if (op === '$pullDocs') {
var pullOp = atomics['$pull'] || (atomics['$pull'] = {})
, selector = pullOp['_id'] || (pullOp['_id'] = {'$in' : [] });
selector['$in'] = selector['$in'].concat(val);
var pullOp = atomics['$pull'] || (atomics['$pull'] = {});
if (val[0] instanceof EmbeddedDocument) {
selector = pullOp['$or'] || (pullOp['$or'] = []);
Array.prototype.push.apply(selector, val.map(function(v) {
return v.toObject({ virtuals: false });
}));
} else {
selector = pullOp['_id'] || (pullOp['_id'] = {'$in' : [] });
selector['$in'] = selector['$in'].concat(val);
}
} else {
atomics[op] = val;
}
@@ -214,7 +231,7 @@ MongooseArray.mixin = {
* @api private
*/
$__getAtomics: function () {
$__getAtomics: function() {
var ret = [];
var keys = Object.keys(this._atomics);
var i = keys.length;
@@ -240,7 +257,7 @@ MongooseArray.mixin = {
}
if ('$addToSet' == op) {
val = { $each: val }
val = { $each: val };
}
ret.push([op, val]);
@@ -258,7 +275,7 @@ MongooseArray.mixin = {
* @receiver MongooseArray
*/
hasAtomics: function hasAtomics () {
hasAtomics: function hasAtomics() {
if (!(this._atomics && 'Object' === this._atomics.constructor.name)) {
return 0;
}
@@ -287,7 +304,7 @@ MongooseArray.mixin = {
* @receiver MongooseArray
*/
push: function () {
push: function() {
var values = [].map.call(arguments, this._mapCast, this);
values = this._schema.applySetters(values, this._parent);
var ret = [].push.apply(this, values);
@@ -312,7 +329,7 @@ MongooseArray.mixin = {
* @receiver MongooseArray
*/
nonAtomicPush: function () {
nonAtomicPush: function() {
var values = [].map.call(arguments, this._mapCast, this);
var ret = [].push.apply(this, values);
this._registerAtomic('$set', this);
@@ -355,7 +372,7 @@ MongooseArray.mixin = {
* @receiver MongooseArray
*/
$pop: function () {
$pop: function() {
this._registerAtomic('$pop', 1);
this._markModified();
@@ -379,7 +396,7 @@ MongooseArray.mixin = {
* @receiver MongooseArray
*/
pop: function () {
pop: function() {
var ret = [].pop.call(this);
this._registerAtomic('$set', this);
this._markModified();
@@ -419,7 +436,7 @@ MongooseArray.mixin = {
* @see mongodb http://www.mongodb.org/display/DOCS/Updating/#Updating-%24pop
*/
$shift: function $shift () {
$shift: function $shift() {
this._registerAtomic('$pop', -1);
this._markModified();
@@ -449,7 +466,7 @@ MongooseArray.mixin = {
* @receiver MongooseArray
*/
shift: function () {
shift: function() {
var ret = [].shift.call(this);
this._registerAtomic('$set', this);
this._markModified();
@@ -457,7 +474,9 @@ MongooseArray.mixin = {
},
/**
* Pulls items from the array atomically.
* Pulls items from the array atomically. Equality is determined by casting
* the provided value to an embedded document and comparing using
* [the `Document.equals()` function.](./api.html#document_Document-equals)
*
* ####Examples:
*
@@ -483,16 +502,16 @@ MongooseArray.mixin = {
* @receiver MongooseArray
*/
pull: function () {
var values = [].map.call(arguments, this._cast, this)
, cur = this._parent.get(this._path)
, i = cur.length
, mem;
pull: function() {
var values = [].map.call(arguments, this._cast, this),
cur = this._parent.get(this._path),
i = cur.length,
mem;
while (i--) {
mem = cur[i];
if (mem instanceof EmbeddedDocument) {
if (values.some(function (v) { return v.equals(mem); } )) {
if (mem instanceof Document) {
if (values.some(function(v) { return v.equals(mem); } )) {
[].splice.call(cur, i, 1);
}
} else if (~cur.indexOf.call(values, mem)) {
@@ -501,7 +520,9 @@ MongooseArray.mixin = {
}
if (values[0] instanceof EmbeddedDocument) {
this._registerAtomic('$pullDocs', values.map( function (v) { return v._id; } ));
this._registerAtomic('$pullDocs', values.map(function(v) {
return v._id || v;
}));
} else {
this._registerAtomic('$pullAll', values);
}
@@ -522,7 +543,7 @@ MongooseArray.mixin = {
* @receiver MongooseArray
*/
splice: function splice () {
splice: function splice() {
var ret, vals, i;
if (arguments.length) {
@@ -552,7 +573,7 @@ MongooseArray.mixin = {
* @receiver MongooseArray
*/
unshift: function () {
unshift: function() {
var values = [].map.call(arguments, this._cast, this);
values = this._schema.applySetters(values, this._parent);
[].unshift.apply(this, values);
@@ -573,7 +594,7 @@ MongooseArray.mixin = {
* @receiver MongooseArray
*/
sort: function () {
sort: function() {
var ret = [].sort.apply(this, arguments);
this._registerAtomic('$set', this);
this._markModified();
@@ -597,7 +618,7 @@ MongooseArray.mixin = {
* @method addToSet
*/
addToSet: function addToSet () {
addToSet: function addToSet() {
var values = [].map.call(arguments, this._mapCast, this);
values = this._schema.applySetters(values, this._parent);
var added = [];
@@ -605,15 +626,15 @@ MongooseArray.mixin = {
values[0] instanceof Date ? 'date' :
'';
values.forEach(function (v) {
values.forEach(function(v) {
var found;
switch (type) {
case 'doc':
found = this.some(function(doc){ return doc.equals(v) });
found = this.some(function(doc) { return doc.equals(v); });
break;
case 'date':
var val = +v;
found = this.some(function(d){ return +d === val });
found = this.some(function(d) { return +d === val; });
break;
default:
found = ~this.indexOf(v);
@@ -657,7 +678,7 @@ MongooseArray.mixin = {
* @receiver MongooseArray
*/
set: function set (i, val) {
set: function set(i, val) {
var value = this._cast(val, i);
value = this._schema.caster instanceof EmbeddedDocument ?
value :
@@ -678,12 +699,12 @@ MongooseArray.mixin = {
* @receiver MongooseArray
*/
toObject: function (options) {
toObject: function(options) {
if (options && options.depopulate) {
return this.map(function (doc) {
return this.map(function(doc) {
return doc instanceof Document
? doc.toObject(options)
: doc
: doc;
});
}
@@ -698,7 +719,7 @@ MongooseArray.mixin = {
* @receiver MongooseArray
*/
inspect: function () {
inspect: function() {
return JSON.stringify(this);
},
@@ -712,11 +733,12 @@ MongooseArray.mixin = {
* @receiver MongooseArray
*/
indexOf: function indexOf (obj) {
indexOf: function indexOf(obj) {
if (obj instanceof ObjectId) obj = obj.toString();
for (var i = 0, len = this.length; i < len; ++i) {
if (obj == this[i])
if (obj == this[i]) {
return i;
}
}
return -1;
}

View File

@@ -2,8 +2,8 @@
* Module dependencies.
*/
var Binary = require('../drivers').Binary
, utils = require('../utils');
var Binary = require('../drivers').Binary,
utils = require('../utils');
/**
* Mongoose Buffer constructor.
@@ -18,7 +18,7 @@ var Binary = require('../drivers').Binary
* @see http://bit.ly/f6CnZU
*/
function MongooseBuffer (value, encode, offset) {
function MongooseBuffer(value, encode, offset) {
var length = arguments.length;
var val;
@@ -46,14 +46,14 @@ function MongooseBuffer (value, encode, offset) {
// make sure these internal props don't show up in Object.keys()
Object.defineProperties(buf, {
validators: { value: [] }
, _path: { value: path }
, _parent: { value: doc }
validators: { value: [] },
_path: { value: path },
_parent: { value: doc }
});
if (doc && "string" === typeof path) {
Object.defineProperty(buf, '_schema', {
value: doc.schema.path(path)
value: doc.schema.path(path)
});
}
@@ -97,7 +97,7 @@ MongooseBuffer.mixin = {
* @receiver MongooseBuffer
*/
_markModified: function () {
_markModified: function() {
var parent = this._parent;
if (parent) {
@@ -114,7 +114,7 @@ MongooseBuffer.mixin = {
* @receiver MongooseBuffer
*/
write: function () {
write: function() {
var written = Buffer.prototype.write.apply(this, arguments);
if (written > 0) {
@@ -137,7 +137,7 @@ MongooseBuffer.mixin = {
* @receiver MongooseBuffer
*/
copy: function (target) {
copy: function(target) {
var ret = Buffer.prototype.copy.apply(this, arguments);
if (target && target.isMongooseBuffer) {
@@ -152,7 +152,7 @@ MongooseBuffer.mixin = {
* Compile other Buffer methods marking this buffer as modified.
*/
;(
(
// node < 0.5
'writeUInt8 writeUInt16 writeUInt32 writeInt8 writeInt16 writeInt32 ' +
'writeFloat writeDouble fill ' +
@@ -162,13 +162,13 @@ MongooseBuffer.mixin = {
'writeUInt16LE writeUInt16BE writeUInt32LE writeUInt32BE ' +
'writeInt16LE writeInt16BE writeInt32LE writeInt32BE ' +
'writeFloatLE writeFloatBE writeDoubleLE writeDoubleBE'
).split(' ').forEach(function (method) {
).split(' ').forEach(function(method) {
if (!Buffer.prototype[method]) return;
MongooseBuffer.mixin[method] = new Function(
'var ret = Buffer.prototype.'+method+'.apply(this, arguments);' +
'var ret = Buffer.prototype.' + method + '.apply(this, arguments);' +
'this._markModified();' +
'return ret;'
)
);
});
/**
@@ -194,7 +194,7 @@ MongooseBuffer.mixin = {
* @receiver MongooseBuffer
*/
MongooseBuffer.mixin.toObject = function (options) {
MongooseBuffer.mixin.toObject = function(options) {
var subtype = 'number' == typeof options
? options
: (this._subtype || 0);
@@ -210,7 +210,7 @@ MongooseBuffer.mixin.toObject = function (options) {
* @receiver MongooseBuffer
*/
MongooseBuffer.mixin.equals = function (other) {
MongooseBuffer.mixin.equals = function(other) {
if (!Buffer.isBuffer(other)) {
return false;
}
@@ -248,7 +248,7 @@ MongooseBuffer.mixin.equals = function (other) {
* @receiver MongooseBuffer
*/
MongooseBuffer.mixin.subtype = function (subtype) {
MongooseBuffer.mixin.subtype = function(subtype) {
if ('number' != typeof subtype) {
throw new TypeError('Invalid subtype. Expected a number');
}

View File

@@ -2,12 +2,12 @@
* Module dependencies.
*/
var MongooseArray = require('./array')
, ObjectId = require('./objectid')
, ObjectIdSchema = require('../schema/objectid')
, utils = require('../utils')
, util = require('util')
, Document = require('../document')
var MongooseArray = require('./array'),
ObjectId = require('./objectid'),
ObjectIdSchema = require('../schema/objectid'),
utils = require('../utils'),
util = require('util'),
Document = require('../document');
/**
* DocumentArray constructor
@@ -21,7 +21,7 @@ var MongooseArray = require('./array')
* @see http://bit.ly/f6CnZU
*/
function MongooseDocumentArray (values, path, doc) {
function MongooseDocumentArray(values, path, doc) {
var arr = [].concat(values);
// Values always have to be passed to the constructor to initialize, since
@@ -66,7 +66,7 @@ MongooseDocumentArray.mixin = Object.create( MongooseArray.mixin );
* @receiver MongooseDocumentArray
*/
MongooseDocumentArray.mixin._cast = function (value, index) {
MongooseDocumentArray.mixin._cast = function(value, index) {
if (value instanceof this._schema.casterConstructor) {
if (!(value.__parent && value.__parentArray)) {
// value may have been created using array.create()
@@ -102,10 +102,10 @@ MongooseDocumentArray.mixin._cast = function (value, index) {
* @receiver MongooseDocumentArray
*/
MongooseDocumentArray.mixin.id = function (id) {
var casted
, sid
, _id
MongooseDocumentArray.mixin.id = function(id) {
var casted,
sid,
_id;
try {
var casted_ = ObjectIdSchema.prototype.cast.call({}, id);
@@ -117,12 +117,13 @@ MongooseDocumentArray.mixin.id = function (id) {
for (var i = 0, l = this.length; i < l; i++) {
_id = this[i].get('_id');
if (_id instanceof Document) {
if (_id === null || typeof _id === 'undefined') {
continue;
} else if (_id instanceof Document) {
sid || (sid = String(id));
if (sid == _id._id) return this[i];
} else if (!(_id instanceof ObjectId)) {
sid || (sid = String(id));
if (sid == _id) return this[i];
if (utils.deepEqual(id, _id)) return this[i];
} else if (casted == _id) {
return this[i];
}
@@ -145,8 +146,8 @@ MongooseDocumentArray.mixin.id = function (id) {
* @receiver MongooseDocumentArray
*/
MongooseDocumentArray.mixin.toObject = function (options) {
return this.map(function (doc) {
MongooseDocumentArray.mixin.toObject = function(options) {
return this.map(function(doc) {
return doc && doc.toObject(options) || null;
});
};
@@ -159,14 +160,14 @@ MongooseDocumentArray.mixin.toObject = function (options) {
* @receiver MongooseDocumentArray
*/
MongooseDocumentArray.mixin.inspect = function () {
return '[' + Array.prototype.map.call(this, function (doc) {
MongooseDocumentArray.mixin.inspect = function() {
return '[' + Array.prototype.map.call(this, function(doc) {
if (doc) {
return doc.inspect
? doc.inspect()
: util.inspect(doc)
: util.inspect(doc);
}
return 'null'
return 'null';
}).join('\n') + ']';
};
@@ -181,9 +182,9 @@ MongooseDocumentArray.mixin.inspect = function () {
* @receiver MongooseDocumentArray
*/
MongooseDocumentArray.mixin.create = function (obj) {
MongooseDocumentArray.mixin.create = function(obj) {
return new this._schema.casterConstructor(obj);
}
};
/**
* Creates a fn that notifies all child docs of `event`.
@@ -195,13 +196,13 @@ MongooseDocumentArray.mixin.create = function (obj) {
* @receiver MongooseDocumentArray
*/
MongooseDocumentArray.mixin.notify = function notify (event) {
MongooseDocumentArray.mixin.notify = function notify(event) {
var self = this;
return function notify (val) {
return function notify(val) {
var i = self.length;
while (i--) {
if (!self[i]) continue;
switch(event) {
switch (event) {
// only swap for save event for now, we may change this to all event types later
case 'save':
val = self[i];
@@ -212,8 +213,8 @@ MongooseDocumentArray.mixin.notify = function notify (event) {
}
self[i].emit(event, val);
}
}
}
};
};
/*!
* Module exports.

View File

@@ -1,10 +1,12 @@
/* eslint no-func-assign: 1 */
/*!
* Module dependencies.
*/
var Document = require('../document_provider')();
var inspect = require('util').inspect;
var Promise = require('../promise');
var PromiseProvider = require('../promise_provider');
/**
* EmbeddedDocument constructor.
@@ -16,7 +18,7 @@ var Promise = require('../promise');
* @api private
*/
function EmbeddedDocument (obj, parentArr, skipId, fields, index) {
function EmbeddedDocument(obj, parentArr, skipId, fields, index) {
if (parentArr) {
this.__parentArray = parentArr;
this.__parent = parentArr._parent;
@@ -29,7 +31,7 @@ function EmbeddedDocument (obj, parentArr, skipId, fields, index) {
Document.call(this, obj, fields, skipId);
var self = this;
this.on('isNew', function (val) {
this.on('isNew', function(val) {
self.isNew = val;
});
}
@@ -54,10 +56,10 @@ EmbeddedDocument.prototype.constructor = EmbeddedDocument;
* @receiver EmbeddedDocument
*/
EmbeddedDocument.prototype.markModified = function (path) {
EmbeddedDocument.prototype.markModified = function(path) {
this.$__.activePaths.modify(path);
if (!this.__parentArray) return;
this.$__.activePaths.modify(path);
if (this.isNew) {
// Mark the WHOLE parent array as modified
// if this is a new document (i.e., we are initializing
@@ -80,11 +82,13 @@ EmbeddedDocument.prototype.markModified = function (path) {
* @api private
*/
EmbeddedDocument.prototype.save = function (fn) {
var promise = new Promise(fn);
promise.fulfill();
return promise;
}
EmbeddedDocument.prototype.save = function(fn) {
var Promise = PromiseProvider.get();
return new Promise.ES6(function(resolve) {
fn && fn();
resolve();
});
};
/**
* Removes the subdocument from its parent array.
@@ -93,7 +97,7 @@ EmbeddedDocument.prototype.save = function (fn) {
* @api public
*/
EmbeddedDocument.prototype.remove = function (fn) {
EmbeddedDocument.prototype.remove = function(fn) {
if (!this.__parentArray) return this;
var _id;
@@ -122,28 +126,28 @@ EmbeddedDocument.prototype.remove = function (fn) {
* @api private
*/
function registerRemoveListener (sub) {
function registerRemoveListener(sub) {
var owner = sub.ownerDocument();
owner.on('save', emitRemove);
owner.on('remove', emitRemove);
function emitRemove () {
function emitRemove() {
owner.removeListener('save', emitRemove);
owner.removeListener('remove', emitRemove);
sub.emit('remove', sub);
owner = sub = emitRemove = null;
};
};
}
}
/**
* Override #update method of parent documents.
* @api private
*/
EmbeddedDocument.prototype.update = function () {
EmbeddedDocument.prototype.update = function() {
throw new Error('The #update method is not available on EmbeddedDocuments');
}
};
/**
* Helper for console.log
@@ -151,7 +155,7 @@ EmbeddedDocument.prototype.update = function () {
* @api public
*/
EmbeddedDocument.prototype.inspect = function () {
EmbeddedDocument.prototype.inspect = function() {
return inspect(this.toObject());
};
@@ -164,9 +168,9 @@ EmbeddedDocument.prototype.inspect = function () {
* @api public
*/
EmbeddedDocument.prototype.invalidate = function (path, err, val, first) {
EmbeddedDocument.prototype.invalidate = function(path, err, val, first) {
if (!this.__parent) {
var msg = 'Unable to invalidate a subdocument that has not been added to an array.'
var msg = 'Unable to invalidate a subdocument that has not been added to an array.';
throw new Error(msg);
}
@@ -218,8 +222,6 @@ EmbeddedDocument.prototype.$markValid = function(path) {
EmbeddedDocument.prototype.$isValid = function(path) {
var index = this.__index;
if (typeof index !== 'undefined') {
var parentPath = this.__parentArray._path;
var fullPath = [parentPath, index, path].join('.');
return !this.__parent.$__.validationError ||
!this.__parent.$__.validationError.errors[path];
@@ -234,7 +236,7 @@ EmbeddedDocument.prototype.$isValid = function(path) {
* @return {Document}
*/
EmbeddedDocument.prototype.ownerDocument = function () {
EmbeddedDocument.prototype.ownerDocument = function() {
if (this.$__.ownerDocument) {
return this.$__.ownerDocument;
}
@@ -247,7 +249,7 @@ EmbeddedDocument.prototype.ownerDocument = function () {
}
return this.$__.ownerDocument = parent;
}
};
/**
* Returns the full path to this document. If optional `path` is passed, it is appended to the full path.
@@ -259,7 +261,7 @@ EmbeddedDocument.prototype.ownerDocument = function () {
* @memberOf EmbeddedDocument
*/
EmbeddedDocument.prototype.$__fullPath = function (path) {
EmbeddedDocument.prototype.$__fullPath = function(path) {
if (!this.$__.fullPath) {
var parent = this;
if (!parent.__parent) return path;
@@ -281,7 +283,7 @@ EmbeddedDocument.prototype.$__fullPath = function (path) {
return path
? this.$__.fullPath + '.' + path
: this.$__.fullPath;
}
};
/**
* Returns this sub-documents parent document.
@@ -289,9 +291,9 @@ EmbeddedDocument.prototype.$__fullPath = function (path) {
* @api public
*/
EmbeddedDocument.prototype.parent = function () {
EmbeddedDocument.prototype.parent = function() {
return this.__parent;
}
};
/**
* Returns this sub-documents parent array.
@@ -299,9 +301,9 @@ EmbeddedDocument.prototype.parent = function () {
* @api public
*/
EmbeddedDocument.prototype.parentArray = function () {
EmbeddedDocument.prototype.parentArray = function() {
return this.__parentArray;
}
};
/*!
* Module exports.

View File

@@ -11,3 +11,5 @@ exports.Embedded = require('./embedded');
exports.DocumentArray = require('./documentarray');
exports.ObjectId = require('./objectid');
exports.Subdocument = require('./subdocument');

87
node_modules/mongoose/lib/types/subdocument.js generated vendored Normal file
View File

@@ -0,0 +1,87 @@
var Document = require('../document');
var PromiseProvider = require('../promise_provider');
module.exports = Subdocument;
/**
* Subdocument constructor.
*
* @inherits Document
* @api private
*/
function Subdocument() {
Document.apply(this, arguments);
this.$isSingleNested = true;
}
Subdocument.prototype = Object.create(Document.prototype);
/**
* Used as a stub for [hooks.js](https://github.com/bnoguchi/hooks-js/tree/31ec571cef0332e21121ee7157e0cf9728572cc3)
*
* ####NOTE:
*
* _This is a no-op. Does not actually save the doc to the db._
*
* @param {Function} [fn]
* @return {Promise} resolved Promise
* @api private
*/
Subdocument.prototype.save = function(fn) {
var Promise = PromiseProvider.get();
return new Promise.ES6(function(resolve) {
fn && fn();
resolve();
});
};
Subdocument.prototype.$isValid = function(path) {
if (this.$parent) {
return this.$parent.$isValid([this.$basePath, path].join('.'));
}
};
Subdocument.prototype.markModified = function(path) {
if (this.$parent) {
this.$parent.markModified([this.$basePath, path].join('.'));
}
};
Subdocument.prototype.$markValid = function(path) {
if (this.$parent) {
this.$parent.$markValid([this.$basePath, path].join('.'));
}
};
Subdocument.prototype.invalidate = function(path, err, val) {
if (this.$parent) {
this.$parent.invalidate([this.$basePath, path].join('.'), err, val);
} else if (err.kind === 'cast' || err.name === 'CastError') {
throw err;
}
};
/**
* Returns the top level document of this sub-document.
*
* @return {Document}
*/
Subdocument.prototype.ownerDocument = function() {
if (this.$__.ownerDocument) {
return this.$__.ownerDocument;
}
var parent = this.$parent;
if (!parent) {
return this;
}
while (parent.$parent) {
parent = parent.$parent;
}
return this.$__.ownerDocument = parent;
};

183
node_modules/mongoose/lib/utils.js generated vendored
View File

@@ -19,7 +19,7 @@ var Document;
* @api private
*/
exports.toCollectionName = function (name, options) {
exports.toCollectionName = function(name, options) {
options = options || {};
if ('system.profile' === name) return name;
if ('system.indexes' === name) return name;
@@ -107,16 +107,16 @@ var uncountables = exports.uncountables;
* @api private
*/
function pluralize (str) {
var rule, found;
if (!~uncountables.indexOf(str.toLowerCase())){
found = rules.filter(function(rule){
function pluralize(str) {
var found;
if (!~uncountables.indexOf(str.toLowerCase())) {
found = rules.filter(function(rule) {
return str.match(rule[0]);
});
if (found[0]) return str.replace(found[0][0], found[0][1]);
}
return str;
};
}
/*!
* Determines if `a` and `b` are deep equal.
@@ -129,7 +129,7 @@ function pluralize (str) {
* @api private
*/
exports.deepEqual = function deepEqual (a, b) {
exports.deepEqual = function deepEqual(a, b) {
if (a === b) return true;
if (a instanceof Date && b instanceof Date)
@@ -150,7 +150,7 @@ exports.deepEqual = function deepEqual (a, b) {
return a == b;
if (a === null || b === null || a === undefined || b === undefined)
return false
return false;
if (a.prototype !== b.prototype) return false;
@@ -212,7 +212,7 @@ exports.deepEqual = function deepEqual (a, b) {
* @api private
*/
exports.clone = function clone (obj, options) {
exports.clone = function clone(obj, options) {
if (obj === undefined || obj === null)
return obj;
@@ -258,15 +258,15 @@ var clone = exports.clone;
* ignore
*/
function cloneObject (obj, options) {
var retainKeyOrder = options && options.retainKeyOrder
, minimize = options && options.minimize
, ret = {}
, hasKeys
, keys
, val
, k
, i
function cloneObject(obj, options) {
var retainKeyOrder = options && options.retainKeyOrder,
minimize = options && options.minimize,
ret = {},
hasKeys,
keys,
val,
k,
i;
if (retainKeyOrder) {
for (k in obj) {
@@ -297,14 +297,14 @@ function cloneObject (obj, options) {
return minimize
? hasKeys && ret
: ret;
};
}
function cloneArray (arr, options) {
function cloneArray(arr, options) {
var ret = [];
for (var i = 0, l = arr.length; i < l; i++)
ret.push(clone(arr[i], options));
return ret;
};
}
/*!
* Shallow copies defaults into options.
@@ -315,10 +315,10 @@ function cloneArray (arr, options) {
* @api private
*/
exports.options = function (defaults, options) {
var keys = Object.keys(defaults)
, i = keys.length
, k ;
exports.options = function(defaults, options) {
var keys = Object.keys(defaults),
i = keys.length,
k;
options = options || {};
@@ -338,7 +338,7 @@ exports.options = function (defaults, options) {
* @api private
*/
exports.random = function () {
exports.random = function() {
return Math.random().toString().substr(3);
};
@@ -350,10 +350,10 @@ exports.random = function () {
* @api private
*/
exports.merge = function merge (to, from) {
var keys = Object.keys(from)
, i = keys.length
, key;
exports.merge = function merge(to, from) {
var keys = Object.keys(from),
i = keys.length,
key;
while (i--) {
key = keys[i];
@@ -371,6 +371,49 @@ exports.merge = function merge (to, from) {
var toString = Object.prototype.toString;
/*!
* Applies toObject recursively.
*
* @param {Document|Array|Object} obj
* @return {Object}
* @api private
*/
exports.toObject = function toObject(obj) {
var ret;
if (exports.isNullOrUndefined(obj)) {
return obj;
}
if (obj instanceof Document) {
return obj.toObject();
}
if (Array.isArray(obj)) {
ret = [];
for (var i = 0, len = obj.length; i < len; ++i) {
ret.push(toObject(obj[i]));
}
return ret;
}
if ((obj.constructor && exports.getFunctionName(obj.constructor) === 'Object') ||
(!obj.constructor && exports.isObject(obj))) {
ret = {};
for (var k in obj) {
ret[k] = toObject(obj[k]);
}
return ret;
}
return obj;
};
/*!
* Determines if `arg` is an object.
*
@@ -379,9 +422,12 @@ var toString = Object.prototype.toString;
* @return {Boolean}
*/
exports.isObject = function (arg) {
exports.isObject = function(arg) {
if (Buffer.isBuffer(arg)) {
return true;
}
return '[object Object]' == toString.call(arg);
}
};
/*!
* A faster Array.prototype.slice.call(arguments) alternative
@@ -401,20 +447,20 @@ exports.args = sliced;
* @api private
*/
exports.tick = function tick (callback) {
exports.tick = function tick(callback) {
if ('function' !== typeof callback) return;
return function () {
return function() {
try {
callback.apply(this, arguments);
} catch (err) {
// only nextTick on err to get out of
// the event loop and avoid state corruption.
process.nextTick(function () {
process.nextTick(function() {
throw err;
});
}
}
}
};
};
/*!
* Returns if `v` is a mongoose object that has a `toObject()` method we can use.
@@ -425,7 +471,7 @@ exports.tick = function tick (callback) {
* @api private
*/
exports.isMongooseObject = function (v) {
exports.isMongooseObject = function(v) {
Document || (Document = require('./document'));
MongooseArray || (MongooseArray = require('./types').Array);
MongooseBuffer || (MongooseBuffer = require('./types').Buffer);
@@ -443,7 +489,7 @@ var isMongooseObject = exports.isMongooseObject;
* @api private
*/
exports.expires = function expires (object) {
exports.expires = function expires(object) {
if (!(object && 'Object' == object.constructor.name)) return;
if (!('expires' in object)) return;
@@ -461,12 +507,15 @@ exports.expires = function expires (object) {
* Populate options constructor
*/
function PopulateOptions (path, select, match, options, model) {
function PopulateOptions(path, select, match, options, model, subPopulate) {
this.path = path;
this.match = match;
this.select = select;
this.options = options;
this.model = model;
if (typeof subPopulate === 'object') {
this.populate = subPopulate;
}
this._docs = {};
}
@@ -480,7 +529,7 @@ exports.PopulateOptions = PopulateOptions;
* populate helper
*/
exports.populate = function populate (path, select, model, match, options) {
exports.populate = function populate(path, select, model, match, options, subPopulate) {
// The order of select/conditions args is opposite Model.find but
// necessary to keep backward compatibility (select could be
// an array, string, or object literal).
@@ -492,7 +541,7 @@ exports.populate = function populate (path, select, model, match, options) {
}
if (Array.isArray(path)) {
return path.map(function(o){
return path.map(function(o) {
return exports.populate(o)[0];
});
}
@@ -502,6 +551,7 @@ exports.populate = function populate (path, select, model, match, options) {
options = path.options;
select = path.select;
model = path.model;
subPopulate = path.populate;
path = path.path;
}
} else if ('string' !== typeof model && 'function' !== typeof model) {
@@ -514,14 +564,18 @@ exports.populate = function populate (path, select, model, match, options) {
throw new TypeError('utils.populate: invalid path. Expected string. Got typeof `' + typeof path + '`');
}
if (typeof subPopulate === 'object') {
subPopulate = exports.populate(subPopulate);
}
var ret = [];
var paths = path.split(' ');
for (var i = 0; i < paths.length; ++i) {
ret.push(new PopulateOptions(paths[i], select, match, options, model));
ret.push(new PopulateOptions(paths[i], select, match, options, model, subPopulate));
}
return ret;
}
};
/*!
* Return the value of `obj` at the given `path`.
@@ -530,9 +584,9 @@ exports.populate = function populate (path, select, model, match, options) {
* @param {Object} obj
*/
exports.getValue = function (path, obj, map) {
exports.getValue = function(path, obj, map) {
return mpath.get(path, obj, '_doc', map);
}
};
/*!
* Sets the value of `obj` at the given `path`.
@@ -542,9 +596,9 @@ exports.getValue = function (path, obj, map) {
* @param {Object} obj
*/
exports.setValue = function (path, val, obj, map) {
exports.setValue = function(path, val, obj, map) {
mpath.set(path, val, obj, '_doc', map);
}
};
/*!
* Returns an array of values from object `o`.
@@ -555,17 +609,17 @@ exports.setValue = function (path, val, obj, map) {
*/
exports.object = {};
exports.object.vals = function vals (o) {
var keys = Object.keys(o)
, i = keys.length
, ret = [];
exports.object.vals = function vals(o) {
var keys = Object.keys(o),
i = keys.length,
ret = [];
while (i--) {
ret.push(o[keys[i]]);
}
return ret;
}
};
/*!
* @see exports.options
@@ -581,9 +635,9 @@ exports.object.shallowCopy = exports.options;
*/
var hop = Object.prototype.hasOwnProperty;
exports.object.hasOwnProperty = function (obj, prop) {
exports.object.hasOwnProperty = function(obj, prop) {
return hop.call(obj, prop);
}
};
/*!
* Determine if `val` is null or undefined
@@ -591,9 +645,9 @@ exports.object.hasOwnProperty = function (obj, prop) {
* @return {Boolean}
*/
exports.isNullOrUndefined = function (val) {
return null == val
}
exports.isNullOrUndefined = function(val) {
return null == val;
};
/*!
* ignore
@@ -612,10 +666,10 @@ exports.array = {};
* @private
*/
exports.array.flatten = function flatten (arr, filter, ret) {
exports.array.flatten = function flatten(arr, filter, ret) {
ret || (ret = []);
arr.forEach(function (item) {
arr.forEach(function(item) {
if (Array.isArray(item)) {
flatten(item, filter, ret);
} else {
@@ -674,7 +728,7 @@ exports.array.unique = function(arr) {
*/
exports.buffer = {};
exports.buffer.areEqual = function (a, b) {
exports.buffer.areEqual = function(a, b) {
if (!Buffer.isBuffer(a)) return false;
if (!Buffer.isBuffer(b)) return false;
if (a.length !== b.length) return false;
@@ -706,9 +760,9 @@ exports.decorate = function(destination, source) {
*/
exports.mergeClone = function(to, from) {
var keys = Object.keys(from)
, i = keys.length
, key
var keys = Object.keys(from),
i = keys.length,
key;
while (i--) {
key = keys[i];
@@ -741,4 +795,3 @@ exports.each = function(arr, fn) {
fn(arr[i]);
}
};

View File

@@ -13,7 +13,7 @@
* @api public
*/
function VirtualType (options, name) {
function VirtualType(options, name) {
this.path = name;
this.getters = [];
this.setters = [];
@@ -35,7 +35,7 @@ function VirtualType (options, name) {
* @api public
*/
VirtualType.prototype.get = function (fn) {
VirtualType.prototype.get = function(fn) {
this.getters.push(fn);
return this;
};
@@ -57,7 +57,7 @@ VirtualType.prototype.get = function (fn) {
* @api public
*/
VirtualType.prototype.set = function (fn) {
VirtualType.prototype.set = function(fn) {
this.setters.push(fn);
return this;
};
@@ -71,7 +71,7 @@ VirtualType.prototype.set = function (fn) {
* @api public
*/
VirtualType.prototype.applyGetters = function (value, scope) {
VirtualType.prototype.applyGetters = function(value, scope) {
var v = value;
for (var l = this.getters.length - 1; l >= 0; l--) {
v = this.getters[l].call(scope, v, this);
@@ -88,7 +88,7 @@ VirtualType.prototype.applyGetters = function (value, scope) {
* @api public
*/
VirtualType.prototype.applySetters = function (value, scope) {
VirtualType.prototype.applySetters = function(value, scope) {
var v = value;
for (var l = this.setters.length - 1; l >= 0; l--) {
v = this.setters[l].call(scope, v, this);

View File

@@ -1,59 +1,86 @@
{
"name": "async",
"description": "Higher-order functions and common patterns for asynchronous code",
"main": "./lib/async",
"_args": [
[
"async@0.9.0",
"/home/mitchell/Desktop/test-mywebsite/mywebsite/node_modules/mongoose"
]
],
"_from": "async@0.9.0",
"_id": "async@0.9.0",
"_inCache": true,
"_installable": true,
"_location": "/mongoose/async",
"_npmUser": {
"email": "caolan.mcmahon@gmail.com",
"name": "caolan"
},
"_npmVersion": "1.4.3",
"_phantomChildren": {},
"_requested": {
"name": "async",
"raw": "async@0.9.0",
"rawSpec": "0.9.0",
"scope": null,
"spec": "0.9.0",
"type": "version"
},
"_requiredBy": [
"/mongoose"
],
"_resolved": "https://registry.npmjs.org/async/-/async-0.9.0.tgz",
"_shasum": "ac3613b1da9bed1b47510bb4651b8931e47146c7",
"_shrinkwrap": null,
"_spec": "async@0.9.0",
"_where": "/home/mitchell/Desktop/test-mywebsite/mywebsite/node_modules/mongoose",
"author": {
"name": "Caolan McMahon"
},
"version": "0.9.0",
"repository": {
"type": "git",
"url": "https://github.com/caolan/async.git"
},
"bugs": {
"url": "https://github.com/caolan/async/issues"
},
"dependencies": {},
"description": "Higher-order functions and common patterns for asynchronous code",
"devDependencies": {
"nodelint": ">0.0.0",
"nodeunit": ">0.0.0",
"uglify-js": "1.2.x"
},
"directories": {},
"dist": {
"shasum": "ac3613b1da9bed1b47510bb4651b8931e47146c7",
"tarball": "http://registry.npmjs.org/async/-/async-0.9.0.tgz"
},
"homepage": "https://github.com/caolan/async",
"jam": {
"include": [
"LICENSE",
"README.md",
"lib/async.js"
],
"main": "lib/async.js"
},
"licenses": [
{
"type": "MIT",
"url": "https://github.com/caolan/async/raw/master/LICENSE"
}
],
"devDependencies": {
"nodeunit": ">0.0.0",
"uglify-js": "1.2.x",
"nodelint": ">0.0.0"
},
"jam": {
"main": "lib/async.js",
"include": [
"lib/async.js",
"README.md",
"LICENSE"
]
},
"scripts": {
"test": "nodeunit test/test-async.js"
},
"homepage": "https://github.com/caolan/async",
"_id": "async@0.9.0",
"dist": {
"shasum": "ac3613b1da9bed1b47510bb4651b8931e47146c7",
"tarball": "http://registry.npmjs.org/async/-/async-0.9.0.tgz"
},
"_from": "async@0.9.0",
"_npmVersion": "1.4.3",
"_npmUser": {
"name": "caolan",
"email": "caolan.mcmahon@gmail.com"
},
"main": "./lib/async",
"maintainers": [
{
"name": "caolan",
"email": "caolan@caolanmcmahon.com"
}
],
"directories": {},
"_shasum": "ac3613b1da9bed1b47510bb4651b8931e47146c7",
"_resolved": "https://registry.npmjs.org/async/-/async-0.9.0.tgz"
"name": "async",
"optionalDependencies": {},
"readme": "ERROR: No README data found!",
"repository": {
"type": "git",
"url": "git+https://github.com/caolan/async.git"
},
"scripts": {
"test": "nodeunit test/test-async.js"
},
"version": "0.9.0"
}

View File

@@ -1,4 +0,0 @@
language: node_js
node_js:
- 0.10 # development version of 0.8, may be unstable
- 0.12

View File

@@ -1,3 +1,87 @@
0.4.19 2015-10-15
-----------------
- Remove all support for bson-ext.
0.4.18 2015-10-15
-----------------
- ObjectID equality check should return boolean instead of throwing exception for invalid oid string #139
- add option for deserializing binary into Buffer object #116
0.4.17 2015-10-15
-----------------
- Validate regexp string for null bytes and throw if there is one.
0.4.16 2015-10-07
-----------------
- Fixed issue with return statement in Map.js.
0.4.15 2015-10-06
-----------------
- Exposed Map correctly via index.js file.
0.4.14 2015-10-06
-----------------
- Exposed Map correctly via bson.js file.
0.4.13 2015-10-06
-----------------
- Added ES6 Map type serialization as well as a polyfill for ES5.
0.4.12 2015-09-18
-----------------
- Made ignore undefined an optional parameter.
0.4.11 2015-08-06
-----------------
- Minor fix for invalid key checking.
0.4.10 2015-08-06
-----------------
- NODE-38 Added new BSONRegExp type to allow direct serialization to MongoDB type.
- Some performance improvements by in lining code.
0.4.9 2015-08-06
----------------
- Undefined fields are omitted from serialization in objects.
0.4.8 2015-07-14
----------------
- Fixed size validation to ensure we can deserialize from dumped files.
0.4.7 2015-06-26
----------------
- Added ability to instruct deserializer to return raw BSON buffers for named array fields.
- Minor deserialization optimization by moving inlined function out.
0.4.6 2015-06-17
----------------
- Fixed serializeWithBufferAndIndex bug.
0.4.5 2015-06-17
----------------
- Removed any references to the shared buffer to avoid non GC collectible bson instances.
0.4.4 2015-06-17
----------------
- Fixed rethrowing of error when not RangeError.
0.4.3 2015-06-17
----------------
- Start buffer at 64K and double as needed, meaning we keep a low memory profile until needed.
0.4.2 2015-06-16
----------------
- More fixes for corrupt Bson
0.4.1 2015-06-16
----------------
- More fixes for corrupt Bson
0.4.0 2015-06-16
----------------
- New JS serializer serializing into a single buffer then copying out the new buffer. Performance is similar to current C++ parser.
- Removed bson-ext extension dependency for now.
0.3.2 2015-03-27
----------------
- Removed node-gyp from install script in package.json.
@@ -39,4 +123,4 @@
0.1.4 2012-09-25
----------------
- Added precompiled c++ native extensions for win32 ia32 and x64
- Added precompiled c++ native extensions for win32 ia32 and x64

View File

@@ -35,7 +35,7 @@ A simple example of how to use BSON in `node.js`:
```javascript
var bson = require("bson");
var BSON = bson.BSONPure.BSON;
var BSON = new bson.BSONPure.BSON();
var Long = bson.BSONPure.Long;
var doc = {long: Long.fromNumber(100)}
@@ -63,6 +63,7 @@ The API consists of two simple methods to serialize/deserialize objects to/from
* **evalFunctions** {Boolean, default:false}, evaluate functions in the BSON document scoped to the object deserialized.
* **cacheFunctions** {Boolean, default:false}, cache evaluated functions for reuse.
* **cacheFunctionsCrc32** {Boolean, default:false}, use a crc32 code for caching, otherwise use the string of the function.
* **promoteBuffers** {Boolean, default:false}, deserialize Binary data directly into node.js Buffer object.
* @param {TypedArray/Array} a TypedArray/Array containing the BSON data
* @param {Object} [options] additional options used for the deserialization.
* @param {Boolean} [isArray] ignore used for recursive parsing.

View File

@@ -2,13 +2,13 @@
* Module dependencies.
* @ignore
*/
if(typeof window === 'undefined') {
if(typeof window === 'undefined') {
var Buffer = require('buffer').Buffer; // TODO just use global Buffer
}
/**
* A class representation of the BSON Binary type.
*
*
* Sub types
* - **BSON.BSON_BINARY_SUBTYPE_DEFAULT**, default BSON type.
* - **BSON.BSON_BINARY_SUBTYPE_FUNCTION**, BSON function type.
@@ -24,13 +24,13 @@ if(typeof window === 'undefined') {
*/
function Binary(buffer, subType) {
if(!(this instanceof Binary)) return new Binary(buffer, subType);
this._bsontype = 'Binary';
if(buffer instanceof Number) {
this.sub_type = buffer;
this.position = 0;
} else {
} else {
this.sub_type = subType == null ? BSON_BINARY_SUBTYPE_DEFAULT : subType;
this.position = 0;
}
@@ -47,12 +47,12 @@ function Binary(buffer, subType) {
throw new Error("only String, Buffer, Uint8Array or Array accepted");
}
} else {
this.buffer = buffer;
this.buffer = buffer;
}
this.position = buffer.length;
} else {
if(typeof Buffer != 'undefined') {
this.buffer = new Buffer(Binary.BUFFER_SIZE);
this.buffer = new Buffer(Binary.BUFFER_SIZE);
} else if(typeof Uint8Array != 'undefined'){
this.buffer = new Uint8Array(new ArrayBuffer(Binary.BUFFER_SIZE));
} else {
@@ -73,21 +73,21 @@ Binary.prototype.put = function put(byte_value) {
// If it's a string and a has more than one character throw an error
if(byte_value['length'] != null && typeof byte_value != 'number' && byte_value.length != 1) throw new Error("only accepts single character String, Uint8Array or Array");
if(typeof byte_value != 'number' && byte_value < 0 || byte_value > 255) throw new Error("only accepts number in a valid unsigned byte range 0-255");
// Decode the byte value once
var decoded_byte = null;
if(typeof byte_value == 'string') {
decoded_byte = byte_value.charCodeAt(0);
decoded_byte = byte_value.charCodeAt(0);
} else if(byte_value['length'] != null) {
decoded_byte = byte_value[0];
} else {
decoded_byte = byte_value;
}
if(this.buffer.length > this.position) {
this.buffer[this.position++] = decoded_byte;
} else {
if(typeof Buffer != 'undefined' && Buffer.isBuffer(this.buffer)) {
if(typeof Buffer != 'undefined' && Buffer.isBuffer(this.buffer)) {
// Create additional overflow buffer
var buffer = new Buffer(Binary.BUFFER_SIZE + this.buffer.length);
// Combine the two buffers together
@@ -101,13 +101,13 @@ Binary.prototype.put = function put(byte_value) {
buffer = new Uint8Array(new ArrayBuffer(Binary.BUFFER_SIZE + this.buffer.length));
} else {
buffer = new Array(Binary.BUFFER_SIZE + this.buffer.length);
}
}
// We need to copy all the content to the new array
for(var i = 0; i < this.buffer.length; i++) {
buffer[i] = this.buffer[i];
}
// Reassign the buffer
this.buffer = buffer;
// Write the byte
@@ -131,9 +131,9 @@ Binary.prototype.write = function write(string, offset) {
if(this.buffer.length < offset + string.length) {
var buffer = null;
// If we are in node.js
if(typeof Buffer != 'undefined' && Buffer.isBuffer(this.buffer)) {
if(typeof Buffer != 'undefined' && Buffer.isBuffer(this.buffer)) {
buffer = new Buffer(this.buffer.length + string.length);
this.buffer.copy(buffer, 0, 0, this.buffer.length);
this.buffer.copy(buffer, 0, 0, this.buffer.length);
} else if(Object.prototype.toString.call(this.buffer) == '[object Uint8Array]') {
// Create a new buffer
buffer = new Uint8Array(new ArrayBuffer(this.buffer.length + string.length))
@@ -142,7 +142,7 @@ Binary.prototype.write = function write(string, offset) {
buffer[i] = this.buffer[i];
}
}
// Assign the new buffer
this.buffer = buffer;
}
@@ -152,14 +152,14 @@ Binary.prototype.write = function write(string, offset) {
this.position = (offset + string.length) > this.position ? (offset + string.length) : this.position;
// offset = string.length
} else if(typeof Buffer != 'undefined' && typeof string == 'string' && Buffer.isBuffer(this.buffer)) {
this.buffer.write(string, 'binary', offset);
this.buffer.write(string, offset, 'binary');
this.position = (offset + string.length) > this.position ? (offset + string.length) : this.position;
// offset = string.length;
} else if(Object.prototype.toString.call(string) == '[object Uint8Array]'
|| Object.prototype.toString.call(string) == '[object Array]' && typeof string != 'string') {
} else if(Object.prototype.toString.call(string) == '[object Uint8Array]'
|| Object.prototype.toString.call(string) == '[object Array]' && typeof string != 'string') {
for(var i = 0; i < string.length; i++) {
this.buffer[offset++] = string[i];
}
}
this.position = offset > this.position ? offset : this.position;
} else if(typeof string == 'string') {
@@ -183,7 +183,7 @@ Binary.prototype.read = function read(position, length) {
length = length && length > 0
? length
: this.position;
// Let's return the data based on the type we have
if(this.buffer['slice']) {
return this.buffer.slice(position, position + length);
@@ -205,12 +205,12 @@ Binary.prototype.read = function read(position, length) {
* @return {string}
*/
Binary.prototype.value = function value(asRaw) {
asRaw = asRaw == null ? false : asRaw;
asRaw = asRaw == null ? false : asRaw;
// Optimize to serialize for the situation where the data == size of buffer
if(asRaw && typeof Buffer != 'undefined' && Buffer.isBuffer(this.buffer) && this.buffer.length == this.position)
return this.buffer;
// If it's a node.js buffer object
if(typeof Buffer != 'undefined' && Buffer.isBuffer(this.buffer)) {
return asRaw ? this.buffer.slice(0, this.position) : this.buffer.toString('binary', 0, this.position);
@@ -261,7 +261,7 @@ Binary.prototype.toString = function(format) {
/**
* Binary default subtype
* @ignore
* @ignore
*/
var BSON_BINARY_SUBTYPE_DEFAULT = 0;
@@ -274,7 +274,7 @@ var writeStringToArray = function(data) {
// Write the content to the buffer
for(var i = 0; i < data.length; i++) {
buffer[i] = data.charCodeAt(i);
}
}
// Write the string to the buffer
return buffer;
}
@@ -289,50 +289,50 @@ var convertArraytoUtf8BinaryString = function(byteArray, startIndex, endIndex) {
for(var i = startIndex; i < endIndex; i++) {
result = result + String.fromCharCode(byteArray[i]);
}
return result;
return result;
};
Binary.BUFFER_SIZE = 256;
/**
* Default BSON type
*
*
* @classconstant SUBTYPE_DEFAULT
**/
Binary.SUBTYPE_DEFAULT = 0;
/**
* Function BSON type
*
*
* @classconstant SUBTYPE_DEFAULT
**/
Binary.SUBTYPE_FUNCTION = 1;
/**
* Byte Array BSON type
*
*
* @classconstant SUBTYPE_DEFAULT
**/
Binary.SUBTYPE_BYTE_ARRAY = 2;
/**
* OLD UUID BSON type
*
*
* @classconstant SUBTYPE_DEFAULT
**/
Binary.SUBTYPE_UUID_OLD = 3;
/**
* UUID BSON type
*
*
* @classconstant SUBTYPE_DEFAULT
**/
Binary.SUBTYPE_UUID = 4;
/**
* MD5 BSON type
*
*
* @classconstant SUBTYPE_DEFAULT
**/
Binary.SUBTYPE_MD5 = 5;
/**
* User BSON type
*
*
* @classconstant SUBTYPE_DEFAULT
**/
Binary.SUBTYPE_USER_DEFINED = 128;
@@ -341,4 +341,4 @@ Binary.SUBTYPE_USER_DEFINED = 128;
* Expose.
*/
module.exports = Binary;
module.exports.Binary = Binary;
module.exports.Binary = Binary;

File diff suppressed because it is too large Load Diff

View File

@@ -1,776 +0,0 @@
var writeIEEE754 = require('./float_parser').writeIEEE754
, Long = require('./long').Long
, Double = require('./double').Double
, Timestamp = require('./timestamp').Timestamp
, ObjectID = require('./objectid').ObjectID
, Symbol = require('./symbol').Symbol
, Code = require('./code').Code
, MinKey = require('./min_key').MinKey
, MaxKey = require('./max_key').MaxKey
, DBRef = require('./db_ref').DBRef
, Binary = require('./binary').Binary
, BinaryParser = require('./binary_parser').BinaryParser;
// Max Document Buffer size
var buffer = new Buffer(1024 * 1024 * 16);
var checkKey = function checkKey (key, dollarsAndDotsOk) {
if (!key.length) return;
// Check if we have a legal key for the object
if (!!~key.indexOf("\x00")) {
// The BSON spec doesn't allow keys with null bytes because keys are
// null-terminated.
throw Error("key " + key + " must not contain null bytes");
}
if (!dollarsAndDotsOk) {
if('$' == key[0]) {
throw Error("key " + key + " must not start with '$'");
} else if (!!~key.indexOf('.')) {
throw Error("key " + key + " must not contain '.'");
}
}
};
var serializeString = function(key, value, index) {
// Encode String type
buffer[index++] = BSON.BSON_DATA_STRING;
// Number of written bytes
var numberOfWrittenBytes = buffer.write(key, index, 'utf8');
// Encode the name
index = index + numberOfWrittenBytes + 1;
buffer[index - 1] = 0;
// Calculate size
var size = Buffer.byteLength(value) + 1;
// Write the size of the string to buffer
buffer[index + 3] = (size >> 24) & 0xff;
buffer[index + 2] = (size >> 16) & 0xff;
buffer[index + 1] = (size >> 8) & 0xff;
buffer[index] = size & 0xff;
// Ajust the index
index = index + 4;
// Write the string
buffer.write(value, index, 'utf8');
// Update index
index = index + size - 1;
// Write zero
buffer[index++] = 0;
return index;
}
var serializeNumber = function(key, value, index) {
// We have an integer value
if(Math.floor(value) === value && value >= BSON.JS_INT_MIN && value <= BSON.JS_INT_MAX) {
// If the value fits in 32 bits encode as int, if it fits in a double
// encode it as a double, otherwise long
if(value >= BSON.BSON_INT32_MIN && value <= BSON.BSON_INT32_MAX) {
// Set int type 32 bits or less
buffer[index++] = BSON.BSON_DATA_INT;
// Number of written bytes
var numberOfWrittenBytes = buffer.write(key, index, 'utf8');
// Encode the name
index = index + numberOfWrittenBytes;
buffer[index++] = 0;
// Write the int value
buffer[index++] = value & 0xff;
buffer[index++] = (value >> 8) & 0xff;
buffer[index++] = (value >> 16) & 0xff;
buffer[index++] = (value >> 24) & 0xff;
} else if(value >= BSON.JS_INT_MIN && value <= BSON.JS_INT_MAX) {
// Encode as double
buffer[index++] = BSON.BSON_DATA_NUMBER;
// Number of written bytes
var numberOfWrittenBytes = buffer.write(key, index, 'utf8');
// Encode the name
index = index + numberOfWrittenBytes;
buffer[index++] = 0;
// Write float
writeIEEE754(buffer, value, index, 'little', 52, 8);
// Ajust index
index = index + 8;
} else {
// Set long type
buffer[index++] = BSON.BSON_DATA_LONG;
// Number of written bytes
var numberOfWrittenBytes = buffer.write(key, index, 'utf8');
// Encode the name
index = index + numberOfWrittenBytes;
buffer[index++] = 0;
var longVal = Long.fromNumber(value);
var lowBits = longVal.getLowBits();
var highBits = longVal.getHighBits();
// Encode low bits
buffer[index++] = lowBits & 0xff;
buffer[index++] = (lowBits >> 8) & 0xff;
buffer[index++] = (lowBits >> 16) & 0xff;
buffer[index++] = (lowBits >> 24) & 0xff;
// Encode high bits
buffer[index++] = highBits & 0xff;
buffer[index++] = (highBits >> 8) & 0xff;
buffer[index++] = (highBits >> 16) & 0xff;
buffer[index++] = (highBits >> 24) & 0xff;
}
} else {
// Encode as double
buffer[index++] = BSON.BSON_DATA_NUMBER;
// Number of written bytes
var numberOfWrittenBytes = buffer.write(key, index, 'utf8');
// Encode the name
index = index + numberOfWrittenBytes;
buffer[index++] = 0;
// Write float
writeIEEE754(buffer, value, index, 'little', 52, 8);
// Ajust index
index = index + 8;
}
return index;
}
var serializeUndefined = function(key, value, index) {
// Set long type
buffer[index++] = BSON.BSON_DATA_NULL;
// Number of written bytes
var numberOfWrittenBytes = buffer.write(key, index, 'utf8');
// Encode the name
index = index + numberOfWrittenBytes;
buffer[index++] = 0;
return index;
}
var serializeBoolean = function(key, value, index) {
// Write the type
buffer[index++] = BSON.BSON_DATA_BOOLEAN;
// Number of written bytes
var numberOfWrittenBytes = buffer.write(key, index, 'utf8');
// Encode the name
index = index + numberOfWrittenBytes;
buffer[index++] = 0;
// Encode the boolean value
buffer[index++] = value ? 1 : 0;
return index;
}
var serializeDate = function(key, value, index) {
// Write the type
buffer[index++] = BSON.BSON_DATA_DATE;
// Number of written bytes
var numberOfWrittenBytes = buffer.write(key, index, 'utf8');
// Encode the name
index = index + numberOfWrittenBytes;
buffer[index++] = 0;
// Write the date
var dateInMilis = Long.fromNumber(value.getTime());
var lowBits = dateInMilis.getLowBits();
var highBits = dateInMilis.getHighBits();
// Encode low bits
buffer[index++] = lowBits & 0xff;
buffer[index++] = (lowBits >> 8) & 0xff;
buffer[index++] = (lowBits >> 16) & 0xff;
buffer[index++] = (lowBits >> 24) & 0xff;
// Encode high bits
buffer[index++] = highBits & 0xff;
buffer[index++] = (highBits >> 8) & 0xff;
buffer[index++] = (highBits >> 16) & 0xff;
buffer[index++] = (highBits >> 24) & 0xff;
return index;
}
var serializeRegExp = function(key, value, index) {
// Write the type
buffer[index++] = BSON.BSON_DATA_REGEXP;
// Number of written bytes
var numberOfWrittenBytes = buffer.write(key, index, 'utf8');
// Encode the name
index = index + numberOfWrittenBytes;
buffer[index++] = 0;
// Write the regular expression string
buffer.write(value.source, index, 'utf8');
// Adjust the index
index = index + Buffer.byteLength(value.source);
// Write zero
buffer[index++] = 0x00;
// Write the parameters
if(value.global) buffer[index++] = 0x73; // s
if(value.ignoreCase) buffer[index++] = 0x69; // i
if(value.multiline) buffer[index++] = 0x6d; // m
// Add ending zero
buffer[index++] = 0x00;
return index;
}
var serializeMinMax = function(key, value, index) {
// Write the type of either min or max key
if(value === null) {
buffer[index++] = BSON.BSON_DATA_NULL;
} else if(value instanceof MinKey) {
buffer[index++] = BSON.BSON_DATA_MIN_KEY;
} else {
buffer[index++] = BSON.BSON_DATA_MAX_KEY;
}
// Number of written bytes
var numberOfWrittenBytes = buffer.write(key, index, 'utf8');
// Encode the name
index = index + numberOfWrittenBytes;
buffer[index++] = 0;
return index;
}
var serializeObjectId = function(key, value, index) {
// Write the type
buffer[index++] = BSON.BSON_DATA_OID;
// Number of written bytes
var numberOfWrittenBytes = buffer.write(key, index, 'utf8');
// Encode the name
index = index + numberOfWrittenBytes;
buffer[index++] = 0;
for(var j = 0; j < 12; j++) {
buffer[index + j] = value.binId[j];
}
// Ajust index
index = index + 12;
return index;
}
var serializeBuffer = function(key, value, index) {
// Write the type
buffer[index++] = BSON.BSON_DATA_BINARY;
// Number of written bytes
var numberOfWrittenBytes = buffer.write(key, index, 'utf8');
// Encode the name
index = index + numberOfWrittenBytes;
buffer[index++] = 0;
// Get size of the buffer (current write point)
var size = value.length;
// Write the size of the string to buffer
buffer[index++] = size & 0xff;
buffer[index++] = (size >> 8) & 0xff;
buffer[index++] = (size >> 16) & 0xff;
buffer[index++] = (size >> 24) & 0xff;
// Write the default subtype
buffer[index++] = BSON.BSON_BINARY_SUBTYPE_DEFAULT;
// Copy the content form the binary field to the buffer
value.copy(buffer, index, 0, size);
// Adjust the index
index = index + size;
return index;
}
var serializeObject = function(key, value, index, checkKeys, depth) {
// Write the type
buffer[index++] = Array.isArray(value) ? BSON.BSON_DATA_ARRAY : BSON.BSON_DATA_OBJECT;
// Number of written bytes
var numberOfWrittenBytes = buffer.write(key, index, 'utf8');
// Encode the name
index = index + numberOfWrittenBytes;
buffer[index++] = 0;
var endIndex = serializeInto(value, checkKeys, index, depth + 1);
// Write size
var size = endIndex - index;
return endIndex;
}
var serializeLong = function(key, value, index) {
// Write the type
buffer[index++] = value instanceof Long ? BSON.BSON_DATA_LONG : BSON.BSON_DATA_TIMESTAMP;
// Number of written bytes
var numberOfWrittenBytes = buffer.write(key, index, 'utf8');
// Encode the name
index = index + numberOfWrittenBytes;
buffer[index++] = 0;
// Write the date
var lowBits = value.getLowBits();
var highBits = value.getHighBits();
// Encode low bits
buffer[index++] = lowBits & 0xff;
buffer[index++] = (lowBits >> 8) & 0xff;
buffer[index++] = (lowBits >> 16) & 0xff;
buffer[index++] = (lowBits >> 24) & 0xff;
// Encode high bits
buffer[index++] = highBits & 0xff;
buffer[index++] = (highBits >> 8) & 0xff;
buffer[index++] = (highBits >> 16) & 0xff;
buffer[index++] = (highBits >> 24) & 0xff;
return index;
}
var serializeDouble = function(key, value, index) {
// Encode as double
buffer[index++] = BSON.BSON_DATA_NUMBER;
// Number of written bytes
var numberOfWrittenBytes = buffer.write(key, index, 'utf8');
// Encode the name
index = index + numberOfWrittenBytes;
buffer[index++] = 0;
// Write float
writeIEEE754(buffer, value, index, 'little', 52, 8);
// Ajust index
index = index + 8;
return index;
}
var serializeCode = function(key, value, index, checkKeys, depth) {
if(value.scope != null && Object.keys(value.scope).length > 0) {
// Write the type
buffer[index++] = BSON.BSON_DATA_CODE_W_SCOPE;
// Number of written bytes
var numberOfWrittenBytes = buffer.write(key, index, 'utf8');
// Encode the name
index = index + numberOfWrittenBytes;
buffer[index++] = 0;
// Starting index
var startIndex = index;
// Serialize the function
// Get the function string
var functionString = typeof value.code == 'string' ? value.code : value.code.toString();
var codeSize = Buffer.byteLength(functionString) + 1;
// Index adjustment
index = index + 4;
// Write the size of the string to buffer
buffer[index] = codeSize & 0xff;
buffer[index + 1] = (codeSize >> 8) & 0xff;
buffer[index + 2] = (codeSize >> 16) & 0xff;
buffer[index + 3] = (codeSize >> 24) & 0xff;
// Write string into buffer
buffer.write(functionString, index + 4, 'utf8');
// Write end 0
buffer[index + 4 + codeSize - 1] = 0;
// Write the
index = index + codeSize + 4;
//
// Serialize the scope value
var endIndex = serializeInto(value.scope, checkKeys, index, depth + 1)
index = endIndex - 1;
// Writ the total
var totalSize = endIndex - startIndex;
// Write the total size of the object
buffer[startIndex++] = totalSize & 0xff;
buffer[startIndex++] = (totalSize >> 8) & 0xff;
buffer[startIndex++] = (totalSize >> 16) & 0xff;
buffer[startIndex++] = (totalSize >> 24) & 0xff;
// Write trailing zero
buffer[index++] = 0;
} else {
buffer[index++] = BSON.BSON_DATA_CODE;
// Number of written bytes
var numberOfWrittenBytes = buffer.write(key, index, 'utf8');
// Encode the name
index = index + numberOfWrittenBytes;
buffer[index++] = 0;
// Function string
var functionString = value.code.toString();
// Function Size
var size = Buffer.byteLength(functionString) + 1;
// Write the size of the string to buffer
buffer[index++] = size & 0xff;
buffer[index++] = (size >> 8) & 0xff;
buffer[index++] = (size >> 16) & 0xff;
buffer[index++] = (size >> 24) & 0xff;
// Write the string
buffer.write(functionString, index, 'utf8');
// Update index
index = index + size - 1;
// Write zero
buffer[index++] = 0;
}
return index;
}
var serializeBinary = function(key, value, index) {
// Write the type
buffer[index++] = BSON.BSON_DATA_BINARY;
// Number of written bytes
var numberOfWrittenBytes = buffer.write(key, index, 'utf8');
// Encode the name
index = index + numberOfWrittenBytes;
buffer[index++] = 0;
// Extract the buffer
var data = value.value(true);
// Calculate size
var size = value.position;
// Write the size of the string to buffer
buffer[index++] = size & 0xff;
buffer[index++] = (size >> 8) & 0xff;
buffer[index++] = (size >> 16) & 0xff;
buffer[index++] = (size >> 24) & 0xff;
// Write the subtype to the buffer
buffer[index++] = value.sub_type;
// If we have binary type 2 the 4 first bytes are the size
if(value.sub_type == Binary.SUBTYPE_BYTE_ARRAY) {
buffer[index++] = size & 0xff;
buffer[index++] = (size >> 8) & 0xff;
buffer[index++] = (size >> 16) & 0xff;
buffer[index++] = (size >> 24) & 0xff;
}
// Write the data to the object
data.copy(buffer, index, 0, value.position);
// Adjust the index
index = index + value.position;
return index;
}
var serializeSymbol = function(key, value, index) {
// Write the type
buffer[index++] = BSON.BSON_DATA_SYMBOL;
// Number of written bytes
var numberOfWrittenBytes = buffer.write(key, index, 'utf8');
// Encode the name
index = index + numberOfWrittenBytes;
buffer[index++] = 0;
// Calculate size
var size = Buffer.byteLength(value.value) + 1;
// Write the size of the string to buffer
buffer[index++] = size & 0xff;
buffer[index++] = (size >> 8) & 0xff;
buffer[index++] = (size >> 16) & 0xff;
buffer[index++] = (size >> 24) & 0xff;
// Write the string
buffer.write(value.value, index, 'utf8');
// Update index
index = index + size - 1;
// Write zero
buffer[index++] = 0x00;
return index;
}
var serializeDBRef = function(key, value, index, depth) {
// Write the type
buffer[index++] = BSON.BSON_DATA_OBJECT;
// Number of written bytes
var numberOfWrittenBytes = buffer.write(key, index, 'utf8');
// Encode the name
index = index + numberOfWrittenBytes;
buffer[index++] = 0;
var startIndex = index;
var endIndex;
// Serialize object
if(null != value.db) {
endIndex = serializeInto({
'$ref': value.namespace
, '$id' : value.oid
, '$db' : value.db
}, false, index, depth + 1);
} else {
endIndex = serializeInto({
'$ref': value.namespace
, '$id' : value.oid
}, false, index, depth + 1);
}
// Calculate object size
var size = endIndex - startIndex;
// Write the size
buffer[startIndex++] = size & 0xff;
buffer[startIndex++] = (size >> 8) & 0xff;
buffer[startIndex++] = (size >> 16) & 0xff;
buffer[startIndex++] = (size >> 24) & 0xff;
// Set index
return endIndex;
}
var BSON = function() {
this.buffer = buffer;
}
BSON.prototype.serialize = function serialize(object, checkKeys, index) {
var finishedBuffer = new Buffer(serializeInto(object, checkKeys, index || 0, 0));
this.buffer.copy(finishedBuffer, 0, 0, finishedBuffer.length);
return finishedBuffer;
}
var serializeInto = function serializeInto(object, checkKeys, startingIndex, depth) {
startingIndex = startingIndex || 0;
// Start place to serialize into
var index = startingIndex + 4;
var self = this;
// Special case isArray
if(Array.isArray(object)) {
// Get object keys
for(var i = 0; i < object.length; i++) {
var key = "" + i;
var type = typeof object[i];
// Check the key and throw error if it's illegal
if(key != '$db' && key != '$ref' && key != '$id') {
checkKey(key, !checkKeys);
}
if(type == 'string') {
index = serializeString(key, object[i], index);
} else if(type == 'number') {
index = serializeNumber(key, object[i], index);
} else if(type == 'undefined') {
index = serializeUndefined(key, object[i], index);
} else if(type == 'boolean') {
index = serializeBoolean(key, object[i], index);
} else if(object[i] instanceof Date) {
index = serializeDate(key, object[i], index);
} else if(object[i] instanceof RegExp || Object.prototype.toString.call(object[i]) === '[object RegExp]') {
index = serializeRegExp(key, object[i], index);
} else if(object[i]['_bsontype'] == 'MinKey' || object[i]['_bsontype'] == 'MaxKey') {
index = serializeMinMax(key, object[i], index);
} else if(object[i]['_bsontype'] == 'ObjectID') {
index = serializeObjectId(key, object[i], index);
} else if(Buffer.isBuffer(object[i])) {
index = serializeBuffer(key, object[i], index);
} else if(type == 'object' && object[i]['_bsontype'] == null) {
index = serializeObject(key, object[i], index, checkKeys, depth);
} else if(object[i]['_bsontype'] == 'Long' || object[i]['_bsontype'] == 'Timestamp') {
index = serializeLong(key, object[i], index);
} else if(object[i]['_bsontype'] == 'Double') {
index = serializeDouble(key, object[i], index);
} else if(object[i]['_bsontype'] == 'Code') {
index = serializeCode(key, object[i], index, checkKeys, depth);
} else if(object[i]['_bsontype'] == 'Binary') {
index = serializeBinary(key, object[i], index);
} else if(object[i]['_bsontype'] == 'Symbol') {
index = serializeSymbol(key, object[i], index);
} else if(object[i]['_bsontype'] == 'DBRef') {
index = serializeDBRef(key, object[i], index, depth);
}
}
} else {
var keys = Object.keys(object);
for(var i = 0; i < keys.length; i++) {
var key = keys[i];
var type = typeof object[key];
// Check the key and throw error if it's illegal
if(key != '$db' && key != '$ref' && key != '$id') {
checkKey(key, !checkKeys);
}
if(type == 'string') {
index = serializeString(key, object[key], index);
} else if(type == 'number') {
index = serializeNumber(key, object[key], index);
} else if(type == 'undefined') {
index = serializeUndefined(key, object[key], index);
} else if(type == 'boolean') {
index = serializeBoolean(key, object[key], index);
} else if(object[key] instanceof Date) {
index = serializeDate(key, object[key], index);
} else if(object[key] instanceof RegExp || Object.prototype.toString.call(object[key]) === '[object RegExp]') {
index = serializeRegExp(key, object[key], index);
} else if(object[key]['_bsontype'] == 'MinKey' || object[key]['_bsontype'] == 'MaxKey') {
index = serializeMinMax(key, object[key], index);
} else if(object[key]['_bsontype'] == 'ObjectID') {
index = serializeObjectId(key, object[key], index);
} else if(Buffer.isBuffer(object[key])) {
index = serializeBuffer(key, object[key], index);
} else if(type == 'object' && object[key]['_bsontype'] == null) {
index = serializeObject(key, object[key], index, checkKeys, depth);
} else if(object[key]['_bsontype'] == 'Long' || object[key]['_bsontype'] == 'Timestamp') {
index = serializeLong(key, object[key], index);
} else if(object[key]['_bsontype'] == 'Double') {
index = serializeDouble(key, object[key], index);
} else if(object[key]['_bsontype'] == 'Code') {
index = serializeCode(key, object[key], index, checkKeys, depth);
} else if(object[key]['_bsontype'] == 'Binary') {
index = serializeBinary(key, object[key], index);
} else if(object[key]['_bsontype'] == 'Symbol') {
index = serializeSymbol(key, object[key], index);
} else if(object[key]['_bsontype'] == 'DBRef') {
index = serializeDBRef(key, object[key], index, depth);
}
}
}
// Final padding byte for object
buffer[index++] = 0x00;
// Final size
var size = index - startingIndex;
// Write the size of the object
buffer[startingIndex++] = size & 0xff;
buffer[startingIndex++] = (size >> 8) & 0xff;
buffer[startingIndex++] = (size >> 16) & 0xff;
buffer[startingIndex++] = (size >> 24) & 0xff;
return index;
}
/**
* @ignore
* @api private
*/
// BSON MAX VALUES
BSON.BSON_INT32_MAX = 0x7FFFFFFF;
BSON.BSON_INT32_MIN = -0x80000000;
BSON.BSON_INT64_MAX = Math.pow(2, 63) - 1;
BSON.BSON_INT64_MIN = -Math.pow(2, 63);
// JS MAX PRECISE VALUES
BSON.JS_INT_MAX = 0x20000000000000; // Any integer up to 2^53 can be precisely represented by a double.
BSON.JS_INT_MIN = -0x20000000000000; // Any integer down to -2^53 can be precisely represented by a double.
// Internal long versions
var JS_INT_MAX_LONG = Long.fromNumber(0x20000000000000); // Any integer up to 2^53 can be precisely represented by a double.
var JS_INT_MIN_LONG = Long.fromNumber(-0x20000000000000); // Any integer down to -2^53 can be precisely represented by a double.
/**
* Number BSON Type
*
* @classconstant BSON_DATA_NUMBER
**/
BSON.BSON_DATA_NUMBER = 1;
/**
* String BSON Type
*
* @classconstant BSON_DATA_STRING
**/
BSON.BSON_DATA_STRING = 2;
/**
* Object BSON Type
*
* @classconstant BSON_DATA_OBJECT
**/
BSON.BSON_DATA_OBJECT = 3;
/**
* Array BSON Type
*
* @classconstant BSON_DATA_ARRAY
**/
BSON.BSON_DATA_ARRAY = 4;
/**
* Binary BSON Type
*
* @classconstant BSON_DATA_BINARY
**/
BSON.BSON_DATA_BINARY = 5;
/**
* ObjectID BSON Type
*
* @classconstant BSON_DATA_OID
**/
BSON.BSON_DATA_OID = 7;
/**
* Boolean BSON Type
*
* @classconstant BSON_DATA_BOOLEAN
**/
BSON.BSON_DATA_BOOLEAN = 8;
/**
* Date BSON Type
*
* @classconstant BSON_DATA_DATE
**/
BSON.BSON_DATA_DATE = 9;
/**
* null BSON Type
*
* @classconstant BSON_DATA_NULL
**/
BSON.BSON_DATA_NULL = 10;
/**
* RegExp BSON Type
*
* @classconstant BSON_DATA_REGEXP
**/
BSON.BSON_DATA_REGEXP = 11;
/**
* Code BSON Type
*
* @classconstant BSON_DATA_CODE
**/
BSON.BSON_DATA_CODE = 13;
/**
* Symbol BSON Type
*
* @classconstant BSON_DATA_SYMBOL
**/
BSON.BSON_DATA_SYMBOL = 14;
/**
* Code with Scope BSON Type
*
* @classconstant BSON_DATA_CODE_W_SCOPE
**/
BSON.BSON_DATA_CODE_W_SCOPE = 15;
/**
* 32 bit Integer BSON Type
*
* @classconstant BSON_DATA_INT
**/
BSON.BSON_DATA_INT = 16;
/**
* Timestamp BSON Type
*
* @classconstant BSON_DATA_TIMESTAMP
**/
BSON.BSON_DATA_TIMESTAMP = 17;
/**
* Long BSON Type
*
* @classconstant BSON_DATA_LONG
**/
BSON.BSON_DATA_LONG = 18;
/**
* MinKey BSON Type
*
* @classconstant BSON_DATA_MIN_KEY
**/
BSON.BSON_DATA_MIN_KEY = 0xff;
/**
* MaxKey BSON Type
*
* @classconstant BSON_DATA_MAX_KEY
**/
BSON.BSON_DATA_MAX_KEY = 0x7f;
/**
* Binary Default Type
*
* @classconstant BSON_BINARY_SUBTYPE_DEFAULT
**/
BSON.BSON_BINARY_SUBTYPE_DEFAULT = 0;
/**
* Binary Function Type
*
* @classconstant BSON_BINARY_SUBTYPE_FUNCTION
**/
BSON.BSON_BINARY_SUBTYPE_FUNCTION = 1;
/**
* Binary Byte Array Type
*
* @classconstant BSON_BINARY_SUBTYPE_BYTE_ARRAY
**/
BSON.BSON_BINARY_SUBTYPE_BYTE_ARRAY = 2;
/**
* Binary UUID Type
*
* @classconstant BSON_BINARY_SUBTYPE_UUID
**/
BSON.BSON_BINARY_SUBTYPE_UUID = 3;
/**
* Binary MD5 Type
*
* @classconstant BSON_BINARY_SUBTYPE_MD5
**/
BSON.BSON_BINARY_SUBTYPE_MD5 = 4;
/**
* Binary User Defined Type
*
* @classconstant BSON_BINARY_SUBTYPE_USER_DEFINED
**/
BSON.BSON_BINARY_SUBTYPE_USER_DEFINED = 128;
// Return BSON
exports.BSON = BSON;

View File

@@ -1,18 +1,19 @@
try {
exports.BSONPure = require('./bson');
exports.BSONNative = require('bson-ext');
exports.BSONNative = require('./bson');
} catch(err) {
// do nothing
}
[ './binary_parser'
, './binary'
, './code'
, './map'
, './db_ref'
, './double'
, './max_key'
, './min_key'
, './objectid'
, './regexp'
, './symbol'
, './timestamp'
, './long'].forEach(function (path) {
@@ -29,11 +30,13 @@ exports.pure = function() {
[ './binary_parser'
, './binary'
, './code'
, './map'
, './db_ref'
, './double'
, './max_key'
, './min_key'
, './objectid'
, './regexp'
, './symbol'
, './timestamp'
, './long'
@@ -54,11 +57,13 @@ exports.native = function() {
[ './binary_parser'
, './binary'
, './code'
, './map'
, './db_ref'
, './double'
, './max_key'
, './min_key'
, './objectid'
, './regexp'
, './symbol'
, './timestamp'
, './long'
@@ -68,10 +73,10 @@ exports.native = function() {
classes[i] = module[i];
}
});
// Catch error and return no classes found
try {
classes['BSON'] = require('bson-ext')
classes['BSON'] = require('./bson');
} catch(err) {
return exports.pure();
}

126
node_modules/mongoose/node_modules/bson/lib/bson/map.js generated vendored Normal file
View File

@@ -0,0 +1,126 @@
"use strict"
// We have an ES6 Map available, return the native instance
if(typeof global.Map !== 'undefined') {
module.exports = global.Map;
module.exports.Map = global.Map;
} else {
// We will return a polyfill
var Map = function(array) {
this._keys = [];
this._values = {};
for(var i = 0; i < array.length; i++) {
if(array[i] == null) continue; // skip null and undefined
var entry = array[i];
var key = entry[0];
var value = entry[1];
// Add the key to the list of keys in order
this._keys.push(key);
// Add the key and value to the values dictionary with a point
// to the location in the ordered keys list
this._values[key] = {v: value, i: this._keys.length - 1};
}
}
Map.prototype.clear = function() {
this._keys = [];
this._values = {};
}
Map.prototype.delete = function(key) {
var value = this._values[key];
if(value == null) return false;
// Delete entry
delete this._values[key];
// Remove the key from the ordered keys list
this._keys.splice(value.i, 1);
return true;
}
Map.prototype.entries = function() {
var self = this;
var index = 0;
return {
next: function() {
var key = self._keys[index++];
return {
value: key !== undefined ? [key, self._values[key].v] : undefined,
done: key !== undefined ? false : true
}
}
};
}
Map.prototype.forEach = function(callback, self) {
self = self || this;
for(var i = 0; i < this._keys.length; i++) {
var key = this._keys[i];
// Call the forEach callback
callback.call(self, this._values[key].v, key, self);
}
}
Map.prototype.get = function(key) {
return this._values[key] ? this._values[key].v : undefined;
}
Map.prototype.has = function(key) {
return this._values[key] != null;
}
Map.prototype.keys = function(key) {
var self = this;
var index = 0;
return {
next: function() {
var key = self._keys[index++];
return {
value: key !== undefined ? key : undefined,
done: key !== undefined ? false : true
}
}
};
}
Map.prototype.set = function(key, value) {
if(this._values[key]) {
this._values[key].v = value;
return this;
}
// Add the key to the list of keys in order
this._keys.push(key);
// Add the key and value to the values dictionary with a point
// to the location in the ordered keys list
this._values[key] = {v: value, i: this._keys.length - 1};
return this;
}
Map.prototype.values = function(key, value) {
var self = this;
var index = 0;
return {
next: function() {
var key = self._keys[index++];
return {
value: key !== undefined ? self._values[key].v : undefined,
done: key !== undefined ? false : true
}
}
};
}
// Last ismaster
Object.defineProperty(Map.prototype, 'size', {
enumerable:true,
get: function() { return this._keys.length; }
});
module.exports = Map;
module.exports.Map = Map;
}

Some files were not shown because too many files have changed in this diff Show More