diff --git a/packages/tools/src/SqlDumper.ts b/packages/tools/src/SqlDumper.ts index 3a6de60c7..c8bb5c6af 100644 --- a/packages/tools/src/SqlDumper.ts +++ b/packages/tools/src/SqlDumper.ts @@ -32,6 +32,12 @@ export class SqlDumper implements AlterProcessor { dialect: SqlDialect; indentLevel = 0; + static keywordsCase = 'upperCase'; + static convertKeywordCase(keyword: any): string { + if (this.keywordsCase == 'lowerCase') return keyword?.toString()?.toLowerCase(); + return keyword?.toString()?.toUpperCase(); + } + constructor(driver: EngineDriver) { this.driver = driver; this.dialect = driver.dialect; @@ -60,10 +66,10 @@ export class SqlDumper implements AlterProcessor { this.putRaw("'"); } putByteArrayValue(value) { - this.putRaw('NULL'); + this.put('^null'); } putValue(value) { - if (value === null) this.putRaw('NULL'); + if (value === null) this.put('^null'); else if (value === true) this.putRaw('1'); else if (value === false) this.putRaw('0'); else if (_isString(value)) this.putStringValue(value); @@ -71,7 +77,7 @@ export class SqlDumper implements AlterProcessor { else if (_isDate(value)) this.putStringValue(new Date(value).toISOString()); else if (value?.type == 'Buffer' && _isArray(value?.data)) this.putByteArrayValue(value?.data); else if (_isPlainObject(value) || _isArray(value)) this.putStringValue(JSON.stringify(value)); - else this.putRaw('NULL'); + else this.put('^null'); } putCmd(format, ...args) { this.put(format, ...args); @@ -92,7 +98,7 @@ export class SqlDumper implements AlterProcessor { case 'k': { if (value) { - this.putRaw(value.toUpperCase()); + this.putRaw(SqlDumper.convertKeywordCase(value)); } } break; @@ -128,7 +134,7 @@ export class SqlDumper implements AlterProcessor { switch (c) { case '^': while (i < length && format[i].match(/[a-z0-9_]/i)) { - this.putRaw(format[i].toUpperCase()); + this.putRaw(SqlDumper.convertKeywordCase(format[i])); i++; } break; diff --git a/packages/web/src/App.svelte b/packages/web/src/App.svelte index 67c6b22cb..6938737e8 100644 --- a/packages/web/src/App.svelte +++ b/packages/web/src/App.svelte @@ -19,6 +19,7 @@ import AppTitleProvider from './utility/AppTitleProvider.svelte'; import getElectron from './utility/getElectron'; import AppStartInfo from './widgets/AppStartInfo.svelte'; + import SettingsListener from './utility/SettingsListener.svelte'; let loadedApi = false; let loadedPlugins = false; @@ -79,6 +80,7 @@ {#if loadedPlugins} + {:else} + import { SqlDumper } from 'dbgate-tools'; import FormStyledButton from '../buttons/FormStyledButton.svelte'; import TableControl from '../elements/TableControl.svelte'; import TextField from '../forms/TextField.svelte'; @@ -63,9 +64,11 @@ const source = sources[sourceIndex]; const target = targets[targetIndex]; if (source && target) { - return `${JOIN_TYPES[joinIndex]} ${target.refTable}${alias ? ` ${alias}` : ''} ON ${target.columnMap + return `${SqlDumper.convertKeywordCase(JOIN_TYPES[joinIndex])} ${target.refTable}${ + alias ? ` ${alias}` : '' + } ${SqlDumper.convertKeywordCase('ON')} ${target.columnMap .map(col => `${source.name}.${col.columnName} = ${alias || target.refTable}.${col.refColumnName}`) - .join(' AND ')}`; + .join(SqlDumper.convertKeywordCase(' AND '))}`; } return ''; } diff --git a/packages/web/src/query/codeCompletion.ts b/packages/web/src/query/codeCompletion.ts index e59503b59..ddb662098 100644 --- a/packages/web/src/query/codeCompletion.ts +++ b/packages/web/src/query/codeCompletion.ts @@ -2,6 +2,7 @@ import _ from 'lodash'; import { addCompleter, setCompleters } from 'ace-builds/src-noconflict/ext-language_tools'; import { getDatabaseInfo } from '../utility/metadataLoaders'; import analyseQuerySources from './analyseQuerySources'; +import { getStringSettingsValue } from '../settings/settingsTools'; const COMMON_KEYWORDS = [ 'select', @@ -78,13 +79,21 @@ export function mountCodeCompletion({ conid, database, editor, getText }) { const line = session.getLine(cursor.row).slice(0, cursor.column); const dbinfo = await getDatabaseInfo({ conid, database }); - let list = COMMON_KEYWORDS.map(word => ({ - name: word, - value: word, - caption: word, - meta: 'keyword', - score: 800, - })); + const convertUpper = getStringSettingsValue('sqlEditor.sqlCommandsCase', 'upperCase') == 'upperCase'; + + let list = COMMON_KEYWORDS.map(word => { + if (convertUpper) { + word = word.toUpperCase(); + } + + return { + name: word, + value: word, + caption: word, + meta: 'keyword', + score: 800, + }; + }); if (dbinfo) { const colMatch = line.match(/([a-zA-Z0-9_]+)\.([a-zA-Z0-9_]*)?$/); diff --git a/packages/web/src/settings/SettingsModal.svelte b/packages/web/src/settings/SettingsModal.svelte index 99e0ca357..ebf2d9a14 100644 --- a/packages/web/src/settings/SettingsModal.svelte +++ b/packages/web/src/settings/SettingsModal.svelte @@ -111,6 +111,19 @@ ORDER BY defaultValue="30" disabled={values['connection.autoRefresh'] === false} /> + +
SQL editor
+ +
Application theme
diff --git a/packages/web/src/settings/settingsTools.ts b/packages/web/src/settings/settingsTools.ts index 7c27ad203..dbf739eee 100644 --- a/packages/web/src/settings/settingsTools.ts +++ b/packages/web/src/settings/settingsTools.ts @@ -21,3 +21,10 @@ export function getBoolSettingsValue(name, defaultValue) { if (res == null) return defaultValue; return !!res; } + +export function getStringSettingsValue(name, defaultValue) { + const settings = getCurrentSettings(); + const res = settings[name]; + if (res == null) return defaultValue; + return res; +} diff --git a/packages/web/src/utility/SettingsListener.svelte b/packages/web/src/utility/SettingsListener.svelte new file mode 100644 index 000000000..7dedd6a87 --- /dev/null +++ b/packages/web/src/utility/SettingsListener.svelte @@ -0,0 +1,8 @@ +