InsertGraphOperation.js 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. const DelegateOperation = require('./DelegateOperation');
  2. const InsertOperation = require('./InsertOperation');
  3. const insertFuncBuilder = require('../graphInserter/inserter');
  4. const GraphInserter = require('../graphInserter/GraphInserter');
  5. class InsertGraphOperation extends DelegateOperation {
  6. constructor(name, opt) {
  7. super(name, opt);
  8. if (!this.delegate.is(InsertOperation)) {
  9. throw new Error('Invalid delegate');
  10. }
  11. // Our delegate operation inherits from `InsertOperation`. Disable the call-time
  12. // validation. We do the validation in onAfter1 instead.
  13. this.delegate.modelOptions.skipValidation = true;
  14. this.insertOpt = opt.opt || {};
  15. }
  16. onAdd(builder, args) {
  17. const retVal = super.onAdd(builder, args);
  18. // We resolve this query here and will not execute it. This is because the root
  19. // value may depend on other models in the graph and cannot be inserted first.
  20. builder.resolve([]);
  21. return retVal;
  22. }
  23. get models() {
  24. return this.delegate.models;
  25. }
  26. get isArray() {
  27. return this.delegate.isArray;
  28. }
  29. onBefore1() {
  30. // Do nothing.
  31. }
  32. onBefore2() {
  33. // Do nothing. We override this with empty implementation so that
  34. // the $beforeInsert() hooks are not called twice for the root models.
  35. }
  36. onBefore3() {
  37. // Do nothing.
  38. }
  39. onBuild() {
  40. // Do nothing.
  41. }
  42. onBuildKnex() {
  43. // Do nothing.
  44. }
  45. beforeGraphInserterCreated(builder) {
  46. // For subclasses to implement.
  47. }
  48. afterGraphInserterCreated(builder, graphInserter) {
  49. // For subclasses to implement.
  50. }
  51. // We overrode all other hooks but this one and do all the work in here.
  52. // This is a bit hacky.
  53. onAfter1(builder) {
  54. const ModelClass = builder.modelClass();
  55. const insertFunc = insertFuncBuilder(builder);
  56. this.beforeGraphInserterCreated(builder);
  57. const graphInserter = new GraphInserter({
  58. modelClass: ModelClass,
  59. models: this.models,
  60. allowedRelations: builder.allowedUpsertExpression(),
  61. queryContext: builder.context(),
  62. knex: builder.knex(),
  63. opt: this.insertOpt
  64. });
  65. this.afterGraphInserterCreated(builder, graphInserter);
  66. return graphInserter.execute(insertFunc).then(() => {
  67. return super.onAfter1(builder, this.models);
  68. });
  69. }
  70. onAfter2() {
  71. // We override this with empty implementation so that the $afterInsert() hooks
  72. // are not called twice for the root models.
  73. return this.isArray ? this.models : this.models[0] || null;
  74. }
  75. }
  76. module.exports = InsertGraphOperation;