35 lines
1.5 KiB
TypeScript
35 lines
1.5 KiB
TypeScript
import { buildSqlSemanticModel } from "@/lib/sql/semantic/model";
|
|
import type { SqlSemanticRowSource } from "@/lib/sql/semantic/types";
|
|
import type { DatabaseType } from "@/types/database";
|
|
|
|
export interface QueryResultSourceLabelOptions {
|
|
database?: string;
|
|
databaseType?: DatabaseType;
|
|
}
|
|
|
|
export function queryResultNameFromPreamble(preamble: string): string | undefined {
|
|
let name: string | undefined;
|
|
const withoutBlockComments = preamble.replace(/\/\*[\s\S]*?\*\//g, "");
|
|
for (const line of withoutBlockComments.split(/\r?\n/)) {
|
|
const candidate = line.match(/^\s*--\s*name\s*:\s*(.*)$/i)?.[1]?.trim();
|
|
if (candidate) name = candidate;
|
|
}
|
|
return name;
|
|
}
|
|
|
|
function firstSourceOfKind(sources: SqlSemanticRowSource[], kind: SqlSemanticRowSource["kind"]): SqlSemanticRowSource | undefined {
|
|
return sources.filter((source) => source.kind === kind).sort((left, right) => left.sourceSpan.start - right.sourceSpan.start)[0];
|
|
}
|
|
|
|
export function queryResultSourceLabel(sql: string, options: QueryResultSourceLabelOptions = {}): string | undefined {
|
|
const statement = sql.trim();
|
|
if (!statement) return undefined;
|
|
|
|
const model = buildSqlSemanticModel(statement, statement.length, { databaseType: options.databaseType });
|
|
const source = firstSourceOfKind(model.rowSources, "mutation_target") ?? firstSourceOfKind(model.rowSources, "table");
|
|
if (!source?.name) return undefined;
|
|
|
|
const qualifier = source.qualifierParts[source.qualifierParts.length - 1]?.trim() || options.database?.trim();
|
|
return qualifier ? `${qualifier}.${source.name}` : source.name;
|
|
}
|