operation.js 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. 'use strict';
  2. const Explain = require('../explain').Explain;
  3. const MongoError = require('../core/error').MongoError;
  4. const Aspect = {
  5. READ_OPERATION: Symbol('READ_OPERATION'),
  6. WRITE_OPERATION: Symbol('WRITE_OPERATION'),
  7. RETRYABLE: Symbol('RETRYABLE'),
  8. EXECUTE_WITH_SELECTION: Symbol('EXECUTE_WITH_SELECTION'),
  9. NO_INHERIT_OPTIONS: Symbol('NO_INHERIT_OPTIONS'),
  10. EXPLAINABLE: Symbol('EXPLAINABLE')
  11. };
  12. /**
  13. * This class acts as a parent class for any operation and is responsible for setting this.options,
  14. * as well as setting and getting a session.
  15. * Additionally, this class implements `hasAspect`, which determines whether an operation has
  16. * a specific aspect.
  17. */
  18. class OperationBase {
  19. constructor(options) {
  20. this.options = Object.assign({}, options);
  21. if (this.hasAspect(Aspect.EXPLAINABLE)) {
  22. this.explain = Explain.fromOptions(options);
  23. } else if (this.options.explain !== undefined) {
  24. throw new MongoError(`explain is not supported on this command`);
  25. }
  26. }
  27. hasAspect(aspect) {
  28. if (this.constructor.aspects == null) {
  29. return false;
  30. }
  31. return this.constructor.aspects.has(aspect);
  32. }
  33. set session(session) {
  34. Object.assign(this.options, { session });
  35. }
  36. get session() {
  37. return this.options.session;
  38. }
  39. clearSession() {
  40. delete this.options.session;
  41. }
  42. get canRetryRead() {
  43. return true;
  44. }
  45. execute() {
  46. throw new TypeError('`execute` must be implemented for OperationBase subclasses');
  47. }
  48. }
  49. function defineAspects(operation, aspects) {
  50. if (!Array.isArray(aspects) && !(aspects instanceof Set)) {
  51. aspects = [aspects];
  52. }
  53. aspects = new Set(aspects);
  54. Object.defineProperty(operation, 'aspects', {
  55. value: aspects,
  56. writable: false
  57. });
  58. return aspects;
  59. }
  60. module.exports = {
  61. Aspect,
  62. defineAspects,
  63. OperationBase
  64. };