|
71 | 71 | query_detail: '/queries/' |
72 | 72 | }; |
73 | 73 |
|
74 | | - var IDENTIFIER_QUOTE = String.fromCharCode(<%= (@identifier_quote_char || "`").ord %>); |
75 | 74 | var RAILS_MIGRATION_VERSION = '<%= @framework_version_major %>.<%= @framework_version_minor %>'; |
76 | 75 |
|
77 | 76 | var csrfMeta = document.querySelector('meta[name="csrf-token"]'); |
|
89 | 88 | function show(e) { e.classList.remove('mg-hidden'); } |
90 | 89 | function hide(e) { e.classList.add('mg-hidden'); } |
91 | 90 | function escHtml(s) { var d = document.createElement('div'); d.textContent = s; return d.innerHTML; } |
92 | | - function quoteIdentifier(name) { |
93 | | - var quote = IDENTIFIER_QUOTE || '`'; |
94 | | - var identifier = String(name); |
95 | | - if (quote === '[') return '[' + identifier.split(']').join(']]') + ']'; |
96 | | - return quote + identifier.split(quote).join(quote + quote) + quote; |
97 | | - } |
98 | 91 |
|
99 | 92 | // --- Table Sorting --- |
100 | 93 |
|
|
159 | 152 | 'COUNT SUM AVG MIN MAX COALESCE IFNULL NULLIF CAST CONVERT CONCAT CONCAT_WS GROUP_CONCAT SUBSTRING SUBSTR REPLACE TRIM LTRIM RTRIM UPPER LOWER UCASE LCASE LENGTH CHAR_LENGTH NOW CURDATE CURTIME DATE_FORMAT DATE_ADD DATE_SUB DATEDIFF TIMESTAMPDIFF UNIX_TIMESTAMP FROM_UNIXTIME IF ELT FIELD FIND_IN_SET FORMAT HEX UNHEX MD5 SHA1 SHA2 AES_ENCRYPT AES_DECRYPT ROUND CEIL CEILING FLOOR ABS MOD POWER SQRT LOG LOG2 LOG10 RAND GREATEST LEAST JSON_EXTRACT JSON_UNQUOTE JSON_SET JSON_OBJECT JSON_ARRAY JSON_CONTAINS JSON_LENGTH ROW_NUMBER RANK DENSE_RANK LAG LEAD FIRST_VALUE LAST_VALUE NTH_VALUE'.split(' ').forEach(function(w) { SQL_FN_SET[w] = true; }); |
160 | 153 |
|
161 | 154 | // Single-pass tokenizer regex: matches tokens in order of priority |
162 | | - // 1) single-quoted strings 2) quoted identifiers 3) numbers 4) words 5) operators 6) punctuation 7) ? placeholder 8) * star 9) whitespace 10) anything else |
163 | | - var SQL_TOKEN_RE = /'[^']*'|`[^`]*`|"(?:""|[^"])*"|\b\d+(?:\.\d+)?\b|[A-Za-z_]\w*|\?|>=|<=|<>|!=|[><=]|[(),;*]|\s+|./g; |
| 155 | + // 1) single-quoted strings 2) backtick identifiers 3) numbers 4) words 5) operators 6) punctuation 7) ? placeholder 8) * star 9) whitespace 10) anything else |
| 156 | + var SQL_TOKEN_RE = /'[^']*'|`[^`]*`|\b\d+(?:\.\d+)?\b|[A-Za-z_]\w*|\?\|>=|<=|<>|!=|[><=]|[(),;*]|\s+|./g; |
164 | 157 |
|
165 | 158 | function highlightSql(sql) { |
166 | 159 | if (!sql) return ''; |
|
174 | 167 | if (ch === "'") { |
175 | 168 | // String literal |
176 | 169 | result.push('<span class="mg-sql-str">' + escHtml(tok) + '</span>'); |
177 | | - } else if (ch === '`' || ch === '"') { |
178 | | - // Quoted identifier |
| 170 | + } else if (ch === '`') { |
| 171 | + // Backtick-quoted identifier |
179 | 172 | result.push('<span class="mg-sql-tbl">' + escHtml(tok) + '</span>'); |
180 | 173 | } else if (/^\d/.test(tok)) { |
181 | 174 | // Number |
|
665 | 658 | var table = el('vb-table').value; |
666 | 659 | if (!table) return ''; |
667 | 660 | var cols = []; |
668 | | - qsa('.vb-col-check:checked').forEach(function(c) { cols.push(quoteIdentifier(c.value)); }); |
| 661 | + qsa('.vb-col-check:checked').forEach(function(c) { cols.push('`' + c.value + '`'); }); |
669 | 662 | if (!cols.length) cols = ['*']; |
670 | | - var sql = 'SELECT ' + cols.join(', ') + ' FROM ' + quoteIdentifier(table); |
| 663 | + var sql = 'SELECT ' + cols.join(', ') + ' FROM `' + table + '`'; |
671 | 664 | var wheres = []; |
672 | 665 | qsa('.vb-filter-row').forEach(function(row) { |
673 | 666 | var col = qs('.vb-filter-col', row).value; |
|
676 | 669 | var val = valEl ? valEl.value : ''; |
677 | 670 | if (!col) return; |
678 | 671 | if (op === 'IS NULL' || op === 'IS NOT NULL') { |
679 | | - wheres.push(quoteIdentifier(col) + ' ' + op); |
| 672 | + wheres.push('`' + col + '` ' + op); |
680 | 673 | } else if (op === 'BETWEEN') { |
681 | 674 | var endEl = qs('.vb-filter-val-end', row); |
682 | 675 | var endVal = endEl ? endEl.value : ''; |
683 | | - wheres.push(quoteIdentifier(col) + " BETWEEN '" + val.replace(/'/g, "''") + "' AND '" + endVal.replace(/'/g, "''") + "'"); |
| 676 | + wheres.push("`" + col + "` BETWEEN '" + val.replace(/'/g, "''") + "' AND '" + endVal.replace(/'/g, "''") + "'"); |
684 | 677 | } else if (op === 'LIKE') { |
685 | | - wheres.push(quoteIdentifier(col) + " LIKE '" + val.replace(/'/g, "''") + "'"); |
| 678 | + wheres.push("`" + col + "` LIKE '" + val.replace(/'/g, "''") + "'"); |
686 | 679 | } else { |
687 | | - wheres.push(quoteIdentifier(col) + " " + op + " '" + val.replace(/'/g, "''") + "'"); |
| 680 | + wheres.push("`" + col + "` " + op + " '" + val.replace(/'/g, "''") + "'"); |
688 | 681 | } |
689 | 682 | }); |
690 | 683 | if (wheres.length) sql += ' WHERE ' + wheres.join(' AND '); |
691 | 684 | var orders = []; |
692 | 685 | qsa('.vb-order-row').forEach(function(row) { |
693 | 686 | var col = qs('.vb-order-col', row).value; |
694 | 687 | var dir = qs('.vb-order-dir', row).value; |
695 | | - if (col) orders.push(quoteIdentifier(col) + ' ' + dir); |
| 688 | + if (col) orders.push('`' + col + '` ' + dir); |
696 | 689 | }); |
697 | 690 | if (orders.length) sql += ' ORDER BY ' + orders.join(', '); |
698 | 691 | return sql; |
|
0 commit comments