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.
		
		
		
		
		
			
		
			
				
					107 lines
				
				2.9 KiB
			
		
		
			
		
	
	
					107 lines
				
				2.9 KiB
			| 
											3 years ago
										 | 'use strict'; | ||
|  | 
 | ||
|  | const CommandOperationV2 = require('./command_v2'); | ||
|  | const Aspect = require('./operation').Aspect; | ||
|  | const defineAspects = require('./operation').defineAspects; | ||
|  | const maxWireVersion = require('../core/utils').maxWireVersion; | ||
|  | const CONSTANTS = require('../constants'); | ||
|  | 
 | ||
|  | const LIST_COLLECTIONS_WIRE_VERSION = 3; | ||
|  | 
 | ||
|  | function listCollectionsTransforms(databaseName) { | ||
|  |   const matching = `${databaseName}.`; | ||
|  | 
 | ||
|  |   return { | ||
|  |     doc: doc => { | ||
|  |       const index = doc.name.indexOf(matching); | ||
|  |       // Remove database name if available
 | ||
|  |       if (doc.name && index === 0) { | ||
|  |         doc.name = doc.name.substr(index + matching.length); | ||
|  |       } | ||
|  | 
 | ||
|  |       return doc; | ||
|  |     } | ||
|  |   }; | ||
|  | } | ||
|  | 
 | ||
|  | class ListCollectionsOperation extends CommandOperationV2 { | ||
|  |   constructor(db, filter, options) { | ||
|  |     super(db, options, { fullResponse: true }); | ||
|  | 
 | ||
|  |     this.db = db; | ||
|  |     this.filter = filter; | ||
|  |     this.nameOnly = !!this.options.nameOnly; | ||
|  | 
 | ||
|  |     if (typeof this.options.batchSize === 'number') { | ||
|  |       this.batchSize = this.options.batchSize; | ||
|  |     } | ||
|  |   } | ||
|  | 
 | ||
|  |   execute(server, callback) { | ||
|  |     if (maxWireVersion(server) < LIST_COLLECTIONS_WIRE_VERSION) { | ||
|  |       let filter = this.filter; | ||
|  |       const databaseName = this.db.s.namespace.db; | ||
|  | 
 | ||
|  |       // If we have legacy mode and have not provided a full db name filter it
 | ||
|  |       if ( | ||
|  |         typeof filter.name === 'string' && | ||
|  |         !new RegExp('^' + databaseName + '\\.').test(filter.name) | ||
|  |       ) { | ||
|  |         filter = Object.assign({}, filter); | ||
|  |         filter.name = this.db.s.namespace.withCollection(filter.name).toString(); | ||
|  |       } | ||
|  | 
 | ||
|  |       // No filter, filter by current database
 | ||
|  |       if (filter == null) { | ||
|  |         filter.name = `/${databaseName}/`; | ||
|  |       } | ||
|  | 
 | ||
|  |       // Rewrite the filter to use $and to filter out indexes
 | ||
|  |       if (filter.name) { | ||
|  |         filter = { $and: [{ name: filter.name }, { name: /^((?!\$).)*$/ }] }; | ||
|  |       } else { | ||
|  |         filter = { name: /^((?!\$).)*$/ }; | ||
|  |       } | ||
|  | 
 | ||
|  |       const transforms = listCollectionsTransforms(databaseName); | ||
|  |       server.query( | ||
|  |         `${databaseName}.${CONSTANTS.SYSTEM_NAMESPACE_COLLECTION}`, | ||
|  |         { query: filter }, | ||
|  |         { batchSize: this.batchSize || 1000 }, | ||
|  |         {}, | ||
|  |         (err, result) => { | ||
|  |           if ( | ||
|  |             result && | ||
|  |             result.message && | ||
|  |             result.message.documents && | ||
|  |             Array.isArray(result.message.documents) | ||
|  |           ) { | ||
|  |             result.message.documents = result.message.documents.map(transforms.doc); | ||
|  |           } | ||
|  | 
 | ||
|  |           callback(err, result); | ||
|  |         } | ||
|  |       ); | ||
|  | 
 | ||
|  |       return; | ||
|  |     } | ||
|  | 
 | ||
|  |     const command = { | ||
|  |       listCollections: 1, | ||
|  |       filter: this.filter, | ||
|  |       cursor: this.batchSize ? { batchSize: this.batchSize } : {}, | ||
|  |       nameOnly: this.nameOnly | ||
|  |     }; | ||
|  | 
 | ||
|  |     return super.executeCommand(server, command, callback); | ||
|  |   } | ||
|  | } | ||
|  | 
 | ||
|  | defineAspects(ListCollectionsOperation, [ | ||
|  |   Aspect.READ_OPERATION, | ||
|  |   Aspect.RETRYABLE, | ||
|  |   Aspect.EXECUTE_WITH_SELECTION | ||
|  | ]); | ||
|  | 
 | ||
|  | module.exports = ListCollectionsOperation; |