弹窗 index
<template>
<el-dialog
title="版本"
:visible.sync="dialogVisible"
width="55%"
center
:close-on-click-modal="false"
:close-on-press-escape="false"
:before-close="beforeClose"
@open="open"
custom-class="dialogClass"
>
<template v-slot:title>
<div>版本</div>
<el-button
v-if="isShowVersion"
style="position: absolute; top: 12px; right: 10%"
type="primary" size="mini"
@click="goVersionComparisonPage">
版本对比
</el-button>
</template>
<div v-loading="dialogLoading || dialogLoading2">
<el-table
:data="tableData"
ref="Table"
size="mini"
empty-text="暂无数据"
:header-cell-style="headerCellStyle"
:cell-style="cellStyle"
:header-cell-class-name="cellClass"
:row-key="getRowKeys"
@selection-change="selectionChange"
style="width: 100%"
>
<el-table-column v-if="isShowVersion" type="selection" width="55" :reserve-selection="true" :selectable="selectable"></el-table-column>
<el-table-column label="提交时间" width="160">
<template slot-scope="scope">
{{ scope.row.createdAt | formatDate }}
</template>
</el-table-column>
<el-table-column label="提交人" prop="createdBy"></el-table-column>
<el-table-column label="变更内容" prop="modifyContent">
<template slot-scope="scope">
<el-tooltip
effect="dark"
placement="top-start"
v-if="
!isOverflow(scope.row.modifyContent, scope.column.realWidth)
"
>
<div slot="content" style="white-space: pre-line">
{{ scope.row.modifyContent }}
</div>
<div class="ellipsis-container">
{{ scope.row.modifyContent }}
</div>
</el-tooltip>
<div v-else>
{{ scope.row.modifyContent }}
</div>
</template>
</el-table-column>
<el-table-column label="操作" width="100" v-if="!isShowVersion">
<template slot-scope="scope">
<el-button
type="text"
size="mini"
@click="rollback(scope)"
:disabled="!disabledRollback"
>
回滚
</el-button>
</template>
</el-table-column>
<el-table-column label="操作" width="100" v-if="realTime == 'real'">
<template slot-scope="scope">
<el-button
type="text"
size="mini"
@click="detailBack(scope)"
:disabled="!disabledRollback"
>
详情
</el-button>
<el-button
type="text"
size="mini"
@click="rollback(scope)"
:disabled="!disabledRollback"
>
回滚
</el-button>
</template>
</el-table-column>
</el-table>
<div class="pagination" v-if="realTime !== 'real'">
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="currentPage"
:page-sizes="[10, 50, 100]"
:page-size="pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="total"
background
>
</el-pagination>
</div>
</div>
<span slot="footer">
<el-button
type="primary"
size="mini"
@click="save"
:disabled="dialogLoading || dialogLoading2"
>确 定</el-button
>
</span>
</el-dialog>
</template>
<script>
import { debounce, formatDate } from "@/utils/index.js";
import dataDevelopment from "@/components/pages/dataDevelopment/schedulinJobs/api/index";
import reatimeJobService from '@/components/pages/dataDevelopment/realtimeJob/api/index.js'
export default {
name: "versionsDialog",
props: {
sqlType: String,
taskSqlCode: {
type: String,
default: "",
},
taskSqlName: {
type: String,
default: "",
},
dialogVisible: {
type: Boolean,
default: false,
},
dialogLoading: {
type: Boolean,
default: false,
},
taskCode: {
type: String,
default: "",
},
taskStatus: {
type: String,
default: "",
},
taskName: {
type: String,
default: "",
},
isShowVersion: {
type: Boolean,
default: false,
},
sqlStatus: {
type: Boolean,
default: false,
},
realTime: {
type: String,
default: "",
},
},
filters: {
formatDate,
},
data() {
return {
tableData: [],
total: 0,
currentPage: 1,
pageSize: 10,
dialogLoading2: false,
multipleSelection: []
};
},
computed: {
disabledRollback() {
if (this.sqlType) {
return this.sqlStatus
}
return this.taskStatus === "1" || this.taskStatus === "0";
},
},
methods: {
/** 去除全选框 */
cellClass(row) {
//若是第一行,即全选框所在的那一行
if (row.columnIndex === 0) {
this.$nextTick(() => {
// 每次触发 headerCell 判断如果是第一个 单元格 调用该方法
// row.column.id 是该单元格的 class 样式
// 通过 class 样式连续找两层 children 节点 如果存在 执行 remove()
let selectBox = document.querySelector(`.${row.column.id}`);
selectBox.children[0].children[0]?.remove();
})
}
},
/** 分页保持选择框 */
getRowKeys(row) {
return row.id;
},
/** 获取选中的数据 */
selectionChange(list) {
if (list.length > 2) {
this.$refs.Table.clearSelection(); //用于多选表格,清空用户的选择
for (let i = 0; i < 2; i++) {
this.$refs.Table.toggleRowSelection(list[i]); //用于多选表格,切换某一行的选中状态,如果使用了第二个参数,则是设置这一行选中与否(selected 为 true 则选中)
}
return;
}
this.multipleSelection = [...list];
},
/** Checkbox是否禁用 */
selectable(row) {
let index = this.multipleSelection.findIndex((v) => v.id === row.id);
return this.multipleSelection.length >= 2 ? index !== -1 ? true : false : true;
},
/** 跳转去版本对比页面 */
goVersionComparisonPage() {
const newList = this.multipleSelection.map(item => item.id);
if (this.realTime == 'real') {
this.$router.push({
name: 'DetailComparison',
query: {
realTime: this.realTime,
multipleSelection: JSON.stringify(newList),
taskCode: this.taskSqlCode,
taskName: this.taskSqlName
}
})
} else {
this.$router.push({
name: 'versionComparison',
query: {
multipleSelection: JSON.stringify(newList),
taskCode: this.taskCode,
taskName: this.taskName
}
})
}
},
/** 每页条数变更 */
handleSizeChange(val) {
this.pageSize = val;
this.queryHistoryPage();
},
/** 当前页码变更 */
handleCurrentChange(val) {
this.currentPage = val;
this.queryHistoryPage();
},
/** 回滚 */
rollback: debounce(function ({ row }) {
if (this.sqlType) {
this.$confirm(
"当前未提交的内容将会被覆盖。",
"提示",
{
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
}
)
.then(() => {
this.$emit("realSqlback", row);
})
.catch(() => {});
} else {
this.$confirm(
"1. 当前未提交的内容将会被覆盖。2. 回滚后要“提交”才能生效。确定要回滚当前版本?",
"提示",
{
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
}
)
.then(() => {
this.$emit("rollback", row);
})
.catch(() => {});
}
}, 300),
/** 版本详情 */
async detailBack(row) {
let params = {
taskCode: this.taskSqlCode,
versionId: row.row.id
}
let res = await reatimeJobService.getVersionDetail(params)
let rowDetail
if (res.data.success) {
rowDetail = res.data?.result
} else {
this.$notification.error(res.data.errorMsg);
}
this.$router.push({
name: 'DetailComparison',
query: {
...rowDetail
}
})
},
/** 弹框关闭 */
beforeClose() {
this.$emit("close");
},
/** 弹框打开 */
open() {
this.pageSize = 10;
this.currentPage = 1;
this.queryHistoryPage();
this.$nextTick(() => {
this.$refs.Table.clearSelection();
})
},
/** 获取版本列表 */
async queryHistoryPage() {
try {
this.dialogLoading2 = true;
let taskCode = this.taskCode;
let res
if (this.sqlType) {
let taskSqlCode = this.taskSqlCode
res = await reatimeJobService.getVersionList(taskSqlCode);
} else {
const params = {
taskCode,
pageSize: this.pageSize,
pageNo: this.currentPage,
};
res = await dataDevelopment.queryHistoryPage(params);
}
if (res.data?.success) {
const result = res.data.result;
if (this.sqlType) {
this.total = result?.length;
this.tableData = result
this.tableData = this.tableData.map(item => {
return {
id: item.versionId,
createdAt: item.submitTime,
createdBy: item.submittedBy,
modifyContent: item.content,
}
})
} else {
this.tableData = result.records;
this.total = result.total;
}
} else {
this.$notification.error(res.data.errorMsg);
}
} catch (error) {
this.tableData = [];
this.total = 0;
console.error(error);
} finally {
this.dialogLoading2 = false;
}
},
/** 确定 */
save() {
this.beforeClose();
},
// 表格居中
cellStyle() {
return "text-align: center;font-size: 12px;";
},
// 表格样式
headerCellStyle() {
return "text-align: center;color: #000000;";
},
/** 是否开启了隐藏 */
isOverflow(text, width) {
const el = document.createElement("span");
el.innerHTML = text;
document.body.appendChild(el);
const flag = el.offsetWidth < width;
document.body.removeChild(el);
return flag;
},
},
};
</script>
<style lang="scss" scoped>
::v-deep .dialogClass {
max-height: 78%;
display: flex;
flex-direction: column;
.el-dialog__body {
padding: 10px;
flex: 1;
overflow-y: auto;
}
}
.pagination {
display: flex;
justify-content: flex-end;
margin: 20px 10px;
}
.ellipsis-container {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
</style>
sql编辑器
<template>
<div class="monaco">
<div ref="container" class="monaco-editor" style="height: 400px"></div>
</div>
</template>
<script>
import * as monaco from "monaco-editor";
import sqlInfo from "./sql";
export default {
name: "Monaco",
data() {
return {
// 编辑器对象
monacoDiffInstance: null,
}
},
methods: {
init(event) {
if (this.monacoDiffInstance) {
this.monacoDiffInstance.dispose()
}
// 初始化container的内容,销毁之前生成的编辑器
this.$refs.container.innerHTML = '';
this.theme();
this.registerSQL();
if (event.realTime) {
// 版本对比
this.monacoDiffInstance = monaco.editor.createDiffEditor(this.$refs['container'], {
value: '', // 编辑器的值
theme: 'vs-dark', // 编辑器主题:vs, hc-black, or vs-dark,更多选择详见官网
roundedSelection: false, // 右侧不显示编辑器预览框
autoIndent: true, // 自动缩进
readOnly: true,
// language: 'json',
automaticLayout: true // 自动布局
});
const { sourceTaskScript, targetTaskScript } = event;
const originalModel = monaco.editor.createModel(sourceTaskScript, 'sql');
const modifiedModel = monaco.editor.createModel(targetTaskScript, 'sql');
this.monacoDiffInstance.setModel({
// oldValue为以前的值
original: originalModel,
// oldValue为新的值
modified: modifiedModel
})
} else {
// 详情
const sqlCode = event;
// 初始化编辑器实例
this.monacoDiffInstance = monaco.editor.create(this.$refs['container'], {
value: sqlCode, // 编辑器的值
language: 'sql', // 设置语言为 SQL
theme: 'vs-dark', // 编辑器主题
readOnly: true,
automaticLayout: true // 自动布局
});
}
},
//自定义主题
theme() {
monaco.editor.defineTheme('hiveTheme', {
base: 'vs-dark',
inherit: true,
rules: [
{ token: 'builtFunc', foreground: 'FF00FF' },//内置方法以及变量、伪列
{ token: 'opera', foreground: '778899' }//运算符
]
})
},
registerSQL() {
monaco.languages.register({ id: 'customSql' });
monaco.languages.setMonarchTokensProvider('customSql', {
ignoreCase: true,//关键字大小写都可高亮
brackets: sqlInfo.brackets,
keywords: sqlInfo.keywords,
operators: sqlInfo.operators,
builtinFunctions: sqlInfo.builtinFunctions,
builtinVariables: sqlInfo.builtinVariables,
pseudoColumns: sqlInfo.pseudoColumns,
tokenizer: sqlInfo.tokenizer
})
}
}
}
</script>
<style scoped>
</style>
filter
<template>
<div class="filter-item">
<div>
<div class="task-desc">
任务:{{ taskName }}
</div>
<div class="form-box">
<el-form class="source-form" ref="sourceForm" :model="sourceForm" label-width="80px" size="mini">
<el-form-item label="版本:" v-if="this.$route.query.realTime == 'real'">
<el-select v-model="sourceForm.version"
placeholder="请选择版本"
filterable
:loading="loading"
@change="getCodeCompareScript('source')">
<el-option v-for="v in sourceVersionList" :label="v.createdAt" :value="v.id" :key="v.id">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="版本:" v-else>
<el-select v-model="sourceForm.version"
placeholder="请选择版本"
filterable
disabled
:loading="loading"
@change="getCodeCompareScript('source')">
<el-option v-for="v in sourceVersionList" :label="v.createdAt" :value="v.id" :key="v.id">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="提交人:">{{ sourceForm.createdBy }}</el-form-item>
<el-form-item label="提交时间:">{{ sourceForm.createdAt }}</el-form-item>
</el-form>
<div v-if="this.$route.query.realTime == 'real'">
<el-divider direction="vertical" class="vertical-form"></el-divider>
<el-form class="target-form" ref="targetForm" :model="targetForm" label-width="80px" size="mini">
<el-form-item label="版本:">
<el-select v-model="targetForm.version" placeholder="请选择版本" @change="getCodeCompareScript('target')">
<el-option v-for="v in sourceVersionList" :label="v.createdAt" :value="v.id" :key="v.id">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="提交人:">{{ targetForm.createdBy }}</el-form-item>
<el-form-item label="提交时间:">{{ targetForm.createdAt }}</el-form-item>
</el-form>
</div>
</div>
</div>
</div>
</template>
<script>
import dayjs from "dayjs";
import {DateFormatEnum} from "@/modal/public-enum";
import reatimeJobService from "../../../realtimeJob/api";
export default {
name: "FilterItems",
data() {
return {
sourceForm: {
version: '',
createdAt: '',
createdBy: ''
},
targetForm: {
version: '',
createdAt: '',
createdBy: ''
},
sourceVersionList: [],
taskCode: '',
taskName: '',
pageSize: 100,
currentPage: 1,
multipleSelection: [],
loading: false
}
},
mounted() {
if (this.$route.query.realTime == 'real') {
this.multipleSelection = JSON.parse(this.$route.query.multipleSelection);
this.taskCode = this.$route.query.taskCode;
this.taskName = this.$route.query.taskName;
this.queryHistoryPage();
} else {
this.sourceForm = this.$route.query
this.sourceForm.version = this.createAt(this.$route.query.createAt)
this.sourceForm.createdAt = this.createAt(this.$route.query.createAt)
this.sourceForm.createdBy = this.$route.query.createBy || '--'
this.getCodeCompareScript()
}
},
methods: {
createAt(val) {
return dayjs(Number(val)).format(DateFormatEnum.DATETIME_FORM)
},
/** 获取版本列表 */
async queryHistoryPage() {
this.loading = true;
try {
const params = {
taskCode: this.taskCode,
pageSize: this.pageSize,
pageNo: this.currentPage,
};
console.log(this.$route.query);
const res = await reatimeJobService.getVersionList(params.taskCode);
if (res.data?.success) {
const result = res.data.result;
if (result.length > 0) {
this.sourceVersionList = result.map(item => {
return {
...item,
id: item.versionId,
createdAt: dayjs(item.submitTime).format(DateFormatEnum.DATETIME_FORM),
}
});
if (this.multipleSelection.length === 0) {
const { id } = this.sourceVersionList[0];
this.sourceForm.version = id;
this.getCodeCompareScript('source');
return;
}
if (this.multipleSelection[0]) {
const { id } = this.setDefaultVersion(this.multipleSelection[0]);
this.sourceForm.version = id;
this.getCodeCompareScript('source');
}
if (this.multipleSelection[1]) {
const { id } = this.setDefaultVersion(this.multipleSelection[1]);
this.targetForm.version = id;
this.getCodeCompareScript();
}
}
} else {
this.$notification.error(res.data.errorMsg);
}
} catch (error) {
this.sourceVersionList = [];
this.total = 0;
} finally {
this.loading = false;
}
},
/**
* 设置默认版本
*/
setDefaultVersion(val) {
return this.sourceVersionList.find(item => item.id === val);
},
/**
* 版本对比
*/
getCodeCompareScript(type) {
if (this.$route.query.realTime == 'real') {
const sourceItem = this.setDefaultVersion(this.sourceForm.version);
const targetItem = this.setDefaultVersion(this.targetForm.version);
this.$emit('codeCompare', {
sourceTaskScript: sourceItem.script,
targetTaskScript: targetItem ? targetItem.script : null,
realTime: this.$route.query.realTime
})
if (type === 'source') {
this.sourceForm.createdBy = sourceItem.submittedBy;
this.sourceForm.createdAt = dayjs(sourceItem.submitTime).format(DateFormatEnum.DATETIME_FORM)
} else {
this.targetForm.createdBy = targetItem.submittedBy;
this.targetForm.createdAt = dayjs(targetItem.submitTime).format(DateFormatEnum.DATETIME_FORM)
}
} else {
const sourceItem = this.sourceForm;
this.$emit('codeCompare', sourceItem.script)
this.sourceForm.createdBy = sourceItem.createdBy;
this.sourceForm.createdAt = sourceItem.createdAt;
}
}
}
}
</script>
<style scoped lang="scss">
.filter-item {
.form-box {
display: flex;
.source-form, target-form {
width: 49%;
}
.target-form {
padding-left: 12px;
}
}
.task-desc {
margin-bottom: 12px;
}
}
</style>
task
<template>
<div class="task">
<FilterItems @codeCompare="codeCompare"></FilterItems>
<el-tabs v-model="activeName" >
<el-tab-pane label="代码" name="code">
<Monaco ref="MonacoRef"></Monaco>
</el-tab-pane>
</el-tabs>
</div>
</template>
<script>
import FilterItems from '../FilterItems/FilterItems'
import Monaco from "./components/Monaco/Monaco";
export default {
name: "task",
components: { FilterItems, Monaco },
data() {
return {
activeName: 'code',
}
},
mounted() {
},
methods: {
codeCompare(event) {
this.$refs.MonacoRef.init(event);
}
}
}
</script>
<style scoped lang="scss">
.task {
.form-box {
display: flex;
.source-form, target-form {
width: 49%;
}
.target-form {
padding-left: 12px;
}
}
.task-desc {
margin-bottom: 12px;
text-align: center;
}
}
</style>
sql
const sqlInfo = {
//括号
brackets:[
{ open: '[', close: ']', token: 'delimiter.square' },
{ open: '(', close: ')', token: 'delimiter.parenthesis' }
],
//关键字
keywords:[
//Non-reserved Keywords
//1.2.0
'ADD','ADMIN','AFTER','ANALYZE','ARCHIVE','ASC','BEFORE','BUCKET',
'BUCKETS','CASCADE','CHANGE','CLUSTER','CLUSTERED','CLUSTERSTATUS',
'COLLECTION','COLUMNS','COMMENT','COMPACT','COMPACTIONS','COMPUTE',
'CONCATENATE','CONTINUE','DATA','DATABASES','DATETIME','DAY',
'DBPROPERTIES','DEFERRED','DEFINED','DELIMITED','DEPENDENCY','DESC',
'DIRECTORIES','DIRECTORY','DISABLE','DISTRIBUTE','ELEM_TYPE',
'ENABLE','ESCAPED','EXCLUSIVE','EXPLAIN', 'EXPORT', 'FIELDS', 'FILE',
'FILEFORMAT','FIRST','FORMAT','FORMATTED','FUNCTIONS','HOLD_DDLTIME',
'HOUR','IDXPROPERTIES','IGNORE','INDEX','INDEXES','INPATH',
'INPUTDRIVER','INPUTFORMAT','ITEMS','JAR','KEYS','KEY_TYPE','LIMIT',
'LINES','LOAD','LOCATION','LOCK','LOCKS','LOGICAL','LONG','MAPJOIN',
'MATERIALIZED','METADATA','MINUS','MINUTE','MONTH','MSCK','NOSCAN',
'NO_DROP', 'OFFLINE','OPTION','OUTPUTDRIVER', 'OUTPUTFORMAT',
'OVERWRITE', 'OWNER', 'PARTITIONED', 'PARTITIONS', 'PLUS', 'PRETTY',
'PRINCIPALS', 'PROTECTION', 'PURGE', 'READ', 'READONLY', 'REBUILD',
'RECORDREADER', 'RECORDWRITER', 'REGEXP', 'RELOAD', 'RENAME',
'REPAIR', 'REPLACE', 'REPLICATION', 'RESTRICT', 'REWRITE', 'RLIKE',
'ROLE', 'ROLES', 'SCHEMA', 'SCHEMAS', 'SECOND', 'SEMI', 'SERDE',
'SERDEPROPERTIES', 'SERVER', 'SETS', 'SHARED', 'SHOW', 'SHOW_DATABASE',
'SKEWED', 'SORT', 'SORTED', 'SSL', 'STATISTICS', 'STORED', 'STREAMTABLE',
'STRING', 'STRUCT', 'TABLES', 'TBLPROPERTIES', 'TEMPORARY', 'TERMINATED',
'TINYINT', 'TOUCH', 'TRANSACTIONS', 'UNARCHIVE', 'UNDO', 'UNIONTYPE',
'UNLOCK', 'UNSET', 'UNSIGNED', 'URI', 'USE', 'UTC', 'UTCTIMESTAMP',
'VALUE_TYPE', 'VIEW', 'WHILE', 'YEAR',
//2.0.0 add remove:REGEXP, RLIKE
'AUTOCOMMIT','ISOLATION', 'LEVEL', 'OFFSET', 'SNAPSHOT', 'TRANSACTION', 'WORK', 'WRITE',
//2.1.0 add
'ABORT', 'KEY', 'LAST', 'NORELY', 'NOVALIDATE', 'NULLS', 'RELY', 'VALIDATE',
//2.2.0 add
'DETAIL', 'DOW', 'EXPRESSION', 'OPERATOR', 'QUARTER', 'SUMMARY', 'VECTORIZATION', 'WEEK', 'YEARS', 'MONTHS', 'WEEKS', 'DAYS', 'HOURS', 'MINUTES', 'SECONDS',
//3.0.0 add
'TIMESTAMPTZ', 'ZONE',
//Reserved Keywords
//2.0.0 add
'COMMIT', 'ONLY', 'REGEXP', 'RLIKE', 'ROLLBACK', 'START',
//2.1.0 add
'CACHE', 'CONSTRAINT', 'FOREIGN', 'PRIMARY', 'REFERENCES',
//2.2.0 add
'DAYOFWEEK', 'EXTRACT', 'FLOOR', 'INTEGER', 'PRECISION', 'VIEWS',
//3.0.0 add
'TIME', 'NUMERIC', 'SYNC',
//1.2.0
'ALL', 'ALTER', 'AND', 'ARRAY', 'AS', 'AUTHORIZATION', 'BETWEEN',
'BIGINT', 'BINARY', 'BOOLEAN', 'BOTH', 'BY', 'CASE', 'CAST', 'CHAR',
'COLUMN', 'CONF', 'CREATE', 'CROSS', 'CUBE', 'CURRENT', 'CURRENT_DATE',
'CURRENT_TIMESTAMP', 'CURSOR', 'DATABASE', 'DATE', 'DECIMAL', 'DELETE',
'DESCRIBE', 'DISTINCT', 'DOUBLE', 'DROP', 'ELSE', 'END', 'EXCHANGE',
'EXISTS', 'EXTENDED', 'EXTERNAL', 'FALSE', 'FETCH', 'FLOAT', 'FOLLOWING',
'FOR', 'FROM', 'FULL', 'FUNCTION', 'GRANT', 'GROUP', 'GROUPING',
'HAVING', 'IF', 'IMPORT', 'IN', 'INNER', 'INSERT', 'INT', 'INTERSECT',
'INTERVAL', 'INTO', 'IS', 'JOIN', 'LATERAL', 'LEFT', 'LESS', 'LIKE',
'LOCAL', 'MACRO', 'MAP', 'MORE', 'NONE', 'NOT', 'NULL', 'OF', 'ON',
'OR', 'ORDER', 'OUT', 'OUTER', 'OVER', 'PARTIALSCAN', 'PARTITION',
'PERCENT', 'PRECEDING', 'PRESERVE', 'PROCEDURE', 'RANGE', 'READS',
'REDUCE', 'REVOKE', 'RIGHT', 'ROLLUP', 'ROW', 'ROWS', 'SELECT',
'SET', 'SMALLINT', 'TABLE', 'TABLESAMPLE', 'THEN', 'TIMESTAMP', 'TO',
'TRANSFORM', 'TRIGGER', 'TRUE', 'TRUNCATE', 'UNBOUNDED', 'UNION',
'UNIQUEJOIN', 'UPDATE', 'USER', 'USING', 'UTC_TMESTAMP', 'VALUES',
'VARCHAR', 'WHEN', 'WHERE', 'WINDOW', 'WITH'
],
//运算符
operators:[
'DIV',
// Logical
'ALL', 'AND', 'ANY', 'BETWEEN', 'EXISTS', 'IN', 'LIKE', 'NOT', 'OR', 'SOME',
// Set
'EXCEPT', 'INTERSECT', 'UNION',
// Join
'APPLY', 'CROSS', 'FULL', 'INNER', 'JOIN', 'LEFT', 'OUTER', 'RIGHT',
// Predicates
'CONTAINS', 'FREETEXT', 'IS', 'NULL',
// Pivoting
'PIVOT', 'UNPIVOT',
// Merging
'MATCHED'
],
//内置方法
builtinFunctions:[
//Complex Type Constructors
'MAP','STRUCT','NAMED_STRUCT','ARRAY','CREATE_UNION',
//Mathematical Functions
'BROUND','CEIL','IN','ln','LOG2','POW','BIN','HEX','UNHEX','CONV','POSITIVE','PMOD','NEGATIVE',
'E','FACTORIAL','CBRT','SHIFTLEFT','SHIFTRIGHT','SHIFTRIGHTUNSIGNED','GREATEST','LEAST','WIDTH_BUCKET',
//Collection Functions
'SIZE','MAP_KEYS','MAP_VALUES','ARRAY_CONTAINS','SORT_ARRAY',
//Type Conversion Functions
'BINARY',
//Date Functions
'FROM_UNIXTIME','UNIX_TIMESTAMP','TO_DATE','QUARTER','HOUR','MINUTE',
'SECOND','WEEKOFYEAR','EXTRACT','DATE_ADD','DATE_SUB','FROM_UTC_TIMESTAMP',
'TO_UTC_TIMESTAMP','CURRENT_DATE','ADD_MONTHS','LAST_DAY','NEXT_DAY',
'TRUNC','MONTHS_BETWEEN','DATE_FORMAT',
//Conditional Functions
'IF','ISNOTNULL','NVL','ASSERT_TRUE',
//String Functions
'BASE64','CHARACTER_LENGTH','CHR','CONTEXT_NGRAMS','CONCAT_WS','DECODE',
'ELT','ENCODE','FIELD','FIND_IN_SET','FORMAT_NUMBER','GET_JSON_OBJECT',
'IN_FILE','INSTR','LENGTH','LOCATE','LPAD','NGRAMS','OCTET_LENGTH',
'PARSE_URL','PRINTF','QUOTE','REGEXP_EXTRACT','REGEXP_REPLACE','REPEAT',
'RPAD','SENTENCES','SPLIT','STR_TO_MAP','SUBSTR','SUBSTRING_INDEX',
'TRANSLATE','TRIM','UNBASE64','INITCAP','LEVENSHTEIN',
//Data Masking Functions
'MASK','MASK_FIRST_N','MASK_LAST_N','MASK_SHOW_FIRST_N','MASK_SHOW_LAST_N','MASK_HASH',
//Misc. Functions
'JAVA_METHOD','REFLECT','HASH','LOGGED_IN_USER','CURRENT_DATABASE','MD5','SHA1','SHA',
'CRC32','SHA2','AES_ENCRYPT','AES_DECRYPT','SURROGATE_KEY','VERSION',
//Built-in Aggregate Functions (UDAF)
'VARIANCE','VAR_SAMP','STDDEV_POP','STDDEV_SAMP','COVAR_POP','COVAR_SAMP',
'CORR','PERCENTILE','PERCENTILE_APPROX','REGR_AVGX','REGR_AVGY','REGR_COUNT',
'REGR_INTERCEPT','REGR_R2','REGR_SLOPE','REGR_SXX','REGR_SXY','REGR_SYY',
'HISTOGRAM_NUMERIC','COLLECT_SET','COLLECT_LIST',
//Built-in Table-Generating Functions (UDTF)
'EXPLODE','POSEXPLODE','INLINE','STACK','JSON_TUPLE','PARSE_URL_TUPLE',
// Aggregate
'AVG', 'CHECKSUM_AGG', 'COUNT', 'COUNT_BIG', 'GROUPING', 'GROUPING_ID', 'MAX', 'MIN', 'SUM', 'STDEV', 'STDEVP', 'VAR', 'VARP',
// Analytic
'CUME_DIST', 'FIRST_VALUE', 'LAG', 'LAST_VALUE', 'LEAD', 'PERCENTILE_CONT', 'PERCENTILE_DISC', 'PERCENT_RANK',
// Collation
'COLLATE', 'COLLATIONPROPERTY', 'TERTIARY_WEIGHTS',
// Azure
'FEDERATION_FILTERING_VALUE',
// Conversion
'CAST', 'CONVERT', 'PARSE', 'TRY_CAST', 'TRY_CONVERT', 'TRY_PARSE',
// Cryptographic
'ASYMKEY_ID', 'ASYMKEYPROPERTY', 'CERTPROPERTY', 'CERT_ID', 'CRYPT_GEN_RANDOM',
'DECRYPTBYASYMKEY', 'DECRYPTBYCERT', 'DECRYPTBYKEY', 'DECRYPTBYKEYAUTOASYMKEY', 'DECRYPTBYKEYAUTOCERT', 'DECRYPTBYPASSPHRASE',
'ENCRYPTBYASYMKEY', 'ENCRYPTBYCERT', 'ENCRYPTBYKEY', 'ENCRYPTBYPASSPHRASE', 'HASHBYTES', 'IS_OBJECTSIGNED',
'KEY_GUID', 'KEY_ID', 'KEY_NAME', 'SIGNBYASYMKEY', 'SIGNBYCERT', 'SYMKEYPROPERTY', 'VERIFYSIGNEDBYCERT', 'VERIFYSIGNEDBYASYMKEY',
// Cursor
'CURSOR_STATUS',
// Datatype
'DATALENGTH', 'IDENT_CURRENT', 'IDENT_INCR', 'IDENT_SEED', 'IDENTITY', 'SQL_VARIANT_PROPERTY',
// Datetime
'CURRENT_TIMESTAMP', 'DATEADD', 'DATEDIFF', 'DATEFROMPARTS', 'DATENAME', 'DATEPART', 'DATETIME2FROMPARTS', 'DATETIMEFROMPARTS',
'DATETIMEOFFSETFROMPARTS', 'DAY', 'EOMONTH', 'GETDATE', 'GETUTCDATE', 'ISDATE', 'MONTH', 'SMALLDATETIMEFROMPARTS', 'SWITCHOFFSET',
'SYSDATETIME', 'SYSDATETIMEOFFSET', 'SYSUTCDATETIME', 'TIMEFROMPARTS', 'TODATETIMEOFFSET', 'YEAR',
// Logical
'CHOOSE', 'COALESCE', 'IIF', 'NULLIF',
// Mathematical
'ABS', 'ACOS', 'ASIN', 'ATAN', 'ATN2', 'CEILING', 'COS', 'COT', 'DEGREES', 'EXP', 'FLOOR', 'LOG', 'LOG10',
'PI', 'POWER', 'RADIANS', 'RAND', 'ROUND', 'SIGN', 'SIN', 'SQRT', 'SQUARE', 'TAN',
// Metadata
'APP_NAME', 'APPLOCK_MODE', 'APPLOCK_TEST', 'ASSEMBLYPROPERTY', 'COL_LENGTH', 'COL_NAME', 'COLUMNPROPERTY',
'DATABASE_PRINCIPAL_ID', 'DATABASEPROPERTYEX', 'DB_ID', 'DB_NAME', 'FILE_ID', 'FILE_IDEX', 'FILE_NAME', 'FILEGROUP_ID',
'FILEGROUP_NAME', 'FILEGROUPPROPERTY', 'FILEPROPERTY', 'FULLTEXTCATALOGPROPERTY', 'FULLTEXTSERVICEPROPERTY',
'INDEX_COL', 'INDEXKEY_PROPERTY', 'INDEXPROPERTY', 'OBJECT_DEFINITION', 'OBJECT_ID',
'OBJECT_NAME', 'OBJECT_SCHEMA_NAME', 'OBJECTPROPERTY', 'OBJECTPROPERTYEX', 'ORIGINAL_DB_NAME', 'PARSENAME',
'SCHEMA_ID', 'SCHEMA_NAME', 'SCOPE_IDENTITY', 'SERVERPROPERTY', 'STATS_DATE', 'TYPE_ID', 'TYPE_NAME', 'TYPEPROPERTY',
// Ranking
'DENSE_RANK', 'NTILE', 'RANK', 'ROW_NUMBER',
// Replication
'PUBLISHINGSERVERNAME',
// Rowset
'OPENDATASOURCE', 'OPENQUERY', 'OPENROWSET', 'OPENXML',
// Security
'CERTENCODED', 'CERTPRIVATEKEY', 'CURRENT_USER', 'HAS_DBACCESS', 'HAS_PERMS_BY_NAME', 'IS_MEMBER', 'IS_ROLEMEMBER', 'IS_SRVROLEMEMBER',
'LOGINPROPERTY', 'ORIGINAL_LOGIN', 'PERMISSIONS', 'PWDENCRYPT', 'PWDCOMPARE', 'SESSION_USER', 'SESSIONPROPERTY', 'SUSER_ID', 'SUSER_NAME',
'SUSER_SID', 'SUSER_SNAME', 'SYSTEM_USER', 'USER', 'USER_ID', 'USER_NAME',
// String
'ASCII', 'CHAR', 'CHARINDEX', 'CONCAT', 'DIFFERENCE', 'FORMAT', 'LEFT', 'LEN', 'LOWER', 'LTRIM', 'NCHAR', 'PATINDEX',
'QUOTENAME', 'REPLACE', 'REPLICATE', 'REVERSE', 'RIGHT', 'RTRIM', 'SOUNDEX', 'SPACE', 'STR', 'STUFF', 'SUBSTRING', 'UNICODE', 'UPPER',
// System
'BINARY_CHECKSUM', 'CHECKSUM', 'CONNECTIONPROPERTY', 'CONTEXT_INFO', 'CURRENT_REQUEST_ID', 'ERROR_LINE', 'ERROR_NUMBER', 'ERROR_MESSAGE',
'ERROR_PROCEDURE', 'ERROR_SEVERITY', 'ERROR_STATE', 'FORMATMESSAGE', 'GETANSINULL', 'GET_FILESTREAM_TRANSACTION_CONTEXT', 'HOST_ID',
'HOST_NAME', 'ISNULL', 'ISNUMERIC', 'MIN_ACTIVE_ROWVERSION', 'NEWID', 'NEWSEQUENTIALID', 'ROWCOUNT_BIG', 'XACT_STATE',
// TextImage
'TEXTPTR', 'TEXTVALID',
// Trigger
'COLUMNS_UPDATED', 'EVENTDATA', 'TRIGGER_NESTLEVEL', 'UPDATE',
// ChangeTracking
'CHANGETABLE', 'CHANGE_TRACKING_CONTEXT', 'CHANGE_TRACKING_CURRENT_VERSION', 'CHANGE_TRACKING_IS_COLUMN_IN_MASK', 'CHANGE_TRACKING_MIN_VALID_VERSION',
// FullTextSearch
'CONTAINSTABLE', 'FREETEXTTABLE',
// SemanticTextSearch
'SEMANTICKEYPHRASETABLE', 'SEMANTICSIMILARITYDETAILSTABLE', 'SEMANTICSIMILARITYTABLE',
// FileStream
'FILETABLEROOTPATH', 'GETFILENAMESPACEPATH', 'GETPATHLOCATOR', 'PATHNAME',
// ServiceBroker
'GET_TRANSMISSION_STATUS',
//SPARK SQL FN
'ACOSH','AGGREGATE','APPROX_COUNT_DISTINCT','APPROX_PRECENTILE','ARRAY_DISTINCT',
'ARRAY_EXCEPT','ARRAY_INTERSECT','ARRAY_JOIN','ARRAY_MAX','ARRAY_MIN','ARRAY_POSITION',
'ARRAY_REMOVE','ARRAY_REPEAT','ARRAY_SORT','ARRAY_UNION','ARRAYS_OVERLAP',
'ARRAYS_ZIP','SAINH','ATANH','ATAN2','BIT_AND','BIT_COUNT','BIT_LENGTH',
'BIT_OR','BIT_XOR','BOOL_AND','BOOL_OR','CARDINALITY','CHAR_LENGTH',
'COSH','COUNT_IF','COUNT_MIN_SKETCH','DATE_PART','DATE_TRUNC','DATEOFMONTH',
'DATEOFYEAR','ELEMENT_AT','EVERY','EXPLODE_OUTER','EXPM1','FILTER','FLATTEN',
'FORALL','FORMAT_STRING','FROM_CSV','FROM_JSON','GROUPING','GROUPING_ID',
'HYPOT','IFNULL','INLINE_OUTER','INPUT_FILR_BLOCK_LENGTH','INPUT_FILR_BLOCK_START',
'INPUT_FILR_NAME','ISNAN','KURTOSIS','LCASE','LOG1P','IPAD','ITRIM','MAKE_DATE','MAKE_INTERVAL','MAKE_TIMESTAMP',
'MAP_CONCAT','MAP_ENTRIES','MAP_FROM_ARRAYS','MAP_FROM_ENTRIES','MAP_ZIP_WITH',
'MAX_BY','MEAN','MIN_BY','MOD','MONOTONICALLY_INCREASING_ID','NANVL','NOW','NVL2',
'OVERLAY','POSEXPLODE_OUTER','POSITION','RANDN','RANDOM','RINT','SCHEMA_OF_CSV',
'SCHEMA_OF_JSON','SEQUENCE','SHUFFLE','SIGNUM','SINH','SKEWNESS','SLICE','SPARK_PARTITION_ID',
'STD','TANH','TO_CSV','TO_JSON','TO_TIMESTAMP','TO_UBIX_TIMESTAMP','TYPEOF',
'UCASE','UUID','WEEKDAY','XPATH','XPATH_BOOLEAN','XPATH_DOUBEL','XPATH_FLOAT','XPATH_INT',
'XPATH_LONG','XPATH_NUMBER','XPATH_SHORT','XPATH_STRING','XXHASH64','ZIP_WITH'
],
//内置变量
builtinVariables:[
// Configuration
'@@DATEFIRST', '@@DBTS', '@@LANGID', '@@LANGUAGE', '@@LOCK_TIMEOUT', '@@MAX_CONNECTIONS', '@@MAX_PRECISION', '@@NESTLEVEL',
'@@OPTIONS', '@@REMSERVER', '@@SERVERNAME', '@@SERVICENAME', '@@SPID', '@@TEXTSIZE', '@@VERSION',
// Cursor
'@@CURSOR_ROWS', '@@FETCH_STATUS',
// Datetime
'@@DATEFIRST',
// Metadata
'@@PROCID',
// System
'@@ERROR', '@@IDENTITY', '@@ROWCOUNT', '@@TRANCOUNT',
// Stats
'@@CONNECTIONS', '@@CPU_BUSY', '@@IDLE', '@@IO_BUSY', '@@PACKET_ERRORS', '@@PACK_RECEIVED', '@@PACK_SENT',
'@@TIMETICKS', '@@TOTAL_ERRORS', '@@TOTAL_READ', '@@TOTAL_WRITE'
],
//伪列
pseudoColumns: [
'$ACTION', '$IDENTITY', '$ROWGUID', '$PARTITION'
],
tokenizer: {
root: [
{ include: '@comments' },
{ include: '@whitespace' },
{ include: '@pseudoColumns' },
{ include: '@numbers' },
{ include: '@strings' },
{ include: '@complexIdentifiers' },
{ include: '@scopes' },
[/[;,.]/, 'delimiter'],
[/[()]/, '@brackets'],
[/[\w@#$]+/, {
cases: {
'@keywords': 'keyword',
'@operators': 'opera',
'@builtinVariables': 'builtFunc',
'@builtinFunctions': 'builtFunc',
'@default': 'identifier'
}
}],
[/[<>=!%&+\-*/|~^]/, 'opera'],
],
whitespace: [
[/\s+/, 'white']
],
comments: [
[/--+.*/, 'comment'],
[/\/\*/, { token: 'comment.quote', next: '@comment' }]
],
comment: [
[/[^*/]+/, 'comment'],
[/\*\//, { token: 'comment.quote', next: '@pop' }],
[/./, 'comment']
],
pseudoColumns: [
[/[$][A-Za-z_][\w@#$]*/, {
cases: {
'@pseudoColumns': 'builtFunc',
'@default': 'identifier'
}
}],
],
numbers: [
[/0[xX][0-9a-fA-F]*/, 'number'],
[/[$][+-]*\d*(\.\d*)?/, 'number'],
[/((\d+(\.\d*)?)|(\.\d+))([eE][\-+]?\d+)?/, 'number']
],
strings: [
[/N'/, { token: 'string', next: '@string' }],
[/'/, { token: 'string', next: '@string' }]
],
string: [
[/[^']+/, 'string'],
[/''/, 'string'],
[/'/, { token: 'string', next: '@pop' }]
],
complexIdentifiers: [
[/\[/, { token: 'identifier.quote', next: '@bracketedIdentifier' }],
[/"/, { token: 'identifier.quote', next: '@quotedIdentifier' }]
],
bracketedIdentifier: [
[/[^\]]+/, 'identifier'],
[/]]/, 'identifier'],
[/]/, { token: 'identifier.quote', next: '@pop' }]
],
quotedIdentifier: [
[/[^"]+/, 'identifier'],
[/""/, 'identifier'],
[/"/, { token: 'identifier.quote', next: '@pop' }]
],
scopes: [
[/BEGIN\s+(DISTRIBUTED\s+)?TRAN(SACTION)?\b/i, 'keyword'],
[/BEGIN\s+TRY\b/i, { token: 'keyword.try' }],
[/END\s+TRY\b/i, { token: 'keyword.try' }],
[/BEGIN\s+CATCH\b/i, { token: 'keyword.catch' }],
[/END\s+CATCH\b/i, { token: 'keyword.catch' }],
[/(BEGIN|CASE)\b/i, { token: 'keyword.block' }],
[/END\b/i, { token: 'keyword.block' }],
[/WHEN\b/i, { token: 'keyword.choice' }],
[/THEN\b/i, { token: 'keyword.choice' }]
]
}
}
export default sqlInfo