|  |  |  | "use strict"; | 
					
						
							|  |  |  | Object.defineProperty(exports, "__esModule", { value: true }); | 
					
						
							|  |  |  | exports.IndexInformationOperation = exports.IndexExistsOperation = exports.ListIndexesOperation = exports.DropIndexesOperation = exports.DropIndexOperation = exports.EnsureIndexOperation = exports.CreateIndexOperation = exports.CreateIndexesOperation = exports.IndexesOperation = void 0; | 
					
						
							|  |  |  | const error_1 = require("../error"); | 
					
						
							|  |  |  | const read_preference_1 = require("../read_preference"); | 
					
						
							|  |  |  | const utils_1 = require("../utils"); | 
					
						
							|  |  |  | const command_1 = require("./command"); | 
					
						
							|  |  |  | const common_functions_1 = require("./common_functions"); | 
					
						
							|  |  |  | const operation_1 = require("./operation"); | 
					
						
							|  |  |  | const VALID_INDEX_OPTIONS = new Set([ | 
					
						
							|  |  |  |     'background', | 
					
						
							|  |  |  |     'unique', | 
					
						
							|  |  |  |     'name', | 
					
						
							|  |  |  |     'partialFilterExpression', | 
					
						
							|  |  |  |     'sparse', | 
					
						
							|  |  |  |     'hidden', | 
					
						
							|  |  |  |     'expireAfterSeconds', | 
					
						
							|  |  |  |     'storageEngine', | 
					
						
							|  |  |  |     'collation', | 
					
						
							|  |  |  |     'version', | 
					
						
							|  |  |  |     // text indexes
 | 
					
						
							|  |  |  |     'weights', | 
					
						
							|  |  |  |     'default_language', | 
					
						
							|  |  |  |     'language_override', | 
					
						
							|  |  |  |     'textIndexVersion', | 
					
						
							|  |  |  |     // 2d-sphere indexes
 | 
					
						
							|  |  |  |     '2dsphereIndexVersion', | 
					
						
							|  |  |  |     // 2d indexes
 | 
					
						
							|  |  |  |     'bits', | 
					
						
							|  |  |  |     'min', | 
					
						
							|  |  |  |     'max', | 
					
						
							|  |  |  |     // geoHaystack Indexes
 | 
					
						
							|  |  |  |     'bucketSize', | 
					
						
							|  |  |  |     // wildcard indexes
 | 
					
						
							|  |  |  |     'wildcardProjection' | 
					
						
							|  |  |  | ]); | 
					
						
							|  |  |  | function isIndexDirection(x) { | 
					
						
							|  |  |  |     return (typeof x === 'number' || x === '2d' || x === '2dsphere' || x === 'text' || x === 'geoHaystack'); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | function isSingleIndexTuple(t) { | 
					
						
							|  |  |  |     return Array.isArray(t) && t.length === 2 && isIndexDirection(t[1]); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | function makeIndexSpec(indexSpec, options) { | 
					
						
							|  |  |  |     const key = new Map(); | 
					
						
							|  |  |  |     const indexSpecs = !Array.isArray(indexSpec) || isSingleIndexTuple(indexSpec) ? [indexSpec] : indexSpec; | 
					
						
							|  |  |  |     // Iterate through array and handle different types
 | 
					
						
							|  |  |  |     for (const spec of indexSpecs) { | 
					
						
							|  |  |  |         if (typeof spec === 'string') { | 
					
						
							|  |  |  |             key.set(spec, 1); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else if (Array.isArray(spec)) { | 
					
						
							|  |  |  |             key.set(spec[0], spec[1] ?? 1); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else if (spec instanceof Map) { | 
					
						
							|  |  |  |             for (const [property, value] of spec) { | 
					
						
							|  |  |  |                 key.set(property, value); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else if ((0, utils_1.isObject)(spec)) { | 
					
						
							|  |  |  |             for (const [property, value] of Object.entries(spec)) { | 
					
						
							|  |  |  |                 key.set(property, value); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return { ...options, key }; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | /** @internal */ | 
					
						
							|  |  |  | class IndexesOperation extends operation_1.AbstractOperation { | 
					
						
							|  |  |  |     constructor(collection, options) { | 
					
						
							|  |  |  |         super(options); | 
					
						
							|  |  |  |         this.options = options; | 
					
						
							|  |  |  |         this.collection = collection; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     execute(server, session, callback) { | 
					
						
							|  |  |  |         const coll = this.collection; | 
					
						
							|  |  |  |         const options = this.options; | 
					
						
							|  |  |  |         (0, common_functions_1.indexInformation)(coll.s.db, coll.collectionName, { full: true, ...options, readPreference: this.readPreference, session }, callback); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | exports.IndexesOperation = IndexesOperation; | 
					
						
							|  |  |  | /** @internal */ | 
					
						
							|  |  |  | class CreateIndexesOperation extends command_1.CommandOperation { | 
					
						
							|  |  |  |     constructor(parent, collectionName, indexes, options) { | 
					
						
							|  |  |  |         super(parent, options); | 
					
						
							|  |  |  |         this.options = options ?? {}; | 
					
						
							|  |  |  |         this.collectionName = collectionName; | 
					
						
							|  |  |  |         this.indexes = indexes.map(userIndex => { | 
					
						
							|  |  |  |             // Ensure the key is a Map to preserve index key ordering
 | 
					
						
							|  |  |  |             const key = userIndex.key instanceof Map ? userIndex.key : new Map(Object.entries(userIndex.key)); | 
					
						
							|  |  |  |             const name = userIndex.name != null ? userIndex.name : Array.from(key).flat().join('_'); | 
					
						
							|  |  |  |             const validIndexOptions = Object.fromEntries(Object.entries({ ...userIndex }).filter(([optionName]) => VALID_INDEX_OPTIONS.has(optionName))); | 
					
						
							|  |  |  |             return { | 
					
						
							|  |  |  |                 ...validIndexOptions, | 
					
						
							|  |  |  |                 name, | 
					
						
							|  |  |  |                 key | 
					
						
							|  |  |  |             }; | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     execute(server, session, callback) { | 
					
						
							|  |  |  |         const options = this.options; | 
					
						
							|  |  |  |         const indexes = this.indexes; | 
					
						
							|  |  |  |         const serverWireVersion = (0, utils_1.maxWireVersion)(server); | 
					
						
							|  |  |  |         const cmd = { createIndexes: this.collectionName, indexes }; | 
					
						
							|  |  |  |         if (options.commitQuorum != null) { | 
					
						
							|  |  |  |             if (serverWireVersion < 9) { | 
					
						
							|  |  |  |                 callback(new error_1.MongoCompatibilityError('Option `commitQuorum` 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, session, cmd, err => { | 
					
						
							|  |  |  |             if (err) { | 
					
						
							|  |  |  |                 callback(err); | 
					
						
							|  |  |  |                 return; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             const indexNames = indexes.map(index => index.name || ''); | 
					
						
							|  |  |  |             callback(undefined, indexNames); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | exports.CreateIndexesOperation = CreateIndexesOperation; | 
					
						
							|  |  |  | /** @internal */ | 
					
						
							|  |  |  | class CreateIndexOperation extends CreateIndexesOperation { | 
					
						
							|  |  |  |     constructor(parent, collectionName, indexSpec, options) { | 
					
						
							|  |  |  |         super(parent, collectionName, [makeIndexSpec(indexSpec, options)], options); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     execute(server, session, callback) { | 
					
						
							|  |  |  |         super.execute(server, session, (err, indexNames) => { | 
					
						
							|  |  |  |             if (err || !indexNames) | 
					
						
							|  |  |  |                 return callback(err); | 
					
						
							|  |  |  |             return callback(undefined, indexNames[0]); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | exports.CreateIndexOperation = CreateIndexOperation; | 
					
						
							|  |  |  | /** @internal */ | 
					
						
							|  |  |  | class EnsureIndexOperation extends CreateIndexOperation { | 
					
						
							|  |  |  |     constructor(db, collectionName, indexSpec, options) { | 
					
						
							|  |  |  |         super(db, collectionName, indexSpec, options); | 
					
						
							|  |  |  |         this.readPreference = read_preference_1.ReadPreference.primary; | 
					
						
							|  |  |  |         this.db = db; | 
					
						
							|  |  |  |         this.collectionName = collectionName; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     execute(server, session, callback) { | 
					
						
							|  |  |  |         const indexName = this.indexes[0].name; | 
					
						
							|  |  |  |         const cursor = this.db.collection(this.collectionName).listIndexes({ session }); | 
					
						
							|  |  |  |         cursor.toArray().then(indexes => { | 
					
						
							|  |  |  |             indexes = Array.isArray(indexes) ? indexes : [indexes]; | 
					
						
							|  |  |  |             if (indexes.some(index => index.name === indexName)) { | 
					
						
							|  |  |  |                 callback(undefined, indexName); | 
					
						
							|  |  |  |                 return; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             super.execute(server, session, callback); | 
					
						
							|  |  |  |         }, error => { | 
					
						
							|  |  |  |             if (error instanceof error_1.MongoError && error.code === error_1.MONGODB_ERROR_CODES.NamespaceNotFound) { | 
					
						
							|  |  |  |                 // ignore "NamespaceNotFound" errors
 | 
					
						
							|  |  |  |                 return super.execute(server, session, callback); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             return callback(error); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | exports.EnsureIndexOperation = EnsureIndexOperation; | 
					
						
							|  |  |  | /** @internal */ | 
					
						
							|  |  |  | class DropIndexOperation extends command_1.CommandOperation { | 
					
						
							|  |  |  |     constructor(collection, indexName, options) { | 
					
						
							|  |  |  |         super(collection, options); | 
					
						
							|  |  |  |         this.options = options ?? {}; | 
					
						
							|  |  |  |         this.collection = collection; | 
					
						
							|  |  |  |         this.indexName = indexName; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     execute(server, session, callback) { | 
					
						
							|  |  |  |         const cmd = { dropIndexes: this.collection.collectionName, index: this.indexName }; | 
					
						
							|  |  |  |         super.executeCommand(server, session, cmd, callback); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | exports.DropIndexOperation = DropIndexOperation; | 
					
						
							|  |  |  | /** @internal */ | 
					
						
							|  |  |  | class DropIndexesOperation extends DropIndexOperation { | 
					
						
							|  |  |  |     constructor(collection, options) { | 
					
						
							|  |  |  |         super(collection, '*', options); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     execute(server, session, callback) { | 
					
						
							|  |  |  |         super.execute(server, session, err => { | 
					
						
							|  |  |  |             if (err) | 
					
						
							|  |  |  |                 return callback(err, false); | 
					
						
							|  |  |  |             callback(undefined, true); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | exports.DropIndexesOperation = DropIndexesOperation; | 
					
						
							|  |  |  | /** @internal */ | 
					
						
							|  |  |  | class ListIndexesOperation extends command_1.CommandOperation { | 
					
						
							|  |  |  |     constructor(collection, options) { | 
					
						
							|  |  |  |         super(collection, options); | 
					
						
							|  |  |  |         this.options = options ?? {}; | 
					
						
							|  |  |  |         this.collectionNamespace = collection.s.namespace; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     execute(server, session, callback) { | 
					
						
							|  |  |  |         const serverWireVersion = (0, utils_1.maxWireVersion)(server); | 
					
						
							|  |  |  |         const cursor = this.options.batchSize ? { batchSize: this.options.batchSize } : {}; | 
					
						
							|  |  |  |         const command = { listIndexes: this.collectionNamespace.collection, cursor }; | 
					
						
							|  |  |  |         // we check for undefined specifically here to allow falsy values
 | 
					
						
							|  |  |  |         // eslint-disable-next-line no-restricted-syntax
 | 
					
						
							|  |  |  |         if (serverWireVersion >= 9 && this.options.comment !== undefined) { | 
					
						
							|  |  |  |             command.comment = this.options.comment; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         super.executeCommand(server, session, command, callback); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | exports.ListIndexesOperation = ListIndexesOperation; | 
					
						
							|  |  |  | /** @internal */ | 
					
						
							|  |  |  | class IndexExistsOperation extends operation_1.AbstractOperation { | 
					
						
							|  |  |  |     constructor(collection, indexes, options) { | 
					
						
							|  |  |  |         super(options); | 
					
						
							|  |  |  |         this.options = options; | 
					
						
							|  |  |  |         this.collection = collection; | 
					
						
							|  |  |  |         this.indexes = indexes; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     execute(server, session, callback) { | 
					
						
							|  |  |  |         const coll = this.collection; | 
					
						
							|  |  |  |         const indexes = this.indexes; | 
					
						
							|  |  |  |         (0, common_functions_1.indexInformation)(coll.s.db, coll.collectionName, { ...this.options, readPreference: this.readPreference, session }, (err, indexInformation) => { | 
					
						
							|  |  |  |             // If we have an error return
 | 
					
						
							|  |  |  |             if (err != null) | 
					
						
							|  |  |  |                 return callback(err); | 
					
						
							|  |  |  |             // Let's check for the index names
 | 
					
						
							|  |  |  |             if (!Array.isArray(indexes)) | 
					
						
							|  |  |  |                 return callback(undefined, indexInformation[indexes] != null); | 
					
						
							|  |  |  |             // Check in list of indexes
 | 
					
						
							|  |  |  |             for (let i = 0; i < indexes.length; i++) { | 
					
						
							|  |  |  |                 if (indexInformation[indexes[i]] == null) { | 
					
						
							|  |  |  |                     return callback(undefined, false); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             // All keys found return true
 | 
					
						
							|  |  |  |             return callback(undefined, true); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | exports.IndexExistsOperation = IndexExistsOperation; | 
					
						
							|  |  |  | /** @internal */ | 
					
						
							|  |  |  | class IndexInformationOperation extends operation_1.AbstractOperation { | 
					
						
							|  |  |  |     constructor(db, name, options) { | 
					
						
							|  |  |  |         super(options); | 
					
						
							|  |  |  |         this.options = options ?? {}; | 
					
						
							|  |  |  |         this.db = db; | 
					
						
							|  |  |  |         this.name = name; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     execute(server, session, callback) { | 
					
						
							|  |  |  |         const db = this.db; | 
					
						
							|  |  |  |         const name = this.name; | 
					
						
							|  |  |  |         (0, common_functions_1.indexInformation)(db, name, { ...this.options, readPreference: this.readPreference, session }, callback); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | exports.IndexInformationOperation = IndexInformationOperation; | 
					
						
							|  |  |  | (0, operation_1.defineAspects)(ListIndexesOperation, [ | 
					
						
							|  |  |  |     operation_1.Aspect.READ_OPERATION, | 
					
						
							|  |  |  |     operation_1.Aspect.RETRYABLE, | 
					
						
							|  |  |  |     operation_1.Aspect.CURSOR_CREATING | 
					
						
							|  |  |  | ]); | 
					
						
							|  |  |  | (0, operation_1.defineAspects)(CreateIndexesOperation, [operation_1.Aspect.WRITE_OPERATION]); | 
					
						
							|  |  |  | (0, operation_1.defineAspects)(CreateIndexOperation, [operation_1.Aspect.WRITE_OPERATION]); | 
					
						
							|  |  |  | (0, operation_1.defineAspects)(EnsureIndexOperation, [operation_1.Aspect.WRITE_OPERATION]); | 
					
						
							|  |  |  | (0, operation_1.defineAspects)(DropIndexOperation, [operation_1.Aspect.WRITE_OPERATION]); | 
					
						
							|  |  |  | (0, operation_1.defineAspects)(DropIndexesOperation, [operation_1.Aspect.WRITE_OPERATION]); | 
					
						
							|  |  |  | //# sourceMappingURL=indexes.js.map
 |