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
						
					
					
				| '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;
 |