新增sql连接,目前支持mysql、sqlite、oracle连接以及相关数据库操作
This commit is contained in:
@@ -0,0 +1,225 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>SQL Editor</title>
|
||||
<style>
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
html, body { width: 100%; height: 100%; overflow: hidden; }
|
||||
#container { width: 100%; height: 100%; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="container"></div>
|
||||
|
||||
<!-- 使用 CDN 加载 Monaco Editor -->
|
||||
<script src="https://cdn.jsdelivr.net/npm/monaco-editor@0.50.0/min/vs/loader.js"></script>
|
||||
<script src="qrc:///qtwebchannel/qwebchannel.js"></script>
|
||||
|
||||
<script>
|
||||
// SQL 关键字补全词库
|
||||
var sqlKeywords = [
|
||||
"SELECT", "FROM", "WHERE", "AND", "OR", "NOT", "IN", "IS", "NULL",
|
||||
"INSERT", "INTO", "VALUES", "UPDATE", "SET", "DELETE",
|
||||
"CREATE", "TABLE", "DROP", "ALTER", "ADD", "COLUMN", "INDEX", "VIEW",
|
||||
"JOIN", "LEFT", "RIGHT", "INNER", "OUTER", "CROSS", "ON",
|
||||
"UNION", "ALL", "DISTINCT", "GROUP", "BY", "HAVING",
|
||||
"ORDER", "ASC", "DESC", "LIMIT", "OFFSET",
|
||||
"AS", "CASE", "WHEN", "THEN", "ELSE", "END", "IF", "EXISTS",
|
||||
"BETWEEN", "LIKE", "ESCAPE", "RLIKE", "REGEXP",
|
||||
"PRIMARY", "KEY", "FOREIGN", "REFERENCES", "CONSTRAINT",
|
||||
"DEFAULT", "AUTO_INCREMENT", "IDENTITY", "UNIQUE", "CHECK",
|
||||
"BEGIN", "COMMIT", "ROLLBACK", "TRANSACTION", "SAVEPOINT",
|
||||
"GRANT", "REVOKE", "PRIVILEGES", "DATABASE", "SCHEMA",
|
||||
"USE", "SHOW", "DESCRIBE", "EXPLAIN", "ANALYZE"
|
||||
];
|
||||
|
||||
var sqlFunctions = [
|
||||
"COUNT()", "SUM()", "AVG()", "MIN()", "MAX()",
|
||||
"CONCAT()", "SUBSTRING()", "LENGTH()", "TRIM()", "LTRIM()", "RTRIM()",
|
||||
"UPPER()", "LOWER()", "REPLACE()", "LEFT()", "RIGHT()", "LOCATE()",
|
||||
"NOW()", "CURDATE()", "CURTIME()", "DATE()", "TIME()", "TIMESTAMP()",
|
||||
"DATE_FORMAT()", "DATE_ADD()", "DATE_SUB()", "DATEDIFF()",
|
||||
"COALESCE()", "IFNULL()", "NULLIF()", "CAST()", "CONVERT()",
|
||||
"ROUND()", "CEIL()", "FLOOR()", "ABS()", "MOD()", "POWER()",
|
||||
"RAND()", "UUID()", "MD5()", "SHA1()", "SHA2()"
|
||||
];
|
||||
|
||||
var editor = null;
|
||||
var cppBridge = null;
|
||||
|
||||
require.config({ paths: { vs: 'https://cdn.jsdelivr.net/npm/monaco-editor@0.50.0/min/vs' } });
|
||||
|
||||
require(['vs/editor/editor.main'], function () {
|
||||
// 注册 SQL 语言
|
||||
monaco.languages.register({ id: 'sql' });
|
||||
|
||||
// 定义 SQL 语法的 Tokenizer
|
||||
monaco.languages.setMonarchTokensProvider('sql', {
|
||||
keywords: sqlKeywords,
|
||||
functions: sqlFunctions.map(function(f) { return f.replace('(', '').replace(')', ''); }),
|
||||
|
||||
tokenizer: {
|
||||
root: [
|
||||
[/--.*$/, 'comment'],
|
||||
[/\/\*/, 'comment', '@comment'],
|
||||
[/\b(?:SELECT|FROM|WHERE|AND|OR|NOT|IN|IS|NULL|INSERT|INTO|VALUES|UPDATE|SET|DELETE|CREATE|TABLE|DROP|ALTER|ADD|COLUMN|INDEX|VIEW|JOIN|LEFT|RIGHT|INNER|OUTER|CROSS|ON|UNION|ALL|DISTINCT|GROUP|BY|HAVING|ORDER|ASC|DESC|LIMIT|OFFSET|AS|CASE|WHEN|THEN|ELSE|END|IF|EXISTS|BETWEEN|LIKE|ESCAPE|PRIMARY|KEY|FOREIGN|REFERENCES|CONSTRAINT|DEFAULT|AUTO_INCREMENT|IDENTITY|UNIQUE|CHECK|BEGIN|COMMIT|ROLLBACK|TRANSACTION|SAVEPOINT|GRANT|REVOKE|PRIVILEGES|DATABASE|SCHEMA|USE|SHOW|DESCRIBE|EXPLAIN|ANALYZE)\b/, 'keyword'],
|
||||
[/\b(?:COUNT|SUM|AVG|MIN|MAX|CONCAT|SUBSTRING|LENGTH|TRIM|LTRIM|RTRIM|UPPER|LOWER|REPLACE|LEFT|RIGHT|LOCATE|NOW|CURDATE|CURTIME|DATE|TIME|TIMESTAMP|DATE_FORMAT|DATE_ADD|DATE_SUB|DATEDIFF|COALESCE|IFNULL|NULLIF|CAST|CONVERT|ROUND|CEIL|FLOOR|ABS|MOD|POWER|RAND|UUID|MD5|SHA1|SHA2)\b(?=\s*\()/, 'type.identifier'],
|
||||
[/'[^']*'/, 'string'],
|
||||
/"[^"]*"/, 'string',
|
||||
[/\b\d+\.?\d*\b/, 'number'],
|
||||
],
|
||||
comment: [
|
||||
[/[^\/*]+/, 'comment'],
|
||||
[/\*\//, 'comment', '@pop'],
|
||||
[/[\/*]/, 'comment']
|
||||
]
|
||||
}
|
||||
});
|
||||
|
||||
// 定义 SQL 主题(深色风格)
|
||||
monaco.editor.defineTheme('sql-dark', {
|
||||
base: 'vs-dark',
|
||||
inherit: true,
|
||||
rules: [
|
||||
{ token: 'keyword', foreground: '569cd6', fontStyle: 'bold' },
|
||||
{ token: 'type.identifier', foreground: 'dcdcaa' },
|
||||
{ token: 'string', foreground: 'ce9178' },
|
||||
{ token: 'number', foreground: 'b5cea8' },
|
||||
{ token: 'comment', foreground: '6a9955', fontStyle: 'italic' },
|
||||
],
|
||||
colors: {
|
||||
'editor.background': '#1e1e1e',
|
||||
'editor.foreground': '#d4d4d4',
|
||||
'editorLineNumber.foreground': '#858585',
|
||||
'editor.selectionBackground': '#264f78',
|
||||
'editor.lineHighlightBackground': '#2a2d2e',
|
||||
}
|
||||
});
|
||||
|
||||
// 创建编辑器实例
|
||||
editor = monaco.editor.create(document.getElementById('container'), {
|
||||
value: '-- 在这里编写你的SQL语句\n-- 按 Ctrl+Enter 执行SQL\n-- 输入关键字自动弹出补全建议',
|
||||
language: 'sql',
|
||||
theme: 'sql-dark',
|
||||
fontSize: 14,
|
||||
fontFamily: 'Consolas, "Courier New", monospace',
|
||||
minimap: { enabled: false },
|
||||
lineNumbers: 'on',
|
||||
scrollBeyondLastLine: false,
|
||||
automaticLayout: true,
|
||||
tabSize: 4,
|
||||
wordWrap: 'off',
|
||||
suggestOnTriggerCharacters: true,
|
||||
quickSuggestions: true,
|
||||
parameterHints: { enabled: true },
|
||||
formatOnPaste: true,
|
||||
formatOnType: true,
|
||||
bracketPairColorization: { enabled: true },
|
||||
guides: { indentation: true, bracketPairs: true },
|
||||
});
|
||||
|
||||
// 注册自动补全项
|
||||
monaco.languages.registerCompletionItemProvider('sql', {
|
||||
provideCompletionItems: function (model, position) {
|
||||
var suggestions = [];
|
||||
|
||||
// 添加关键字
|
||||
for (var i = 0; i < sqlKeywords.length; i++) {
|
||||
suggestions.push({
|
||||
label: sqlKeywords[i],
|
||||
kind: monaco.languages.CompletionItemKind.Keyword,
|
||||
insertText: sqlKeywords[i],
|
||||
detail: 'SQL Keyword'
|
||||
});
|
||||
}
|
||||
|
||||
// 添加函数
|
||||
for (var j = 0; j < sqlFunctions.length; j++) {
|
||||
suggestions.push({
|
||||
label: sqlFunctions[j],
|
||||
kind: monaco.languages.CompletionItemKind.Function,
|
||||
insertText: sqlFunctions[j],
|
||||
detail: 'SQL Function'
|
||||
});
|
||||
}
|
||||
|
||||
return { suggestions: suggestions };
|
||||
}
|
||||
});
|
||||
|
||||
// Ctrl+Enter 快捷键执行 SQL
|
||||
editor.addAction({
|
||||
id: 'execute-sql',
|
||||
label: 'Execute SQL',
|
||||
keybindings: [monaco.KeyMod.CtrlCmd | monaco.KeyCode.Enter],
|
||||
run: function () {
|
||||
if (cppBridge && cppBridge.executeSql) {
|
||||
cppBridge.executeSql(editor.getValue());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Ctrl+S 快捷键保存/提交
|
||||
editor.addAction({
|
||||
id: 'submit-changes',
|
||||
label: 'Submit Changes',
|
||||
keybindings: [monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyS],
|
||||
run: function () {
|
||||
if (cppBridge && cppBridge.submitChanges) {
|
||||
cppBridge.submitChanges();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// 窗口大小变化时自适应
|
||||
window.addEventListener('resize', function () {
|
||||
editor.layout();
|
||||
});
|
||||
});
|
||||
|
||||
// 连接 Qt WebChannel
|
||||
new QWebChannel(qt.webChannelTransport, function(channel) {
|
||||
cppBridge = channel.objects.cppBridge;
|
||||
|
||||
// C++ 调用:获取编辑器内容
|
||||
cppBridge.getEditorContent.connect(function() {
|
||||
if (cppBridge.contentReady) {
|
||||
cppBridge.contentReady(editor.getValue());
|
||||
}
|
||||
});
|
||||
|
||||
// C++ 调用:设置编辑器内容
|
||||
cppBridge.setEditorContent.connect(function(content) {
|
||||
if (editor) {
|
||||
editor.setValue(content);
|
||||
}
|
||||
});
|
||||
|
||||
// C++ 调用:追加内容
|
||||
cppBridge.appendContent.connect(function(content) {
|
||||
if (editor) {
|
||||
var pos = editor.getPosition();
|
||||
editor.executeEdits('', [{
|
||||
range: new monaco.Range(pos.lineNumber, pos.column, pos.lineNumber, pos.column),
|
||||
text: content
|
||||
}]);
|
||||
editor.focus();
|
||||
}
|
||||
});
|
||||
|
||||
// C++ 调用:插入选中的表名
|
||||
cppBridge.insertTableName.connect(function(tableName) {
|
||||
if (editor) {
|
||||
editor.trigger('source', 'editor.action.insertSnippet', { snippet: '`' + tableName + '`' });
|
||||
}
|
||||
});
|
||||
|
||||
// 通知 C++ 编辑器已就绪
|
||||
if (cppBridge.editorReady) {
|
||||
cppBridge.editorReady();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user