mirror of
https://gitee.com/dromara/mayfly-go
synced 2025-12-03 14:30:24 +08:00
!44 feat: sql字段提示优化
Merge pull request !44 from zongyangleo/dev_20230613
This commit is contained in:
@@ -2,7 +2,7 @@
|
|||||||
<div>
|
<div>
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col :span="4">
|
<el-col :span="4">
|
||||||
<el-button type="primary" icon="plus" @click="addQueryTab({ id: nowDbInst.id }, state.db)"
|
<el-button type="primary" icon="plus" @click="addQueryTab({ id: nowDbInst.id, dbs: nowDbInst.databases }, state.db)"
|
||||||
size="small">新建查询</el-button>
|
size="small">新建查询</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="20" v-if="state.db">
|
<el-col :span="20" v-if="state.db">
|
||||||
@@ -245,8 +245,8 @@ const nodeClick = async (data: any) => {
|
|||||||
const nodeKey = data.key;
|
const nodeKey = data.key;
|
||||||
const dataType = data.type;
|
const dataType = data.type;
|
||||||
// 点击数据库,修改当前数据库信息
|
// 点击数据库,修改当前数据库信息
|
||||||
if (dataType === NodeType.Db || dataType === NodeType.SqlMenu || dataType === NodeType.TableMenu) {
|
if (dataType === NodeType.Db || dataType === NodeType.SqlMenu || dataType === NodeType.TableMenu || dataType === NodeType.DbInst) {
|
||||||
changeSchema({ id: params.id, name: params.name, type: params.type, tagPath: params.tagPath }, params.db);
|
changeSchema({ id: params.id, name: params.name, type: params.type, tagPath: params.tagPath, databases: params.database}, params.db);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -440,7 +440,7 @@ const reloadTables = (nodeKey: string) => {
|
|||||||
const registerSqlCompletionItemProvider = () => {
|
const registerSqlCompletionItemProvider = () => {
|
||||||
// 参考 https://microsoft.github.io/monaco-editor/playground.html#extending-language-services-completion-provider-example
|
// 参考 https://microsoft.github.io/monaco-editor/playground.html#extending-language-services-completion-provider-example
|
||||||
self.completionItemProvider = self.completionItemProvider || monaco.languages.registerCompletionItemProvider('sql', {
|
self.completionItemProvider = self.completionItemProvider || monaco.languages.registerCompletionItemProvider('sql', {
|
||||||
triggerCharacters: ['.'],
|
triggerCharacters: ['.', ' '],
|
||||||
provideCompletionItems: async (model: editor.ITextModel, position: Position): Promise<languages.CompletionList | null | undefined> => {
|
provideCompletionItems: async (model: editor.ITextModel, position: Position): Promise<languages.CompletionList | null | undefined> => {
|
||||||
let word = model.getWordUntilPosition(position);
|
let word = model.getWordUntilPosition(position);
|
||||||
const nowTab = state.tabs.get(state.activeName);
|
const nowTab = state.tabs.get(state.activeName);
|
||||||
@@ -490,16 +490,46 @@ const registerSqlCompletionItemProvider = () => {
|
|||||||
// // const nextToken = nextTokens[0].toLowerCase()
|
// // const nextToken = nextTokens[0].toLowerCase()
|
||||||
const tokens = textBeforePointer.trim().split(/\s+/)
|
const tokens = textBeforePointer.trim().split(/\s+/)
|
||||||
const lastToken = tokens[tokens.length - 1].toLowerCase()
|
const lastToken = tokens[tokens.length - 1].toLowerCase()
|
||||||
|
const secondToken = tokens.length >2 && tokens[tokens.length - 2].toLowerCase() || ''
|
||||||
|
|
||||||
const dbs = nowTab.params && nowTab.params.dbs;
|
const dbs = nowTab.params?.dbs?.split(' ') || [];
|
||||||
// console.log("光标前文本:=>" + textBeforePointerMulti)
|
// console.log("光标前文本:=>" + textBeforePointerMulti)
|
||||||
|
|
||||||
// console.log("最后输入的:=>" + lastToken)
|
// console.log("最后输入的:=>" + lastToken)
|
||||||
if (lastToken.endsWith('.')) {
|
|
||||||
|
let suggestions: languages.CompletionItem[] = []
|
||||||
|
const tables = await dbInst.loadTables(db);
|
||||||
|
|
||||||
|
async function hintTableColumns (tableName, db) {
|
||||||
|
let dbHits = await dbInst.loadDbHints(db)
|
||||||
|
let columns = dbHits[tableName]
|
||||||
|
let suggestions: languages.CompletionItem[] = []
|
||||||
|
columns?.forEach((a: string, index: any) => {
|
||||||
|
// 字段数据格式 字段名 字段注释, 如: create_time [datetime][创建时间]
|
||||||
|
const nameAndComment = a.split(" ")
|
||||||
|
const fieldName = nameAndComment[0]
|
||||||
|
suggestions.push({
|
||||||
|
label: {
|
||||||
|
label: a,
|
||||||
|
description: 'column'
|
||||||
|
},
|
||||||
|
kind: monaco.languages.CompletionItemKind.Property,
|
||||||
|
detail: '', // 不显示detail, 否则选中时备注等会被遮挡
|
||||||
|
insertText: fieldName + ' ', // create_time
|
||||||
|
range,
|
||||||
|
sortText: 100 + index + '' // 使用表字段声明顺序排序,排序需为字符串类型
|
||||||
|
});
|
||||||
|
})
|
||||||
|
return suggestions
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lastToken.indexOf('.') > -1 || secondToken.indexOf('.') > -1) {
|
||||||
// 如果是.触发代码提示,则进行【 库.表名联想 】 或 【 表别名.表字段联想 】
|
// 如果是.触发代码提示,则进行【 库.表名联想 】 或 【 表别名.表字段联想 】
|
||||||
let str = lastToken.substring(0, lastToken.lastIndexOf('.'))
|
let str = lastToken.substring(0, lastToken.lastIndexOf('.'))
|
||||||
// 库.表名联想
|
if(lastToken.trim().startsWith('.')){
|
||||||
|
str = secondToken
|
||||||
|
}
|
||||||
|
|
||||||
|
// 库.表名联想
|
||||||
if (dbs && dbs.filter((a: any) => a === str)?.length > 0) {
|
if (dbs && dbs.filter((a: any) => a === str)?.length > 0) {
|
||||||
let tables = await dbInst.loadTables(str)
|
let tables = await dbInst.loadTables(str)
|
||||||
let suggestions: languages.CompletionItem[] = []
|
let suggestions: languages.CompletionItem[] = []
|
||||||
@@ -522,36 +552,43 @@ const registerSqlCompletionItemProvider = () => {
|
|||||||
// 表别名.表字段联想
|
// 表别名.表字段联想
|
||||||
let tableInfo = getTableByAlias(sql, db, str)
|
let tableInfo = getTableByAlias(sql, db, str)
|
||||||
if (tableInfo.tableName) {
|
if (tableInfo.tableName) {
|
||||||
let table = tableInfo.tableName
|
let tableName = tableInfo.tableName
|
||||||
let db = tableInfo.dbName;
|
let db = tableInfo.dbName;
|
||||||
// 取出表名并提示
|
// 取出表名并提示
|
||||||
let dbHits = await dbInst.loadDbHints(db)
|
let suggestions = await hintTableColumns(tableName, db);
|
||||||
let columns = dbHits[table]
|
if(suggestions.length > 0){
|
||||||
let suggestions: languages.CompletionItem[] = []
|
return { suggestions };
|
||||||
columns?.forEach((a: string, index: any) => {
|
}
|
||||||
// 字段数据格式 字段名 字段注释, 如: create_time [datetime][创建时间]
|
|
||||||
const nameAndComment = a.split(" ")
|
|
||||||
const fieldName = nameAndComment[0]
|
|
||||||
suggestions.push({
|
|
||||||
label: {
|
|
||||||
label: a,
|
|
||||||
description: 'column'
|
|
||||||
},
|
|
||||||
kind: monaco.languages.CompletionItemKind.Property,
|
|
||||||
detail: '', // 不显示detail, 否则选中时备注等会被遮挡
|
|
||||||
insertText: fieldName + ' ', // create_time
|
|
||||||
range,
|
|
||||||
sortText: 100 + index + '' // 使用表字段声明顺序排序,排序需为字符串类型
|
|
||||||
});
|
|
||||||
})
|
|
||||||
return { suggestions }
|
|
||||||
}
|
}
|
||||||
return { suggestions: [] }
|
return { suggestions: [] }
|
||||||
|
}else{
|
||||||
|
// 如果sql里含有表名,则提示表字段
|
||||||
|
let mat = textBeforePointerMulti.match(/from\n*\s+\n*(\w+)\n*\s+\n*/i)
|
||||||
|
if(mat && mat.length > 1){
|
||||||
|
let tableName = mat[1]
|
||||||
|
// 取出表名并提示
|
||||||
|
let suggestions = await hintTableColumns(tableName, db);
|
||||||
|
if(suggestions.length > 0){
|
||||||
|
return { suggestions };
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 库名联想
|
// 表名联想
|
||||||
|
tables.forEach((tableMeta: any) => {
|
||||||
|
const {tableName, tableComment} = tableMeta;
|
||||||
|
suggestions.push({
|
||||||
|
label: {
|
||||||
|
label: tableName + ' - ' + tableComment,
|
||||||
|
description: 'table'
|
||||||
|
},
|
||||||
|
kind: monaco.languages.CompletionItemKind.File,
|
||||||
|
detail: tableComment,
|
||||||
|
insertText: tableName + ' ',
|
||||||
|
range
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
let suggestions: languages.CompletionItem[] = []
|
|
||||||
// mysql关键字
|
// mysql关键字
|
||||||
sqlLanguage.keywords.forEach((item: any) => {
|
sqlLanguage.keywords.forEach((item: any) => {
|
||||||
suggestions.push({
|
suggestions.push({
|
||||||
@@ -602,7 +639,7 @@ const registerSqlCompletionItemProvider = () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// 库名提示
|
// 库名提示
|
||||||
if (dbs) {
|
if (dbs && dbs.length > 0) {
|
||||||
dbs.forEach((a: any) => {
|
dbs.forEach((a: any) => {
|
||||||
suggestions.push({
|
suggestions.push({
|
||||||
label: {
|
label: {
|
||||||
@@ -616,22 +653,6 @@ const registerSqlCompletionItemProvider = () => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const tables = await dbInst.loadTables(db);
|
|
||||||
// 表名联想
|
|
||||||
tables.forEach((tableMeta: any) => {
|
|
||||||
const { tableName, tableComment } = tableMeta
|
|
||||||
suggestions.push({
|
|
||||||
label: {
|
|
||||||
label: tableName + ' - ' + tableComment,
|
|
||||||
description: 'table'
|
|
||||||
},
|
|
||||||
kind: monaco.languages.CompletionItemKind.File,
|
|
||||||
detail: tableComment,
|
|
||||||
insertText: tableName + ' ',
|
|
||||||
range
|
|
||||||
});
|
|
||||||
})
|
|
||||||
|
|
||||||
// 默认提示
|
// 默认提示
|
||||||
return {
|
return {
|
||||||
suggestions: suggestions
|
suggestions: suggestions
|
||||||
|
|||||||
@@ -30,6 +30,9 @@ export class DbInst {
|
|||||||
*/
|
*/
|
||||||
dbs: Map<string, Db> = new Map()
|
dbs: Map<string, Db> = new Map()
|
||||||
|
|
||||||
|
/** 数据库schema,多个用空格隔开 */
|
||||||
|
databases: string
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 默认查询分页数量
|
* 默认查询分页数量
|
||||||
*/
|
*/
|
||||||
@@ -216,6 +219,7 @@ export class DbInst {
|
|||||||
dbInst.id = inst.id;
|
dbInst.id = inst.id;
|
||||||
dbInst.name = inst.name;
|
dbInst.name = inst.name;
|
||||||
dbInst.type = inst.type;
|
dbInst.type = inst.type;
|
||||||
|
dbInst.databases = inst.databases;
|
||||||
|
|
||||||
dbInstCache.set(dbInst.id, dbInst);
|
dbInstCache.set(dbInst.id, dbInst);
|
||||||
return dbInst;
|
return dbInst;
|
||||||
|
|||||||
Reference in New Issue
Block a user