mirror of
https://gitee.com/dromara/mayfly-go
synced 2025-11-02 15:30:25 +08:00
!66 refactor: sql代码提示重构
Merge pull request !66 from zongyangleo/dev_1212
This commit is contained in:
@@ -482,7 +482,7 @@ const addQueryTab = async (db: any, dbName: string, sqlName: string = '') => {
|
||||
state.tabs.set(key, tab);
|
||||
|
||||
// 注册当前sql编辑框提示词
|
||||
registerDbCompletionItemProvider('sql', tab.dbId, tab.db, tab.params.dbs);
|
||||
registerDbCompletionItemProvider(tab.dbId, tab.db, tab.params.dbs, nowDbInst.value.type);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -554,7 +554,7 @@ const onTabChange = () => {
|
||||
|
||||
if (nowTab?.type == TabType.Query) {
|
||||
// 注册sql提示
|
||||
registerDbCompletionItemProvider('sql', nowTab.dbId, nowTab.db, nowTab.params.dbs);
|
||||
registerDbCompletionItemProvider(nowTab.dbId, nowTab.db, nowTab.params.dbs, nowDbInst.value.type);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -2,19 +2,11 @@
|
||||
import { dbApi } from './api';
|
||||
import { getTextWidth } from '@/common/utils/string';
|
||||
import SqlExecBox from './component/sqleditor/SqlExecBox';
|
||||
|
||||
import { language as sqlLanguage } from 'monaco-editor/esm/vs/basic-languages/mysql/mysql.js';
|
||||
import { language as addSqlLanguage } from './dialect/mysql_dialect';
|
||||
import * as monaco from 'monaco-editor/esm/vs/editor/editor.api';
|
||||
import { editor, languages, Position } from 'monaco-editor';
|
||||
|
||||
import { registerCompletionItemProvider } from '@/components/monaco/completionItemProvider';
|
||||
import { getDbDialect } from './dialect';
|
||||
|
||||
const sqlCompletionKeywords = [...sqlLanguage.keywords, ...addSqlLanguage.keywords];
|
||||
const sqlCompletionOperators = [...sqlLanguage.operators, ...addSqlLanguage.operators];
|
||||
const sqlCompletionBuiltinFunctions = [...sqlLanguage.builtinFunctions, ...addSqlLanguage.builtinFunctions];
|
||||
const sqlCompletionBuiltinVariables = [...sqlLanguage.builtinVariables, ...addSqlLanguage.builtinVariables];
|
||||
import { EditorCompletionItem, getDbDialect } from './dialect';
|
||||
|
||||
const dbInstCache: Map<number, DbInst> = new Map();
|
||||
|
||||
@@ -511,16 +503,38 @@ export class TabInfo {
|
||||
}
|
||||
}
|
||||
|
||||
function registerCompletions(
|
||||
completions: EditorCompletionItem[],
|
||||
suggestions: languages.CompletionItem[],
|
||||
kind: monaco.languages.CompletionItemKind,
|
||||
range: any
|
||||
) {
|
||||
// mysql关键字
|
||||
completions.forEach((item: EditorCompletionItem) => {
|
||||
let { label, insertText, description } = item;
|
||||
suggestions.push({
|
||||
label: { label, description },
|
||||
kind,
|
||||
insertText: insertText || label,
|
||||
range,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册数据库表、字段等信息提示
|
||||
*
|
||||
* @param language 语言
|
||||
* @param dbId 数据库id
|
||||
* @param db 库名
|
||||
* @param dbs 该库所有库名
|
||||
* @param dbType 数据库类型
|
||||
*/
|
||||
export function registerDbCompletionItemProvider(language: string, dbId: number, db: string, dbs: any[] = []) {
|
||||
registerCompletionItemProvider(language, {
|
||||
export function registerDbCompletionItemProvider(dbId: number, db: string, dbs: any[] = [], dbType: string) {
|
||||
let dbDialect = getDbDialect(dbType);
|
||||
let dbDialectInfo = dbDialect.getInfo();
|
||||
|
||||
let { keywords, operators, functions, variables } = dbDialectInfo.editorCompletions;
|
||||
registerCompletionItemProvider('sql', {
|
||||
triggerCharacters: ['.', ' '],
|
||||
provideCompletionItems: async (model: editor.ITextModel, position: Position): Promise<languages.CompletionList | null | undefined> => {
|
||||
let word = model.getWordUntilPosition(position);
|
||||
@@ -664,73 +678,10 @@ export function registerDbCompletionItemProvider(language: string, dbId: number,
|
||||
});
|
||||
});
|
||||
|
||||
// mysql关键字
|
||||
sqlCompletionKeywords.forEach((item: any) => {
|
||||
suggestions.push({
|
||||
label: {
|
||||
label: item,
|
||||
description: 'keyword',
|
||||
},
|
||||
kind: monaco.languages.CompletionItemKind.Keyword,
|
||||
insertText: item,
|
||||
range,
|
||||
});
|
||||
});
|
||||
|
||||
// 操作符
|
||||
sqlCompletionOperators.forEach((item: any) => {
|
||||
suggestions.push({
|
||||
label: {
|
||||
label: item,
|
||||
description: 'opt',
|
||||
},
|
||||
kind: monaco.languages.CompletionItemKind.Operator,
|
||||
insertText: item,
|
||||
range,
|
||||
});
|
||||
});
|
||||
|
||||
let replacedFunctions = [] as string[];
|
||||
|
||||
// 添加的函数
|
||||
addSqlLanguage.replaceFunctions.forEach((item: any) => {
|
||||
replacedFunctions.push(item.label);
|
||||
suggestions.push({
|
||||
label: {
|
||||
label: item.label,
|
||||
description: item.description,
|
||||
},
|
||||
kind: monaco.languages.CompletionItemKind.Function,
|
||||
insertText: item.insertText,
|
||||
range,
|
||||
});
|
||||
});
|
||||
|
||||
// 内置函数
|
||||
sqlCompletionBuiltinFunctions.forEach((item: any) => {
|
||||
replacedFunctions.indexOf(item) < 0 &&
|
||||
suggestions.push({
|
||||
label: {
|
||||
label: item,
|
||||
description: 'func',
|
||||
},
|
||||
kind: monaco.languages.CompletionItemKind.Function,
|
||||
insertText: item,
|
||||
range,
|
||||
});
|
||||
});
|
||||
// 内置变量
|
||||
sqlCompletionBuiltinVariables.forEach((item: string) => {
|
||||
suggestions.push({
|
||||
label: {
|
||||
label: item,
|
||||
description: 'var',
|
||||
},
|
||||
kind: monaco.languages.CompletionItemKind.Variable,
|
||||
insertText: item,
|
||||
range,
|
||||
});
|
||||
});
|
||||
registerCompletions(keywords, suggestions, monaco.languages.CompletionItemKind.Keyword, range);
|
||||
registerCompletions(operators, suggestions, monaco.languages.CompletionItemKind.Operator, range);
|
||||
registerCompletions(functions, suggestions, monaco.languages.CompletionItemKind.Function, range);
|
||||
registerCompletions(variables, suggestions, monaco.languages.CompletionItemKind.Variable, range);
|
||||
|
||||
// 默认提示
|
||||
return {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { DbDialect, sqlColumnType, DialectInfo, RowDefinition, IndexDefinition } from './index';
|
||||
|
||||
import { DbDialect, sqlColumnType, DialectInfo, RowDefinition, IndexDefinition, EditorCompletionItem, commonCustomKeywords, EditorCompletion } from './index';
|
||||
import { language as sqlLanguage } from 'monaco-editor/esm/vs/basic-languages/sql/sql.js';
|
||||
export { DMDialect, DM_TYPE_LIST };
|
||||
|
||||
// 参考文档:https://eco.dameng.com/document/dm/zh-cn/sql-dev/dmpl-sql-datatype.html#%E5%AD%97%E7%AC%A6%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B
|
||||
@@ -42,15 +42,323 @@ const DM_TYPE_LIST: sqlColumnType[] = [
|
||||
{ udtName: 'BFILE', dataType: 'BFILE', desc: '二进制文件', space: '', range: '100G-1' },
|
||||
];
|
||||
|
||||
const dmDialectInfo: DialectInfo = {
|
||||
icon: 'iconfont icon-db-dm',
|
||||
defaultPort: 5236,
|
||||
formatSqlDialect: 'postgresql',
|
||||
columnTypes: DM_TYPE_LIST.sort((a, b) => a.udtName.localeCompare(b.udtName)),
|
||||
};
|
||||
const replaceFunctions: EditorCompletionItem[] = [
|
||||
// 数值函数
|
||||
{ label: 'ABS', insertText: 'ABS(n)', description: '求数值 n 的绝对值' },
|
||||
{ label: 'ACOS', insertText: 'ACOS(n)', description: '求数值 n 的反余弦值' },
|
||||
{ label: 'ASIN', insertText: 'ASIN(n)', description: '求数值 n 的反正弦值' },
|
||||
{ label: 'ATAN', insertText: 'ATAN(n)', description: '求数值 n 的反正切值' },
|
||||
{ label: 'ATAN2', insertText: 'ATAN2(n1,n2)', description: '求数值 n1/n2 的反正切值' },
|
||||
{ label: 'CEIL', insertText: 'CEIL(n)', description: '求大于或等于数值 n 的最小整数' },
|
||||
{ label: 'CEILING', insertText: 'CEILING(n)', description: '求大于或等于数值 n 的最小整数,等价于 CEIL(n)' },
|
||||
{ label: 'COS', insertText: 'COS(n)', description: '求数值 n 的余弦值' },
|
||||
{ label: 'COSH', insertText: 'COSH(n)', description: '求数值 n 的双曲余弦值' },
|
||||
{ label: 'COT', insertText: 'COT(n)', description: '求数值 n 的余切值' },
|
||||
{ label: 'DEGREES', insertText: 'DEGREES(n)', description: '求弧度 n 对应的角度值' },
|
||||
{ label: 'EXP', insertText: 'EXP(n)', description: '求数值 n 的自然指数' },
|
||||
{ label: 'FLOOR', insertText: 'FLOOR(n)', description: '求小于或等于数值 n 的最大整数' },
|
||||
{ label: 'GREATEST', insertText: 'GREATEST(n, n2)', description: '求一个或多个数中最大的一个' },
|
||||
{ label: 'GREAT', insertText: 'GREAT(n1, n2)', description: '求 n1、n2 两个数中最大的一个' },
|
||||
{ label: 'LEAST', insertText: 'LEAST(n, n2)', description: '求一个或多个数中最小的一个' },
|
||||
{ label: 'LN', insertText: 'LN(n)', description: '求数值 n 的自然对数' },
|
||||
{ label: 'LOG', insertText: 'LOG(n1,n2)', description: '求数值 n2 以 n1 为底数的对数' },
|
||||
{ label: 'LOG10', insertText: 'LOG10(n)', description: '求数值 n 以 10 为底的对数' },
|
||||
{ label: 'MOD', insertText: 'MOD(m,n)', description: '求数值 m 被数值 n 除的余数' },
|
||||
{ label: 'PI', insertText: 'PI()', description: '得到常数 π' },
|
||||
{ label: 'POWER', insertText: 'POWER(n1,n2)', description: '求数值 n2 以 n1 为基数的指数' },
|
||||
{ label: 'RADIANS', insertText: 'RADIANS(n)', description: '求角度 n 对应的弧度值' },
|
||||
{ label: 'RAND', insertText: 'RAND', description: '求一个 0 到 1 之间的随机浮点数' },
|
||||
{ label: 'ROUND', insertText: 'ROUND(n [,m]})', description: '返回四舍五入到小数点后面 m 位的 n 值' },
|
||||
{ label: 'SIGN', insertText: 'SIGN(n)', description: '判断数值的数学符号' },
|
||||
{ label: 'SIN', insertText: 'SIN(n)', description: '求数值 n 的正弦值' },
|
||||
{ label: 'SINH', insertText: 'SINH(n)', description: '求数值 n 的双曲正弦值' },
|
||||
{ label: 'SQRT', insertText: 'SQRT(n)', description: '求数值 n 的平方根' },
|
||||
{ label: 'TAN', insertText: 'TAN(n)', description: '求数值 n 的正切值' },
|
||||
{ label: 'TANH', insertText: 'TANH(n)', description: '求数值 n 的双曲正切值' },
|
||||
{ label: 'TO_NUMBER', insertText: 'TO_NUMBER (char [,fmt])', description: '将 CHAR、VARCHAR、VARCHAR2 等类型的字符串转换为 DECIMAL 类型的数值' },
|
||||
{ label: 'TRUNC', insertText: 'TRUNC(n [,m])', description: "截取数值函数,str 内只能为数字和'-', '+', '.' 的组合" },
|
||||
{ label: 'TRUNCATE', insertText: 'TRUNCATE(n [,m])', description: '截取数值函数,等价于 TRUNC 函数' },
|
||||
{ label: 'TO_CHAR', insertText: 'TO_CHAR(n [, fmt])', description: '将数值类型的数据转换为 VARCHAR 类型输出' },
|
||||
{ label: 'BITAND', insertText: 'BITAND(n1, n2)', description: '求两个数值型数值按位进行 AND 运算的结果' },
|
||||
{ label: 'NANVL', insertText: 'NANVL(n1, n2)', description: '有一个参数为空则返回空,否则返回 n1 的值' },
|
||||
{ label: 'REMAINDER', insertText: 'REMAINDER(n1, n2)', description: '计算 n1 除 n2 的余数,余数取绝对值更小的那一个' },
|
||||
{ label: 'TO_BINARY_FLOAT', insertText: 'TO_BINARY_FLOAT(n)', description: '将 number、real 或 double 类型数值转换成 binary float 类型' },
|
||||
{ label: 'TO_BINARY_DOUBLE', insertText: 'TO_BINARY_DOUBLE(n)', description: '将 number、real 或 float 类型数值转换成 binary double 类型' },
|
||||
// 字符串函数
|
||||
{ label: 'ASCII', insertText: 'ASCII(char)', description: '返回字符对应的整数' },
|
||||
{ label: 'ASCIISTR', insertText: 'ASCIISTR(char)', description: '将字符串 char 中,非 ASCII 的字符转成 \\XXXX(UTF-16)格式,ASCII 字符保持不变' },
|
||||
{ label: 'BIT_LENGTH', insertText: 'BIT_LENGTH(char)', description: '求字符串的位长度' },
|
||||
{ label: 'CHAR', insertText: 'CHAR(n)', description: '返回整数 n 对应的字符' },
|
||||
{ label: 'CHAR_LENGTH', insertText: 'CHAR_LENGTH(char)', description: '求字符串的串长度' },
|
||||
{ label: 'CHARACTER_LENGTH', insertText: 'CHARACTER_LENGTH(char)', description: '求字符串的串长度' },
|
||||
{ label: 'CHR', insertText: 'CHR(n)', description: '返回整数 n 对应的字符,等价于 CHAR(n)' },
|
||||
{ label: 'CONCAT', insertText: 'CONCAT(char1,char2,char3,...)', description: '顺序联结多个字符串成为一个字符串' },
|
||||
{
|
||||
label: 'DIFFERENCE',
|
||||
insertText: 'DIFFERENCE(char1,char2)',
|
||||
description: '返回两个值串同一位置出现相同字符的个数。',
|
||||
},
|
||||
{ label: 'INITCAP', insertText: 'INITCAP(char)', description: '将字符串中单词的首字符转换成大写的字符' },
|
||||
{
|
||||
label: 'INS',
|
||||
insertText: 'INS(char1,begin,n,char2)',
|
||||
description: '删除在字符串 char1 中以 begin 参数所指位置开始的 n 个字符, 再把 char2 插入到 char1 串的 begin 所指位置',
|
||||
},
|
||||
{
|
||||
label: 'INSERT',
|
||||
insertText: 'INSERT(char1,n1,n2,char2)',
|
||||
description: '将字符串 char1 从 n1 的位置开始删除 n2 个字符,并将 char2 插入到 char1 中 n1 的位置',
|
||||
},
|
||||
{
|
||||
label: 'INSSTR',
|
||||
insertText: 'INSERT(char1,n1,n2,char2)',
|
||||
description: '将字符串 char1 从 n1 的位置开始删除 n2 个字符,并将 char2 插入到 char1 中 n1 的位置',
|
||||
},
|
||||
{
|
||||
label: 'INSTR',
|
||||
insertText: 'INSTR(char1,char2[,n,[m]])',
|
||||
description: '从输入字符串char1的第n个字符开始查找字符串 char2 的第 m 次出现的位置,以字符计算',
|
||||
},
|
||||
{ label: 'INSTRB', insertText: 'INSTRB(char1,char2[,n,[m]])', description: '从 char1 的第 n 个字节开始查找字符串 char2 的第 m 次出现的位置,以字节计算' },
|
||||
{ label: 'LCASE', insertText: 'LCASE(char)', description: '将大写的字符串转换为小写的字符串' },
|
||||
{ label: 'LEFT', insertText: 'LEFT(char,n)', description: '返回字符串最左边的 n 个字符组成的字符串' },
|
||||
{ label: 'LEFTSTR', insertText: 'LEFTSTR(char,n)', description: '返回字符串最左边的 n 个字符组成的字符串' },
|
||||
{ label: 'LEN', insertText: 'LEN(char)', description: '返回给定字符串表达式的字符(而不是字节)个数(汉字为一个字符),其中不包含尾随空格' },
|
||||
{ label: 'LENGTH', insertText: 'LENGTH(clob)', description: '返回给定字符串表达式的字符(而不是字节)个数(汉字为一个字符),其中包含尾随空格' },
|
||||
{ label: 'OCTET_LENGTH', insertText: 'OCTET_LENGTH(char)', description: '返回输入字符串的字节数' },
|
||||
{ label: 'LOCATE', insertText: 'LOCATE(char1,char2[,n])', description: '返回 char1 在 char2 中首次出现的位置' },
|
||||
{ label: 'LOWER', insertText: 'LOWER(char)', description: '将大写的字符串转换为小写的字符串' },
|
||||
{ label: 'LPAD', insertText: 'LPAD(char1,n,char2)', description: '在输入字符串的左边填充上 char2 指定的字符,将其拉伸至 n 个字节长度' },
|
||||
{ label: 'LTRIM', insertText: 'LTRIM(str[,set])', description: '删除字符串 str 左边起,出现在 set 中的任何字符,当遇到不在 set 中的第一个字符时返回结果' },
|
||||
{ label: 'POSITION', insertText: 'POSITION(char1, char2)', description: '求串 1 在串 2 中第一次出现的位置' },
|
||||
{ label: 'REPEAT', insertText: 'REPEAT(char,n)', description: '返回将字符串重复 n 次形成的字符串' },
|
||||
{ label: 'REPEATSTR', insertText: 'REPEATSTR(char,n)', description: '返回将字符串重复 n 次形成的字符串' },
|
||||
{
|
||||
label: 'REPLACE',
|
||||
insertText: 'REPLACE(str, search [,replace])',
|
||||
description: '将输入字符串 STR 中所有出现的字符串 search 都替换成字符串 replace ,其中 str 为 char、clob 或 text 类型',
|
||||
},
|
||||
{ label: 'REPLICATE', insertText: 'REPLICATE(char,times)', description: '把字符串 char 自己复制 times 份' },
|
||||
{ label: 'REVERSE', insertText: 'REVERSE(char)', description: '将字符串反序' },
|
||||
{ label: 'RIGHT', insertText: 'RIGHT', description: '返回字符串最右边 n 个字符组成的字符串' },
|
||||
{ label: 'RIGHTSTR', insertText: 'RIGHTSTR(char,n)', description: '返回字符串最右边 n 个字符组成的字符串' },
|
||||
{ label: 'RPAD', insertText: 'RPAD(char1,n[,char2])', description: '类似 LPAD 函数,只是向右拉伸该字符串使之达到 n 个字节长度' },
|
||||
{ label: 'RTRIM', insertText: 'RTRIM(str[,set])', description: '删除字符串str右边起出现的set中的任何字符,当遇到不在 set 中的第一个字符时返回结果' },
|
||||
{ label: 'SOUNDEX', insertText: 'SOUNDEX(char)', description: '返回一个表示字符串发音的字符串' },
|
||||
{ label: 'SPACE', insertText: 'SPACE(n)', description: '返回一个包含 n 个空格的字符串' },
|
||||
{ label: 'STRPOSDEC', insertText: 'STRPOSDEC(char[,pos])', description: '把字符串 char 中指定位置 pos 上的字节值减一' },
|
||||
{ label: 'STRPOSINC', insertText: 'STRPOSINC(char)', description: '把字符串 char 中最后一个字节的值加一' },
|
||||
{ label: 'STRPOSINC', insertText: 'STRPOSINC(char,pos)', description: '把字符串 char 中指定位置 pos 上的字节值加一' },
|
||||
{
|
||||
label: 'STUFF',
|
||||
insertText: 'STUFF(char1,begin,n,char2)',
|
||||
description: '删除在字符串 char1 中以 begin 参数所指位置开始的 n 个字符, 再把 char2 插入到 char1 串的 begin 所指位置',
|
||||
},
|
||||
{ label: 'SUBSTR', insertText: 'SUBSTR(char[,m[,n]])', description: '返回 char 中从字符位置 m 开始的 n 个字符' },
|
||||
{ label: 'SUBSTRING', insertText: 'SUBSTRING(char [FROM m [FOR n]])', description: '返回 char 中从字符位置 m 开始的 n 个字符' },
|
||||
{ label: 'SUBSTRB', insertText: 'SUBSTRB(char,m[,n])', description: 'SUBSTR 函数等价的单字节形式' },
|
||||
{ label: 'TO_CHAR', insertText: 'TO_CHAR(character)', description: '将 VARCHAR、CLOB、TEXT 类型的数据转化为 VARCHAR 类型输出' },
|
||||
{ label: 'TRANSLATE', insertText: 'TRANSLATE(char,from,to)', description: '将所有出现在搜索字符集中的字符转换成字符集中的相应字符' },
|
||||
{ label: 'TRIM', insertText: 'TRIM([<<LEADING|TRAILING|BOTH>[char] | char> FROM] str)', description: '删去字符串 str 中由 char 指定的字符' },
|
||||
{ label: 'UCASE', insertText: 'UCASE(char)', description: '将小写的字符串转换为大写的字符串' },
|
||||
{ label: 'UPPER', insertText: 'UPPER(char)', description: '将小写的字符串转换为大写的字符串' },
|
||||
{ label: 'NLS_UPPER', insertText: 'NLS_UPPER(char)', description: '将小写的字符串转换为大写的字符串' },
|
||||
{ label: 'REGEXP', insertText: 'REGEXP', description: '根据符合 POSIX 标准的正则表达式进行字符串匹配' },
|
||||
{
|
||||
label: 'OVERLAY',
|
||||
insertText: 'OVERLAY(char1 PLACING char2 FROM int [FOR int])',
|
||||
description: '字符串覆盖函数,用 char2 覆盖 char1 中指定的子串,返回修改后的 char1',
|
||||
},
|
||||
{ label: 'TEXT_EQUAL', insertText: 'TEXT_EQUAL(n1,n2)', description: '返回两个 LONGVARCHAR 类型的值的比较结果,相同返回 1,否则返回 0' },
|
||||
{ label: 'BLOB_EQUAL', insertText: 'BLOB_EQUAL(n1,n2)', description: '返回两个 LONGVARBINARY 类型的值的比较结果,相同返回 1,否则返回 0' },
|
||||
{ label: 'NLSSORT', insertText: 'NLSSORT(str1 [,nls_sort=str2])', description: '返回对自然语言排序的编码' },
|
||||
{ label: 'GREATEST', insertText: 'GREATEST(char {,char})', description: '求一个或多个字符串中最大的字符串' },
|
||||
{ label: 'GREAT', insertText: 'GREAT (char1, char2)', description: '求 char 1、char 2 中最大的字符串' },
|
||||
{ label: 'TO_SINGLE_BYTE', insertText: 'TO_SINGLE_BYTE (char)', description: '将多字节形式的字符(串)转换为对应的单字节形式' },
|
||||
{ label: 'TO_MULTI_BYTE', insertText: 'TO_MULTI_BYTE (char)', description: '将单字节形式的字符(串)转换为对应的多字节形式' },
|
||||
{ label: 'EMPTY_CLOB', insertText: 'EMPTY_CLOB ()', description: '初始化 clob 字段' },
|
||||
{ label: 'EMPTY_BLOB', insertText: 'EMPTY_BLOB ()', description: '初始化 blob 字段' },
|
||||
{
|
||||
label: 'UNISTR',
|
||||
insertText: 'UNISTR (char)',
|
||||
description: '将字符串 char 中,ASCII 编码或 Unicode 编码(‗XXXX‘4 个 16 进制字符格式)转成本地字符。对于其他字符保持不变',
|
||||
},
|
||||
{ label: 'ISNULL', insertText: 'ISNULL(char)', description: '判断表达式是否为 NULL' },
|
||||
{ label: 'CONCAT_WS', insertText: 'CONCAT_WS(delim, char1,char2,char3,…)', description: '顺序联结多个字符串成为一个字符串,并用 delim 分割' },
|
||||
{ label: 'SUBSTRING_INDEX', insertText: 'SUBSTRING_INDEX(char, delim, count)', description: '按关键字截取字符串,截取到指定分隔符出现指定次数位置之前' },
|
||||
{ label: 'COMPOSE', insertText: 'COMPOSE(varchar str)', description: '在 UTF8 库下,将 str 以本地编码的形式返回' },
|
||||
{
|
||||
label: 'FIND_IN_SET',
|
||||
insertText: 'FIND_IN_SET(str, strlist[,separator])',
|
||||
description: '查询 strlist 中是否包含 str,返回 str 在 strlist 中第一次出现的位置或 NULL',
|
||||
},
|
||||
{ label: 'TRUNC', insertText: 'TRUNC(str1, str2)', description: '截取字符串函数' },
|
||||
//日期时间函数
|
||||
{ label: 'ADD_DAYS', insertText: 'ADD_DAYS(date,n)', description: '返回日期加上 n 天后的新日期' },
|
||||
{ label: 'ADD_MONTHS', insertText: 'ADD_MONTHS(date,n)', description: '在输入日期上加上指定的几个月返回一个新日期' },
|
||||
{ label: 'ADD_WEEKS', insertText: 'ADD_WEEKS(date,n)', description: '返回日期加上 n 个星期后的新日期' },
|
||||
{ label: 'CURDATE', insertText: 'CURDATE()', description: '返回系统当前日期' },
|
||||
{ label: 'CURTIME', insertText: 'CURTIME(n)', description: '返回系统当前时间' },
|
||||
{ label: 'CURRENT_DATE', insertText: 'CURRENT_DATE()', description: '返回系统当前日期' },
|
||||
{ label: 'CURRENT_TIME', insertText: 'CURRENT_TIME(n)', description: '返回系统当前时间' },
|
||||
{ label: 'CURRENT_TIMESTAMP', insertText: 'CURRENT_TIMESTAMP(n)', description: '返回系统当前带会话时区信息的时间戳' },
|
||||
{ label: 'DATEADD', insertText: 'DATEADD(datepart,n,date)', description: '向指定的日期加上一段时间' },
|
||||
{ label: 'DATEDIFF', insertText: 'DATEDIFF(datepart,date1,date2)', description: '返回跨两个指定日期的日期和时间边界数' },
|
||||
{ label: 'DATEPART', insertText: 'DATEPART(datepart,date)', description: '返回代表日期的指定部分的整数' },
|
||||
{ label: 'DAY', insertText: 'DAY(date)', description: '返回日期中的天数' },
|
||||
{ label: 'DAYNAME', insertText: 'DAYNAME(date)', description: '返回日期的星期名称' },
|
||||
{ label: 'DAYOFMONTH', insertText: 'DAYOFMONTH(date)', description: '返回日期为所在月份中的第几天' },
|
||||
{ label: 'DAYOFWEEK', insertText: 'DAYOFWEEK(date)', description: '返回日期为所在星期中的第几天' },
|
||||
{ label: 'DAYOFYEAR', insertText: 'DAYOFYEAR(date)', description: '返回日期为所在年中的第几天' },
|
||||
{ label: 'DAYS_BETWEEN', insertText: 'DAYS_BETWEEN(date1,date2)', description: '返回两个日期之间的天数' },
|
||||
{ label: 'EXTRACT', insertText: 'EXTRACT(时间字段 FROM date)', description: '抽取日期时间或时间间隔类型中某一个字段的值' },
|
||||
{ label: 'GETDATE', insertText: 'GETDATE(n)', description: '返回系统当前时间戳' },
|
||||
{ label: 'GREATEST', insertText: 'GREATEST(date {,date})', description: '求一个或多个日期中的最大日期' },
|
||||
{ label: 'GREAT', insertText: 'GREAT(date1,date2)', description: '求 date1、date2 中的最大日期' },
|
||||
{ label: 'HOUR', insertText: 'HOUR(time)', description: '返回时间中的小时分量' },
|
||||
{ label: 'LAST_DAY', insertText: 'LAST_DAY(date)', description: '返回输入日期所在月份最后一天的日期' },
|
||||
{ label: 'LEAST', insertText: 'LEAST(date {,date})', description: '求一个或多个日期中的最小日期' },
|
||||
{ label: 'MINUTE', insertText: 'MINUTE(time)', description: '返回时间中的分钟分量' },
|
||||
{ label: 'MONTH', insertText: 'MONTH(date)', description: '返回日期中的月份分量' },
|
||||
{ label: 'MONTHNAME', insertText: 'MONTHNAME(date)', description: '返回日期中月分量的名称' },
|
||||
{ label: 'MONTHS_BETWEEN', insertText: 'MONTHS_BETWEEN(date1,date2)', description: '返回两个日期之间的月份数' },
|
||||
{ label: 'NEXT_DAY', insertText: 'NEXT_DAY(date1,char2)', description: '返回输入日期指定若干天后的日期' },
|
||||
{ label: 'NOW', insertText: 'NOW(n)', description: '返回系统当前时间戳' },
|
||||
{ label: 'QUARTER', insertText: 'QUARTER(date)', description: '返回日期在所处年中的季节数' },
|
||||
{ label: 'SECOND', insertText: 'SECOND(time)', description: '返回时间中的秒分量' },
|
||||
{ label: 'ROUND', insertText: 'ROUND(date1[, fmt])', description: '把日期四舍五入到最接近格式元素指定的形式' },
|
||||
{ label: 'TIMESTAMPADD', insertText: 'TIMESTAMPADD(datepart,n,timestamp)', description: '返回时间戳 timestamp 加上 n 个 datepart 指定的时间段的结果' },
|
||||
{
|
||||
label: 'TIMESTAMPDIFF',
|
||||
insertText: 'TIMESTAMPDIFF(datepart,timestamp1,timestamp2)',
|
||||
description: '返回一个表明timestamp2与timestamp1之间的指定 datepart 类型时间间隔的整数',
|
||||
},
|
||||
{ label: 'SYSDATE', insertText: 'SYSDATE()', description: '返回系统的当前日期' },
|
||||
{ label: 'TO_DATE', insertText: "TO_DATE(CHAR[,fmt[,'nls']])", description: '字符串转换为日期时间数据类型' },
|
||||
{
|
||||
label: 'FROM_TZ',
|
||||
insertText: 'FROM_TZ(timestamp,timezonetz_name])',
|
||||
description: '将时间戳类型 timestamp 和时区类型 timezone(或时区名称 tz_name ) 转 化 为 timestamp with timezone 类型',
|
||||
},
|
||||
{ label: 'TZ_OFFSET', insertText: 'TZ_OFFSET(timezone|[tz_name])', description: '返回给定的时区或时区名和标准时区(UTC)的偏移量' },
|
||||
{ label: 'TRUNC', insertText: 'TRUNC(date[,fmt])', description: '把日期截断到最接近格式元素指定的形式' },
|
||||
{ label: 'WEEK', insertText: 'WEEK(date)', description: '返回日期为所在年中的第几周' },
|
||||
{ label: 'WEEKDAY', insertText: 'WEEKDAY(date)', description: '返回当前日期的星期值' },
|
||||
{ label: 'WEEKS_BETWEEN', insertText: 'WEEKS_BETWEEN(date1,date2)', description: '返回两个日期之间相差周数' },
|
||||
{ label: 'YEAR', insertText: 'YEAR(date)', description: '返回日期的年分量' },
|
||||
{ label: 'YEARS_BETWEEN', insertText: 'YEARS_BETWEEN(date1,date2)', description: '返回两个日期之间相差年数' },
|
||||
{ label: 'LOCALTIME', insertText: 'LOCALTIME(n)', description: '返回系统当前时间' },
|
||||
{ label: 'LOCALTIMESTAMP', insertText: 'LOCALTIMESTAMP(n)', description: '返回系统当前时间戳' },
|
||||
{ label: 'OVERLAPS', insertText: 'OVERLAPS', description: '返回两个时间段是否存在重叠' },
|
||||
{
|
||||
label: 'TO_CHAR',
|
||||
insertText: 'TO_CHAR(date[,fmt[,nls]])',
|
||||
description: '将日期数据类型 DATE 转换为一个在日期语法 fmt 中指定语法的 VARCHAR 类型字符串。',
|
||||
},
|
||||
{ label: 'SYSTIMESTAMP', insertText: 'SYSTIMESTAMP(n)', description: '返回系统当前带数据库时区信息的时间戳' },
|
||||
{ label: 'NUMTODSINTERVAL', insertText: 'NUMTODSINTERVAL(dec,interval_unit)', description: '转换一个指定的 DEC 类型到 INTERVAL DAY TO SECOND' },
|
||||
{ label: 'NUMTOYMINTERVAL', insertText: 'NUMTOYMINTERVAL (dec,interval_unit)', description: '转换一个指定的 DEC 类型值到 INTERVAL YEAR TO MONTH' },
|
||||
{ label: 'WEEK', insertText: 'WEEK(date, mode)', description: '根据指定的 mode 计算日期为年中的第几周' },
|
||||
{
|
||||
label: 'UNIX_TIMESTAMP',
|
||||
insertText: 'UNIX_TIMESTAMP (datetime)',
|
||||
description: "返回自标准时区的'1970-01-01 00:00:00 +0:00'的到本地会话时区的指定时间的秒数差",
|
||||
},
|
||||
{ label: 'FROM_UNIXTIME', insertText: 'FROM_UNIXTIME(unixtime)', description: "返回将自'1970-01-01 00:00:00'的秒数差转成本地会话时区的时间戳类型" },
|
||||
{
|
||||
label: 'FROM_UNIXTIME',
|
||||
insertText: 'FROM_UNIXTIME(unixtime, fmt)',
|
||||
description: "将自'1970-01-01 00:00:00'的秒数差转成本地会话时区的指定 fmt 格式的时间串",
|
||||
},
|
||||
{ label: 'SESSIONTIMEZONE', insertText: 'SESSIONTIMEZONE', description: '返回当前会话的时区' },
|
||||
{ label: 'DBTIMEZONE', insertText: 'DBTIMEZONE', description: '返回当前数据库的时区' },
|
||||
{ label: 'DATE_FORMAT', insertText: 'DATE_FORMAT(d, format)', description: '以不同的格式显示日期/时间数据' },
|
||||
{ label: 'TIME_TO_SEC', insertText: 'TIME_TO_SEC(d)', description: '将时间换算成秒' },
|
||||
{ label: 'SEC_TO_TIME', insertText: 'SEC_TO_TIME(sec)', description: '将秒换算成时间' },
|
||||
{ label: 'TO_DAYS', insertText: 'TO_DAYS(timestamp)', description: '转换成公元 0 年 1 月 1 日的天数差' },
|
||||
{ label: 'DATE_ADD', insertText: 'DATE_ADD(datetime, interval)', description: '返回一个日期或时间值加上一个时间间隔的时间值' },
|
||||
{ label: 'DATE_SUB', insertText: 'DATE_SUB(datetime, interval)', description: '返回一个日期或时间值减去一个时间间隔的时间值' },
|
||||
{ label: 'SYS_EXTRACT_UTC', insertText: 'SYS_EXTRACT_UTC(d timestamp)', description: '将所给时区信息转换为 UTC 时区信息' },
|
||||
{ label: 'TO_DSINTERVAL', insertText: 'TO_DSINTERVAL(d timestamp)', description: '转换一个 timestamp 类型值到 INTERVAL DAY TO SECOND' },
|
||||
{ label: 'TO_YMINTERVAL', insertText: 'TO_YMINTERVAL(d timestamp)', description: '转换一个 timestamp 类型值到 INTERVAL YEAR TO MONTH' },
|
||||
// 空值判断函数
|
||||
{ label: 'COALESCE', insertText: 'COALESCE(n1,n2,…nx)', description: '返回第一个非空的值' },
|
||||
{ label: 'IFNULL', insertText: 'IFNULL(n1,n2)', description: '当 n1 为非空时,返回 n1;若 n1 为空,则返回 n2' },
|
||||
{ label: 'ISNULL', insertText: 'ISNULL(n1,n2)', description: '当 n1 为非空时,返回 n1;若 n1 为空,则返回 n2' },
|
||||
{ label: 'NULLIF', insertText: 'NULLIF(n1,n2)', description: '如果 n1=n2 返回 NULL,否则返回 n1' },
|
||||
{ label: 'NVL', insertText: 'NVL(n1,n2)', description: '返回第一个非空的值' },
|
||||
{ label: 'NULL_EQU', insertText: 'NULL_EQU', description: '返回两个类型相同的值的比较' },
|
||||
// 类型转换函数
|
||||
{ label: 'CAST', insertText: 'CAST(value AS 类型说明)', description: '将 value 转换为指定的类型' },
|
||||
{
|
||||
label: 'CONVERT',
|
||||
insertText: 'CONVERT(类型说明,value)',
|
||||
description:
|
||||
'用于当 INI 参数 ENABLE_CS_CVT=0 时,将 value 转换为指定的类型;用于当 INI 参数 ENABLE_CS_CVT=1 时,将字符串从原串编码格式转换成目的编码格式',
|
||||
},
|
||||
{
|
||||
label: 'CONVERT',
|
||||
insertText: 'CONVERT(char, dest_char_set [,source_char_set ] )',
|
||||
description:
|
||||
'用于当 INI 参数 ENABLE_CS_CVT=0 时,将 value 转换为指定的类型;用于当 INI 参数 ENABLE_CS_CVT=1 时,将字符串从原串编码格式转换成目的编码格式',
|
||||
},
|
||||
{ label: 'HEXTORAW', insertText: 'HEXTORAW(exp)', description: '将 exp 转换为 BLOB 类型' },
|
||||
{ label: 'RAWTOHEX', insertText: 'RAWTOHEX(exp)', description: '将 exp 转换为 VARCHAR 类型' },
|
||||
{ label: 'BINTOCHAR', insertText: 'BINTOCHAR(exp)', description: '将 exp 转换为 CHAR' },
|
||||
{ label: 'TO_BLOB', insertText: 'TO_BLOB(value)', description: '将 value 转换为 blob' },
|
||||
{ label: 'UNHEX', insertText: 'UNHEX(exp)', description: '将十六进制的 exp 转换为格式字符串' },
|
||||
{ label: 'HEX', insertText: 'HEX(exp)', description: '将字符串的 exp 转换为十六进制字符串' },
|
||||
// 杂类函数
|
||||
{ label: 'DECODE', insertText: 'DECODE(exp, search1, result1, … searchn, resultn [,default])', description: '查表译码' },
|
||||
{ label: 'ISDATE', insertText: 'ISDATE(exp)', description: '判断表达式是否为有效的日期' },
|
||||
{ label: 'ISNUMERIC', insertText: 'ISNUMERIC(exp)', description: '判断表达式是否为有效的数值' },
|
||||
{ label: 'DM_HASH', insertText: 'DM_HASH(exp)', description: '根据给定表达式生成 HASH 值' },
|
||||
{ label: 'LNNVL', insertText: 'LNNVL(condition)', description: '根据表达式计算结果返回布尔值' },
|
||||
{ label: 'LENGTHB', insertText: 'LENGTHB(value)', description: '返回 value 的字节数' },
|
||||
{
|
||||
label: 'FIELD',
|
||||
insertText: 'FIELD(value, e1, e2, e3, e4...en)',
|
||||
description: '返回 value 在列表 e1, e2, e3, e4...en 中的位置序号,不在输入列表时则返回 0',
|
||||
},
|
||||
{ label: 'ORA_HASH', insertText: 'ORA_HASH(exp [,max_bucket [,seed_value]])', description: '为表达式 exp 生成 HASH 桶值' },
|
||||
];
|
||||
|
||||
let dmDialectInfo: DialectInfo;
|
||||
class DMDialect implements DbDialect {
|
||||
getInfo() {
|
||||
getInfo(): DialectInfo {
|
||||
if (dmDialectInfo) {
|
||||
return dmDialectInfo;
|
||||
}
|
||||
|
||||
let { keywords, operators, builtinVariables } = sqlLanguage;
|
||||
let functionNames = replaceFunctions.map((a) => a.label);
|
||||
let excludeKeywords = new Set(functionNames.concat(operators));
|
||||
|
||||
let editorCompletions: EditorCompletion = {
|
||||
keywords: keywords
|
||||
.filter((a: string) => !excludeKeywords.has(a)) // 移除已存在的operator、function
|
||||
.map((a: string): EditorCompletionItem => ({ label: a, description: 'keyword' }))
|
||||
.concat(
|
||||
// 加上自定义的关键字
|
||||
commonCustomKeywords.map(
|
||||
(a): EditorCompletionItem => ({
|
||||
label: a,
|
||||
description: 'keyword',
|
||||
})
|
||||
)
|
||||
),
|
||||
operators: operators.map((a: string): EditorCompletionItem => ({ label: a, description: 'operator' })),
|
||||
functions: replaceFunctions,
|
||||
variables: builtinVariables.map((a: string): EditorCompletionItem => ({ label: a, description: 'var' })),
|
||||
};
|
||||
|
||||
dmDialectInfo = {
|
||||
icon: 'iconfont icon-db-dm',
|
||||
defaultPort: 5236,
|
||||
formatSqlDialect: 'postgresql',
|
||||
columnTypes: DM_TYPE_LIST.sort((a, b) => a.udtName.localeCompare(b.udtName)),
|
||||
editorCompletions,
|
||||
};
|
||||
return dmDialectInfo;
|
||||
}
|
||||
|
||||
|
||||
@@ -30,6 +30,27 @@ export interface IndexDefinition {
|
||||
indexType: string;
|
||||
indexComment?: string;
|
||||
}
|
||||
export const commonCustomKeywords = ['GROUP BY', 'ORDER BY', 'LEFT JOIN', 'RIGHT JOIN', 'INNER JOIN', 'SELECT * FROM'];
|
||||
|
||||
export interface EditorCompletionItem {
|
||||
/** 用于显示 */
|
||||
label: string;
|
||||
/** 用于插入编辑器,可预置一些变量方便使用函数 */
|
||||
insertText?: string;
|
||||
/** 用于描述 */
|
||||
description: string;
|
||||
}
|
||||
|
||||
export interface EditorCompletion {
|
||||
/** 关键字 */
|
||||
keywords: EditorCompletionItem[];
|
||||
/** 操作关键字 */
|
||||
operators: EditorCompletionItem[];
|
||||
/** 函数,包括内置函数和自定义函数 */
|
||||
functions: EditorCompletionItem[];
|
||||
/** 内置变量 */
|
||||
variables: EditorCompletionItem[];
|
||||
}
|
||||
|
||||
// 数据库基础信息
|
||||
export interface DialectInfo {
|
||||
@@ -52,6 +73,11 @@ export interface DialectInfo {
|
||||
* 列字段类型
|
||||
*/
|
||||
columnTypes: sqlColumnType[];
|
||||
|
||||
/**
|
||||
* 编辑器一些固定代码提示(关键字、操作符)
|
||||
*/
|
||||
editorCompletions: EditorCompletion;
|
||||
}
|
||||
|
||||
export const DbType = {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { DbDialect, DialectInfo, IndexDefinition, RowDefinition } from './index';
|
||||
import { commonCustomKeywords, DbDialect, DialectInfo, EditorCompletion, EditorCompletionItem, IndexDefinition, RowDefinition } from './index';
|
||||
import { language as mysqlLanguage } from 'monaco-editor/esm/vs/basic-languages/mysql/mysql.js';
|
||||
|
||||
export { MYSQL_TYPE_LIST, MysqlDialect, language };
|
||||
export { MYSQL_TYPE_LIST, MysqlDialect };
|
||||
|
||||
const MYSQL_TYPE_LIST = [
|
||||
'bigint',
|
||||
@@ -29,15 +30,83 @@ const MYSQL_TYPE_LIST = [
|
||||
'varchar',
|
||||
];
|
||||
|
||||
const mysqlDialectInfo: DialectInfo = {
|
||||
icon: 'iconfont icon-op-mysql',
|
||||
defaultPort: 3306,
|
||||
formatSqlDialect: 'mysql',
|
||||
columnTypes: MYSQL_TYPE_LIST.map((a) => ({ udtName: a, dataType: a, desc: '', space: '' })),
|
||||
};
|
||||
const replaceFunctions: EditorCompletionItem[] = [
|
||||
/** 字符串相关函数 */
|
||||
{ label: 'CONCAT', insertText: 'CONCAT(str1,str2,...)', description: '多字符串合并' },
|
||||
{ label: 'ASCII', insertText: 'ASCII(char)', description: '返回字符的ASCII值' },
|
||||
{ label: 'BIT_LENGTH', insertText: 'BIT_LENGTH(str1)', description: '多字符串合并' },
|
||||
{ label: 'INSTR', insertText: 'INSTR(str,substr)', description: '返回字符串substr所在str位置' },
|
||||
{ label: 'LEFT', insertText: 'LEFT(str,len)', description: '返回字符串str的左端len个字符' },
|
||||
{ label: 'RIGHT', insertText: 'RIGHT(str,len)', description: '返回字符串str的右端len个字符' },
|
||||
{ label: 'MID', insertText: 'MID(str,pos,len)', description: '返回字符串str的位置pos起len个字符' },
|
||||
{ label: 'SUBSTRING', insertText: 'SUBSTRING(exp, start, length)', description: '截取字符串' },
|
||||
{ label: 'REPLACE', insertText: 'REPLACE(str,from_str,to_str)', description: '替换字符串' },
|
||||
{ label: 'REPEAT', insertText: 'REPEAT(str,count)', description: '重复字符串count遍' },
|
||||
{ label: 'UPPER', insertText: 'UPPER(str)', description: '返回大写的字符串' },
|
||||
{ label: 'LOWER', insertText: 'LOWER(str)', description: '返回小写的字符串' },
|
||||
{ label: 'TRIM', insertText: 'TRIM(str)', description: '去除字符串首尾空格' },
|
||||
/** 数学相关函数 */
|
||||
{ label: 'ABS', insertText: 'ABS(n)', description: '返回n的绝对值' },
|
||||
{ label: 'FLOOR', insertText: 'FLOOR(n)', description: '返回不大于n的最大整数' },
|
||||
{ label: 'CEILING', insertText: 'CEILING(n)', description: '返回不小于n的最小整数值' },
|
||||
{ label: 'ROUND', insertText: 'ROUND(n,d)', description: '返回n的四舍五入值,保留d(默认0)位小数' },
|
||||
{ label: 'RAND', insertText: 'RAND()', description: '返回在范围0到1.0内的随机浮点值' },
|
||||
|
||||
/** 日期函数 */
|
||||
{ label: 'DATE', insertText: "DATE('date')", description: '返回指定表达式的日期部分' },
|
||||
{ label: 'WEEK', insertText: "WEEK('date')", description: '返回指定日期是一年中的第几周' },
|
||||
{ label: 'MONTH', insertText: "MONTH('date')", description: '返回指定日期的月份' },
|
||||
{ label: 'QUARTER', insertText: "QUARTER('date')", description: '返回指定日期是一年的第几个季度' },
|
||||
{ label: 'YEAR', insertText: "YEAR('date')", description: '返回指定日期的年份' },
|
||||
{ label: 'DATE_ADD', insertText: "DATE_ADD('date', interval 1 day)", description: '日期函数加减运算' },
|
||||
{ label: 'DATE_SUB', insertText: "DATE_SUB('date', interval 1 day)", description: '日期函数加减运算' },
|
||||
{ label: 'DATE_FORMAT', insertText: "DATE_FORMAT('date', '%Y-%m-%d %h:%i:%s')", description: '' },
|
||||
{ label: 'CURDATE', insertText: 'CURDATE()', description: '返回当前日期' },
|
||||
{ label: 'CURTIME', insertText: 'CURTIME()', description: '返回当前时间' },
|
||||
{ label: 'NOW', insertText: 'NOW()', description: '返回当前日期时间' },
|
||||
{ label: 'DATEDIFF', insertText: 'DATEDIFF(expr1,expr2)', description: '返回结束日expr1和起始日expr2之间的天数' },
|
||||
{ label: 'UNIX_TIMESTAMP', insertText: 'UNIX_TIMESTAMP()', description: '返回指定时间(默认当前)unix时间戳' },
|
||||
{ label: 'FROM_UNIXTIME', insertText: 'FROM_UNIXTIME(timestamp)', description: '把时间戳格式为年月日时分秒' },
|
||||
|
||||
/** 逻辑函数 */
|
||||
{ label: 'IFNULL', insertText: 'IFNULL(expression, alt_value)', description: '表达式为空取第二个参数值,否则取表达式值' },
|
||||
{ label: 'IF', insertText: 'IF(expr1, expr2, expr3)', description: 'expr1为true则取expr2,否则取expr3' },
|
||||
{ label: 'CASE', insertText: '\n(\n CASE\n WHEN expr1 THEN expr2\n ELSE expr3\n END\n ) col', description: 'CASE WHEN THEN ELSE END' },
|
||||
];
|
||||
|
||||
let mysqlDialectInfo: DialectInfo;
|
||||
|
||||
class MysqlDialect implements DbDialect {
|
||||
getInfo(): DialectInfo {
|
||||
if (mysqlDialectInfo) {
|
||||
return mysqlDialectInfo;
|
||||
}
|
||||
|
||||
let { keywords, operators, builtinVariables, builtinFunctions } = mysqlLanguage;
|
||||
let replaceFunctionNames = replaceFunctions.map((a) => a.label);
|
||||
let functions = builtinFunctions
|
||||
.filter((a: string) => replaceFunctionNames.indexOf(a) < 0) // 删除重写的函数
|
||||
.map((a: string): EditorCompletionItem => ({ label: a, insertText: `${a}()`, description: 'func' }))
|
||||
.concat(replaceFunctions);
|
||||
|
||||
let excludeKeywords = new Set(builtinFunctions.concat(replaceFunctionNames).concat(operators));
|
||||
let editorCompletions: EditorCompletion = {
|
||||
keywords: keywords
|
||||
.filter((a: string) => !excludeKeywords.has(a)) // 移除已存在的operator、function
|
||||
.map((a: string): EditorCompletionItem => ({ label: a, description: 'keyword' }))
|
||||
.concat(commonCustomKeywords.map((a): EditorCompletionItem => ({ label: a, description: 'keyword' }))),
|
||||
operators: operators.map((a: string): EditorCompletionItem => ({ label: a, description: 'operator' })),
|
||||
functions,
|
||||
variables: builtinVariables.map((a: string): EditorCompletionItem => ({ label: a, description: 'var' })),
|
||||
};
|
||||
|
||||
mysqlDialectInfo = {
|
||||
icon: 'iconfont icon-op-mysql',
|
||||
defaultPort: 3306,
|
||||
formatSqlDialect: 'mysql',
|
||||
columnTypes: MYSQL_TYPE_LIST.map((a) => ({ udtName: a, dataType: a, desc: '', space: '' })),
|
||||
editorCompletions,
|
||||
};
|
||||
return mysqlDialectInfo;
|
||||
}
|
||||
|
||||
@@ -235,56 +304,3 @@ class MysqlDialect implements DbDialect {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
// src/basic-languages/mysql/mysql.ts
|
||||
var language = {
|
||||
keywords: ['GROUP BY', 'ORDER BY', 'LEFT JOIN', 'RIGHT JOIN', 'INNER JOIN', 'SELECT * FROM'],
|
||||
operators: [],
|
||||
builtinFunctions: [],
|
||||
builtinVariables: [],
|
||||
replaceFunctions: [
|
||||
// 自定义修改函数提示
|
||||
|
||||
/** 字符串相关函数 */
|
||||
{ label: 'CONCAT', insertText: 'CONCAT(str1,str2,...)', description: '多字符串合并' },
|
||||
{ label: 'ASCII', insertText: 'ASCII(char)', description: '返回字符的ASCII值' },
|
||||
{ label: 'BIT_LENGTH', insertText: 'BIT_LENGTH(str1)', description: '多字符串合并' },
|
||||
{ label: 'INSTR', insertText: 'INSTR(str,substr)', description: '返回字符串substr所在str位置' },
|
||||
{ label: 'LEFT', insertText: 'LEFT(str,len)', description: '返回字符串str的左端len个字符' },
|
||||
{ label: 'RIGHT', insertText: 'RIGHT(str,len)', description: '返回字符串str的右端len个字符' },
|
||||
{ label: 'MID', insertText: 'MID(str,pos,len)', description: '返回字符串str的位置pos起len个字符' },
|
||||
{ label: 'SUBSTRING', insertText: 'SUBSTRING(exp, start, length)', description: '截取字符串' },
|
||||
{ label: 'REPLACE', insertText: 'REPLACE(str,from_str,to_str)', description: '替换字符串' },
|
||||
{ label: 'REPEAT', insertText: 'REPEAT(str,count)', description: '重复字符串count遍' },
|
||||
{ label: 'UPPER', insertText: 'UPPER(str)', description: '返回大写的字符串' },
|
||||
{ label: 'LOWER', insertText: 'LOWER(str)', description: '返回小写的字符串' },
|
||||
{ label: 'TRIM', insertText: 'TRIM(str)', description: '去除字符串首尾空格' },
|
||||
/** 数学相关函数 */
|
||||
{ label: 'ABS', insertText: 'ABS(n)', description: '返回n的绝对值' },
|
||||
{ label: 'FLOOR', insertText: 'FLOOR(n)', description: '返回不大于n的最大整数' },
|
||||
{ label: 'CEILING', insertText: 'CEILING(n)', description: '返回不小于n的最小整数值' },
|
||||
{ label: 'ROUND', insertText: 'ROUND(n,d)', description: '返回n的四舍五入值,保留d(默认0)位小数' },
|
||||
{ label: 'RAND', insertText: 'RAND()', description: '返回在范围0到1.0内的随机浮点值' },
|
||||
|
||||
/** 日期函数 */
|
||||
{ label: 'DATE', insertText: "DATE('date')", description: '返回指定表达式的日期部分' },
|
||||
{ label: 'WEEK', insertText: "WEEK('date')", description: '返回指定日期是一年中的第几周' },
|
||||
{ label: 'MONTH', insertText: "MONTH('date')", description: '返回指定日期的月份' },
|
||||
{ label: 'QUARTER', insertText: "QUARTER('date')", description: '返回指定日期是一年的第几个季度' },
|
||||
{ label: 'YEAR', insertText: "YEAR('date')", description: '返回指定日期的年份' },
|
||||
{ label: 'DATE_ADD', insertText: "DATE_ADD('date', interval 1 day)", description: '日期函数加减运算' },
|
||||
{ label: 'DATE_SUB', insertText: "DATE_SUB('date', interval 1 day)", description: '日期函数加减运算' },
|
||||
{ label: 'DATE_FORMAT', insertText: "DATE_FORMAT('date', '%Y-%m-%d %h:%i:%s')", description: '' },
|
||||
{ label: 'CURDATE', insertText: 'CURDATE()', description: '返回当前日期' },
|
||||
{ label: 'CURTIME', insertText: 'CURTIME()', description: '返回当前时间' },
|
||||
{ label: 'NOW', insertText: 'NOW()', description: '返回当前日期时间' },
|
||||
{ label: 'DATEDIFF', insertText: 'DATEDIFF(expr1,expr2)', description: '返回结束日expr1和起始日expr2之间的天数' },
|
||||
{ label: 'UNIX_TIMESTAMP', insertText: 'UNIX_TIMESTAMP()', description: '返回指定时间(默认当前)unix时间戳' },
|
||||
{ label: 'FROM_UNIXTIME', insertText: 'FROM_UNIXTIME(timestamp)', description: '把时间戳格式为年月日时分秒' },
|
||||
|
||||
/** 逻辑函数 */
|
||||
{ label: 'IFNULL', insertText: 'IFNULL(expression, alt_value)', description: '表达式为空取第二个参数值,否则取表达式值' },
|
||||
{ label: 'IF', insertText: 'IF(expr1, expr2, expr3)', description: 'expr1为true则取expr2,否则取expr3' },
|
||||
{ label: 'CASE', insertText: '(CASE \n WHEN expr1 THEN expr2 \n ELSE expr3) col', description: 'CASE WHEN THEN ELSE' },
|
||||
],
|
||||
};
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { DbDialect, DialectInfo, IndexDefinition, RowDefinition, sqlColumnType } from './index';
|
||||
import { commonCustomKeywords, DbDialect, DialectInfo, EditorCompletion, EditorCompletionItem, IndexDefinition, RowDefinition, sqlColumnType } from './index';
|
||||
import { language as pgsqlLanguage } from 'monaco-editor/esm/vs/basic-languages/pgsql/pgsql.js';
|
||||
|
||||
export { PostgresqlDialect, GAUSS_TYPE_LIST };
|
||||
|
||||
@@ -82,16 +83,42 @@ const GAUSS_TYPE_LIST: sqlColumnType[] = [
|
||||
{ udtName: 'macaddr', dataType: 'macaddr', desc: 'MAC地址', space: '6字节' },
|
||||
];
|
||||
|
||||
const postgresDialectInfo: DialectInfo = {
|
||||
icon: 'iconfont icon-op-postgres',
|
||||
defaultPort: 5432,
|
||||
formatSqlDialect: 'postgresql',
|
||||
columnTypes: GAUSS_TYPE_LIST.sort((a, b) => a.udtName.localeCompare(b.udtName)),
|
||||
};
|
||||
const replaceFunctions: EditorCompletionItem[] = [];
|
||||
|
||||
let pgDialectInfo: DialectInfo;
|
||||
|
||||
class PostgresqlDialect implements DbDialect {
|
||||
getInfo(): DialectInfo {
|
||||
return postgresDialectInfo;
|
||||
if (pgDialectInfo) {
|
||||
return pgDialectInfo;
|
||||
}
|
||||
|
||||
let { keywords, operators, builtinVariables, builtinFunctions } = pgsqlLanguage;
|
||||
let replaceFunctionNames = replaceFunctions.map((a) => a.label);
|
||||
let functions = builtinFunctions
|
||||
.filter((a: string) => replaceFunctionNames.indexOf(a) < 0)
|
||||
.map((a: string): EditorCompletionItem => ({ label: a, insertText: `${a}()`, description: 'func' }))
|
||||
.concat(replaceFunctions);
|
||||
let excludeKeywords = new Set(builtinFunctions.concat(replaceFunctionNames).concat(operators));
|
||||
|
||||
let editorCompletions: EditorCompletion = {
|
||||
keywords: keywords
|
||||
.filter((a: string) => !excludeKeywords.has(a)) // 移除已存在的operator、function
|
||||
.map((a: string): EditorCompletionItem => ({ label: a, description: 'keyword' }))
|
||||
.concat(commonCustomKeywords.map((a): EditorCompletionItem => ({ label: a, description: 'keyword' }))),
|
||||
operators: operators.map((a: string): EditorCompletionItem => ({ label: a, description: 'operator' })),
|
||||
functions,
|
||||
variables: builtinVariables.map((a: string): EditorCompletionItem => ({ label: a, description: 'var' })),
|
||||
};
|
||||
|
||||
pgDialectInfo = {
|
||||
icon: 'iconfont icon-op-postgres',
|
||||
defaultPort: 5432,
|
||||
formatSqlDialect: 'postgresql',
|
||||
columnTypes: GAUSS_TYPE_LIST.sort((a, b) => a.udtName.localeCompare(b.udtName)),
|
||||
editorCompletions,
|
||||
};
|
||||
return pgDialectInfo;
|
||||
}
|
||||
|
||||
getDefaultSelectSql(table: string, condition: string, orderBy: string, pageNum: number, limit: number) {
|
||||
|
||||
Reference in New Issue
Block a user