Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ui: add MySqlFormatter to customize the sql formatter #805

Merged
merged 3 commits into from
Nov 24, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
371 changes: 371 additions & 0 deletions ui/lib/utils/MySqlFormatter/MySqlFormatter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,371 @@
// This file is copied from 'sql-formatter-plus-plus/src/languages/StandardSqlFormatter.js'.
// And changed the following lines:
// `namedPlaceholderTypes: ['@', ':'],` => `namedPlaceholderTypes: [':'],`
// Add the following line which copied from Db2Formatter.js:
// `specialWordChars: ['@'],`

import Formatter from 'sql-formatter-plus-plus/src/core/Formatter'
import Tokenizer from 'sql-formatter-plus-plus/src/core/Tokenizer'

const reservedWords = [
'ACCESSIBLE',
'ACTION',
'AGAINST',
'AGGREGATE',
'ALGORITHM',
'ALL',
'ALTER',
'ANALYSE',
'ANALYZE',
'AS',
'ASC',
'AUTOCOMMIT',
'AUTO_INCREMENT',
'BACKUP',
'BEGIN',
'BETWEEN',
'BINLOG',
'BOTH',
'CASCADE',
'CASE',
'CHANGE',
'CHANGED',
'CHARACTER SET',
'CHARSET',
'CHECK',
'CHECKSUM',
'COLLATE',
'COLLATION',
'COLUMN',
'COLUMNS',
'COMMENT',
'COMMIT',
'COMMITTED',
'COMPRESSED',
'CONCURRENT',
'CONSTRAINT',
'CONTAINS',
'CONVERT',
'CREATE',
'CROSS',
'CURRENT_TIMESTAMP',
'DATABASE',
'DATABASES',
'DAY',
'DAY_HOUR',
'DAY_MINUTE',
'DAY_SECOND',
'DEFAULT',
'DEFINER',
'DELAYED',
'DELETE',
'DESC',
'DESCRIBE',
'DETERMINISTIC',
'DISTINCT',
'DISTINCTROW',
'DIV',
'DO',
'DROP',
'DUMPFILE',
'DUPLICATE',
'DYNAMIC',
'ELSE',
'ENCLOSED',
'END',
'ENGINE',
'ENGINES',
'ENGINE_TYPE',
'ESCAPE',
'ESCAPED',
'EVENTS',
'EXEC',
'EXECUTE',
'EXISTS',
'EXPLAIN',
'EXTENDED',
'FAST',
'FETCH',
'FIELDS',
'FILE',
'FIRST',
'FIXED',
'FLUSH',
'FOR',
'FORCE',
'FOREIGN',
'FULL',
'FULLTEXT',
'FUNCTION',
'GLOBAL',
'GRANT',
'GRANTS',
'GROUP_CONCAT',
'HEAP',
'HIGH_PRIORITY',
'HOSTS',
'HOUR',
'HOUR_MINUTE',
'HOUR_SECOND',
'IDENTIFIED',
'IF',
'IFNULL',
'IGNORE',
'IN',
'INDEX',
'INDEXES',
'INFILE',
'INSERT',
'INSERT_ID',
'INSERT_METHOD',
'INTERVAL',
'INTO',
'INVOKER',
'IS',
'ISOLATION',
'KEY',
'KEYS',
'KILL',
'LAST_INSERT_ID',
'LEADING',
'LEVEL',
'LIKE',
'LINEAR',
'LINES',
'LOAD',
'LOCAL',
'LOCK',
'LOCKS',
'LOGS',
'LOW_PRIORITY',
'MARIA',
'MASTER',
'MASTER_CONNECT_RETRY',
'MASTER_HOST',
'MASTER_LOG_FILE',
'MATCH',
'MAX_CONNECTIONS_PER_HOUR',
'MAX_QUERIES_PER_HOUR',
'MAX_ROWS',
'MAX_UPDATES_PER_HOUR',
'MAX_USER_CONNECTIONS',
'MEDIUM',
'MERGE',
'MINUTE',
'MINUTE_SECOND',
'MIN_ROWS',
'MODE',
'MODIFY',
'MONTH',
'MRG_MYISAM',
'MYISAM',
'NAMES',
'NATURAL',
'NOT',
'NOW()',
'NULL',
'OFFSET',
'ON DELETE',
'ON UPDATE',
'ON',
'ONLY',
'OPEN',
'OPTIMIZE',
'OPTION',
'OPTIONALLY',
'OUTFILE',
'PACK_KEYS',
'PAGE',
'PARTIAL',
'PARTITION',
'PARTITIONS',
'PASSWORD',
'PRIMARY',
'PRIVILEGES',
'PROCEDURE',
'PROCESS',
'PROCESSLIST',
'PURGE',
'QUICK',
'RAID0',
'RAID_CHUNKS',
'RAID_CHUNKSIZE',
'RAID_TYPE',
'RANGE',
'READ',
'READ_ONLY',
'READ_WRITE',
'REFERENCES',
'REGEXP',
'RELOAD',
'RENAME',
'REPAIR',
'REPEATABLE',
'REPLACE',
'REPLICATION',
'RESET',
'RESTORE',
'RESTRICT',
'RETURN',
'RETURNS',
'REVOKE',
'RLIKE',
'ROLLBACK',
'ROW',
'ROWS',
'ROW_FORMAT',
'SECOND',
'SECURITY',
'SEPARATOR',
'SERIALIZABLE',
'SESSION',
'SHARE',
'SHOW',
'SHUTDOWN',
'SLAVE',
'SONAME',
'SOUNDS',
'SQL',
'SQL_AUTO_IS_NULL',
'SQL_BIG_RESULT',
'SQL_BIG_SELECTS',
'SQL_BIG_TABLES',
'SQL_BUFFER_RESULT',
'SQL_CACHE',
'SQL_CALC_FOUND_ROWS',
'SQL_LOG_BIN',
'SQL_LOG_OFF',
'SQL_LOG_UPDATE',
'SQL_LOW_PRIORITY_UPDATES',
'SQL_MAX_JOIN_SIZE',
'SQL_NO_CACHE',
'SQL_QUOTE_SHOW_CREATE',
'SQL_SAFE_UPDATES',
'SQL_SELECT_LIMIT',
'SQL_SLAVE_SKIP_COUNTER',
'SQL_SMALL_RESULT',
'SQL_WARNINGS',
'START',
'STARTING',
'STATUS',
'STOP',
'STORAGE',
'STRAIGHT_JOIN',
'STRING',
'STRIPED',
'SUPER',
'TABLE',
'TABLES',
'TEMPORARY',
'TERMINATED',
'THEN',
'TO',
'TRAILING',
'TRANSACTIONAL',
'TRUE',
'TRUNCATE',
'TYPE',
'TYPES',
'UNCOMMITTED',
'UNIQUE',
'UNLOCK',
'UNSIGNED',
'USAGE',
'USE',
'USING',
'VARIABLES',
'VIEW',
'WHEN',
'WITH',
'WORK',
'WRITE',
'YEAR_MONTH',
]

