You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					123 lines
				
				3.4 KiB
			
		
		
			
		
	
	
					123 lines
				
				3.4 KiB
			| 
											3 years ago
										 | 'use strict'; | ||
|  | 
 | ||
|  | const Aspect = require('./operation').Aspect; | ||
|  | const OperationBase = require('./operation').OperationBase; | ||
|  | const applyWriteConcern = require('../utils').applyWriteConcern; | ||
|  | const debugOptions = require('../utils').debugOptions; | ||
|  | const handleCallback = require('../utils').handleCallback; | ||
|  | const MongoError = require('../core').MongoError; | ||
|  | const ReadPreference = require('../core').ReadPreference; | ||
|  | const MongoDBNamespace = require('../utils').MongoDBNamespace; | ||
|  | const extractCommand = require('../command_utils').extractCommand; | ||
|  | 
 | ||
|  | const debugFields = [ | ||
|  |   'authSource', | ||
|  |   'w', | ||
|  |   'wtimeout', | ||
|  |   'j', | ||
|  |   'native_parser', | ||
|  |   'forceServerObjectId', | ||
|  |   'serializeFunctions', | ||
|  |   'raw', | ||
|  |   'promoteLongs', | ||
|  |   'promoteValues', | ||
|  |   'promoteBuffers', | ||
|  |   'bsonRegExp', | ||
|  |   'bufferMaxEntries', | ||
|  |   'numberOfRetries', | ||
|  |   'retryMiliSeconds', | ||
|  |   'readPreference', | ||
|  |   'pkFactory', | ||
|  |   'parentDb', | ||
|  |   'promiseLibrary', | ||
|  |   'noListener' | ||
|  | ]; | ||
|  | 
 | ||
|  | class CommandOperation extends OperationBase { | ||
|  |   constructor(db, options, collection, command) { | ||
|  |     super(options); | ||
|  | 
 | ||
|  |     if (!this.hasAspect(Aspect.WRITE_OPERATION)) { | ||
|  |       if (collection != null) { | ||
|  |         this.options.readPreference = ReadPreference.resolve(collection, options); | ||
|  |       } else { | ||
|  |         this.options.readPreference = ReadPreference.resolve(db, options); | ||
|  |       } | ||
|  |     } else { | ||
|  |       if (collection != null) { | ||
|  |         applyWriteConcern(this.options, { db, coll: collection }, this.options); | ||
|  |       } else { | ||
|  |         applyWriteConcern(this.options, { db }, this.options); | ||
|  |       } | ||
|  |       this.options.readPreference = ReadPreference.primary; | ||
|  |     } | ||
|  | 
 | ||
|  |     this.db = db; | ||
|  | 
 | ||
|  |     if (command != null) { | ||
|  |       this.command = command; | ||
|  |     } | ||
|  | 
 | ||
|  |     if (collection != null) { | ||
|  |       this.collection = collection; | ||
|  |     } | ||
|  |   } | ||
|  | 
 | ||
|  |   _buildCommand() { | ||
|  |     if (this.command != null) { | ||
|  |       return this.command; | ||
|  |     } | ||
|  |   } | ||
|  | 
 | ||
|  |   execute(callback) { | ||
|  |     const db = this.db; | ||
|  |     const options = Object.assign({}, this.options); | ||
|  | 
 | ||
|  |     // Did the user destroy the topology
 | ||
|  |     if (db.serverConfig && db.serverConfig.isDestroyed()) { | ||
|  |       return callback(new MongoError('topology was destroyed')); | ||
|  |     } | ||
|  | 
 | ||
|  |     let command; | ||
|  |     try { | ||
|  |       command = this._buildCommand(); | ||
|  |     } catch (e) { | ||
|  |       return callback(e); | ||
|  |     } | ||
|  | 
 | ||
|  |     // Get the db name we are executing against
 | ||
|  |     const dbName = options.dbName || options.authdb || db.databaseName; | ||
|  | 
 | ||
|  |     // Convert the readPreference if its not a write
 | ||
|  |     if (this.hasAspect(Aspect.WRITE_OPERATION)) { | ||
|  |       if (options.writeConcern && (!options.session || !options.session.inTransaction())) { | ||
|  |         command.writeConcern = options.writeConcern; | ||
|  |       } | ||
|  |     } | ||
|  | 
 | ||
|  |     // Debug information
 | ||
|  |     if (db.s.logger.isDebug()) { | ||
|  |       const extractedCommand = extractCommand(command); | ||
|  |       db.s.logger.debug( | ||
|  |         `executing command ${JSON.stringify( | ||
|  |           extractedCommand.shouldRedact ? `${extractedCommand.name} details REDACTED` : command | ||
|  |         )} against ${dbName}.$cmd with options [${JSON.stringify( | ||
|  |           debugOptions(debugFields, options) | ||
|  |         )}]`
 | ||
|  |       ); | ||
|  |     } | ||
|  | 
 | ||
|  |     const namespace = | ||
|  |       this.namespace != null ? this.namespace : new MongoDBNamespace(dbName, '$cmd'); | ||
|  | 
 | ||
|  |     // Execute command
 | ||
|  |     db.s.topology.command(namespace, command, options, (err, result) => { | ||
|  |       if (err) return handleCallback(callback, err); | ||
|  |       if (options.full) return handleCallback(callback, null, result); | ||
|  |       handleCallback(callback, null, result.result); | ||
|  |     }); | ||
|  |   } | ||
|  | } | ||
|  | 
 | ||
|  | module.exports = CommandOperation; |