2019-06-04 00:37:17 +02:00
|
|
|
const Raw = require('./raw');
|
2021-01-07 02:04:10 +02:00
|
|
|
const {
|
|
|
|
columnize: columnize_,
|
|
|
|
wrap: wrap_,
|
|
|
|
unwrapRaw: unwrapRaw_,
|
|
|
|
operator: operator_,
|
|
|
|
outputQuery: outputQuery_,
|
|
|
|
rawOrFn: rawOrFn_,
|
|
|
|
} = require('./formatter/wrappingFormatter');
|
|
|
|
const {
|
|
|
|
compileCallback: compileCallback_,
|
|
|
|
} = require('./formatter/formatterUtils');
|
2015-05-09 13:58:18 -04:00
|
|
|
|
2016-05-17 01:01:34 +10:00
|
|
|
// Valid values for the `order by` clause generation.
|
2016-05-18 19:59:24 +10:00
|
|
|
const orderBys = ['asc', 'desc'];
|
2016-05-17 01:01:34 +10:00
|
|
|
|
2019-06-04 00:37:17 +02:00
|
|
|
class Formatter {
|
2018-02-01 23:41:01 +01:00
|
|
|
constructor(client, builder) {
|
2018-07-09 08:10:34 -04:00
|
|
|
this.client = client;
|
|
|
|
this.builder = builder;
|
|
|
|
this.bindings = [];
|
2016-09-12 18:26:49 -04:00
|
|
|
}
|
2015-05-09 13:58:18 -04:00
|
|
|
|
|
|
|
// Accepts a string or array of columns to wrap as appropriate.
|
2016-05-06 13:28:50 +10:00
|
|
|
columnize(target) {
|
2021-01-07 02:04:10 +02:00
|
|
|
return columnize_(target, this.builder, this.client, this);
|
2016-09-12 18:26:49 -04:00
|
|
|
}
|
2015-05-09 13:58:18 -04:00
|
|
|
|
|
|
|
// Turns a list of values into a list of ?'s, joining them with commas unless
|
|
|
|
// a "joining" value is specified (e.g. ' and ')
|
2016-05-06 13:28:50 +10:00
|
|
|
parameterize(values, notSetValue) {
|
2015-05-09 13:58:18 -04:00
|
|
|
if (typeof values === 'function') return this.parameter(values);
|
2016-05-18 19:59:24 +10:00
|
|
|
values = Array.isArray(values) ? values : [values];
|
2018-07-09 08:10:34 -04:00
|
|
|
let str = '',
|
|
|
|
i = -1;
|
2015-05-09 13:58:18 -04:00
|
|
|
while (++i < values.length) {
|
2018-07-09 08:10:34 -04:00
|
|
|
if (i > 0) str += ', ';
|
|
|
|
str += this.parameter(values[i] === undefined ? notSetValue : values[i]);
|
2015-05-09 13:58:18 -04:00
|
|
|
}
|
|
|
|
return str;
|
2016-09-12 18:26:49 -04:00
|
|
|
}
|
2015-05-09 13:58:18 -04:00
|
|
|
|
2018-02-22 07:51:09 +11:00
|
|
|
// Formats `values` into a parenthesized list of parameters for a `VALUES`
|
|
|
|
// clause.
|
|
|
|
//
|
|
|
|
// [1, 2] -> '(?, ?)'
|
|
|
|
// [[1, 2], [3, 4]] -> '((?, ?), (?, ?))'
|
|
|
|
// knex('table') -> '(select * from "table")'
|
|
|
|
// knex.raw('select ?', 1) -> '(select ?)'
|
|
|
|
//
|
|
|
|
values(values) {
|
|
|
|
if (Array.isArray(values)) {
|
|
|
|
if (Array.isArray(values[0])) {
|
2018-07-09 08:10:34 -04:00
|
|
|
return `(${values
|
|
|
|
.map((value) => `(${this.parameterize(value)})`)
|
|
|
|
.join(', ')})`;
|
2018-02-22 07:51:09 +11:00
|
|
|
}
|
|
|
|
return `(${this.parameterize(values)})`;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (values instanceof Raw) {
|
|
|
|
return `(${this.parameter(values)})`;
|
|
|
|
}
|
|
|
|
|
|
|
|
return this.parameter(values);
|
|
|
|
}
|
|
|
|
|
2015-05-09 13:58:18 -04:00
|
|
|
// Checks whether a value is a function... if it is, we compile it
|
|
|
|
// otherwise we check whether it's a raw
|
2016-05-06 13:28:50 +10:00
|
|
|
parameter(value) {
|
2015-05-09 13:58:18 -04:00
|
|
|
if (typeof value === 'function') {
|
|
|
|
return this.outputQuery(this.compileCallback(value), true);
|
|
|
|
}
|
|
|
|
return this.unwrapRaw(value, true) || '?';
|
2016-09-12 18:26:49 -04:00
|
|
|
}
|
2015-05-09 13:58:18 -04:00
|
|
|
|
2016-05-06 13:28:50 +10:00
|
|
|
unwrapRaw(value, isParameter) {
|
2021-01-07 02:04:10 +02:00
|
|
|
return unwrapRaw_(value, isParameter, this.builder, this.client, this);
|
2016-09-12 18:26:49 -04:00
|
|
|
}
|
2015-05-09 13:58:18 -04:00
|
|
|
|
2017-10-31 21:33:28 +02:00
|
|
|
/**
|
|
|
|
* Creates SQL for a parameter, which might be passed to where() or .with() or
|
|
|
|
* pretty much anywhere in API.
|
|
|
|
*
|
2021-01-07 02:04:10 +02:00
|
|
|
* @param value Callback (for where or complete builder), Raw or QueryBuilder
|
2017-10-31 21:33:28 +02:00
|
|
|
* @param method Optional at least 'select' or 'update' are valid
|
|
|
|
*/
|
2016-05-06 13:28:50 +10:00
|
|
|
rawOrFn(value, method) {
|
2021-01-07 02:04:10 +02:00
|
|
|
return rawOrFn_(value, method, this.builder, this.client, this);
|
2016-09-12 18:26:49 -04:00
|
|
|
}
|
2015-05-09 13:58:18 -04:00
|
|
|
|
|
|
|
// Puts the appropriate wrapper around a value depending on the database
|
|
|
|
// engine, unless it's a knex.raw value, in which case it's left alone.
|
2019-10-29 04:38:01 +08:00
|
|
|
wrap(value, isParameter) {
|
2021-01-07 02:04:10 +02:00
|
|
|
return wrap_(value, isParameter, this.builder, this.client, this);
|
2016-09-12 18:26:49 -04:00
|
|
|
}
|
2016-02-02 14:46:18 -03:00
|
|
|
|
2016-05-06 13:28:50 +10:00
|
|
|
alias(first, second) {
|
2015-05-09 13:58:18 -04:00
|
|
|
return first + ' as ' + second;
|
2016-09-12 18:26:49 -04:00
|
|
|
}
|
2015-05-09 13:58:18 -04:00
|
|
|
|
2016-05-06 13:28:50 +10:00
|
|
|
operator(value) {
|
2021-01-07 02:04:10 +02:00
|
|
|
return operator_(value, this.builder, this.client, this);
|
2016-09-12 18:26:49 -04:00
|
|
|
}
|
2015-05-09 13:58:18 -04:00
|
|
|
|
|
|
|
// Specify the direction of the ordering.
|
2016-05-06 13:28:50 +10:00
|
|
|
direction(value) {
|
2016-05-17 01:01:34 +10:00
|
|
|
const raw = this.unwrapRaw(value);
|
2015-05-09 13:58:18 -04:00
|
|
|
if (raw) return raw;
|
|
|
|
return orderBys.indexOf((value || '').toLowerCase()) !== -1 ? value : 'asc';
|
2016-09-12 18:26:49 -04:00
|
|
|
}
|
2015-05-09 13:58:18 -04:00
|
|
|
|
|
|
|
// Compiles a callback using the query builder.
|
2016-05-06 13:28:50 +10:00
|
|
|
compileCallback(callback, method) {
|
2021-01-07 02:04:10 +02:00
|
|
|
return compileCallback_(callback, method, this.client, this);
|
2016-09-12 18:26:49 -04:00
|
|
|
}
|
2015-05-09 13:58:18 -04:00
|
|
|
|
|
|
|
// Ensures the query is aliased if necessary.
|
2016-05-06 13:28:50 +10:00
|
|
|
outputQuery(compiled, isParameter) {
|
2021-01-07 02:04:10 +02:00
|
|
|
return outputQuery_(compiled, isParameter, this.builder, this.client, this);
|
2017-10-17 01:43:20 +03:00
|
|
|
}
|
2016-09-12 18:26:49 -04:00
|
|
|
}
|
2019-06-04 00:37:17 +02:00
|
|
|
|
|
|
|
module.exports = Formatter;
|