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