UNPKG

@sentry/core

Version:
102 lines (100 loc) 4.27 kB
const MAX_SUMMARY_LENGTH = 255; const TABLE_NAME_CHARS = /[^\s(,;)]+/; const TABLE_NAME = TABLE_NAME_CHARS.source; const DDL_RE = new RegExp( `^\\s*(?<operation>(?:CREATE|DROP)\\s+(?:TABLE|INDEX)|ALTER\\s+TABLE)(?:\\s+IF\\s+(?:NOT\\s+)?EXISTS)?\\s+(?<table>${TABLE_NAME})`, "i" ); const INSERT_RE = new RegExp(`^\\s*(?<operation>INSERT)\\s+INTO\\s+(?<table>${TABLE_NAME})`, "i"); const UPDATE_RE = new RegExp(`^\\s*(?<operation>UPDATE)\\s+(?<table>${TABLE_NAME})`, "i"); const DELETE_RE = new RegExp(`^\\s*(?<operation>DELETE)\\s+FROM\\s+(?<table>${TABLE_NAME})`, "i"); const SELECT_RE = /^\s*\(?\s*(?<operation>SELECT)\b/i; const PRAGMA_RE = /^\s*(?<operation>PRAGMA)\s+(?<command>\S+)/i; const TOKEN_RE = /\b(?:FROM|JOIN)\s+|\(\s*(SELECT)\b|\b(?:UNION|INTERSECT|EXCEPT|MINUS)\s+(?:ALL\s+)?(SELECT)\b/gi; const QUOTED_OR_PLAIN_TABLE_RE = /^(?:"[^"]*"|'[^']*'|[^\s(,;)]+)/; const COMMA_TABLE_RE = /^\s*,\s*((?:"[^"]*"|'[^']*'|[^\s(,;)]+))/; const SUBQUERY_SELECT_RE = /^\(\s*(SELECT)\b/i; function getSqlQuerySummary(query) { if (!query) { return void 0; } const pragmaMatch = PRAGMA_RE.exec(query); if (pragmaMatch?.groups?.["operation"] && pragmaMatch.groups["command"]) { const operation = pragmaMatch.groups["operation"]; const command = pragmaMatch.groups["command"]; const parenIdx = command.indexOf("("); return truncate(`${operation} ${parenIdx >= 0 ? command.substring(0, parenIdx) : command}`); } const ddlMatch = DDL_RE.exec(query); if (ddlMatch?.groups?.["operation"] && ddlMatch.groups["table"]) { return truncate(`${ddlMatch.groups["operation"]} ${ddlMatch.groups["table"]}`); } const insertMatch = INSERT_RE.exec(query); if (insertMatch?.groups?.["operation"] && insertMatch.groups["table"]) { const parts = [insertMatch.groups["operation"], insertMatch.groups["table"]]; const rest = query.slice(insertMatch[0].length); const subSelect = /\b(SELECT)\b/i.exec(rest); if (subSelect?.[1]) { parts.push(subSelect[1]); const selectTables = extractTableNames(rest.slice(subSelect.index)); parts.push(...selectTables); } return truncate(parts.join(" ")); } const updateMatch = UPDATE_RE.exec(query); if (updateMatch?.groups?.["operation"] && updateMatch.groups["table"]) { return truncate(`${updateMatch.groups["operation"]} ${updateMatch.groups["table"]}`); } const deleteMatch = DELETE_RE.exec(query); if (deleteMatch?.groups?.["operation"] && deleteMatch.groups["table"]) { return truncate(`${deleteMatch.groups["operation"]} ${deleteMatch.groups["table"]}`); } const selectMatch = SELECT_RE.exec(query); if (selectMatch?.groups?.["operation"]) { const tables = extractTableNames(query.slice(selectMatch[0].length)); if (tables.length > 0) { return truncate(`${selectMatch.groups["operation"]} ${tables.join(" ")}`); } return selectMatch.groups["operation"]; } return truncate(query.trim().split(/\s+/)[0] ?? query); } function extractTableNames(sql) { const tables = []; TOKEN_RE.lastIndex = 0; let match; while ((match = TOKEN_RE.exec(sql)) !== null) { if (match[1] || match[2]) { tables.push(match[1] || match[2]); continue; } const rest = sql.slice(match.index + match[0].length); const subqueryMatch = SUBQUERY_SELECT_RE.exec(rest); if (subqueryMatch?.[1]) { tables.push(subqueryMatch[1]); TOKEN_RE.lastIndex = match.index + match[0].length + subqueryMatch[0].length; continue; } const tableMatch = QUOTED_OR_PLAIN_TABLE_RE.exec(rest); if (!tableMatch) continue; tables.push(tableMatch[0]); let afterTable = rest.slice(tableMatch[0].length); let commaMatch; while ((commaMatch = COMMA_TABLE_RE.exec(afterTable)) !== null) { if (!commaMatch[1]) break; tables.push(commaMatch[1]); afterTable = afterTable.slice(commaMatch[0].length); } } return tables; } function truncate(summary) { if (summary.length <= MAX_SUMMARY_LENGTH) { return summary; } const truncated = summary.substring(0, MAX_SUMMARY_LENGTH); const lastSpace = truncated.lastIndexOf(" "); return lastSpace > 0 ? truncated.substring(0, lastSpace) : truncated; } export { getSqlQuerySummary }; //# sourceMappingURL=sql.js.map