Files
dbx/apps/desktop/src/lib/historyActivityKind.ts
T

44 lines
1.5 KiB
TypeScript

export type HistoryActivityKind = "query" | "data_change" | "schema_change" | "import" | "transfer";
export type HistoryActivitySource = {
activity_kind?: HistoryActivityKind;
operation?: string;
sql?: string;
};
const READ_RE = /^\s*(SELECT|WITH|SHOW|DESCRIBE|DESC|EXPLAIN)\b/i;
const WRITE_RE = /^\s*(INSERT|UPDATE|DELETE|MERGE|REPLACE|TRUNCATE)\b/i;
const SCHEMA_RE = /^\s*(CREATE|ALTER|DROP|RENAME)\b/i;
function stripSqlComments(sql: string): string {
return sql
.replace(/\/\*[\s\S]*?\*\//g, " ")
.replace(/--.*$/gm, " ")
.replace(/#.*$/gm, " ");
}
function statementsFor(sql: string): string[] {
return stripSqlComments(sql)
.split(";")
.map((stmt) => stmt.trim())
.filter(Boolean);
}
export function classifySqlActivityKind(sql: string): "query" | "data_change" | "schema_change" {
const statements = statementsFor(sql);
if (statements.some((stmt) => SCHEMA_RE.test(stmt))) return "schema_change";
if (statements.some((stmt) => WRITE_RE.test(stmt))) return "data_change";
if (statements.every((stmt) => READ_RE.test(stmt))) return "query";
return "query";
}
export function resolveHistoryActivityKind(entry: HistoryActivitySource): HistoryActivityKind {
if (entry.activity_kind && entry.activity_kind !== "query") return entry.activity_kind;
const operation = entry.operation?.trim();
if (operation && SCHEMA_RE.test(operation)) return "schema_change";
if (operation && WRITE_RE.test(operation)) return "data_change";
return entry.sql ? classifySqlActivityKind(entry.sql) : "query";
}