create_index.js 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. 'use strict';
  2. const Aspect = require('./operation').Aspect;
  3. const CommandOperation = require('./command');
  4. const defineAspects = require('./operation').defineAspects;
  5. const handleCallback = require('../utils').handleCallback;
  6. const MongoError = require('../core').MongoError;
  7. const parseIndexOptions = require('../utils').parseIndexOptions;
  8. const keysToOmit = new Set([
  9. 'name',
  10. 'key',
  11. 'writeConcern',
  12. 'w',
  13. 'wtimeout',
  14. 'j',
  15. 'fsync',
  16. 'readPreference',
  17. 'session'
  18. ]);
  19. class CreateIndexOperation extends CommandOperation {
  20. constructor(db, name, fieldOrSpec, options) {
  21. super(db, options);
  22. // Build the index
  23. const indexParameters = parseIndexOptions(fieldOrSpec);
  24. // Generate the index name
  25. const indexName = typeof options.name === 'string' ? options.name : indexParameters.name;
  26. // Set up the index
  27. const indexesObject = { name: indexName, key: indexParameters.fieldHash };
  28. this.name = name;
  29. this.fieldOrSpec = fieldOrSpec;
  30. this.indexes = indexesObject;
  31. }
  32. _buildCommand() {
  33. const options = this.options;
  34. const name = this.name;
  35. const indexes = this.indexes;
  36. // merge all the options
  37. for (let optionName in options) {
  38. if (!keysToOmit.has(optionName)) {
  39. indexes[optionName] = options[optionName];
  40. }
  41. }
  42. // Create command, apply write concern to command
  43. const cmd = { createIndexes: name, indexes: [indexes] };
  44. return cmd;
  45. }
  46. execute(callback) {
  47. const db = this.db;
  48. const options = this.options;
  49. const indexes = this.indexes;
  50. // Get capabilities
  51. const capabilities = db.s.topology.capabilities();
  52. // Did the user pass in a collation, check if our write server supports it
  53. if (options.collation && capabilities && !capabilities.commandsTakeCollation) {
  54. // Create a new error
  55. const error = new MongoError('server/primary/mongos does not support collation');
  56. error.code = 67;
  57. // Return the error
  58. return callback(error);
  59. }
  60. // Ensure we have a callback
  61. if (options.writeConcern && typeof callback !== 'function') {
  62. throw MongoError.create({
  63. message: 'Cannot use a writeConcern without a provided callback',
  64. driver: true
  65. });
  66. }
  67. // Attempt to run using createIndexes command
  68. super.execute((err, result) => {
  69. if (err == null) return handleCallback(callback, err, indexes.name);
  70. return handleCallback(callback, err, result);
  71. });
  72. }
  73. }
  74. defineAspects(CreateIndexOperation, Aspect.WRITE_OPERATION);
  75. module.exports = CreateIndexOperation;