WhereInCompositeMsSqlOperation.js 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. const ObjectionToKnexConvertingOperation = require('../ObjectionToKnexConvertingOperation');
  2. const { getTempColumn } = require('../../../utils/tmpColumnUtils');
  3. const { flatten, zipObject } = require('../../../utils/objectUtils');
  4. class WhereInCompositeMsSqlOperation extends ObjectionToKnexConvertingOperation {
  5. constructor(name, opt) {
  6. super(name, opt);
  7. this.prefix = this.opt.prefix || null;
  8. }
  9. onBuildKnex(knexBuilder, builder) {
  10. this.build(builder.knex(), knexBuilder, this.args[0], this.args[1]);
  11. }
  12. build(knex, knexBuilder, columns, values) {
  13. let isCompositeKey = Array.isArray(columns) && columns.length > 1;
  14. if (isCompositeKey) {
  15. this.buildComposite(knex, knexBuilder, columns, values);
  16. } else {
  17. this.buildNonComposite(knexBuilder, columns, values);
  18. }
  19. }
  20. buildComposite(knex, knexBuilder, columns, values) {
  21. const helperColumns = columns.map((_, index) => getTempColumn(index));
  22. if (Array.isArray(values)) {
  23. this.buildCompositeValue(knex, knexBuilder, columns, helperColumns, values);
  24. } else {
  25. this.buildCompositeSubquery(
  26. knex,
  27. knexBuilder,
  28. columns,
  29. helperColumns,
  30. values.as(knex.raw(`V(${helperColumns.map(_ => '??')})`, helperColumns))
  31. );
  32. }
  33. }
  34. buildCompositeValue(knex, knexBuilder, columns, helperColumns, values) {
  35. return this.buildCompositeSubquery(
  36. knex,
  37. knexBuilder,
  38. columns,
  39. helperColumns,
  40. knex.raw(
  41. `(VALUES ${values
  42. .map(value => `(${value.map(_ => '?').join(',')})`)
  43. .join(',')}) AS V(${helperColumns.map(_ => '??').join(',')})`,
  44. flatten(values).concat(helperColumns)
  45. )
  46. );
  47. }
  48. buildCompositeSubquery(knex, knexBuilder, columns, helperColumns, subQuery) {
  49. const wrapperQuery = knex
  50. .from(subQuery)
  51. .where(zipObject(helperColumns, columns.map(column => knex.raw('??', column))));
  52. if (this.prefix === 'not') {
  53. return knexBuilder.whereNotExists(wrapperQuery);
  54. } else {
  55. return knexBuilder.whereExists(wrapperQuery);
  56. }
  57. }
  58. buildNonComposite(knexBuilder, columns, values) {
  59. const col = typeof columns === 'string' ? columns : columns[0];
  60. if (Array.isArray(values)) {
  61. values = pickNonNull(values, []);
  62. } else {
  63. values = [values];
  64. }
  65. this.whereIn(knexBuilder, col, values);
  66. }
  67. whereIn(knexBuilder, col, val) {
  68. if (this.prefix === 'not') {
  69. knexBuilder.whereNotIn(col, val);
  70. } else {
  71. knexBuilder.whereIn(col, val);
  72. }
  73. }
  74. }
  75. function pickNonNull(values, output) {
  76. for (let i = 0, l = values.length; i < l; ++i) {
  77. const val = values[i];
  78. if (Array.isArray(val)) {
  79. pickNonNull(val, output);
  80. } else if (val !== null && val !== undefined) {
  81. output.push(val);
  82. }
  83. }
  84. return output;
  85. }
  86. module.exports = WhereInCompositeMsSqlOperation;