@qrvey/formula-lang
Version:
QFormula support for qrvey projects
111 lines • 4.07 kB
JavaScript
import { AST_PRIMITIVES } from '../constants';
import { isDateParam, isNumberParam, isStringParam, removeQuotes, } from '../utils';
import { greaterThanOrEqualToReference } from '../utils/greaterThanOrEqualToReference';
import { isAnAllowedValue } from '../utils/isAnAllowedValue';
import { isInteger } from '../utils/isInteger';
/**
* `DATESUBTRACT` Subtract a specific date part value to a given date.
*/
export const DATESUBTRACT = {
identifier: 'DATESUBTRACT',
parameters: [
{
identifier: 'DATE',
optional: false,
expectedPrimitive: AST_PRIMITIVES.DATE,
validator: [isDateParam],
},
{
identifier: 'UNIT',
optional: false,
expectedPrimitive: AST_PRIMITIVES.STRING,
validator: [
isStringParam,
isAnAllowedValue(['Y', 'M', 'D', 'H', 'MI', 'S']),
],
},
{
identifier: 'INTERVAL',
optional: false,
expectedPrimitive: AST_PRIMITIVES.NUMBER,
validator: [
isNumberParam,
greaterThanOrEqualToReference(0),
isInteger,
],
},
],
transpiler: {
elasticsearch,
snowflake,
redshift,
postgresql,
},
primitiveResult: AST_PRIMITIVES.DATE,
};
function elasticsearch(date, unit, interval) {
unit = removeQuotes(unit);
switch (unit) {
case 'Y':
return `${date}.minusYears((long) Math.floor(${interval}))`;
case 'M':
return `${date}.minusMonths((long) Math.floor(${interval}))`;
case 'D':
return `${date}.minusDays((long) Math.floor(${interval}))`;
case 'H':
return `${date}.minusHours((long) Math.floor(${interval}))`;
case 'MI':
return `${date}.minusMinutes((long) Math.floor(${interval}))`;
case 'S':
return `${date}.minusSeconds((long) Math.floor(${interval}))`;
default:
return '';
}
}
function SQL(date, unit, interval) {
unit = removeQuotes(unit);
const sqlDateSubtract = (_date, _unit, _interval) => `DATEADD(${_unit}, FLOOR(${_interval})::INTEGER * -1, ${_date})`;
switch (unit) {
case 'Y':
return sqlDateSubtract(date, `month`, `${interval} * 12`); // Year to month conversion to get the same result for leap years. Redshift behavior is different for leap year example `2016-02-29` https://docs.aws.amazon.com/redshift/latest/dg/r_DATEADD_function.html
case 'M':
return sqlDateSubtract(date, `month`, interval);
case 'D':
return sqlDateSubtract(date, `day`, interval);
case 'H':
return sqlDateSubtract(date, `hour`, interval);
case 'MI':
return sqlDateSubtract(date, `minute`, interval);
case 'S':
return sqlDateSubtract(date, `second`, interval);
default:
return '';
}
}
function snowflake(date, unit, interval) {
return SQL(date, unit, interval);
}
function redshift(date, unit, interval) {
return SQL(date, unit, interval);
}
function postgresql(date, unit, interval) {
unit = removeQuotes(unit);
const sqlDateSubtract = (_date, _unit) => `${_date} - interval ${_unit}`;
switch (unit) {
case 'Y':
return sqlDateSubtract(date, `'1 year' * FLOOR(${interval})::INTEGER`);
case 'M':
return sqlDateSubtract(date, `'1 month' * FLOOR(${interval})::INTEGER`);
case 'D':
return sqlDateSubtract(date, `'1 day' * FLOOR(${interval})::INTEGER`);
case 'H':
return sqlDateSubtract(date, `'1 hour' * FLOOR(${interval})::INTEGER`);
case 'MI':
return sqlDateSubtract(date, `'1 minute' * FLOOR(${interval})::INTEGER`);
case 'S':
return sqlDateSubtract(date, `'1 second' * FLOOR(${interval})::INTEGER`);
default:
return '';
}
}
//# sourceMappingURL=datesubtract.js.map