UNPKG

pgsql-deparser

Version:
86 lines (85 loc) 3.34 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.QuoteUtils = void 0; const RESERVED_WORDS = new Set([ 'all', 'analyse', 'analyze', 'and', 'any', 'array', 'as', 'asc', 'asymmetric', 'authorization', 'binary', 'both', 'case', 'cast', 'check', 'collate', 'collation', 'column', 'concurrently', 'constraint', 'create', 'cross', 'current_catalog', 'current_date', 'current_role', 'current_schema', 'current_time', 'current_timestamp', 'current_user', 'default', 'deferrable', 'desc', 'distinct', 'do', 'else', 'end', 'except', 'false', 'fetch', 'for', 'foreign', 'freeze', 'from', 'full', 'grant', 'group', 'having', 'ilike', 'in', 'initially', 'inner', 'intersect', 'into', 'is', 'isnull', 'join', 'lateral', 'leading', 'left', 'like', 'limit', 'localtime', 'localtimestamp', 'natural', 'not', 'notnull', 'null', 'offset', 'on', 'only', 'or', 'order', 'outer', 'overlaps', 'placing', 'primary', 'references', 'returning', 'right', 'select', 'session_user', 'similar', 'some', 'symmetric', 'table', 'tablesample', 'then', 'to', 'trailing', 'true', 'union', 'unique', 'user', 'using', 'variadic', 'verbose', 'when', 'where', 'window', 'with' ]); class QuoteUtils { static needsQuotes(value) { if (!value || typeof value !== 'string') { return false; } const lowerValue = value.toLowerCase(); if (RESERVED_WORDS.has(lowerValue)) { return true; } if (!/^[a-z_][a-z0-9_$]*$/i.test(value)) { return true; } if (value !== value.toLowerCase()) { return true; } return false; } static quote(value) { if (value == null) { return null; } if (Array.isArray(value)) { return value.map(v => this.quote(v)); } if (typeof value !== 'string') { return value; } if (this.needsQuotes(value)) { return `"${value}"`; } return value; } static escape(literal) { return `'${literal.replace(/'/g, "''")}'`; } /** * Escapes a string value for use in E-prefixed string literals * Handles both backslashes and single quotes properly */ static escapeEString(value) { return value.replace(/\\/g, '\\\\').replace(/'/g, "''"); } /** * Formats a string as an E-prefixed string literal with proper escaping * This wraps the complete E-prefix logic including detection and formatting */ static formatEString(value) { const needsEscape = QuoteUtils.needsEscapePrefix(value); if (needsEscape) { const escapedValue = QuoteUtils.escapeEString(value); return `E'${escapedValue}'`; } else { return QuoteUtils.escape(value); } } /** * Determines if a string value needs E-prefix for escaped string literals * Detects backslash escape sequences that require E-prefix in PostgreSQL */ static needsEscapePrefix(value) { // Always use E'' if the string contains any backslashes, // unless it's a raw \x... bytea-style literal. return !/^\\x[0-9a-fA-F]+$/i.test(value) && value.includes('\\'); } } exports.QuoteUtils = QuoteUtils;