123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104 |
- const ObjectionToKnexConvertingOperation = require('../ObjectionToKnexConvertingOperation');
- const { getTempColumn } = require('../../../utils/tmpColumnUtils');
- const { flatten, zipObject } = require('../../../utils/objectUtils');
- class WhereInCompositeMsSqlOperation extends ObjectionToKnexConvertingOperation {
- constructor(name, opt) {
- super(name, opt);
- this.prefix = this.opt.prefix || null;
- }
- onBuildKnex(knexBuilder, builder) {
- this.build(builder.knex(), knexBuilder, this.args[0], this.args[1]);
- }
- build(knex, knexBuilder, columns, values) {
- let isCompositeKey = Array.isArray(columns) && columns.length > 1;
- if (isCompositeKey) {
- this.buildComposite(knex, knexBuilder, columns, values);
- } else {
- this.buildNonComposite(knexBuilder, columns, values);
- }
- }
- buildComposite(knex, knexBuilder, columns, values) {
- const helperColumns = columns.map((_, index) => getTempColumn(index));
- if (Array.isArray(values)) {
- this.buildCompositeValue(knex, knexBuilder, columns, helperColumns, values);
- } else {
- this.buildCompositeSubquery(
- knex,
- knexBuilder,
- columns,
- helperColumns,
- values.as(knex.raw(`V(${helperColumns.map(_ => '??')})`, helperColumns))
- );
- }
- }
- buildCompositeValue(knex, knexBuilder, columns, helperColumns, values) {
- return this.buildCompositeSubquery(
- knex,
- knexBuilder,
- columns,
- helperColumns,
- knex.raw(
- `(VALUES ${values
- .map(value => `(${value.map(_ => '?').join(',')})`)
- .join(',')}) AS V(${helperColumns.map(_ => '??').join(',')})`,
- flatten(values).concat(helperColumns)
- )
- );
- }
- buildCompositeSubquery(knex, knexBuilder, columns, helperColumns, subQuery) {
- const wrapperQuery = knex
- .from(subQuery)
- .where(zipObject(helperColumns, columns.map(column => knex.raw('??', column))));
- if (this.prefix === 'not') {
- return knexBuilder.whereNotExists(wrapperQuery);
- } else {
- return knexBuilder.whereExists(wrapperQuery);
- }
- }
- buildNonComposite(knexBuilder, columns, values) {
- const col = typeof columns === 'string' ? columns : columns[0];
- if (Array.isArray(values)) {
- values = pickNonNull(values, []);
- } else {
- values = [values];
- }
- this.whereIn(knexBuilder, col, values);
- }
- whereIn(knexBuilder, col, val) {
- if (this.prefix === 'not') {
- knexBuilder.whereNotIn(col, val);
- } else {
- knexBuilder.whereIn(col, val);
- }
- }
- }
- function pickNonNull(values, output) {
- for (let i = 0, l = values.length; i < l; ++i) {
- const val = values[i];
- if (Array.isArray(val)) {
- pickNonNull(val, output);
- } else if (val !== null && val !== undefined) {
- output.push(val);
- }
- }
- return output;
- }
- module.exports = WhereInCompositeMsSqlOperation;
|