const reservedTopLevelWords = [
'ADD',
'AFTER',
'ALTER COLUMN',
'ALTER TABLE',
'DELETE FROM',
'EXCEPT',
'FETCH FIRST',
'FROM',
'GROUP BY',
'GO',
'HAVING',
'INSERT INTO',
'INSERT',
'LIMIT',
'MODIFY',
'ORDER BY',
'SELECT',
'SET CURRENT SCHEMA',
'SET SCHEMA',
'SET',
'UPDATE',
'VALUES',
'WHERE',
]

const reservedTopLevelWordsNoIndent = [
'INTERSECT',
'INTERSECT ALL',
'MINUS',
'UNION',
'UNION ALL',
]

const reservedNewlineWords = [
'AND',
'CROSS APPLY',
'CROSS JOIN',
'ELSE',
'INNER JOIN',
'JOIN',
'LEFT JOIN',
'LEFT OUTER JOIN',
'OR',
'OUTER APPLY',
'OUTER JOIN',
'RIGHT JOIN',
'RIGHT OUTER JOIN',
'WHEN',
'XOR',
]

let tokenizer

export default class MySqlFormatter {
/**
* @param {Object} cfg Different set of configurations
*/
constructor(public cfg) {
this.cfg = cfg
}

/**
* Format the whitespace in a Standard SQL string to make it easier to read
*
* @param {String} query The Standard SQL string
* @return {String} formatted string
*/
format(query) {
if (!tokenizer) {
tokenizer = new Tokenizer({
reservedWords,
reservedTopLevelWords,
reservedNewlineWords,
reservedTopLevelWordsNoIndent,
stringTypes: [`""`, "N''", "''", '``', '[]'],
openParens: ['(', 'CASE'],
closeParens: [')', 'END'],
indexedPlaceholderTypes: ['?'],
namedPlaceholderTypes: [':'],
lineCommentTypes: ['#', '--'],
specialWordChars: ['@'],
})
}
return new Formatter(this.cfg, tokenizer).format(query)
}
}
6 changes: 4 additions & 2 deletions ui/lib/utils/formatSql.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import sqlFormatter from 'sql-formatter-plus-plus'
import MySqlFormatter from './MySqlFormatter/MySqlFormatter'
baurine marked this conversation as resolved.
Show resolved Hide resolved

const mySqlFormatter = new MySqlFormatter({ uppercase: true })

export default function formatSql(sql?: string): string {
return sqlFormatter.format(sql || '', { uppercase: true })
return mySqlFormatter.format(sql || '')
}