123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192 |
- const once = require('../../utils/objectUtils').once;
- const QueryBuilderOperation = require('./QueryBuilderOperation');
- const { isPlainObject, isObject } = require('../../utils/objectUtils');
- const { isKnexQueryBuilder, isKnexJoinBuilder, isKnexRaw } = require('../../utils/knexUtils');
- const getQueryBuilderBase = once(() => require('../QueryBuilderBase'));
- const getJoinBuilder = once(() => require('../JoinBuilder'));
- // An abstract operation base class that converts all arguments from objection types
- // to knex types. For example objection query builders are converted into knex query
- // builders and objection RawBuilder instances are converted into knex Raw instances.
- class ObjectionToKnexConvertingOperation extends QueryBuilderOperation {
- constructor(name, opt) {
- super(name, opt);
- this.args = null;
- }
- onAdd(builder, args) {
- this.args = args;
- return shouldBeAdded(this.name, builder, args);
- }
- onBuild(builder) {
- this.args = convertArgs(this.name, builder, this.args);
- }
- }
- function shouldBeAdded(opName, builder, args) {
- const skipUndefined = builder.internalOptions().skipUndefined;
- for (let i = 0, l = args.length; i < l; ++i) {
- const arg = args[i];
- if (isUndefined(arg)) {
- if (skipUndefined) {
- return false;
- } else {
- throw new Error(
- `undefined passed as argument #${i} for '${opName}' operation. Call skipUndefined() method to ignore the undefined values.`
- );
- }
- }
- }
- return true;
- }
- function convertArgs(opName, builder, args) {
- const skipUndefined = builder.internalOptions().skipUndefined;
- const out = new Array(args.length);
- for (let i = 0, l = args.length; i < l; ++i) {
- const arg = args[i];
- if (hasToKnexRawMethod(arg)) {
- out[i] = convertToKnexRaw(arg, builder);
- } else if (isObjectionQueryBuilderBase(arg)) {
- out[i] = convertQueryBuilderBase(arg, builder);
- } else if (isArray(arg)) {
- out[i] = convertArray(arg, builder, i, opName, skipUndefined);
- } else if (isFunction(arg)) {
- out[i] = convertFunction(arg, builder);
- } else if (isModel(arg)) {
- out[i] = convertModel(arg);
- } else if (isPlainObject(arg)) {
- out[i] = convertPlainObject(arg, builder, i, opName, skipUndefined);
- } else {
- out[i] = arg;
- }
- }
- return out;
- }
- function isUndefined(item) {
- return item === undefined;
- }
- function hasToKnexRawMethod(item) {
- return isObject(item) && typeof item.toKnexRaw === 'function';
- }
- function convertToKnexRaw(item, builder) {
- return item.toKnexRaw(builder.knex());
- }
- function isObjectionQueryBuilderBase(item) {
- return isObject(item) && item.isObjectionQueryBuilderBase === true;
- }
- function convertQueryBuilderBase(item, builder) {
- return item.subqueryOf(builder).build();
- }
- function isArray(item) {
- return Array.isArray(item);
- }
- function convertArray(arr, builder, i, opName, skipUndefined) {
- const out = [];
- for (let j = 0, l = arr.length; j < l; ++j) {
- const item = arr[j];
- if (item === undefined) {
- if (!skipUndefined) {
- throw new Error(
- `undefined passed as an item in argument #${i} for '${opName}' operation. Call skipUndefined() method to ignore the undefined values.`
- );
- }
- } else if (hasToKnexRawMethod(item)) {
- out.push(convertToKnexRaw(item, builder));
- } else if (isObjectionQueryBuilderBase(item)) {
- out.push(convertQueryBuilderBase(item));
- } else {
- out.push(item);
- }
- }
- return out;
- }
- function isFunction(item) {
- return typeof item === 'function';
- }
- function convertFunction(func, builder) {
- return function convertedKnexArgumentFunction() {
- if (isKnexQueryBuilder(this)) {
- convertQueryBuilderFunction(this, func, builder);
- } else if (isKnexJoinBuilder(this)) {
- convertJoinBuilderFunction(this, func, builder);
- } else {
- return func.apply(this, arguments);
- }
- };
- }
- function convertQueryBuilderFunction(knexQueryBuilder, func, builder) {
- const QueryBuilderBase = getQueryBuilderBase();
- const convertedQueryBuilder = new QueryBuilderBase(builder.knex());
- convertedQueryBuilder.subqueryOf(builder);
- func.call(convertedQueryBuilder, convertedQueryBuilder);
- convertedQueryBuilder.buildInto(knexQueryBuilder);
- }
- function convertJoinBuilderFunction(knexJoinBuilder, func, builder) {
- const JoinBuilder = getJoinBuilder();
- const joinClauseBuilder = new JoinBuilder(builder.knex());
- joinClauseBuilder.subqueryOf(builder);
- func.call(joinClauseBuilder, joinClauseBuilder);
- joinClauseBuilder.buildInto(knexJoinBuilder);
- }
- function isModel(item) {
- return isObject(item) && item.$isObjectionModel;
- }
- function convertModel(model) {
- return model.$toDatabaseJson();
- }
- function convertPlainObject(obj, builder, i, opName, skipUndefined) {
- const out = {};
- const keys = Object.keys(obj);
- for (let j = 0, l = keys.length; j < l; ++j) {
- const key = keys[j];
- const item = obj[key];
- if (item === undefined) {
- if (!skipUndefined) {
- throw new Error(
- `undefined passed as a property in argument #${i} for '${opName}' operation. Call skipUndefined() method to ignore the undefined values.`
- );
- }
- } else if (hasToKnexRawMethod(item)) {
- out[key] = convertToKnexRaw(item, builder);
- } else if (isObjectionQueryBuilderBase(item)) {
- out[key] = convertQueryBuilderBase(item, builder);
- } else {
- out[key] = item;
- }
- }
- return out;
- }
- module.exports = ObjectionToKnexConvertingOperation;
|