mirror of
https://gitee.com/dromara/mayfly-go
synced 2025-11-03 16:00:25 +08:00
feat: 数据库表操作显示表size&其他小优化
This commit is contained in:
@@ -3,21 +3,16 @@
|
|||||||
* @param size byte size
|
* @param size byte size
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export function formatByteSize(size: any) {
|
export function formatByteSize(size: number, fixed = 2) {
|
||||||
const value = Number(size);
|
if (size === 0) {
|
||||||
if (size && !isNaN(value)) {
|
return '0B';
|
||||||
const units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB', 'BB'];
|
|
||||||
let index = 0;
|
|
||||||
let k = value;
|
|
||||||
if (value >= 1024) {
|
|
||||||
while (k > 1024) {
|
|
||||||
k = k / 1024;
|
|
||||||
index++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return `${k.toFixed(2)}${units[index]}`;
|
|
||||||
}
|
}
|
||||||
return '-';
|
|
||||||
|
const units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
|
||||||
|
const base = 1024;
|
||||||
|
const exponent = Math.floor(Math.log(size) / Math.log(base));
|
||||||
|
|
||||||
|
return parseFloat((size / Math.pow(base, exponent)).toFixed(fixed)) + units[exponent];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -169,7 +169,6 @@ self.MonacoEnvironment = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
editorHeight: '500px',
|
|
||||||
languageMode: 'shell',
|
languageMode: 'shell',
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,8 @@
|
|||||||
<span class="ml3">
|
<span class="ml3">
|
||||||
<slot name="label" :data="data"> {{ data.label }}</slot>
|
<slot name="label" :data="data"> {{ data.label }}</slot>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
|
<slot :node="node" :data="data" name="suffix"></slot>
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
</el-tree>
|
</el-tree>
|
||||||
|
|||||||
@@ -201,7 +201,7 @@ const columns = ref([
|
|||||||
TableColumn.new('tagPath', '标签路径').isSlot().setAddWidth(20),
|
TableColumn.new('tagPath', '标签路径').isSlot().setAddWidth(20),
|
||||||
TableColumn.new('instanceName', '实例名'),
|
TableColumn.new('instanceName', '实例名'),
|
||||||
TableColumn.new('type', '类型'),
|
TableColumn.new('type', '类型'),
|
||||||
TableColumn.new('host', 'ip:port').isSlot().setAddWidth(20),
|
TableColumn.new('host', 'ip:port').isSlot().setAddWidth(40),
|
||||||
TableColumn.new('username', 'username'),
|
TableColumn.new('username', 'username'),
|
||||||
TableColumn.new('name', '名称'),
|
TableColumn.new('name', '名称'),
|
||||||
TableColumn.new('database', '数据库').isSlot().setMinWidth(70),
|
TableColumn.new('database', '数据库').isSlot().setMinWidth(70),
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div class="db-sql-exec">
|
||||||
<el-row class="mb5">
|
<el-row class="mb5">
|
||||||
<el-col :span="4">
|
<el-col :span="4">
|
||||||
<el-button
|
<el-button
|
||||||
@@ -11,6 +11,7 @@
|
|||||||
>新建查询</el-button
|
>新建查询</el-button
|
||||||
>
|
>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
<el-col :span="20" v-if="state.db">
|
<el-col :span="20" v-if="state.db">
|
||||||
<el-descriptions :column="4" size="small" border style="height: 10px" class="ml5">
|
<el-descriptions :column="4" size="small" border style="height: 10px" class="ml5">
|
||||||
<el-descriptions-item label-align="right" label="tag">{{ nowDbInst.tagPath }}</el-descriptions-item>
|
<el-descriptions-item label-align="right" label="tag">{{ nowDbInst.tagPath }}</el-descriptions-item>
|
||||||
@@ -27,6 +28,7 @@
|
|||||||
</el-descriptions>
|
</el-descriptions>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
<el-row type="flex">
|
<el-row type="flex">
|
||||||
<el-col :span="4">
|
<el-col :span="4">
|
||||||
<tag-tree
|
<tag-tree
|
||||||
@@ -74,8 +76,13 @@
|
|||||||
|
|
||||||
<SvgIcon name="Files" v-if="data.type == NodeType.SqlMenu || data.type == NodeType.Sql" color="#f56c6c" />
|
<SvgIcon name="Files" v-if="data.type == NodeType.SqlMenu || data.type == NodeType.Sql" color="#f56c6c" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<template #suffix="{ data }">
|
||||||
|
<span class="db-table-size" v-if="data.type == NodeType.Table">{{ ` ${data.params.size}` }}</span>
|
||||||
|
</template>
|
||||||
</tag-tree>
|
</tag-tree>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
<el-col :span="20">
|
<el-col :span="20">
|
||||||
<el-container id="data-exec" class="mt5 ml5">
|
<el-container id="data-exec" class="mt5 ml5">
|
||||||
<el-tabs @tab-remove="onRemoveTab" @tab-change="onTabChange" style="width: 100%" v-model="state.activeName">
|
<el-tabs @tab-remove="onRemoveTab" @tab-change="onTabChange" style="width: 100%" v-model="state.activeName">
|
||||||
@@ -110,7 +117,7 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { defineAsyncComponent, onMounted, reactive, ref, toRefs, onBeforeUnmount } from 'vue';
|
import { defineAsyncComponent, onMounted, reactive, ref, toRefs, onBeforeUnmount } from 'vue';
|
||||||
import { ElMessage } from 'element-plus';
|
import { ElMessage } from 'element-plus';
|
||||||
|
import { formatByteSize } from '@/common/utils/format';
|
||||||
import { DbInst, TabInfo, TabType, registerDbCompletionItemProvider } from './db';
|
import { DbInst, TabInfo, TabType, registerDbCompletionItemProvider } from './db';
|
||||||
import { TagTreeNode } from '../component/tag';
|
import { TagTreeNode } from '../component/tag';
|
||||||
import TagTree from '../component/TagTree.vue';
|
import TagTree from '../component/TagTree.vue';
|
||||||
@@ -304,6 +311,7 @@ const getTables = async (params: any) => {
|
|||||||
db,
|
db,
|
||||||
tableName: x.tableName,
|
tableName: x.tableName,
|
||||||
tableComment: x.tableComment,
|
tableComment: x.tableComment,
|
||||||
|
size: formatByteSize(x.dataLength + x.indexLength, 1),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -461,47 +469,54 @@ const reloadTables = (nodeKey: string) => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
.sql-file-exec {
|
.db-sql-exec {
|
||||||
display: inline-flex;
|
.sql-file-exec {
|
||||||
flex-direction: row;
|
display: inline-flex;
|
||||||
align-items: center;
|
flex-direction: row;
|
||||||
justify-content: center;
|
align-items: center;
|
||||||
vertical-align: middle;
|
justify-content: center;
|
||||||
position: relative;
|
vertical-align: middle;
|
||||||
text-decoration: none;
|
position: relative;
|
||||||
}
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
.sqlEditor {
|
.db-table-size {
|
||||||
font-size: 8pt;
|
color: #c4c9c4;
|
||||||
font-weight: 600;
|
font-size: 10px;
|
||||||
border: 1px solid #ccc;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
.editor-move-resize {
|
.sqlEditor {
|
||||||
cursor: n-resize;
|
font-size: 8pt;
|
||||||
height: 3px;
|
font-weight: 600;
|
||||||
text-align: center;
|
border: 1px solid #ccc;
|
||||||
}
|
}
|
||||||
|
|
||||||
#data-exec {
|
.editor-move-resize {
|
||||||
min-height: calc(100vh - 155px);
|
cursor: n-resize;
|
||||||
|
height: 3px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
.el-tabs__header {
|
#data-exec {
|
||||||
margin: 0 0 5px;
|
min-height: calc(100vh - 155px);
|
||||||
|
|
||||||
.el-tabs__item {
|
.el-tabs__header {
|
||||||
padding: 0 5px;
|
margin: 0 0 5px;
|
||||||
|
|
||||||
|
.el-tabs__item {
|
||||||
|
padding: 0 5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.update_field_active {
|
||||||
|
background-color: var(--el-color-success);
|
||||||
|
}
|
||||||
|
|
||||||
|
.instances-pop-form {
|
||||||
|
.el-form-item {
|
||||||
|
margin-bottom: unset;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.update_field_active {
|
|
||||||
background-color: var(--el-color-success);
|
|
||||||
}
|
|
||||||
|
|
||||||
.instances-pop-form {
|
|
||||||
.el-form-item {
|
|
||||||
margin-bottom: unset;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ export const dbApi = {
|
|||||||
tableInfos: Api.newGet('/dbs/{id}/t-infos'),
|
tableInfos: Api.newGet('/dbs/{id}/t-infos'),
|
||||||
tableIndex: Api.newGet('/dbs/{id}/t-index'),
|
tableIndex: Api.newGet('/dbs/{id}/t-index'),
|
||||||
tableDdl: Api.newGet('/dbs/{id}/t-create-ddl'),
|
tableDdl: Api.newGet('/dbs/{id}/t-create-ddl'),
|
||||||
tableMetadata: Api.newGet('/dbs/{id}/t-metadata'),
|
|
||||||
columnMetadata: Api.newGet('/dbs/{id}/c-metadata'),
|
columnMetadata: Api.newGet('/dbs/{id}/c-metadata'),
|
||||||
// 获取表即列提示
|
// 获取表即列提示
|
||||||
hintTables: Api.newGet('/dbs/{id}/hint-tables'),
|
hintTables: Api.newGet('/dbs/{id}/hint-tables'),
|
||||||
@@ -27,7 +26,7 @@ export const dbApi = {
|
|||||||
|
|
||||||
// 获取权限列表
|
// 获取权限列表
|
||||||
instances: Api.newGet('/instances'),
|
instances: Api.newGet('/instances'),
|
||||||
getInstance: Api.newGet("/instances/{instanceId}"),
|
getInstance: Api.newGet('/instances/{instanceId}'),
|
||||||
getAllDatabase: Api.newGet('/instances/{instanceId}/databases'),
|
getAllDatabase: Api.newGet('/instances/{instanceId}/databases'),
|
||||||
saveInstance: Api.newPost('/instances'),
|
saveInstance: Api.newPost('/instances'),
|
||||||
getInstancePwd: Api.newGet('/instances/{id}/pwd'),
|
getInstancePwd: Api.newGet('/instances/{id}/pwd'),
|
||||||
|
|||||||
@@ -44,7 +44,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<MonacoEditor ref="monacoEditorRef" class="mt5" v-model="state.sql" language="sql" :height="editorHeight" :id="'MonacoTextarea-' + ti.key" />
|
<MonacoEditor ref="monacoEditorRef" class="mt5" v-model="state.sql" language="sql" :height="state.editorHeight" :id="'MonacoTextarea-' + ti.key" />
|
||||||
|
|
||||||
<div class="editor-move-resize" @mousedown="onDragSetHeight">
|
<div class="editor-move-resize" @mousedown="onDragSetHeight">
|
||||||
<el-icon>
|
<el-icon>
|
||||||
|
|||||||
@@ -33,26 +33,26 @@
|
|||||||
<el-link @click="onDeleteData()" type="danger" icon="delete" :underline="false"></el-link>
|
<el-link @click="onDeleteData()" type="danger" icon="delete" :underline="false"></el-link>
|
||||||
<el-divider direction="vertical" border-style="dashed" />
|
<el-divider direction="vertical" border-style="dashed" />
|
||||||
|
|
||||||
<el-tooltip class="box-item" effect="dark" content="commit" placement="top">
|
<el-tooltip :show-after="500" class="box-item" effect="dark" content="commit" placement="top">
|
||||||
<el-link @click="onCommit()" type="success" icon="CircleCheck" :underline="false"> </el-link>
|
<el-link @click="onCommit()" type="success" icon="CircleCheck" :underline="false"> </el-link>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
<el-divider direction="vertical" border-style="dashed" />
|
<el-divider direction="vertical" border-style="dashed" />
|
||||||
|
|
||||||
<el-tooltip class="box-item" effect="dark" content="生成insert sql" placement="top">
|
<el-tooltip :show-after="500" class="box-item" effect="dark" content="生成insert sql" placement="top">
|
||||||
<el-link @click="onGenerateInsertSql()" type="success" :underline="false">gi</el-link>
|
<el-link @click="onGenerateInsertSql()" type="success" :underline="false">gi</el-link>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
<el-divider direction="vertical" border-style="dashed" />
|
<el-divider direction="vertical" border-style="dashed" />
|
||||||
|
|
||||||
<el-tooltip class="box-item" effect="dark" content="导出当前页的csv文件" placement="top">
|
<el-tooltip :show-after="500" class="box-item" effect="dark" content="导出当前页的csv文件" placement="top">
|
||||||
<el-link type="success" :underline="false" @click="exportData"><span class="f12">导出</span></el-link>
|
<el-link type="success" :underline="false" @click="exportData"><span class="f12">导出</span></el-link>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
<el-divider direction="vertical" border-style="dashed" />
|
<el-divider direction="vertical" border-style="dashed" />
|
||||||
|
|
||||||
<el-tooltip v-if="hasUpdatedFileds" class="box-item" effect="dark" content="提交修改" placement="top">
|
<el-tooltip :show-after="500" v-if="hasUpdatedFileds" class="box-item" effect="dark" content="提交修改" placement="top">
|
||||||
<el-link @click="submitUpdateFields()" type="success" :underline="false" class="f12">提交</el-link>
|
<el-link @click="submitUpdateFields()" type="success" :underline="false" class="f12">提交</el-link>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
<el-divider v-if="hasUpdatedFileds" direction="vertical" border-style="dashed" />
|
<el-divider v-if="hasUpdatedFileds" direction="vertical" border-style="dashed" />
|
||||||
<el-tooltip v-if="hasUpdatedFileds" class="box-item" effect="dark" content="取消修改" placement="top">
|
<el-tooltip :show-after="500" v-if="hasUpdatedFileds" class="box-item" effect="dark" content="取消修改" placement="top">
|
||||||
<el-link @click="cancelUpdateFields" type="warning" :underline="false" class="f12">取消</el-link>
|
<el-link @click="cancelUpdateFields" type="warning" :underline="false" class="f12">取消</el-link>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ export class DbInst {
|
|||||||
db.columnsMap?.clear();
|
db.columnsMap?.clear();
|
||||||
db.tableHints = null;
|
db.tableHints = null;
|
||||||
console.log(`load tables -> dbName: ${dbName}`);
|
console.log(`load tables -> dbName: ${dbName}`);
|
||||||
tables = await dbApi.tableMetadata.request({ id: this.id, db: dbName });
|
tables = await dbApi.tableInfos.request({ id: this.id, db: dbName });
|
||||||
db.tables = tables;
|
db.tables = tables;
|
||||||
return tables;
|
return tables;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -195,7 +195,7 @@ const queryConfig = [TableQuery.slot('tagPath', '标签', 'tagPathSelect'), Tabl
|
|||||||
const columns = ref([
|
const columns = ref([
|
||||||
TableColumn.new('tagPath', '标签路径').isSlot().setAddWidth(20),
|
TableColumn.new('tagPath', '标签路径').isSlot().setAddWidth(20),
|
||||||
TableColumn.new('name', '名称'),
|
TableColumn.new('name', '名称'),
|
||||||
TableColumn.new('ipPort', 'ip:port').isSlot().setAddWidth(45),
|
TableColumn.new('ipPort', 'ip:port').isSlot().setAddWidth(50),
|
||||||
TableColumn.new('username', '用户名'),
|
TableColumn.new('username', '用户名'),
|
||||||
TableColumn.new('status', '状态').isSlot().setMinWidth(85),
|
TableColumn.new('status', '状态').isSlot().setMinWidth(85),
|
||||||
TableColumn.new('remark', '备注'),
|
TableColumn.new('remark', '备注'),
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { defineAsyncComponent, watch, ref, shallowReactive, reactive, computed, toRefs, onMounted } from 'vue';
|
import { defineAsyncComponent, watch, ref, shallowReactive, reactive, computed, onMounted } from 'vue';
|
||||||
import { ElMessage } from 'element-plus';
|
import { ElMessage } from 'element-plus';
|
||||||
import KeyHeader from './KeyHeader.vue';
|
import KeyHeader from './KeyHeader.vue';
|
||||||
|
|
||||||
@@ -107,8 +107,6 @@ watch(
|
|||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
setKeyInfo(props.keyInfo);
|
setKeyInfo(props.keyInfo);
|
||||||
});
|
});
|
||||||
|
|
||||||
const {} = toRefs(state);
|
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
.key-tab-container {
|
.key-tab-container {
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
<div class="key-header-item key-ttl-input">
|
<div class="key-header-item key-ttl-input">
|
||||||
<el-input type="number" v-model.number="ki.timed" placeholder="单位(秒),负数永久" title="点击修改过期时间">
|
<el-input type="number" v-model.number="ki.timed" placeholder="单位(秒),负数永久" title="点击修改过期时间">
|
||||||
<template #prepend>
|
<template #prepend>
|
||||||
<span slot="prepend">TTL</span>
|
<span>TTL</span>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #suffix>
|
<template #suffix>
|
||||||
@@ -37,8 +37,8 @@
|
|||||||
|
|
||||||
<!-- del & refresh btn -->
|
<!-- del & refresh btn -->
|
||||||
<div class="key-header-item key-header-btn-con">
|
<div class="key-header-item key-header-btn-con">
|
||||||
<el-button slot="reference" type="success" @click="refreshKey" icon="refresh" title="刷新"></el-button>
|
<el-button type="success" @click="refreshKey" icon="refresh" title="刷新"></el-button>
|
||||||
<el-button v-auth="'redis:data:del'" slot="reference" type="danger" @click="delKey" icon="delete" title="删除"></el-button>
|
<el-button v-auth="'redis:data:del'" type="danger" @click="delKey" icon="delete" title="删除"></el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -74,6 +74,7 @@ const state = reactive({
|
|||||||
timed: -1,
|
timed: -1,
|
||||||
} as any,
|
} as any,
|
||||||
oldKey: '',
|
oldKey: '',
|
||||||
|
memuse: 0,
|
||||||
});
|
});
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
|||||||
@@ -114,14 +114,14 @@ const getListValue = async (resetTableData = false) => {
|
|||||||
state.loadMoreDisable = state.values.length === state.total;
|
state.loadMoreDisable = state.values.length === state.total;
|
||||||
};
|
};
|
||||||
|
|
||||||
const lset = async (row: any, rowIndex: number) => {
|
// const lset = async (row: any, rowIndex: number) => {
|
||||||
await redisApi.setListValue.request({
|
// await redisApi.setListValue.request({
|
||||||
...getBaseReqParam(),
|
// ...getBaseReqParam(),
|
||||||
index: (state.pageNum - 1) * state.pageSize + rowIndex,
|
// index: (state.pageNum - 1) * state.pageSize + rowIndex,
|
||||||
value: row.value,
|
// value: row.value,
|
||||||
});
|
// });
|
||||||
ElMessage.success('数据保存成功');
|
// ElMessage.success('数据保存成功');
|
||||||
};
|
// };
|
||||||
|
|
||||||
const showEditDialog = (row: any) => {
|
const showEditDialog = (row: any) => {
|
||||||
state.editDialog.dataRow = row;
|
state.editDialog.dataRow = row;
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ export const redisApi = {
|
|||||||
|
|
||||||
keyInfo: Api.newGet('/redis/{id}/{db}/key-info'),
|
keyInfo: Api.newGet('/redis/{id}/{db}/key-info'),
|
||||||
keyTtl: Api.newGet('/redis/{id}/{db}/key-ttl'),
|
keyTtl: Api.newGet('/redis/{id}/{db}/key-ttl'),
|
||||||
|
keyMemuse: Api.newGet('/redis/{id}/{db}/key-memuse'),
|
||||||
renameKey: Api.newPost('/redis/{id}/{db}/rename-key'),
|
renameKey: Api.newPost('/redis/{id}/{db}/rename-key'),
|
||||||
expireKey: Api.newPost('/redis/{id}/{db}/expire-key'),
|
expireKey: Api.newPost('/redis/{id}/{db}/expire-key'),
|
||||||
persistKey: Api.newDelete('/redis/{id}/{db}/persist-key'),
|
persistKey: Api.newDelete('/redis/{id}/{db}/persist-key'),
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ require (
|
|||||||
github.com/pkg/errors v0.9.1
|
github.com/pkg/errors v0.9.1
|
||||||
github.com/pkg/sftp v1.13.6
|
github.com/pkg/sftp v1.13.6
|
||||||
github.com/pquerna/otp v1.4.0
|
github.com/pquerna/otp v1.4.0
|
||||||
github.com/redis/go-redis/v9 v9.2.1
|
github.com/redis/go-redis/v9 v9.3.0
|
||||||
github.com/robfig/cron/v3 v3.0.1 // 定时任务
|
github.com/robfig/cron/v3 v3.0.1 // 定时任务
|
||||||
github.com/stretchr/testify v1.8.4
|
github.com/stretchr/testify v1.8.4
|
||||||
go.mongodb.org/mongo-driver v1.12.1 // mongo
|
go.mongodb.org/mongo-driver v1.12.1 // mongo
|
||||||
|
|||||||
@@ -83,34 +83,6 @@ func (d *Db) DeleteDb(rc *req.Ctx) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Db) getDbConn(g *gin.Context) *dbm.DbConn {
|
|
||||||
dc, err := d.DbApp.GetDbConn(getDbId(g), getDbName(g))
|
|
||||||
biz.ErrIsNil(err)
|
|
||||||
return dc
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Db) TableInfos(rc *req.Ctx) {
|
|
||||||
res, err := d.getDbConn(rc.GinCtx).GetMeta().GetTableInfos()
|
|
||||||
biz.ErrIsNilAppendErr(err, "获取表信息失败: %s")
|
|
||||||
rc.ResData = res
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Db) TableIndex(rc *req.Ctx) {
|
|
||||||
tn := rc.GinCtx.Query("tableName")
|
|
||||||
biz.NotEmpty(tn, "tableName不能为空")
|
|
||||||
res, err := d.getDbConn(rc.GinCtx).GetMeta().GetTableIndex(tn)
|
|
||||||
biz.ErrIsNilAppendErr(err, "获取表索引信息失败: %s")
|
|
||||||
rc.ResData = res
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Db) GetCreateTableDdl(rc *req.Ctx) {
|
|
||||||
tn := rc.GinCtx.Query("tableName")
|
|
||||||
biz.NotEmpty(tn, "tableName不能为空")
|
|
||||||
res, err := d.getDbConn(rc.GinCtx).GetMeta().GetCreateTableDdl(tn)
|
|
||||||
biz.ErrIsNilAppendErr(err, "获取表ddl失败: %s")
|
|
||||||
rc.ResData = res
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Db) ExecSql(rc *req.Ctx) {
|
func (d *Db) ExecSql(rc *req.Ctx) {
|
||||||
g := rc.GinCtx
|
g := rc.GinCtx
|
||||||
form := &form.DbSqlExecForm{}
|
form := &form.DbSqlExecForm{}
|
||||||
@@ -348,7 +320,7 @@ func (d *Db) dumpDb(writer *gzipWriter, dbId uint64, dbName string, tables []str
|
|||||||
|
|
||||||
dbMeta := dbConn.GetMeta()
|
dbMeta := dbConn.GetMeta()
|
||||||
if len(tables) == 0 {
|
if len(tables) == 0 {
|
||||||
ti, err := dbMeta.GetTableInfos()
|
ti, err := dbMeta.GetTables()
|
||||||
biz.ErrIsNil(err)
|
biz.ErrIsNil(err)
|
||||||
tables = make([]string, len(ti))
|
tables = make([]string, len(ti))
|
||||||
for i, table := range ti {
|
for i, table := range ti {
|
||||||
@@ -396,11 +368,17 @@ func (d *Db) dumpDb(writer *gzipWriter, dbId uint64, dbName string, tables []str
|
|||||||
writer.WriteString(dbConn.Info.Type.StmtSetForeignKeyChecks(true))
|
writer.WriteString(dbConn.Info.Type.StmtSetForeignKeyChecks(true))
|
||||||
}
|
}
|
||||||
|
|
||||||
// @router /api/db/:dbId/t-metadata [get]
|
func (d *Db) TableInfos(rc *req.Ctx) {
|
||||||
func (d *Db) TableMA(rc *req.Ctx) {
|
res, err := d.getDbConn(rc.GinCtx).GetMeta().GetTables()
|
||||||
dbi := d.getDbConn(rc.GinCtx)
|
biz.ErrIsNilAppendErr(err, "获取表信息失败: %s")
|
||||||
res, err := dbi.GetMeta().GetTables()
|
rc.ResData = res
|
||||||
biz.ErrIsNilAppendErr(err, "获取表基础信息失败: %s")
|
}
|
||||||
|
|
||||||
|
func (d *Db) TableIndex(rc *req.Ctx) {
|
||||||
|
tn := rc.GinCtx.Query("tableName")
|
||||||
|
biz.NotEmpty(tn, "tableName不能为空")
|
||||||
|
res, err := d.getDbConn(rc.GinCtx).GetMeta().GetTableIndex(tn)
|
||||||
|
biz.ErrIsNilAppendErr(err, "获取表索引信息失败: %s")
|
||||||
rc.ResData = res
|
rc.ResData = res
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -458,6 +436,14 @@ func (d *Db) HintTables(rc *req.Ctx) {
|
|||||||
rc.ResData = res
|
rc.ResData = res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *Db) GetCreateTableDdl(rc *req.Ctx) {
|
||||||
|
tn := rc.GinCtx.Query("tableName")
|
||||||
|
biz.NotEmpty(tn, "tableName不能为空")
|
||||||
|
res, err := d.getDbConn(rc.GinCtx).GetMeta().GetCreateTableDdl(tn)
|
||||||
|
biz.ErrIsNilAppendErr(err, "获取表ddl失败: %s")
|
||||||
|
rc.ResData = res
|
||||||
|
}
|
||||||
|
|
||||||
// @router /api/db/:dbId/sql [post]
|
// @router /api/db/:dbId/sql [post]
|
||||||
func (d *Db) SaveSql(rc *req.Ctx) {
|
func (d *Db) SaveSql(rc *req.Ctx) {
|
||||||
g := rc.GinCtx
|
g := rc.GinCtx
|
||||||
@@ -536,3 +522,9 @@ func getDbName(g *gin.Context) string {
|
|||||||
biz.NotEmpty(db, "db不能为空")
|
biz.NotEmpty(db, "db不能为空")
|
||||||
return db
|
return db
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *Db) getDbConn(g *gin.Context) *dbm.DbConn {
|
||||||
|
dc, err := d.DbApp.GetDbConn(getDbId(g), getDbName(g))
|
||||||
|
biz.ErrIsNil(err)
|
||||||
|
return dc
|
||||||
|
}
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ type Index struct {
|
|||||||
// 数据库元信息接口(表、列、获取表数据等元信息)
|
// 数据库元信息接口(表、列、获取表数据等元信息)
|
||||||
type DbMetadata interface {
|
type DbMetadata interface {
|
||||||
|
|
||||||
// 获取表基础元信息
|
// 获取表信息
|
||||||
GetTables() ([]Table, error)
|
GetTables() ([]Table, error)
|
||||||
|
|
||||||
// 获取指定表名的所有列元信息
|
// 获取指定表名的所有列元信息
|
||||||
@@ -52,8 +52,8 @@ type DbMetadata interface {
|
|||||||
// 获取表主键字段名,没有主键标识则默认第一个字段
|
// 获取表主键字段名,没有主键标识则默认第一个字段
|
||||||
GetPrimaryKey(tablename string) (string, error)
|
GetPrimaryKey(tablename string) (string, error)
|
||||||
|
|
||||||
// 获取表信息,比GetTables获取更详细的表信息
|
// // 获取表信息,比GetTables获取更详细的表信息
|
||||||
GetTableInfos() ([]Table, error)
|
// GetTableInfos() ([]Table, error)
|
||||||
|
|
||||||
// 获取表索引信息
|
// 获取表索引信息
|
||||||
GetTableIndex(tableName string) ([]Index, error)
|
GetTableIndex(tableName string) ([]Index, error)
|
||||||
|
|||||||
@@ -1,15 +1,3 @@
|
|||||||
--MYSQL_TABLE_MA 表信息元数据
|
|
||||||
SELECT
|
|
||||||
table_name tableName,
|
|
||||||
table_comment tableComment
|
|
||||||
from
|
|
||||||
information_schema.tables
|
|
||||||
WHERE
|
|
||||||
table_schema = (
|
|
||||||
SELECT
|
|
||||||
database ()
|
|
||||||
)
|
|
||||||
---------------------------------------
|
|
||||||
--MYSQL_TABLE_INFO 表详细信息
|
--MYSQL_TABLE_INFO 表详细信息
|
||||||
SELECT
|
SELECT
|
||||||
table_name tableName,
|
table_name tableName,
|
||||||
@@ -21,7 +9,8 @@ SELECT
|
|||||||
FROM
|
FROM
|
||||||
information_schema.tables
|
information_schema.tables
|
||||||
WHERE
|
WHERE
|
||||||
table_schema = (
|
table_type = 'BASE TABLE'
|
||||||
|
AND table_schema = (
|
||||||
SELECT
|
SELECT
|
||||||
database ()
|
database ()
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,33 +1,22 @@
|
|||||||
--PGSQL_TABLE_MA 表信息元数据
|
|
||||||
SELECT
|
|
||||||
obj_description (c.oid) AS "tableComment",
|
|
||||||
c.relname AS "tableName"
|
|
||||||
FROM
|
|
||||||
pg_class c
|
|
||||||
JOIN pg_namespace n ON c.relnamespace = n.oid
|
|
||||||
WHERE
|
|
||||||
n.nspname = (
|
|
||||||
select
|
|
||||||
current_schema ()
|
|
||||||
)
|
|
||||||
AND c.reltype > 0
|
|
||||||
---------------------------------------
|
|
||||||
--PGSQL_TABLE_INFO 表详细信息
|
--PGSQL_TABLE_INFO 表详细信息
|
||||||
SELECT
|
select
|
||||||
obj_description (c.oid) AS "tableComment",
|
c.relname as "tableName",
|
||||||
c.relname AS "tableName",
|
obj_description (c.oid) as "tableComment",
|
||||||
pg_table_size ('"' || n.nspname || '"."' || c.relname || '"') as "dataLength",
|
pg_table_size ('"' || n.nspname || '"."' || c.relname || '"') as "dataLength",
|
||||||
pg_indexes_size ('"' || n.nspname || '"."' || c.relname || '"') as "indexLength",
|
pg_indexes_size ('"' || n.nspname || '"."' || c.relname || '"') as "indexLength",
|
||||||
c.reltuples as "tableRows"
|
psut.n_live_tup as "tableRows"
|
||||||
FROM
|
from
|
||||||
pg_class c
|
pg_class c
|
||||||
JOIN pg_namespace n ON c.relnamespace = n.oid
|
join pg_namespace n on
|
||||||
WHERE
|
c.relnamespace = n.oid
|
||||||
n.nspname = (
|
join pg_stat_user_tables psut on
|
||||||
select
|
psut.relid = c."oid"
|
||||||
current_schema ()
|
where
|
||||||
|
n.nspname = (
|
||||||
|
select
|
||||||
|
current_schema ()
|
||||||
)
|
)
|
||||||
AND c.reltype > 0
|
and c.reltype > 0
|
||||||
---------------------------------------
|
---------------------------------------
|
||||||
--PGSQL_INDEX_INFO 表索引信息
|
--PGSQL_INDEX_INFO 表索引信息
|
||||||
SELECT
|
SELECT
|
||||||
|
|||||||
@@ -34,7 +34,6 @@ func getMysqlDB(d *DbInfo) (*sql.DB, error) {
|
|||||||
// ---------------------------------- mysql元数据 -----------------------------------
|
// ---------------------------------- mysql元数据 -----------------------------------
|
||||||
const (
|
const (
|
||||||
MYSQL_META_FILE = "metasql/mysql_meta.sql"
|
MYSQL_META_FILE = "metasql/mysql_meta.sql"
|
||||||
MYSQL_TABLE_MA_KEY = "MYSQL_TABLE_MA"
|
|
||||||
MYSQL_TABLE_INFO_KEY = "MYSQL_TABLE_INFO"
|
MYSQL_TABLE_INFO_KEY = "MYSQL_TABLE_INFO"
|
||||||
MYSQL_INDEX_INFO_KEY = "MYSQL_INDEX_INFO"
|
MYSQL_INDEX_INFO_KEY = "MYSQL_INDEX_INFO"
|
||||||
MYSQL_COLUMN_MA_KEY = "MYSQL_COLUMN_MA"
|
MYSQL_COLUMN_MA_KEY = "MYSQL_COLUMN_MA"
|
||||||
@@ -46,7 +45,7 @@ type MysqlMetadata struct {
|
|||||||
|
|
||||||
// 获取表基础元信息, 如表名等
|
// 获取表基础元信息, 如表名等
|
||||||
func (mm *MysqlMetadata) GetTables() ([]Table, error) {
|
func (mm *MysqlMetadata) GetTables() ([]Table, error) {
|
||||||
_, res, err := mm.dc.SelectData(GetLocalSql(MYSQL_META_FILE, MYSQL_TABLE_MA_KEY))
|
_, res, err := mm.dc.SelectData(GetLocalSql(MYSQL_META_FILE, MYSQL_TABLE_INFO_KEY))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -56,6 +55,10 @@ func (mm *MysqlMetadata) GetTables() ([]Table, error) {
|
|||||||
tables = append(tables, Table{
|
tables = append(tables, Table{
|
||||||
TableName: re["tableName"].(string),
|
TableName: re["tableName"].(string),
|
||||||
TableComment: anyx.ConvString(re["tableComment"]),
|
TableComment: anyx.ConvString(re["tableComment"]),
|
||||||
|
CreateTime: anyx.ConvString(re["createTime"]),
|
||||||
|
TableRows: anyx.ConvInt(re["tableRows"]),
|
||||||
|
DataLength: anyx.ConvInt64(re["dataLength"]),
|
||||||
|
IndexLength: anyx.ConvInt64(re["indexLength"]),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return tables, nil
|
return tables, nil
|
||||||
@@ -110,27 +113,6 @@ func (mm *MysqlMetadata) GetPrimaryKey(tablename string) (string, error) {
|
|||||||
return columns[0].ColumnName, nil
|
return columns[0].ColumnName, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取表信息,比GetTableMetedatas获取更详细的表信息
|
|
||||||
func (mm *MysqlMetadata) GetTableInfos() ([]Table, error) {
|
|
||||||
_, res, err := mm.dc.SelectData(GetLocalSql(MYSQL_META_FILE, MYSQL_TABLE_INFO_KEY))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
tables := make([]Table, 0)
|
|
||||||
for _, re := range res {
|
|
||||||
tables = append(tables, Table{
|
|
||||||
TableName: re["tableName"].(string),
|
|
||||||
TableComment: anyx.ConvString(re["tableComment"]),
|
|
||||||
CreateTime: anyx.ConvString(re["createTime"]),
|
|
||||||
TableRows: anyx.ConvInt(re["tableRows"]),
|
|
||||||
DataLength: anyx.ConvInt64(re["dataLength"]),
|
|
||||||
IndexLength: anyx.ConvInt64(re["indexLength"]),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return tables, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取表索引信息
|
// 获取表索引信息
|
||||||
func (mm *MysqlMetadata) GetTableIndex(tableName string) ([]Index, error) {
|
func (mm *MysqlMetadata) GetTableIndex(tableName string) ([]Index, error) {
|
||||||
_, res, err := mm.dc.SelectData(fmt.Sprintf(GetLocalSql(MYSQL_META_FILE, MYSQL_INDEX_INFO_KEY), tableName))
|
_, res, err := mm.dc.SelectData(fmt.Sprintf(GetLocalSql(MYSQL_META_FILE, MYSQL_INDEX_INFO_KEY), tableName))
|
||||||
|
|||||||
@@ -67,7 +67,6 @@ func (pd *PqSqlDialer) DialTimeout(network, address string, timeout time.Duratio
|
|||||||
// ---------------------------------- pgsql元数据 -----------------------------------
|
// ---------------------------------- pgsql元数据 -----------------------------------
|
||||||
const (
|
const (
|
||||||
PGSQL_META_FILE = "metasql/pgsql_meta.sql"
|
PGSQL_META_FILE = "metasql/pgsql_meta.sql"
|
||||||
PGSQL_TABLE_MA_KEY = "PGSQL_TABLE_MA"
|
|
||||||
PGSQL_TABLE_INFO_KEY = "PGSQL_TABLE_INFO"
|
PGSQL_TABLE_INFO_KEY = "PGSQL_TABLE_INFO"
|
||||||
PGSQL_INDEX_INFO_KEY = "PGSQL_INDEX_INFO"
|
PGSQL_INDEX_INFO_KEY = "PGSQL_INDEX_INFO"
|
||||||
PGSQL_COLUMN_MA_KEY = "PGSQL_COLUMN_MA"
|
PGSQL_COLUMN_MA_KEY = "PGSQL_COLUMN_MA"
|
||||||
@@ -80,7 +79,7 @@ type PgsqlMetadata struct {
|
|||||||
|
|
||||||
// 获取表基础元信息, 如表名等
|
// 获取表基础元信息, 如表名等
|
||||||
func (pm *PgsqlMetadata) GetTables() ([]Table, error) {
|
func (pm *PgsqlMetadata) GetTables() ([]Table, error) {
|
||||||
_, res, err := pm.dc.SelectData(GetLocalSql(PGSQL_META_FILE, PGSQL_TABLE_MA_KEY))
|
_, res, err := pm.dc.SelectData(GetLocalSql(PGSQL_META_FILE, PGSQL_TABLE_INFO_KEY))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -90,6 +89,10 @@ func (pm *PgsqlMetadata) GetTables() ([]Table, error) {
|
|||||||
tables = append(tables, Table{
|
tables = append(tables, Table{
|
||||||
TableName: re["tableName"].(string),
|
TableName: re["tableName"].(string),
|
||||||
TableComment: anyx.ConvString(re["tableComment"]),
|
TableComment: anyx.ConvString(re["tableComment"]),
|
||||||
|
CreateTime: anyx.ConvString(re["createTime"]),
|
||||||
|
TableRows: anyx.ConvInt(re["tableRows"]),
|
||||||
|
DataLength: anyx.ConvInt64(re["dataLength"]),
|
||||||
|
IndexLength: anyx.ConvInt64(re["indexLength"]),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return tables, nil
|
return tables, nil
|
||||||
@@ -142,27 +145,6 @@ func (pm *PgsqlMetadata) GetPrimaryKey(tablename string) (string, error) {
|
|||||||
return columns[0].ColumnName, nil
|
return columns[0].ColumnName, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取表信息,比GetTables获取更详细的表信息
|
|
||||||
func (pm *PgsqlMetadata) GetTableInfos() ([]Table, error) {
|
|
||||||
_, res, err := pm.dc.SelectData(GetLocalSql(PGSQL_META_FILE, PGSQL_TABLE_INFO_KEY))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
tables := make([]Table, 0)
|
|
||||||
for _, re := range res {
|
|
||||||
tables = append(tables, Table{
|
|
||||||
TableName: re["tableName"].(string),
|
|
||||||
TableComment: anyx.ConvString(re["tableComment"]),
|
|
||||||
CreateTime: anyx.ConvString(re["createTime"]),
|
|
||||||
TableRows: anyx.ConvInt(re["tableRows"]),
|
|
||||||
DataLength: anyx.ConvInt64(re["dataLength"]),
|
|
||||||
IndexLength: anyx.ConvInt64(re["indexLength"]),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return tables, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取表索引信息
|
// 获取表索引信息
|
||||||
func (pm *PgsqlMetadata) GetTableIndex(tableName string) ([]Index, error) {
|
func (pm *PgsqlMetadata) GetTableIndex(tableName string) ([]Index, error) {
|
||||||
_, res, err := pm.dc.SelectData(fmt.Sprintf(GetLocalSql(PGSQL_META_FILE, PGSQL_INDEX_INFO_KEY), tableName))
|
_, res, err := pm.dc.SelectData(fmt.Sprintf(GetLocalSql(PGSQL_META_FILE, PGSQL_INDEX_INFO_KEY), tableName))
|
||||||
|
|||||||
@@ -31,10 +31,6 @@ func InitDbRouter(router *gin.RouterGroup) {
|
|||||||
|
|
||||||
req.NewDelete(":dbId", d.DeleteDb).Log(req.NewLogSave("db-删除数据库信息")),
|
req.NewDelete(":dbId", d.DeleteDb).Log(req.NewLogSave("db-删除数据库信息")),
|
||||||
|
|
||||||
req.NewGet(":dbId/t-infos", d.TableInfos),
|
|
||||||
|
|
||||||
req.NewGet(":dbId/t-index", d.TableIndex),
|
|
||||||
|
|
||||||
req.NewGet(":dbId/t-create-ddl", d.GetCreateTableDdl),
|
req.NewGet(":dbId/t-create-ddl", d.GetCreateTableDdl),
|
||||||
|
|
||||||
req.NewPost(":dbId/exec-sql", d.ExecSql).Log(req.NewLog("db-执行Sql")),
|
req.NewPost(":dbId/exec-sql", d.ExecSql).Log(req.NewLog("db-执行Sql")),
|
||||||
@@ -43,7 +39,9 @@ func InitDbRouter(router *gin.RouterGroup) {
|
|||||||
|
|
||||||
req.NewGet(":dbId/dump", d.DumpSql).Log(req.NewLogSave("db-导出sql文件")).NoRes(),
|
req.NewGet(":dbId/dump", d.DumpSql).Log(req.NewLogSave("db-导出sql文件")).NoRes(),
|
||||||
|
|
||||||
req.NewGet(":dbId/t-metadata", d.TableMA),
|
req.NewGet(":dbId/t-infos", d.TableInfos),
|
||||||
|
|
||||||
|
req.NewGet(":dbId/t-index", d.TableIndex),
|
||||||
|
|
||||||
req.NewGet(":dbId/c-metadata", d.ColumnMA),
|
req.NewGet(":dbId/c-metadata", d.ColumnMA),
|
||||||
|
|
||||||
|
|||||||
@@ -66,7 +66,8 @@ func (m *MachineScript) RunMachineScript(rc *req.Ctx) {
|
|||||||
script := ms.Script
|
script := ms.Script
|
||||||
// 如果有脚本参数,则用脚本参数替换脚本中的模板占位符参数
|
// 如果有脚本参数,则用脚本参数替换脚本中的模板占位符参数
|
||||||
if params := g.Query("params"); params != "" {
|
if params := g.Query("params"); params != "" {
|
||||||
script = stringx.TemplateParse(ms.Script, jsonx.ToMap(params))
|
script, err = stringx.TemplateParse(ms.Script, jsonx.ToMap(params))
|
||||||
|
biz.ErrIsNilAppendErr(err, "脚本模板参数解析失败: %s")
|
||||||
}
|
}
|
||||||
cli, err := m.MachineApp.GetCli(machineId)
|
cli, err := m.MachineApp.GetCli(machineId)
|
||||||
biz.ErrIsNilAppendErr(err, "获取客户端连接失败: %s")
|
biz.ErrIsNilAppendErr(err, "获取客户端连接失败: %s")
|
||||||
|
|||||||
@@ -131,6 +131,11 @@ func (r *Redis) TtlKey(rc *req.Ctx) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *Redis) MemoryUsage(rc *req.Ctx) {
|
||||||
|
ri, key := r.checkKeyAndGetRedisConn(rc)
|
||||||
|
rc.ResData = ri.GetCmdable().MemoryUsage(context.Background(), key).Val()
|
||||||
|
}
|
||||||
|
|
||||||
func (r *Redis) DeleteKey(rc *req.Ctx) {
|
func (r *Redis) DeleteKey(rc *req.Ctx) {
|
||||||
ri, key := r.checkKeyAndGetRedisConn(rc)
|
ri, key := r.checkKeyAndGetRedisConn(rc)
|
||||||
rc.ReqParam = collx.Kvs("redis", ri.Info, "key", key)
|
rc.ReqParam = collx.Kvs("redis", ri.Info, "key", key)
|
||||||
|
|||||||
@@ -45,6 +45,8 @@ func InitRedisRouter(router *gin.RouterGroup) {
|
|||||||
|
|
||||||
req.NewGet(":id/:db/key-ttl", rs.TtlKey),
|
req.NewGet(":id/:db/key-ttl", rs.TtlKey),
|
||||||
|
|
||||||
|
req.NewGet(":id/:db/key-memuse", rs.MemoryUsage),
|
||||||
|
|
||||||
req.NewDelete(":id/:db/key", rs.DeleteKey).Log(req.NewLogSave("redis-删除key")).RequiredPermission(deleteDataP),
|
req.NewDelete(":id/:db/key", rs.DeleteKey).Log(req.NewLogSave("redis-删除key")).RequiredPermission(deleteDataP),
|
||||||
|
|
||||||
req.NewPost(":id/:db/rename-key", rs.RenameKey).Log(req.NewLogSave("redis-重命名key")).RequiredPermission(saveDataP),
|
req.NewPost(":id/:db/rename-key", rs.RenameKey).Log(req.NewLogSave("redis-重命名key")).RequiredPermission(saveDataP),
|
||||||
|
|||||||
@@ -5,24 +5,24 @@ import (
|
|||||||
"text/template"
|
"text/template"
|
||||||
)
|
)
|
||||||
|
|
||||||
func parse(t *template.Template, vars any) string {
|
func parse(t *template.Template, vars any) (string, error) {
|
||||||
var tmplBytes bytes.Buffer
|
var tmplBytes bytes.Buffer
|
||||||
|
|
||||||
err := t.Execute(&tmplBytes, vars)
|
err := t.Execute(&tmplBytes, vars)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
return "", err
|
||||||
}
|
}
|
||||||
return tmplBytes.String()
|
return tmplBytes.String(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// 模板字符串解析
|
// 模板字符串解析
|
||||||
// @param str 模板字符串
|
// @param str 模板字符串
|
||||||
// @param vars 参数变量
|
// @param vars 参数变量
|
||||||
func TemplateParse(str string, vars any) string {
|
func TemplateParse(str string, vars any) (string, error) {
|
||||||
tmpl, err := template.New("tmpl").Parse(str)
|
tmpl, err := template.New("tmpl").Parse(str)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
return "", err
|
||||||
}
|
}
|
||||||
return parse(tmpl, vars)
|
return parse(tmpl, vars)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user