mirror of
https://gitee.com/dromara/mayfly-go
synced 2025-11-06 17:30:25 +08:00
!97 一些优化
* refactor: 重构表格分页组件,适配大数据量分页 * fix:定时任务修复 * feat: gaussdb单独提出来
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -81,6 +81,13 @@
|
|||||||
"font_class": "MSSQLNATIVE",
|
"font_class": "MSSQLNATIVE",
|
||||||
"unicode": "e600",
|
"unicode": "e600",
|
||||||
"unicode_decimal": 58880
|
"unicode_decimal": 58880
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "7699332",
|
||||||
|
"name": "gaussdb",
|
||||||
|
"font_class": "gauss",
|
||||||
|
"unicode": "e683",
|
||||||
|
"unicode_decimal": 59011
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,13 +9,18 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item prop="type" label="类型" required>
|
<el-form-item prop="type" label="类型" required>
|
||||||
<el-select @change="changeDbType" style="width: 100%" v-model="form.type" placeholder="请选择数据库类型">
|
<el-select @change="changeDbType" style="width: 100%" v-model="form.type" placeholder="请选择数据库类型">
|
||||||
<el-option v-for="(dbTypeAndDialect, key) in getDbDialectMap()" :key="key" :value="dbTypeAndDialect[0]">
|
<el-option
|
||||||
<SvgIcon :name="dbTypeAndDialect[1].getInfo().icon" :size="18" />
|
v-for="(dbTypeAndDialect, key) in getDbDialectMap()"
|
||||||
|
:key="key"
|
||||||
|
:value="dbTypeAndDialect[0]"
|
||||||
|
:label="dbTypeAndDialect[1].getInfo().name"
|
||||||
|
>
|
||||||
|
<SvgIcon :name="dbTypeAndDialect[1].getInfo().icon" :size="20" />
|
||||||
{{ dbTypeAndDialect[1].getInfo().name }}
|
{{ dbTypeAndDialect[1].getInfo().name }}
|
||||||
</el-option>
|
</el-option>
|
||||||
|
|
||||||
<template #prefix>
|
<template #prefix>
|
||||||
<SvgIcon :name="getDbDialect(form.type).getInfo().icon" :size="18" />
|
<SvgIcon :name="getDbDialect(form.type).getInfo().icon" :size="20" />
|
||||||
</template>
|
</template>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|||||||
@@ -443,7 +443,7 @@ onBeforeUnmount(() => {
|
|||||||
* 设置editor高度和数据表高度
|
* 设置editor高度和数据表高度
|
||||||
*/
|
*/
|
||||||
const setHeight = () => {
|
const setHeight = () => {
|
||||||
state.dataTabsTableHeight = window.innerHeight - 270 + 'px';
|
state.dataTabsTableHeight = window.innerHeight - 253 + 'px';
|
||||||
state.tablesOpHeight = window.innerHeight - 225 + 'px';
|
state.tablesOpHeight = window.innerHeight - 225 + 'px';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -158,21 +158,62 @@
|
|||||||
@data-delete="onRefresh"
|
@data-delete="onRefresh"
|
||||||
></db-table-data>
|
></db-table-data>
|
||||||
|
|
||||||
<el-row type="flex" class="mt5" justify="center">
|
<el-row type="flex" class="mt5" :gutter="10" justify="end" style="user-select: none">
|
||||||
<el-pagination
|
<el-col :span="12">
|
||||||
small
|
<el-text
|
||||||
:total="count"
|
style="color: var(--el-color-info-light-3); font-size: 12px; margin-top: 5px"
|
||||||
@size-change="handleSizeChange"
|
class="is-truncated"
|
||||||
@current-change="pageChange()"
|
@click="handleCopySql(sql)"
|
||||||
layout="prev, pager, next, total, sizes, jumper"
|
:title="sql"
|
||||||
v-model:current-page="pageNum"
|
>{{ sql }}</el-text
|
||||||
v-model:page-size="pageSize"
|
>
|
||||||
:page-sizes="pageSizes"
|
</el-col>
|
||||||
></el-pagination>
|
<el-col :span="12">
|
||||||
|
<el-row :gutter="10" justify="center">
|
||||||
|
<el-link class="op-page" :underline="false" @click="pageNum = 1" :disabled="pageNum == 1" icon="DArrowLeft" title="首页" />
|
||||||
|
<el-link class="op-page" :underline="false" @click="pageNum = --pageNum || 1" :disabled="pageNum == 1" icon="Back" title="上一页" />
|
||||||
|
<div class="op-page">
|
||||||
|
<el-input-number
|
||||||
|
style="width: 50px"
|
||||||
|
:controls="false"
|
||||||
|
:min="1"
|
||||||
|
v-model="state.setPageNum"
|
||||||
|
size="small"
|
||||||
|
@blur="handleSetPageNum"
|
||||||
|
@keydown.enter="handleSetPageNum"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<el-link class="op-page" :underline="false" @click="++pageNum" icon="Right" />
|
||||||
|
<el-link class="op-page" :underline="false" @click="handleEndPage" icon="DArrowRight" />
|
||||||
|
<div style="width: 90px; margin-left: 20px" class="op-page">
|
||||||
|
<el-select size="small" :default-first-option="true" v-model="pageSize" @change="handleSizeChange">
|
||||||
|
<el-option
|
||||||
|
style="font-size: 12px; height: 24px; line-height: 24px"
|
||||||
|
v-for="(op, i) in pageSizes"
|
||||||
|
:key="i"
|
||||||
|
:label="op + '条/页'"
|
||||||
|
:value="op"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</div>
|
||||||
|
<el-link
|
||||||
|
class="op-page"
|
||||||
|
style="margin-left: 20px"
|
||||||
|
v-if="!state.counting"
|
||||||
|
:underline="false"
|
||||||
|
@click="handleCount"
|
||||||
|
icon="Stopwatch"
|
||||||
|
title="计数"
|
||||||
|
/>
|
||||||
|
<el-link class="op-page" style="margin-left: 20px" v-if="state.counting" :underline="false" title="计数中...">
|
||||||
|
<el-icon class="is-loading">
|
||||||
|
<Loading />
|
||||||
|
</el-icon>
|
||||||
|
</el-link>
|
||||||
|
<el-text class="op-page" style="font-size: 12px" v-if="state.showTotal">总 {{ state.total }} 条</el-text>
|
||||||
|
</el-row>
|
||||||
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
<div style="padding: 0 10px">
|
|
||||||
<span style="color: var(--el-color-info-light-3)" class="font10 el-text el-text--small is-truncated">{{ state.sql }}</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<el-dialog v-model="conditionDialog.visible" :title="conditionDialog.title" width="420px">
|
<el-dialog v-model="conditionDialog.visible" :title="conditionDialog.title" width="420px">
|
||||||
<el-row>
|
<el-row>
|
||||||
@@ -242,6 +283,7 @@ import { DbDialect, getDbDialect } from '@/views/ops/db/dialect';
|
|||||||
import SvgIcon from '@/components/svgIcon/index.vue';
|
import SvgIcon from '@/components/svgIcon/index.vue';
|
||||||
import ColumnFormItem from './ColumnFormItem.vue';
|
import ColumnFormItem from './ColumnFormItem.vue';
|
||||||
import { useEventListener, useStorage } from '@vueuse/core';
|
import { useEventListener, useStorage } from '@vueuse/core';
|
||||||
|
import { copyToClipboard } from '@/common/utils/string';
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
dbId: {
|
dbId: {
|
||||||
@@ -290,7 +332,10 @@ const state = reactive({
|
|||||||
defaultPageSize * 40,
|
defaultPageSize * 40,
|
||||||
defaultPageSize * 80,
|
defaultPageSize * 80,
|
||||||
],
|
],
|
||||||
count: 0,
|
setPageNum: 0,
|
||||||
|
total: 0,
|
||||||
|
showTotal: 0,
|
||||||
|
counting: false,
|
||||||
selectionDatas: [] as any,
|
selectionDatas: [] as any,
|
||||||
condPopVisible: false,
|
condPopVisible: false,
|
||||||
columnNameSearch: '',
|
columnNameSearch: '',
|
||||||
@@ -314,7 +359,7 @@ const state = reactive({
|
|||||||
dbDialect: {} as DbDialect,
|
dbDialect: {} as DbDialect,
|
||||||
});
|
});
|
||||||
|
|
||||||
const { datas, condition, loading, columns, pageNum, pageSize, pageSizes, count, hasUpdatedFileds, conditionDialog, addDataDialog, dbDialect } = toRefs(state);
|
const { datas, condition, loading, columns, pageNum, pageSize, pageSizes, sql, hasUpdatedFileds, conditionDialog, addDataDialog, dbDialect } = toRefs(state);
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => props.tableHeight,
|
() => props.tableHeight,
|
||||||
@@ -347,18 +392,19 @@ const onRefresh = async () => {
|
|||||||
await selectData();
|
await selectData();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
watch(
|
||||||
* 数据tab修改页数
|
() => state.pageNum,
|
||||||
*/
|
async () => {
|
||||||
const pageChange = async () => {
|
await selectData();
|
||||||
await selectData();
|
}
|
||||||
};
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 单表数据信息查询数据
|
* 单表数据信息查询数据
|
||||||
*/
|
*/
|
||||||
const selectData = async () => {
|
const selectData = async () => {
|
||||||
state.loading = true;
|
state.loading = true;
|
||||||
|
state.setPageNum = state.pageNum;
|
||||||
const dbInst = getNowDbInst();
|
const dbInst = getNowDbInst();
|
||||||
const db = props.dbName;
|
const db = props.dbName;
|
||||||
const table = props.tableName;
|
const table = props.tableName;
|
||||||
@@ -371,16 +417,10 @@ const selectData = async () => {
|
|||||||
state.columns = columns;
|
state.columns = columns;
|
||||||
}
|
}
|
||||||
|
|
||||||
const countRes = await dbInst.runSql(db, dbInst.getDefaultCountSql(table, state.condition));
|
|
||||||
state.count = parseInt(countRes.res[0].count || countRes.res[0].COUNT || 0);
|
|
||||||
let sql = dbInst.getDefaultSelectSql(db, table, state.condition, state.orderBy, state.pageNum, state.pageSize);
|
let sql = dbInst.getDefaultSelectSql(db, table, state.condition, state.orderBy, state.pageNum, state.pageSize);
|
||||||
state.sql = sql;
|
state.sql = sql;
|
||||||
if (state.count > 0) {
|
const colAndData: any = await dbInst.runSql(db, sql);
|
||||||
const colAndData: any = await dbInst.runSql(db, sql);
|
state.datas = colAndData.res;
|
||||||
state.datas = colAndData.res;
|
|
||||||
} else {
|
|
||||||
state.datas = [];
|
|
||||||
}
|
|
||||||
} finally {
|
} finally {
|
||||||
state.loading = false;
|
state.loading = false;
|
||||||
}
|
}
|
||||||
@@ -392,6 +432,38 @@ const handleSizeChange = async (size: any) => {
|
|||||||
await selectData();
|
await selectData();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleEndPage = async () => {
|
||||||
|
await handleCount();
|
||||||
|
state.pageNum = Math.ceil(state.total / state.pageSize);
|
||||||
|
await selectData();
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSetPageNum = async () => {
|
||||||
|
state.pageNum = state.setPageNum;
|
||||||
|
await selectData();
|
||||||
|
};
|
||||||
|
const handleCount = async () => {
|
||||||
|
state.counting = true;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const db = props.dbName;
|
||||||
|
const table = props.tableName;
|
||||||
|
const dbInst = getNowDbInst();
|
||||||
|
const countRes = await dbInst.runSql(db, dbInst.getDefaultCountSql(table, state.condition));
|
||||||
|
state.total = parseInt(countRes.res[0].count || countRes.res[0].COUNT || 0);
|
||||||
|
state.showTotal = true;
|
||||||
|
} catch (e) {
|
||||||
|
/* empty */
|
||||||
|
}
|
||||||
|
|
||||||
|
state.counting = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleCopySql = async (sql: string) => {
|
||||||
|
await copyToClipboard(sql);
|
||||||
|
ElMessage.success('复制成功');
|
||||||
|
};
|
||||||
|
|
||||||
// 完整的条件,每次选中后会重置条件框内容,故需要这个变量在获取建议时将文本框内容保存
|
// 完整的条件,每次选中后会重置条件框内容,故需要这个变量在获取建议时将文本框内容保存
|
||||||
let completeCond = '';
|
let completeCond = '';
|
||||||
// 是否存在列建议
|
// 是否存在列建议
|
||||||
@@ -586,4 +658,8 @@ const addRow = async () => {
|
|||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss"></style>
|
<style lang="scss">
|
||||||
|
.op-page {
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
17
mayfly_go_web/src/views/ops/db/dialect/gauss_dialect.ts
Normal file
17
mayfly_go_web/src/views/ops/db/dialect/gauss_dialect.ts
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
import { PostgresqlDialect } from '@/views/ops/db/dialect/postgres_dialect';
|
||||||
|
import { DialectInfo } from '@/views/ops/db/dialect/index';
|
||||||
|
|
||||||
|
let gsDialectInfo: DialectInfo;
|
||||||
|
export class GaussDialect extends PostgresqlDialect {
|
||||||
|
getInfo(): DialectInfo {
|
||||||
|
if (gsDialectInfo) {
|
||||||
|
return gsDialectInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
gsDialectInfo = {} as DialectInfo;
|
||||||
|
Object.assign(gsDialectInfo, super.getInfo());
|
||||||
|
gsDialectInfo.icon = 'iconfont icon-gauss';
|
||||||
|
gsDialectInfo.name = 'GaussDB';
|
||||||
|
return gsDialectInfo;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,6 +5,7 @@ import { OracleDialect } from '@/views/ops/db/dialect/oracle_dialect';
|
|||||||
import { MariadbDialect } from '@/views/ops/db/dialect/mariadb_dialect';
|
import { MariadbDialect } from '@/views/ops/db/dialect/mariadb_dialect';
|
||||||
import { SqliteDialect } from '@/views/ops/db/dialect/sqlite_dialect';
|
import { SqliteDialect } from '@/views/ops/db/dialect/sqlite_dialect';
|
||||||
import { MssqlDialect } from '@/views/ops/db/dialect/mssql_dialect';
|
import { MssqlDialect } from '@/views/ops/db/dialect/mssql_dialect';
|
||||||
|
import { GaussDialect } from '@/views/ops/db/dialect/gauss_dialect';
|
||||||
|
|
||||||
export interface sqlColumnType {
|
export interface sqlColumnType {
|
||||||
udtName: string;
|
udtName: string;
|
||||||
@@ -116,6 +117,7 @@ export const DbType = {
|
|||||||
mysql: 'mysql',
|
mysql: 'mysql',
|
||||||
mariadb: 'mariadb',
|
mariadb: 'mariadb',
|
||||||
postgresql: 'postgres',
|
postgresql: 'postgres',
|
||||||
|
gauss: 'gauss',
|
||||||
dm: 'dm', // 达梦
|
dm: 'dm', // 达梦
|
||||||
oracle: 'oracle',
|
oracle: 'oracle',
|
||||||
sqlite: 'sqlite',
|
sqlite: 'sqlite',
|
||||||
@@ -126,7 +128,7 @@ export const DbType = {
|
|||||||
export const noSchemaTypes = [DbType.mysql, DbType.mariadb, DbType.sqlite];
|
export const noSchemaTypes = [DbType.mysql, DbType.mariadb, DbType.sqlite];
|
||||||
|
|
||||||
// 有schema层的数据库
|
// 有schema层的数据库
|
||||||
export const schemaDbTypes = [DbType.postgresql, DbType.dm, DbType.oracle, DbType.mssql];
|
export const schemaDbTypes = [DbType.postgresql, DbType.gauss, DbType.dm, DbType.oracle, DbType.mssql];
|
||||||
|
|
||||||
export const editDbTypes = [...noSchemaTypes, ...schemaDbTypes];
|
export const editDbTypes = [...noSchemaTypes, ...schemaDbTypes];
|
||||||
|
|
||||||
@@ -225,6 +227,7 @@ export const getDbDialect = (dbType: string): DbDialect => {
|
|||||||
registerDbDialect(DbType.mysql, mysqlDialect);
|
registerDbDialect(DbType.mysql, mysqlDialect);
|
||||||
registerDbDialect(DbType.mariadb, new MariadbDialect());
|
registerDbDialect(DbType.mariadb, new MariadbDialect());
|
||||||
registerDbDialect(DbType.postgresql, new PostgresqlDialect());
|
registerDbDialect(DbType.postgresql, new PostgresqlDialect());
|
||||||
|
registerDbDialect(DbType.gauss, new GaussDialect());
|
||||||
registerDbDialect(DbType.dm, new DMDialect());
|
registerDbDialect(DbType.dm, new DMDialect());
|
||||||
registerDbDialect(DbType.oracle, new OracleDialect());
|
registerDbDialect(DbType.oracle, new OracleDialect());
|
||||||
registerDbDialect(DbType.sqlite, new SqliteDialect());
|
registerDbDialect(DbType.sqlite, new SqliteDialect());
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/google/uuid"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type DataSyncTask struct {
|
type DataSyncTask struct {
|
||||||
@@ -46,13 +45,6 @@ func (d *DataSyncTask) SaveTask(rc *req.Ctx) {
|
|||||||
task.DataSql = sql
|
task.DataSql = sql
|
||||||
form.DataSql = sql
|
form.DataSql = sql
|
||||||
|
|
||||||
key := task.TaskKey
|
|
||||||
// 判断key为空就生成随机key
|
|
||||||
if key == "" {
|
|
||||||
key = uuid.New().String()
|
|
||||||
task.TaskKey = key
|
|
||||||
}
|
|
||||||
|
|
||||||
rc.ReqParam = form
|
rc.ReqParam = form
|
||||||
biz.ErrIsNil(d.DataSyncTaskApp.Save(rc.MetaCtx, task))
|
biz.ErrIsNil(d.DataSyncTaskApp.Save(rc.MetaCtx, task))
|
||||||
}
|
}
|
||||||
@@ -88,7 +80,7 @@ func (d *DataSyncTask) ChangeStatus(rc *req.Ctx) {
|
|||||||
func (d *DataSyncTask) Run(rc *req.Ctx) {
|
func (d *DataSyncTask) Run(rc *req.Ctx) {
|
||||||
taskId := getTaskId(rc.GinCtx)
|
taskId := getTaskId(rc.GinCtx)
|
||||||
rc.ReqParam = taskId
|
rc.ReqParam = taskId
|
||||||
d.DataSyncTaskApp.RunCronJob(taskId)
|
_ = d.DataSyncTaskApp.RunCronJob(taskId)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *DataSyncTask) Stop(rc *req.Ctx) {
|
func (d *DataSyncTask) Stop(rc *req.Ctx) {
|
||||||
|
|||||||
@@ -154,7 +154,7 @@ func (d *dbAppImpl) GetDbConn(dbId uint64, dbName string) (*dbi.DbConn, error) {
|
|||||||
|
|
||||||
checkDb := dbName
|
checkDb := dbName
|
||||||
// 兼容pgsql/dm db/schema模式
|
// 兼容pgsql/dm db/schema模式
|
||||||
if dbi.DbTypePostgres.Equal(instance.Type) || dbi.DbTypeDM.Equal(instance.Type) || dbi.DbTypeOracle.Equal(instance.Type) || dbi.DbTypeMssql.Equal(instance.Type) {
|
if dbi.DbTypePostgres.Equal(instance.Type) || dbi.DbTypeGauss.Equal(instance.Type) || dbi.DbTypeDM.Equal(instance.Type) || dbi.DbTypeOracle.Equal(instance.Type) || dbi.DbTypeMssql.Equal(instance.Type) {
|
||||||
ss := strings.Split(dbName, "/")
|
ss := strings.Split(dbName, "/")
|
||||||
if len(ss) > 1 {
|
if len(ss) > 1 {
|
||||||
checkDb = ss[0]
|
checkDb = ss[0]
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
"database/sql"
|
"database/sql"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/google/uuid"
|
||||||
"mayfly-go/internal/db/dbm/dbi"
|
"mayfly-go/internal/db/dbm/dbi"
|
||||||
"mayfly-go/internal/db/domain/entity"
|
"mayfly-go/internal/db/domain/entity"
|
||||||
"mayfly-go/internal/db/domain/repository"
|
"mayfly-go/internal/db/domain/repository"
|
||||||
@@ -53,8 +54,8 @@ var (
|
|||||||
dateTimeReg = regexp.MustCompile(`^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$`)
|
dateTimeReg = regexp.MustCompile(`^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$`)
|
||||||
)
|
)
|
||||||
|
|
||||||
func (d *dataSyncAppImpl) InjectDbDataSyncTaskRepo(repo repository.DataSyncTask) {
|
func (app *dataSyncAppImpl) InjectDbDataSyncTaskRepo(repo repository.DataSyncTask) {
|
||||||
d.Repo = repo
|
app.Repo = repo
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *dataSyncAppImpl) GetPageList(condition *entity.DataSyncTaskQuery, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error) {
|
func (app *dataSyncAppImpl) GetPageList(condition *entity.DataSyncTaskQuery, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error) {
|
||||||
@@ -64,15 +65,22 @@ func (app *dataSyncAppImpl) GetPageList(condition *entity.DataSyncTaskQuery, pag
|
|||||||
func (app *dataSyncAppImpl) Save(ctx context.Context, taskEntity *entity.DataSyncTask) error {
|
func (app *dataSyncAppImpl) Save(ctx context.Context, taskEntity *entity.DataSyncTask) error {
|
||||||
var err error
|
var err error
|
||||||
if taskEntity.Id == 0 {
|
if taskEntity.Id == 0 {
|
||||||
|
// 新建时生成key
|
||||||
|
taskEntity.TaskKey = uuid.New().String()
|
||||||
err = app.Insert(ctx, taskEntity)
|
err = app.Insert(ctx, taskEntity)
|
||||||
} else {
|
} else {
|
||||||
err = app.UpdateById(ctx, taskEntity)
|
err = app.UpdateById(ctx, taskEntity)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
app.AddCronJob(taskEntity)
|
task, err := app.GetById(new(entity.DataSyncTask), taskEntity.Id)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
app.AddCronJob(task)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,9 +100,13 @@ func (app *dataSyncAppImpl) AddCronJob(taskEntity *entity.DataSyncTask) {
|
|||||||
// 根据状态添加新的任务
|
// 根据状态添加新的任务
|
||||||
if taskEntity.Status == entity.DataSyncTaskStatusEnable {
|
if taskEntity.Status == entity.DataSyncTaskStatusEnable {
|
||||||
scheduler.AddFunByKey(key, taskEntity.TaskCron, func() {
|
scheduler.AddFunByKey(key, taskEntity.TaskCron, func() {
|
||||||
if err := app.RunCronJob(taskEntity.Id); err != nil {
|
go func() {
|
||||||
logx.Errorf("定时执行数据同步任务失败: %s", err.Error())
|
taskId := taskEntity.Id
|
||||||
}
|
logx.Infof("开始执行同步任务: %d", taskId)
|
||||||
|
if err := app.RunCronJob(taskId); err != nil {
|
||||||
|
logx.Errorf("定时执行数据同步任务失败: %s", err.Error())
|
||||||
|
}
|
||||||
|
}()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ const (
|
|||||||
DbTypeMysql DbType = "mysql"
|
DbTypeMysql DbType = "mysql"
|
||||||
DbTypeMariadb DbType = "mariadb"
|
DbTypeMariadb DbType = "mariadb"
|
||||||
DbTypePostgres DbType = "postgres"
|
DbTypePostgres DbType = "postgres"
|
||||||
|
DbTypeGauss DbType = "gauss"
|
||||||
DbTypeDM DbType = "dm"
|
DbTypeDM DbType = "dm"
|
||||||
DbTypeOracle DbType = "oracle"
|
DbTypeOracle DbType = "oracle"
|
||||||
DbTypeSqlite DbType = "sqlite"
|
DbTypeSqlite DbType = "sqlite"
|
||||||
@@ -43,7 +44,7 @@ func (dbType DbType) QuoteIdentifier(name string) string {
|
|||||||
switch dbType {
|
switch dbType {
|
||||||
case DbTypeMysql, DbTypeMariadb:
|
case DbTypeMysql, DbTypeMariadb:
|
||||||
return quoteIdentifier(name, "`")
|
return quoteIdentifier(name, "`")
|
||||||
case DbTypePostgres:
|
case DbTypePostgres, DbTypeGauss:
|
||||||
return quoteIdentifier(name, `"`)
|
return quoteIdentifier(name, `"`)
|
||||||
case DbTypeMssql:
|
case DbTypeMssql:
|
||||||
return fmt.Sprintf("[%s]", name)
|
return fmt.Sprintf("[%s]", name)
|
||||||
@@ -56,7 +57,7 @@ func (dbType DbType) RemoveQuote(name string) string {
|
|||||||
switch dbType {
|
switch dbType {
|
||||||
case DbTypeMysql, DbTypeMariadb:
|
case DbTypeMysql, DbTypeMariadb:
|
||||||
return removeQuote(name, "`")
|
return removeQuote(name, "`")
|
||||||
case DbTypePostgres:
|
case DbTypePostgres, DbTypeGauss:
|
||||||
return removeQuote(name, `"`)
|
return removeQuote(name, `"`)
|
||||||
default:
|
default:
|
||||||
return removeQuote(name, `"`)
|
return removeQuote(name, `"`)
|
||||||
@@ -69,7 +70,7 @@ func (dbType DbType) QuoteLiteral(literal string) string {
|
|||||||
literal = strings.ReplaceAll(literal, `\`, `\\`)
|
literal = strings.ReplaceAll(literal, `\`, `\\`)
|
||||||
literal = strings.ReplaceAll(literal, `'`, `''`)
|
literal = strings.ReplaceAll(literal, `'`, `''`)
|
||||||
return "'" + literal + "'"
|
return "'" + literal + "'"
|
||||||
case DbTypePostgres:
|
case DbTypePostgres, DbTypeGauss:
|
||||||
return pq.QuoteLiteral(literal)
|
return pq.QuoteLiteral(literal)
|
||||||
default:
|
default:
|
||||||
return pq.QuoteLiteral(literal)
|
return pq.QuoteLiteral(literal)
|
||||||
@@ -80,7 +81,7 @@ func (dbType DbType) MetaDbName() string {
|
|||||||
switch dbType {
|
switch dbType {
|
||||||
case DbTypeMysql, DbTypeMariadb:
|
case DbTypeMysql, DbTypeMariadb:
|
||||||
return ""
|
return ""
|
||||||
case DbTypePostgres:
|
case DbTypePostgres, DbTypeGauss:
|
||||||
return "postgres"
|
return "postgres"
|
||||||
case DbTypeDM:
|
case DbTypeDM:
|
||||||
return ""
|
return ""
|
||||||
@@ -93,7 +94,7 @@ func (dbType DbType) Dialect() sqlparser.Dialect {
|
|||||||
switch dbType {
|
switch dbType {
|
||||||
case DbTypeMysql, DbTypeMariadb:
|
case DbTypeMysql, DbTypeMariadb:
|
||||||
return sqlparser.MysqlDialect{}
|
return sqlparser.MysqlDialect{}
|
||||||
case DbTypePostgres:
|
case DbTypePostgres, DbTypeGauss:
|
||||||
return sqlparser.PostgresDialect{}
|
return sqlparser.PostgresDialect{}
|
||||||
default:
|
default:
|
||||||
return sqlparser.PostgresDialect{}
|
return sqlparser.PostgresDialect{}
|
||||||
@@ -121,7 +122,7 @@ func (dbType DbType) StmtSetForeignKeyChecks(check bool) string {
|
|||||||
} else {
|
} else {
|
||||||
return "SET FOREIGN_KEY_CHECKS = 0;\n"
|
return "SET FOREIGN_KEY_CHECKS = 0;\n"
|
||||||
}
|
}
|
||||||
case DbTypePostgres:
|
case DbTypePostgres, DbTypeGauss:
|
||||||
// not currently supported postgres
|
// not currently supported postgres
|
||||||
return ""
|
return ""
|
||||||
default:
|
default:
|
||||||
@@ -133,7 +134,7 @@ func (dbType DbType) StmtUseDatabase(dbName string) string {
|
|||||||
switch dbType {
|
switch dbType {
|
||||||
case DbTypeMysql, DbTypeMariadb:
|
case DbTypeMysql, DbTypeMariadb:
|
||||||
return fmt.Sprintf("USE %s;\n", dbType.QuoteIdentifier(dbName))
|
return fmt.Sprintf("USE %s;\n", dbType.QuoteIdentifier(dbName))
|
||||||
case DbTypePostgres:
|
case DbTypePostgres, DbTypeGauss:
|
||||||
// not currently supported postgres
|
// not currently supported postgres
|
||||||
return ""
|
return ""
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -16,13 +16,18 @@ import (
|
|||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
dbi.Register(dbi.DbTypePostgres, new(PostgresMeta))
|
dbi.Register(dbi.DbTypePostgres, new(PostgresMeta))
|
||||||
|
|
||||||
|
gauss := new(PostgresMeta)
|
||||||
|
gauss.Param = "dbtype=gauss"
|
||||||
|
dbi.Register(dbi.DbTypeGauss, gauss)
|
||||||
}
|
}
|
||||||
|
|
||||||
type PostgresMeta struct {
|
type PostgresMeta struct {
|
||||||
|
Param string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (md *PostgresMeta) GetSqlDb(d *dbi.DbInfo) (*sql.DB, error) {
|
func (md *PostgresMeta) GetSqlDb(d *dbi.DbInfo) (*sql.DB, error) {
|
||||||
driverName := string(d.Type)
|
driverName := "postgres"
|
||||||
// SSH Conect
|
// SSH Conect
|
||||||
if d.SshTunnelMachineId > 0 {
|
if d.SshTunnelMachineId > 0 {
|
||||||
// 如果使用了隧道,则使用`postgres:ssh:隧道机器id`注册名
|
// 如果使用了隧道,则使用`postgres:ssh:隧道机器id`注册名
|
||||||
@@ -67,6 +72,10 @@ func (md *PostgresMeta) GetSqlDb(d *dbi.DbInfo) (*sql.DB, error) {
|
|||||||
dsn = fmt.Sprintf("%s %s", dsn, strings.Join(strings.Split(d.Params, "&"), " "))
|
dsn = fmt.Sprintf("%s %s", dsn, strings.Join(strings.Split(d.Params, "&"), " "))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if md.Param != "" && !strings.Contains(dsn, "dbtype") {
|
||||||
|
dsn = fmt.Sprintf("%s %s", dsn, md.Param)
|
||||||
|
}
|
||||||
|
|
||||||
return sql.Open(driverName, dsn)
|
return sql.Open(driverName, dsn)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user