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.
		
		
		
		
		
			
		
			
				
					
					
						
							138 lines
						
					
					
						
							3.7 KiB
						
					
					
				
			
		
		
	
	
							138 lines
						
					
					
						
							3.7 KiB
						
					
					
				'use strict';
 | 
						|
 | 
						|
const Aspect = require('./operation').Aspect;
 | 
						|
const defineAspects = require('./operation').defineAspects;
 | 
						|
const CommandOperationV2 = require('./command_v2');
 | 
						|
const MongoError = require('../core').MongoError;
 | 
						|
const parseIndexOptions = require('../utils').parseIndexOptions;
 | 
						|
const maxWireVersion = require('../core/utils').maxWireVersion;
 | 
						|
 | 
						|
const VALID_INDEX_OPTIONS = new Set([
 | 
						|
  'background',
 | 
						|
  'unique',
 | 
						|
  'name',
 | 
						|
  'partialFilterExpression',
 | 
						|
  'sparse',
 | 
						|
  'expireAfterSeconds',
 | 
						|
  'storageEngine',
 | 
						|
  'collation',
 | 
						|
 | 
						|
  // text indexes
 | 
						|
  'weights',
 | 
						|
  'default_language',
 | 
						|
  'language_override',
 | 
						|
  'textIndexVersion',
 | 
						|
 | 
						|
  // 2d-sphere indexes
 | 
						|
  '2dsphereIndexVersion',
 | 
						|
 | 
						|
  // 2d indexes
 | 
						|
  'bits',
 | 
						|
  'min',
 | 
						|
  'max',
 | 
						|
 | 
						|
  // geoHaystack Indexes
 | 
						|
  'bucketSize',
 | 
						|
 | 
						|
  // wildcard indexes
 | 
						|
  'wildcardProjection'
 | 
						|
]);
 | 
						|
 | 
						|
class CreateIndexesOperation extends CommandOperationV2 {
 | 
						|
  /**
 | 
						|
   * @ignore
 | 
						|
   */
 | 
						|
  constructor(parent, collection, indexes, options) {
 | 
						|
    super(parent, options);
 | 
						|
    this.collection = collection;
 | 
						|
 | 
						|
    // createIndex can be called with a variety of styles:
 | 
						|
    //   coll.createIndex('a');
 | 
						|
    //   coll.createIndex({ a: 1 });
 | 
						|
    //   coll.createIndex([['a', 1]]);
 | 
						|
    // createIndexes is always called with an array of index spec objects
 | 
						|
    if (!Array.isArray(indexes) || Array.isArray(indexes[0])) {
 | 
						|
      this.onlyReturnNameOfCreatedIndex = true;
 | 
						|
      // TODO: remove in v4 (breaking change); make createIndex return full response as createIndexes does
 | 
						|
 | 
						|
      const indexParameters = parseIndexOptions(indexes);
 | 
						|
      // Generate the index name
 | 
						|
      const name = typeof options.name === 'string' ? options.name : indexParameters.name;
 | 
						|
      // Set up the index
 | 
						|
      const indexSpec = { name, key: indexParameters.fieldHash };
 | 
						|
      // merge valid index options into the index spec
 | 
						|
      for (let optionName in options) {
 | 
						|
        if (VALID_INDEX_OPTIONS.has(optionName)) {
 | 
						|
          indexSpec[optionName] = options[optionName];
 | 
						|
        }
 | 
						|
      }
 | 
						|
      this.indexes = [indexSpec];
 | 
						|
      return;
 | 
						|
    }
 | 
						|
 | 
						|
    this.indexes = indexes;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * @ignore
 | 
						|
   */
 | 
						|
  execute(server, callback) {
 | 
						|
    const options = this.options;
 | 
						|
    const indexes = this.indexes;
 | 
						|
 | 
						|
    const serverWireVersion = maxWireVersion(server);
 | 
						|
 | 
						|
    // Ensure we generate the correct name if the parameter is not set
 | 
						|
    for (let i = 0; i < indexes.length; i++) {
 | 
						|
      // Did the user pass in a collation, check if our write server supports it
 | 
						|
      if (indexes[i].collation && serverWireVersion < 5) {
 | 
						|
        callback(
 | 
						|
          new MongoError(
 | 
						|
            `Server ${server.name}, which reports wire version ${serverWireVersion}, does not support collation`
 | 
						|
          )
 | 
						|
        );
 | 
						|
        return;
 | 
						|
      }
 | 
						|
 | 
						|
      if (indexes[i].name == null) {
 | 
						|
        const keys = [];
 | 
						|
 | 
						|
        for (let name in indexes[i].key) {
 | 
						|
          keys.push(`${name}_${indexes[i].key[name]}`);
 | 
						|
        }
 | 
						|
 | 
						|
        // Set the name
 | 
						|
        indexes[i].name = keys.join('_');
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    const cmd = { createIndexes: this.collection, indexes };
 | 
						|
 | 
						|
    if (options.commitQuorum != null) {
 | 
						|
      if (serverWireVersion < 9) {
 | 
						|
        callback(
 | 
						|
          new MongoError('`commitQuorum` option for `createIndexes` not supported on servers < 4.4')
 | 
						|
        );
 | 
						|
        return;
 | 
						|
      }
 | 
						|
      cmd.commitQuorum = options.commitQuorum;
 | 
						|
    }
 | 
						|
 | 
						|
    // collation is set on each index, it should not be defined at the root
 | 
						|
    this.options.collation = undefined;
 | 
						|
 | 
						|
    super.executeCommand(server, cmd, (err, result) => {
 | 
						|
      if (err) {
 | 
						|
        callback(err);
 | 
						|
        return;
 | 
						|
      }
 | 
						|
 | 
						|
      callback(null, this.onlyReturnNameOfCreatedIndex ? indexes[0].name : result);
 | 
						|
    });
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
defineAspects(CreateIndexesOperation, [Aspect.WRITE_OPERATION, Aspect.EXECUTE_WITH_SELECTION]);
 | 
						|
 | 
						|
module.exports = CreateIndexesOperation;
 |