Skip to content

Commit

Permalink
cleanup of read preferences
Browse files Browse the repository at this point in the history
  • Loading branch information
christkv committed Nov 8, 2012
1 parent afdd8a8 commit 7b2f2f3
Show file tree
Hide file tree
Showing 79 changed files with 988 additions and 1,134 deletions.
117 changes: 62 additions & 55 deletions lib/mongodb/collection.js
Expand Up @@ -167,7 +167,7 @@ Collection.prototype.remove = function remove(selector, options, callback) {
var self = this;
var errorOptions = _getWriteConcern(self, options, callback);
// Execute the command, do not add a callback as it's async
if(errorOptions && errorOptions != false) {
if(_hasWriteConcern(errorOptions) && typeof callback == 'function') {
// Insert options
var commandOptions = {read:false};
// If we have safe set set async to false
Expand Down Expand Up @@ -195,6 +195,8 @@ Collection.prototype.remove = function remove(selector, options, callback) {
callback(null, error[0].n);
}
});
} else if(_hasWriteConcern(errorOptions) && callback == null) {
throw new Error("Cannot use a writeConcern without a provided callback");
} else {
var result = this.db._executeRemoveCommand(deleteCommand);
// If no callback just return
Expand Down Expand Up @@ -278,7 +280,7 @@ var insertAll = function insertAll (self, docs, options, callback) {
, dbName + "." + self.collectionName, true, insertFlags);

// Add the documents and decorate them with id's if they have none
for (var index = 0, len = docs.length; index < len; ++index) {
for(var index = 0, len = docs.length; index < len; ++index) {
var doc = docs[index];

// Add id to each document if it's not already defined
Expand All @@ -294,7 +296,7 @@ var insertAll = function insertAll (self, docs, options, callback) {
// Default command options
var commandOptions = {};
// If safe is defined check for error message
if(errorOptions && errorOptions != false && errorOptions.w != -1 && errorOptions.w != 0) {
if(_hasWriteConcern(errorOptions) && typeof callback == 'function') {
// Insert options
commandOptions['read'] = false;
// If we have safe set set async to false
Expand Down Expand Up @@ -323,6 +325,8 @@ var insertAll = function insertAll (self, docs, options, callback) {
callback(null, docs);
}
});
} else if(_hasWriteConcern(errorOptions) && callback == null) {
throw new Error("Cannot use a writeConcern without a provided callback");
} else {
var result = self.db._executeInsertCommand(insertCommand, commandOptions, callback);
// If no callback just return
Expand Down Expand Up @@ -361,11 +365,13 @@ Collection.prototype.save = function save(doc, options, callback) {
if(!('function' === typeof callback)) callback = null;
// Extract the id, if we have one we need to do a update command
var id = doc['_id'];
var commandOptions = _getWriteConcern(this, options, callback);

if(id) {
this.update({ _id: id }, doc, { upsert: true, safe: _getWriteConcern(this, options, callback) }, callback);
commandOptions.upsert = true;
this.update({ _id: id }, doc, commandOptions, callback);
} else {
this.insert(doc, { safe: _getWriteConcern(this, options, callback) }, callback && function (err, docs) {
this.insert(doc, commandOptions, callback && function (err, docs) {
if (err) return callback(err, null);

if (Array.isArray(docs)) {
Expand Down Expand Up @@ -429,8 +435,8 @@ Collection.prototype.update = function update(selector, document, options, callb
var self = this;
// Unpack the error options if any
var errorOptions = _getWriteConcern(this, options, callback);
// If we are executing in safe mode or safe both the update and the safe command must happen on the same line
if(errorOptions && errorOptions != false && errorOptions.w != -1 && errorOptions.w != 0) {
// If safe is defined check for error message
if(_hasWriteConcern(errorOptions) && typeof callback == 'function') {
// Insert options
var commandOptions = {read:false};
// If we have safe set set async to false
Expand Down Expand Up @@ -459,6 +465,8 @@ Collection.prototype.update = function update(selector, document, options, callb
callback(null, error[0].n, error[0]);
}
});
} else if(_hasWriteConcern(errorOptions) && callback == null) {
throw new Error("Cannot use a writeConcern without a provided callback");
} else {
// Execute update
var result = this.db._executeUpdateCommand(updateCommand);
Expand Down Expand Up @@ -1634,61 +1642,60 @@ Object.defineProperty(Collection.prototype, "hint", {
/**
* @ignore
*/
var _getWriteConcern = function(self, options, callback) {
// Collect errorOptions
var errorOptions = options.safe != null ? options.safe : null;
errorOptions = errorOptions == null && self.opts.safe != null ? self.opts.safe : errorOptions;
errorOptions = errorOptions == null && self.db.safe != null ? self.db.safe : errorOptions;

// Local options first
if(typeof options.w == 'number'
|| typeof options.journal == 'boolean' || typeof options.fsync == 'boolean') {
errorOptions = options;
} else if(typeof self.opts.w == 'number'
|| typeof self.opts.journal == 'boolean' || typeof self.opts.fsync == 'boolean') {
errorOptions = self.opts;
} else if(typeof self.db.options.w == 'number'
|| typeof self.db.options.journal == 'boolean' || typeof self.db.options.fsync == 'boolean') {
errorOptions = self.db.options;
}

// Check that we have a valid combination
if(typeof errorOptions.w == 'number' && errorOptions.w < 1 && (errorOptions.journal == true || errorOptions.fsync == true)) {
throw new Error("No acknowlegement using w < 1 cannot be combined with journal:ture or fsync:true");
}

// Verify correct behavior of the error conditions
if(errorOptions
&& (errorOptions == true || errorOptions.w >= 1)
&& typeof callback !== 'function') throw new Error("safe cannot be used without a callback");
var _hasWriteConcern = function(errorOptions) {
return errorOptions == true
|| errorOptions.w > 0
|| errorOptions.w == 'majority'
|| errorOptions.journal == true
|| errorOptions.fsync == true
}

// Clean up the options ensuring no invalid data is there
/**
* @ignore
*/
var _setWriteConcernHash = function(options) {
var finalOptions = {};
if(errorOptions.w) finalOptions.w = errorOptions.w;
if(errorOptions.fsync) finalOptions.fsync = errorOptions.fsync;
if(errorOptions.journal) finalOptions.journal = errorOptions.journal;
if(errorOptions.wtimeout) finalOptions.wtimeout = errorOptions.wtimeout;
if(errorOptions == true) finalOptions.w = 1;
if(typeof errorOptions == 'object' && Object.keys(errorOptions).length == 0) finalOptions.w = 1;

// Return the error options
if(options.w != null) finalOptions.w = options.w;
if(options.journal == true) finalOptions.journal = options.journal;
if(options.fsync == true) finalOptions.fsync = options.fsync;
if(options.wtimeout != null) finalOptions.wtimeout = options.wtimeout;
return finalOptions;
}

/**
* Expose.
* @ignore
*/
exports.Collection = Collection;










var _getWriteConcern = function(self, options, callback) {
// Final options
var finalOptions = {w:1};
// Local options verification
if(options.w != null || typeof options.journal == 'boolean' || typeof options.fsync == 'boolean') {
finalOptions = _setWriteConcernHash(options);
} else if(typeof options.safe == "boolean") {
finalOptions = {w: (options.safe ? 1 : 0)};
} else if(options.safe != null && typeof options.safe == 'object') {
finalOptions = _setWriteConcernHash(options.safe);
} else if(self.opts.w != null || typeof self.opts.journal == 'boolean' || typeof self.opts.fsync == 'boolean') {
finalOptions = _setWriteConcernHash(self.opts);
} else if(typeof self.opts.safe == "boolean") {
finalOptions = {w: (self.opts.safe ? 1 : 0)};
} else if(self.db.safe.w != null || typeof self.db.safe.journal == 'boolean' || typeof self.db.safe.fsync == 'boolean') {
finalOptions = _setWriteConcernHash(self.db.safe);
} else if(self.db.options.w != null || typeof self.db.options.journal == 'boolean' || typeof self.db.options.fsync == 'boolean') {
finalOptions = _setWriteConcernHash(self.db.options);
} else if(typeof self.db.safe == "boolean") {
finalOptions = {w: (self.db.safe ? 1 : 0)};
}

// Ensure we don't have an invalid combination of write concerns
if(finalOptions.w < 1
&& (finalOptions.journal == true) || (finalOptions.fsync == true)) throw new Error("No acknowlegement using w < 1 cannot be combined with journal:ture or fsync:true");

// Return the options
return finalOptions;
}

/**
* Expose.
*/
exports.Collection = Collection;

0 comments on commit 7b2f2f3

Please sign in to comment.