Skip to content

Commit

Permalink
feat(collection): add colleciton level document mapping/unmapping
Browse files Browse the repository at this point in the history
  • Loading branch information
j authored and daprahamian committed May 10, 2018
1 parent 9854850 commit d03335e
Show file tree
Hide file tree
Showing 3 changed files with 410 additions and 33 deletions.
76 changes: 43 additions & 33 deletions lib/collection.js
Original file line number Diff line number Diff line change
Expand Up @@ -378,14 +378,14 @@ Collection.prototype.find = function(query, options, callback) {
// Decorate find command with collation options
decorateWithCollation(findCommand, this, options);

// Create the cursor
if (typeof callback === 'function')
return handleCallback(
callback,
null,
this.s.topology.cursor(this.s.namespace, findCommand, newOptions)
);
return this.s.topology.cursor(this.s.namespace, findCommand, newOptions);
const cursor = this.s.topology.cursor(this.s.namespace, findCommand, newOptions);

// automatically call map on the cursor if the map option is set
if (typeof this.s.options.map === 'function') {
cursor.map(this.s.options.map);
}

return typeof callback === 'function' ? handleCallback(callback, null, cursor) : cursor;
};

/**
Expand Down Expand Up @@ -491,19 +491,7 @@ Collection.prototype.insertMany = function(docs, options, callback) {
// If keep going set unordered
options['serializeFunctions'] = options['serializeFunctions'] || self.s.serializeFunctions;

// Set up the force server object id
var forceServerObjectId =
typeof options.forceServerObjectId === 'boolean'
? options.forceServerObjectId
: self.s.db.options.forceServerObjectId;

// Do we want to force the server to assign the _id key
if (forceServerObjectId !== true) {
// Add _id if not specified
for (var i = 0; i < docs.length; i++) {
if (docs[i]._id == null) docs[i]._id = self.s.pkFactory.createPk();
}
}
docs = prepareDocs(this, docs, options);

// Generate the bulk write operations
var operations = [
Expand Down Expand Up @@ -683,18 +671,7 @@ var insertDocuments = function(self, docs, options, callback) {
if (finalOptions.keepGoing === true) finalOptions.ordered = false;
finalOptions['serializeFunctions'] = options['serializeFunctions'] || self.s.serializeFunctions;

// Set up the force server object id
var forceServerObjectId =
typeof options.forceServerObjectId === 'boolean'
? options.forceServerObjectId
: self.s.db.options.forceServerObjectId;

// Add _id if not specified
if (forceServerObjectId !== true) {
for (var i = 0; i < docs.length; i++) {
if (docs[i]._id === void 0) docs[i]._id = self.s.pkFactory.createPk();
}
}
docs = prepareDocs(self, docs, options);

// File inserts
self.s.topology.insert(self.s.namespace, docs, finalOptions, function(err, result) {
Expand Down Expand Up @@ -909,6 +886,10 @@ Collection.prototype.replaceOne = function(filter, doc, options, callback) {
options.ignoreUndefined = this.s.options.ignoreUndefined;
}

if (typeof this.s.options.unmap === 'function') {
doc = this.s.options.unmap(doc);
}

return executeOperation(this.s.topology, replaceOne, [this, filter, doc, options, callback]);
};

Expand Down Expand Up @@ -2253,6 +2234,11 @@ var findAndModify = function(self, query, sort, doc, options, callback) {
// Execute the command
self.s.db.command(queryObject, finalOptions, function(err, result) {
if (err) return handleCallback(callback, err, null);

if (result && result.value && typeof self.s.options.map === 'function') {
result.value = self.s.options.map(result.value);
}

return handleCallback(callback, null, result);
});
};
Expand Down Expand Up @@ -3028,4 +3014,28 @@ var getReadPreference = function(self, options, db) {
return options;
};

// modifies documents before being inserted or updated
const prepareDocs = function(self, docs, options) {
const forceServerObjectId =
typeof options.forceServerObjectId === 'boolean'
? options.forceServerObjectId
: self.s.db.options.forceServerObjectId;

const unmap = typeof self.s.options.unmap === 'function' ? self.s.options.unmap : false;

// no need to modify the docs if server sets the ObjectId
// and unmap collection option is unset
if (forceServerObjectId === true && !unmap) {
return docs;
}

return docs.map(function(doc) {
if (forceServerObjectId !== true && doc._id == null) {
doc._id = self.s.pkFactory.createPk();
}

return unmap ? unmap(doc) : doc;
});
};

module.exports = Collection;
2 changes: 2 additions & 0 deletions lib/db.js
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,8 @@ var collectionKeys = [
* @param {(ReadPreference|string)} [options.readPreference=null] The preferred read preference (ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST).
* @param {boolean} [options.serializeFunctions=false] Serialize functions on any object.
* @param {boolean} [options.strict=false] Returns an error if the collection does not exist
* @param {function} [options.map] Function to map documents returned in find, findOne, and findAndModify commands.
* @param {function} [options.unmap] Function to unmap documents passed to insertOne, insertMany, and replaceOne commands.
* @param {object} [options.readConcern=null] Specify a read concern for the collection. (only MongoDB 3.2 or higher supported)
* @param {object} [options.readConcern.level='local'] Specify a read concern level for the collection operations, one of [local|majority]. (only MongoDB 3.2 or higher supported)
* @param {Db~collectionResultCallback} [callback] The collection result callback
Expand Down
Loading

0 comments on commit d03335e

Please sign in to comment.