QueryBuilderOperation.js 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. // An abstract base class for all query builder operations. QueryBuilderOperations almost always
  2. // correspond to a single query builder method call. For example SelectOperation could be added when
  3. // a `select` method is called.
  4. //
  5. // QueryBuilderOperation is just a bunch of query execution lifecycle hooks that subclasses
  6. // can (but don't have to) implement.
  7. //
  8. // Basically a query builder is nothing but an array of QueryBuilderOperations. When the query is
  9. // executed the hooks are called in the order explained below. The hooks are called so that a
  10. // certain hook is called for _all_ operations before the next hook is called. For example if
  11. // a builder has 5 operations, onBefore1 hook is called for each of them (and their results are awaited)
  12. // before onBefore2 hook is called for any of the operations.
  13. class QueryBuilderOperation {
  14. constructor(name, opt) {
  15. this.name = name;
  16. this.opt = opt || {};
  17. }
  18. is(OperationClass) {
  19. return this instanceof OperationClass;
  20. }
  21. // This is called immediately when a query builder method is called.
  22. //
  23. // This method must be synchronous.
  24. // This method should never call any methods that add operations to the builder.
  25. onAdd(builder, args) {
  26. return true;
  27. }
  28. // This is called as the first thing when the query is executed but before
  29. // the actual database operation (knex query) is executed.
  30. //
  31. // This method can be asynchronous.
  32. // You may call methods that add operations to to the builder.
  33. onBefore1(builder, result) {}
  34. hasOnBefore1() {
  35. return this.onBefore1 !== QueryBuilderOperation.prototype.onBefore1;
  36. }
  37. // This is called as the second thing when the query is executed but before
  38. // the actual database operation (knex query) is executed.
  39. //
  40. // This method can be asynchronous.
  41. // You may call methods that add operations to to the builder.
  42. onBefore2(builder, result) {}
  43. hasOnBefore2() {
  44. return this.onBefore2 !== QueryBuilderOperation.prototype.onBefore2;
  45. }
  46. // This is called as the third thing when the query is executed but before
  47. // the actual database operation (knex query) is executed.
  48. //
  49. // This method can be asynchronous.
  50. // You may call methods that add operations to to the builder.
  51. onBefore3(builder, result) {}
  52. hasOnBefore3() {
  53. return this.onBefore3 !== QueryBuilderOperation.prototype.onBefore3;
  54. }
  55. // This is called as the last thing when the query is executed but before
  56. // the actual database operation (knex query) is executed. If your operation
  57. // needs to call other query building operations (methods that add QueryBuilderOperations)
  58. // this is the best and last place to do it.
  59. //
  60. // This method must be synchronous.
  61. // You may call methods that add operations to to the builder.
  62. onBuild(builder) {}
  63. hasOnBuild() {
  64. return this.onBuild !== QueryBuilderOperation.prototype.onBuild;
  65. }
  66. // This is called when the knex query is built. Here you should only call knex
  67. // methods. You may call getters and other immutable methods of the `builder`
  68. // but you should never call methods that add QueryBuilderOperations.
  69. //
  70. // This method must be synchronous.
  71. // This method should never call any methods that add operations to the builder.
  72. onBuildKnex(knexBuilder, builder) {}
  73. hasOnBuildKnex() {
  74. return this.onBuildKnex !== QueryBuilderOperation.prototype.onBuildKnex;
  75. }
  76. // The raw knex result is passed to this method right after the database query
  77. // has finished. This method may modify it and return the modified rows. The
  78. // rows are automatically converted to models (if possible) after this hook
  79. // is called.
  80. //
  81. // This method can be asynchronous.
  82. onRawResult(builder, rows) {
  83. return rows;
  84. }
  85. hasOnRawResult() {
  86. return this.onRawResult !== QueryBuilderOperation.prototype.onRawResult;
  87. }
  88. // This is called as the first thing after the query has been executed and
  89. // rows have been converted to model instances.
  90. //
  91. // This method can be asynchronous.
  92. onAfter1(builder, result) {
  93. return result;
  94. }
  95. hasOnAfter1() {
  96. return this.onAfter1 !== QueryBuilderOperation.prototype.onAfter1;
  97. }
  98. // This is called as the second thing after the query has been executed and
  99. // rows have been converted to model instances.
  100. //
  101. // This method can be asynchronous.
  102. onAfter2(builder, result) {
  103. return result;
  104. }
  105. hasOnAfter2() {
  106. return this.onAfter2 !== QueryBuilderOperation.prototype.onAfter2;
  107. }
  108. // This is called as the third thing after the query has been executed and
  109. // rows have been converted to model instances.
  110. //
  111. // This method can be asynchronous.
  112. onAfter3(builder, result) {
  113. return result;
  114. }
  115. hasOnAfter3() {
  116. return this.onAfter3 !== QueryBuilderOperation.prototype.onAfter3;
  117. }
  118. // This method can be implemented to return another operation that will replace
  119. // this one. This method is called after all `onBeforeX` and `onBuildX` hooks
  120. // but before the database query is executed.
  121. //
  122. // This method must return a QueryBuilder instance.
  123. queryExecutor(builder) {}
  124. hasQueryExecutor() {
  125. return this.queryExecutor !== QueryBuilderOperation.prototype.queryExecutor;
  126. }
  127. // This is called if an error occurs in the query execution.
  128. //
  129. // This method must return a QueryBuilder instance.
  130. onError(builder, error) {}
  131. hasOnError() {
  132. return this.onError !== QueryBuilderOperation.prototype.onError;
  133. }
  134. }
  135. module.exports = QueryBuilderOperation;