thoughts/node_modules/mongoose/lib/drivers/node-mongodb-native/collection.js
node_modules/mongoose/lib/drivers/node-mongodb-native/collection.jsRaw
1
2/*!
3 * Module dependencies.
4 */
5
6var MongooseCollection = require('../../collection')
7 , Collection = require('mongodb').Collection
8 , STATES = require('../../connectionstate')
9 , utils = require('../../utils')
10
11/**
12 * A [node-mongodb-native](https://github.com/mongodb/node-mongodb-native) collection implementation.
13 *
14 * All methods methods from the [node-mongodb-native](https://github.com/mongodb/node-mongodb-native) driver are copied and wrapped in queue management.
15 *
16 * @inherits Collection
17 * @api private
18 */
19
20function NativeCollection () {
21 this.collection = null;
22 MongooseCollection.apply(this, arguments);
23}
24
25/*!
26 * Inherit from abstract Collection.
27 */
28
29NativeCollection.prototype.__proto__ = MongooseCollection.prototype;
30
31/**
32 * Called when the connection opens.
33 *
34 * @api private
35 */
36
37NativeCollection.prototype.onOpen = function () {
38 var self = this;
39
40 // always get a new collection in case the user changed host:port
41 // of parent db instance when re-opening the connection.
42
43 if (!self.opts.capped.size) {
44 // non-capped
45 return self.conn.db.collection(self.name, callback);
46 }
47
48 // capped
49 return self.conn.db.collection(self.name, function (err, c) {
50 if (err) return callback(err);
51
52 // discover if this collection exists and if it is capped
53 c.options(function (err, exists) {
54 if (err) return callback(err);
55
56 if (exists) {
57 if (exists.capped) {
58 callback(null, c);
59 } else {
60 var msg = 'A non-capped collection exists with the name: '+ self.name +'\n\n'
61 + ' To use this collection as a capped collection, please '
62 + 'first convert it.\n'
63 + ' http://www.mongodb.org/display/DOCS/Capped+Collections#CappedCollections-Convertingacollectiontocapped'
64 err = new Error(msg);
65 callback(err);
66 }
67 } else {
68 // create
69 var opts = utils.clone(self.opts.capped);
70 opts.capped = true;
71 self.conn.db.createCollection(self.name, opts, callback);
72 }
73 });
74 });
75
76 function callback (err, collection) {
77 if (err) {
78 // likely a strict mode error
79 self.conn.emit('error', err);
80 } else {
81 self.collection = collection;
82 MongooseCollection.prototype.onOpen.call(self);
83 }
84 };
85};
86
87/**
88 * Called when the connection closes
89 *
90 * @api private
91 */
92
93NativeCollection.prototype.onClose = function () {
94 MongooseCollection.prototype.onClose.call(this);
95};
96
97/*!
98 * Copy the collection methods and make them subject to queues
99 */
100
101for (var i in Collection.prototype) {
102 (function(i){
103 NativeCollection.prototype[i] = function () {
104 if (this.buffer) {
105 this.addQueue(i, arguments);
106 return;
107 }
108
109 var collection = this.collection
110 , args = arguments
111 , self = this
112 , debug = self.conn.base.options.debug;
113
114 if (debug) {
115 if ('function' === typeof debug) {
116 debug.apply(debug
117 , [self.name, i].concat(utils.args(args, 0, args.length-1)));
118 } else {
119 console.error('\x1B[0;36mMongoose:\x1B[0m %s.%s(%s) %s %s %s'
120 , self.name
121 , i
122 , print(args[0])
123 , print(args[1])
124 , print(args[2])
125 , print(args[3]))
126 }
127 }
128
129 collection[i].apply(collection, args);
130 };
131 })(i);
132}
133
134/*!
135 * Debug print helper
136 */
137
138function print (arg) {
139 var type = typeof arg;
140 if ('function' === type || 'undefined' === type) return '';
141 return format(arg);
142}
143
144/*!
145 * Debug print helper
146 */
147
148function format (obj, sub) {
149 var x = utils.clone(obj);
150 if (x) {
151 if ('Binary' === x.constructor.name) {
152 x = '[object Buffer]';
153 } else if ('ObjectID' === x.constructor.name) {
154 var representation = 'ObjectId("' + x.toHexString() + '")';
155 x = { inspect: function() { return representation; } };
156 } else if ('Date' === x.constructor.name) {
157 var representation = 'new Date("' + x.toUTCString() + '")';
158 x = { inspect: function() { return representation; } };
159 } else if ('Object' === x.constructor.name) {
160 var keys = Object.keys(x)
161 , i = keys.length
162 , key
163 while (i--) {
164 key = keys[i];
165 if (x[key]) {
166 if ('Binary' === x[key].constructor.name) {
167 x[key] = '[object Buffer]';
168 } else if ('Object' === x[key].constructor.name) {
169 x[key] = format(x[key], true);
170 } else if ('ObjectID' === x[key].constructor.name) {
171 ;(function(x){
172 var representation = 'ObjectId("' + x[key].toHexString() + '")';
173 x[key] = { inspect: function() { return representation; } };
174 })(x)
175 } else if ('Date' === x[key].constructor.name) {
176 ;(function(x){
177 var representation = 'new Date("' + x[key].toUTCString() + '")';
178 x[key] = { inspect: function() { return representation; } };
179 })(x)
180 } else if (Array.isArray(x[key])) {
181 x[key] = x[key].map(function (o) {
182 return format(o, true)
183 });
184 }
185 }
186 }
187 }
188 if (sub) return x;
189 }
190
191 return require('util')
192 .inspect(x, false, 10, true)
193 .replace(/\n/g, '')
194 .replace(/\s{2,}/g, ' ')
195}
196
197/**
198 * Retreives information about this collections indexes.
199 *
200 * @param {Function} callback
201 * @method getIndexes
202 * @api public
203 */
204
205NativeCollection.prototype.getIndexes = NativeCollection.prototype.indexInformation;
206
207/*!
208 * Module exports.
209 */
210
211module.exports = NativeCollection;