find.js 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.FindOperation = void 0;
  4. const error_1 = require("../error");
  5. const read_concern_1 = require("../read_concern");
  6. const sort_1 = require("../sort");
  7. const utils_1 = require("../utils");
  8. const command_1 = require("./command");
  9. const operation_1 = require("./operation");
  10. const SUPPORTS_WRITE_CONCERN_AND_COLLATION = 5;
  11. /** @internal */
  12. class FindOperation extends command_1.CommandOperation {
  13. constructor(collection, ns, filter = {}, options = {}) {
  14. super(collection, options);
  15. this.options = options;
  16. this.ns = ns;
  17. if (typeof filter !== 'object' || Array.isArray(filter)) {
  18. throw new error_1.MongoInvalidArgumentError('Query filter must be a plain object or ObjectId');
  19. }
  20. // If the filter is a buffer, validate that is a valid BSON document
  21. if (Buffer.isBuffer(filter)) {
  22. const objectSize = filter[0] | (filter[1] << 8) | (filter[2] << 16) | (filter[3] << 24);
  23. if (objectSize !== filter.length) {
  24. throw new error_1.MongoInvalidArgumentError(`Query filter raw message size does not match message header size [${filter.length}] != [${objectSize}]`);
  25. }
  26. }
  27. // special case passing in an ObjectId as a filter
  28. this.filter = filter != null && filter._bsontype === 'ObjectID' ? { _id: filter } : filter;
  29. }
  30. execute(server, session, callback) {
  31. this.server = server;
  32. const serverWireVersion = (0, utils_1.maxWireVersion)(server);
  33. const options = this.options;
  34. if (options.allowDiskUse != null && serverWireVersion < 4) {
  35. callback(new error_1.MongoCompatibilityError('Option "allowDiskUse" is not supported on MongoDB < 3.2'));
  36. return;
  37. }
  38. if (options.collation && serverWireVersion < SUPPORTS_WRITE_CONCERN_AND_COLLATION) {
  39. callback(new error_1.MongoCompatibilityError(`Server ${server.name}, which reports wire version ${serverWireVersion}, does not support collation`));
  40. return;
  41. }
  42. let findCommand = makeFindCommand(this.ns, this.filter, options);
  43. if (this.explain) {
  44. findCommand = (0, utils_1.decorateWithExplain)(findCommand, this.explain);
  45. }
  46. server.command(this.ns, findCommand, {
  47. ...this.options,
  48. ...this.bsonOptions,
  49. documentsReturnedIn: 'firstBatch',
  50. session
  51. }, callback);
  52. }
  53. }
  54. exports.FindOperation = FindOperation;
  55. function makeFindCommand(ns, filter, options) {
  56. const findCommand = {
  57. find: ns.collection,
  58. filter
  59. };
  60. if (options.sort) {
  61. findCommand.sort = (0, sort_1.formatSort)(options.sort);
  62. }
  63. if (options.projection) {
  64. let projection = options.projection;
  65. if (projection && Array.isArray(projection)) {
  66. projection = projection.length
  67. ? projection.reduce((result, field) => {
  68. result[field] = 1;
  69. return result;
  70. }, {})
  71. : { _id: 1 };
  72. }
  73. findCommand.projection = projection;
  74. }
  75. if (options.hint) {
  76. findCommand.hint = (0, utils_1.normalizeHintField)(options.hint);
  77. }
  78. if (typeof options.skip === 'number') {
  79. findCommand.skip = options.skip;
  80. }
  81. if (typeof options.limit === 'number') {
  82. if (options.limit < 0) {
  83. findCommand.limit = -options.limit;
  84. findCommand.singleBatch = true;
  85. }
  86. else {
  87. findCommand.limit = options.limit;
  88. }
  89. }
  90. if (typeof options.batchSize === 'number') {
  91. if (options.batchSize < 0) {
  92. if (options.limit &&
  93. options.limit !== 0 &&
  94. Math.abs(options.batchSize) < Math.abs(options.limit)) {
  95. findCommand.limit = -options.batchSize;
  96. }
  97. findCommand.singleBatch = true;
  98. }
  99. else {
  100. findCommand.batchSize = options.batchSize;
  101. }
  102. }
  103. if (typeof options.singleBatch === 'boolean') {
  104. findCommand.singleBatch = options.singleBatch;
  105. }
  106. // we check for undefined specifically here to allow falsy values
  107. // eslint-disable-next-line no-restricted-syntax
  108. if (options.comment !== undefined) {
  109. findCommand.comment = options.comment;
  110. }
  111. if (typeof options.maxTimeMS === 'number') {
  112. findCommand.maxTimeMS = options.maxTimeMS;
  113. }
  114. const readConcern = read_concern_1.ReadConcern.fromOptions(options);
  115. if (readConcern) {
  116. findCommand.readConcern = readConcern.toJSON();
  117. }
  118. if (options.max) {
  119. findCommand.max = options.max;
  120. }
  121. if (options.min) {
  122. findCommand.min = options.min;
  123. }
  124. if (typeof options.returnKey === 'boolean') {
  125. findCommand.returnKey = options.returnKey;
  126. }
  127. if (typeof options.showRecordId === 'boolean') {
  128. findCommand.showRecordId = options.showRecordId;
  129. }
  130. if (typeof options.tailable === 'boolean') {
  131. findCommand.tailable = options.tailable;
  132. }
  133. if (typeof options.timeout === 'boolean') {
  134. findCommand.noCursorTimeout = !options.timeout;
  135. }
  136. else if (typeof options.noCursorTimeout === 'boolean') {
  137. findCommand.noCursorTimeout = options.noCursorTimeout;
  138. }
  139. if (typeof options.awaitData === 'boolean') {
  140. findCommand.awaitData = options.awaitData;
  141. }
  142. if (typeof options.allowPartialResults === 'boolean') {
  143. findCommand.allowPartialResults = options.allowPartialResults;
  144. }
  145. if (options.collation) {
  146. findCommand.collation = options.collation;
  147. }
  148. if (typeof options.allowDiskUse === 'boolean') {
  149. findCommand.allowDiskUse = options.allowDiskUse;
  150. }
  151. if (options.let) {
  152. findCommand.let = options.let;
  153. }
  154. return findCommand;
  155. }
  156. (0, operation_1.defineAspects)(FindOperation, [
  157. operation_1.Aspect.READ_OPERATION,
  158. operation_1.Aspect.RETRYABLE,
  159. operation_1.Aspect.EXPLAINABLE,
  160. operation_1.Aspect.CURSOR_CREATING
  161. ]);
  162. //# sourceMappingURL=find.js.map