diff --git a/mayfly_go_web/src/views/ops/db/SqlExec.vue b/mayfly_go_web/src/views/ops/db/SqlExec.vue index 82845e42..a5a6fa62 100644 --- a/mayfly_go_web/src/views/ops/db/SqlExec.vue +++ b/mayfly_go_web/src/views/ops/db/SqlExec.vue @@ -2,7 +2,7 @@
- 新建查询 @@ -245,8 +245,8 @@ const nodeClick = async (data: any) => { const nodeKey = data.key; const dataType = data.type; // 点击数据库,修改当前数据库信息 - if (dataType === NodeType.Db || dataType === NodeType.SqlMenu || dataType === NodeType.TableMenu) { - changeSchema({ id: params.id, name: params.name, type: params.type, tagPath: params.tagPath }, params.db); + 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, databases: params.database}, params.db); return; } @@ -296,9 +296,9 @@ const getTables = async (params: any) => { /** * 加载用户保存的sql脚本 - * - * @param inst - * @param schema + * + * @param inst + * @param schema */ const loadSqls = async (id: any, db: string, dbs: any) => { const sqls = await dbApi.getSqlNames.request({ id: id, db: db, }) @@ -440,7 +440,7 @@ const reloadTables = (nodeKey: string) => { const registerSqlCompletionItemProvider = () => { // 参考 https://microsoft.github.io/monaco-editor/playground.html#extending-language-services-completion-provider-example self.completionItemProvider = self.completionItemProvider || monaco.languages.registerCompletionItemProvider('sql', { - triggerCharacters: ['.'], + triggerCharacters: ['.', ' '], provideCompletionItems: async (model: editor.ITextModel, position: Position): Promise => { let word = model.getWordUntilPosition(position); const nowTab = state.tabs.get(state.activeName); @@ -490,16 +490,46 @@ const registerSqlCompletionItemProvider = () => { // // const nextToken = nextTokens[0].toLowerCase() const tokens = textBeforePointer.trim().split(/\s+/) 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("最后输入的:=>" + 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('.')) - // 库.表名联想 + if(lastToken.trim().startsWith('.')){ + str = secondToken + } + // 库.表名联想 if (dbs && dbs.filter((a: any) => a === str)?.length > 0) { let tables = await dbInst.loadTables(str) let suggestions: languages.CompletionItem[] = [] @@ -522,36 +552,43 @@ const registerSqlCompletionItemProvider = () => { // 表别名.表字段联想 let tableInfo = getTableByAlias(sql, db, str) if (tableInfo.tableName) { - let table = tableInfo.tableName + let tableName = tableInfo.tableName let db = tableInfo.dbName; // 取出表名并提示 - let dbHits = await dbInst.loadDbHints(db) - let columns = dbHits[table] - 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 } + let suggestions = await hintTableColumns(tableName, db); + if(suggestions.length > 0){ + 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关键字 sqlLanguage.keywords.forEach((item: any) => { suggestions.push({ @@ -602,7 +639,7 @@ const registerSqlCompletionItemProvider = () => { }) // 库名提示 - if (dbs) { + if (dbs && dbs.length > 0) { dbs.forEach((a: any) => { suggestions.push({ 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 { suggestions: suggestions diff --git a/mayfly_go_web/src/views/ops/db/db.ts b/mayfly_go_web/src/views/ops/db/db.ts index 552bb573..f2099349 100644 --- a/mayfly_go_web/src/views/ops/db/db.ts +++ b/mayfly_go_web/src/views/ops/db/db.ts @@ -30,6 +30,9 @@ export class DbInst { */ dbs: Map = new Map() + /** 数据库schema,多个用空格隔开 */ + databases: string + /** * 默认查询分页数量 */ @@ -124,7 +127,7 @@ export class DbInst { /** * 执行sql - * + * * @param sql sql * @param remark 执行备注 */ @@ -186,7 +189,7 @@ export class DbInst { return `DELETE FROM ${table} WHERE ${primaryKeyColumnName} IN (${ids})`; } - /* + /* * 弹框提示是否执行sql */ promptExeSql = (db: string, sql: string, cancelFunc: any = null, successFunc: any = null) => { @@ -216,6 +219,7 @@ export class DbInst { dbInst.id = inst.id; dbInst.name = inst.name; dbInst.type = inst.type; + dbInst.databases = inst.databases; dbInstCache.set(dbInst.id, dbInst); return dbInst; @@ -283,14 +287,14 @@ export class DbInst { /** * 判断字段类型是否为数字类型 * @param columnType 字段类型 - * @returns + * @returns */ static isNumber(columnType: string) { return columnType.match(/int|double|float|nubmer|decimal|byte|bit/gi); }; /** - * + * * @param str 字符串 * @param tableData 表数据 * @param flag 标志 @@ -483,4 +487,4 @@ export type FieldsMeta = { oldValue: string // 新值 newValue: string -} \ No newline at end of file +}