Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(collection): add colleciton level document mapping/unmapping #1698

Merged
merged 1 commit into from
May 10, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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