Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 47 additions & 1 deletion src/formatCurrentFile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,45 @@ import {sqlFileToFormatPath} from './constants';
import { SqlxBlockMetadata } from './types';
import { logger } from './logger';

interface TemplateReplacement {
placeholder: string;
original: string;
}

function preprocessSqlForSqlfluff(sqlText: string): { processedSql: string; replacements: TemplateReplacement[] } {
const replacements: TemplateReplacement[] = [];
let processedSql = sqlText;
let placeholderCounter = 1;

const templateRegex = /\$\{[^}]+\}/g;
let match;

while ((match = templateRegex.exec(sqlText)) !== null) {
const original = match[0];
const placeholder = `DATAFORM_PLACEHOLDER_${placeholderCounter}`;

replacements.push({
placeholder,
original
});

processedSql = processedSql.replace(original, placeholder);
placeholderCounter++;
}

return { processedSql, replacements };
}

function restoreDataformSyntax(formattedSql: string, replacements: TemplateReplacement[]): string {
let restoredSql = formattedSql;

for (const replacement of replacements) {
restoredSql = restoredSql.replace(replacement.placeholder, replacement.original);
}

return restoredSql;
}

export async function formatDataformSqlxFile(document:vscode.TextDocument){
let formattingCli = vscode.workspace.getConfiguration("vscode-dataform-tools").get("formattingCli");
if (formattingCli === "sqlfluff") {
Expand Down Expand Up @@ -50,7 +89,9 @@ export async function formatSqlxFile(document:vscode.TextDocument, currentActive
let spaceBetweenSameOps = '\n\n';

let sqlBlockText = await getTextForBlock(document, sqlBlockMeta);
writeCompiledSqlToFile(sqlBlockText, sqlFileToFormatPath);

const { processedSql, replacements } = preprocessSqlForSqlfluff(sqlBlockText);
writeCompiledSqlToFile(processedSql, sqlFileToFormatPath);

let [jsBlockText] = await Promise.all([ getTextForBlock(document, jsBlockMeta) ]);
try {
Expand Down Expand Up @@ -95,6 +136,11 @@ export async function formatSqlxFile(document:vscode.TextDocument, currentActive
try {
await getStdoutFromCliRun(exec, formatCmd);
let formattedSql = await readFile(sqlFileToFormatPath);

if (typeof formattedSql === 'string') {
formattedSql = restoreDataformSyntax(formattedSql, replacements);
}

(formattedSql === "") ? formattedSql: formattedSql = spaceBetweenBlocks + formattedSql;

if (typeof formattedSql === 'string'){
Expand Down
3 changes: 2 additions & 1 deletion src/test/test-workspace/.sqlfluff
Original file line number Diff line number Diff line change
Expand Up @@ -122,9 +122,10 @@ unquoted_identifiers_policy = all
quoted_identifiers_policy = none

[sqlfluff:templater:placeholder]
param_regex = (?s)\${\s*(?P<param_name>[\w_]+)(?P<rec>(?:[^{}]+|{(?&rec)})*+)}|(?P<param_name>config|pre_operations|post_operations)\s*{(?&rec)}
param_regex = (?s)\${\s*(?P<param_name>[\w_]+)(?P<rec>(?:[^{}]+|{(?&rec)})*+)}|(?P<param_name>config|pre_operations|post_operations|js)\s*{(?&rec)}
ref = ref_table_placeholder
self = self_table_placeholder
when =
config =
pre_operations =
js =