WhereInCompositeSqliteOperation.js 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. const ObjectionToKnexConvertingOperation = require('../ObjectionToKnexConvertingOperation');
  2. const { isKnexQueryBuilder } = require('../../../utils/knexUtils');
  3. class WhereInCompositeSqliteOperation extends ObjectionToKnexConvertingOperation {
  4. constructor(name, opt) {
  5. super(name, opt);
  6. this.prefix = this.opt.prefix || null;
  7. }
  8. onBuildKnex(knexBuilder) {
  9. this.build(knexBuilder, this.args[0], this.args[1]);
  10. }
  11. build(knexBuilder, columns, values) {
  12. let isCompositeKey = Array.isArray(columns) && columns.length > 1;
  13. if (isCompositeKey) {
  14. this.buildComposite(knexBuilder, columns, values);
  15. } else {
  16. this.buildNonComposite(knexBuilder, columns, values);
  17. }
  18. }
  19. buildComposite(knexBuilder, columns, values) {
  20. const whereMethod = this.prefix === 'not' ? 'whereNot' : 'where';
  21. if (!Array.isArray(values)) {
  22. // If the `values` is not an array of values but a function or a subquery
  23. // we have no way to implement this method.
  24. throw new Error(`sqlite doesn't support multi-column where in clauses`);
  25. }
  26. // Sqlite doesn't support the `where in` syntax for multiple columns but
  27. // we can emulate it using grouped `or` clauses.
  28. knexBuilder[whereMethod](builder => {
  29. values.forEach(val => {
  30. builder.orWhere(builder => {
  31. columns.forEach((col, idx) => {
  32. builder.andWhere(col, val[idx]);
  33. });
  34. });
  35. });
  36. });
  37. }
  38. buildNonComposite(knexBuilder, columns, values) {
  39. let col = typeof columns === 'string' ? columns : columns[0];
  40. if (Array.isArray(values)) {
  41. values = pickNonNull(values, []);
  42. } else if (!isKnexQueryBuilder(values)) {
  43. values = [values];
  44. }
  45. // For non-composite keys we can use the normal whereIn.
  46. if (this.prefix === 'not') {
  47. knexBuilder.whereNotIn(col, values);
  48. } else {
  49. knexBuilder.whereIn(col, values);
  50. }
  51. }
  52. }
  53. function pickNonNull(values, output) {
  54. for (let i = 0, l = values.length; i < l; ++i) {
  55. const val = values[i];
  56. if (Array.isArray(val)) {
  57. pickNonNull(val, output);
  58. } else if (val !== null && val !== undefined) {
  59. output.push(val);
  60. }
  61. }
  62. return output;
  63. }
  64. module.exports = WhereInCompositeSqliteOperation;