miniml
Version:
A minimal, embeddable semantic data modeling language for generating SQL queries from YAML model definitions. Inspired by LookML.
116 lines • 4.33 kB
JavaScript
export function constructCurrentTimeOffsetExpression(dialect, date_offset, date_part, is_date) {
date_part = parseDatePart(date_part);
const now = is_date ? "CURRENT_DATE" : "CURRENT_TIMESTAMP";
if (dialect === "bigquery")
return `${now} - INTERVAL ${date_offset} ${date_part}`;
else if (dialect == "snowflake")
return `${now} - INTERVAL '${date_offset} ${date_part}'`;
else
throw new Error(`Invalid dialect "${dialect}"`);
}
export function constructDateRangeExpression(dialect, date_field, date_offset, date_part, include_today, is_date) {
let expression = `${date_field} >= ${constructCurrentTimeOffsetExpression(dialect, date_offset, date_part, is_date)}`;
if (!include_today)
expression += ` AND ${date_field} < ${constructTodayAtMidnightExpression(dialect, is_date)}`;
return expression;
}
export function constructDateTruncExpression(dialect, date_expr, date_granularity) {
date_expr = date_expr.trim();
date_granularity = date_granularity.trim().toUpperCase();
if (!["MINUTE", "HOUR", "DAY", "WEEK", "MONTH", "QUARTER", "YEAR"].includes(date_granularity))
throw new Error(`Invalid date_granularity "${date_granularity}"`);
if (dialect === "bigquery")
return `DATE_TRUNC(${date_expr}, ${date_granularity})`;
else if (dialect === "snowflake")
return `DATE_TRUNC(${date_granularity}, ${date_expr})`;
else
throw new Error(`Invalid dialect "${dialect}"`);
}
export function constructDateAddExpression(dialect, expression, num, date_part) {
date_part = parseDatePart(date_part);
if (dialect === "bigquery")
return `DATE_ADD(${expression}, INTERVAL ${num} ${date_part})`;
else if (dialect === "snowflake")
return `DATEADD(${date_part}, ${num}, ${expression})`;
else
throw new Error(`Invalid dialect "${dialect}"`);
}
export function constructDateSubExpression(dialect, date_field, num, date_part) {
date_part = parseDatePart(date_part);
if (dialect === "bigquery")
return `DATE_SUB(${date_field}, INTERVAL ${num} ${date_part})`;
else if (dialect === "snowflake")
return `DATEADD(${date_part}, -${num}, ${date_field})`;
else
throw new Error(`Invalid dialect "${dialect}"`);
}
export function constructTodayAtMidnightExpression(dialect, is_date) {
if (is_date)
return `CURRENT_DATE`;
if (dialect === "bigquery")
return `DATE_TRUNC(CURRENT_TIMESTAMP, DAY)`;
else if (dialect === "snowflake")
return `DATE_TRUNC('DAY', CURRENT_TIMESTAMP)`;
else
throw new Error(`Invalid dialect "${dialect}"`);
}
export function normalizeQuotesForBigQuery(expression) {
if (!expression)
return expression;
let result = "";
let inSingle = false, inDouble = false;
for (let i = 0; i < expression.length; i++) {
const ch = expression[i];
if (inSingle) {
if (ch === "\\") {
result += ch + (expression[i + 1] ?? "");
i++;
}
else if (ch === "'" && expression[i + 1] === "'") {
result += "\\'";
i++;
}
else {
result += ch;
if (ch === "'")
inSingle = false;
}
}
else if (inDouble) {
result += ch;
if (ch === "\\") {
result += expression[i + 1] ?? "";
i++;
}
else if (ch === '"')
inDouble = false;
}
else {
result += ch;
if (ch === "'")
inSingle = true;
else if (ch === '"')
inDouble = true;
}
}
return result;
}
function parseDatePart(text) {
if (/^days?$/i.test(text))
return "DAY";
else if (/^weeks?$/i.test(text))
return "WEEK";
else if (/^months?$/i.test(text))
return "MONTH";
else if (/^years?$/i.test(text))
return "YEAR";
else if (/^hours?$/i.test(text))
return "HOUR";
else if (/^minutes?$/i.test(text))
return "MINUTE";
else if (/^seconds?$/i.test(text))
return "SECOND";
else
throw new Error(`Invalid date part "${text}"`);
}
//# sourceMappingURL=dialect.js.map