mirror of
				https://gitee.com/dromara/mayfly-go
				synced 2025-11-04 16: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",
 | 
			
		||||
      "unicode": "e600",
 | 
			
		||||
      "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 prop="type" label="类型" required>
 | 
			
		||||
                            <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]">
 | 
			
		||||
                                    <SvgIcon :name="dbTypeAndDialect[1].getInfo().icon" :size="18" />
 | 
			
		||||
                                <el-option
 | 
			
		||||
                                    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 }}
 | 
			
		||||
                                </el-option>
 | 
			
		||||
 | 
			
		||||
                                <template #prefix>
 | 
			
		||||
                                    <SvgIcon :name="getDbDialect(form.type).getInfo().icon" :size="18" />
 | 
			
		||||
                                    <SvgIcon :name="getDbDialect(form.type).getInfo().icon" :size="20" />
 | 
			
		||||
                                </template>
 | 
			
		||||
                            </el-select>
 | 
			
		||||
                        </el-form-item>
 | 
			
		||||
 
 | 
			
		||||
@@ -443,7 +443,7 @@ onBeforeUnmount(() => {
 | 
			
		||||
 * 设置editor高度和数据表高度
 | 
			
		||||
 */
 | 
			
		||||
const setHeight = () => {
 | 
			
		||||
    state.dataTabsTableHeight = window.innerHeight - 270 + 'px';
 | 
			
		||||
    state.dataTabsTableHeight = window.innerHeight - 253 + 'px';
 | 
			
		||||
    state.tablesOpHeight = window.innerHeight - 225 + 'px';
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -158,21 +158,62 @@
 | 
			
		||||
            @data-delete="onRefresh"
 | 
			
		||||
        ></db-table-data>
 | 
			
		||||
 | 
			
		||||
        <el-row type="flex" class="mt5" justify="center">
 | 
			
		||||
            <el-pagination
 | 
			
		||||
                small
 | 
			
		||||
                :total="count"
 | 
			
		||||
                @size-change="handleSizeChange"
 | 
			
		||||
                @current-change="pageChange()"
 | 
			
		||||
                layout="prev, pager, next, total, sizes, jumper"
 | 
			
		||||
                v-model:current-page="pageNum"
 | 
			
		||||
                v-model:page-size="pageSize"
 | 
			
		||||
                :page-sizes="pageSizes"
 | 
			
		||||
            ></el-pagination>
 | 
			
		||||
        </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>
 | 
			
		||||
        <el-row type="flex" class="mt5" :gutter="10" justify="end" style="user-select: none">
 | 
			
		||||
            <el-col :span="12">
 | 
			
		||||
                <el-text
 | 
			
		||||
                    style="color: var(--el-color-info-light-3); font-size: 12px; margin-top: 5px"
 | 
			
		||||
                    class="is-truncated"
 | 
			
		||||
                    @click="handleCopySql(sql)"
 | 
			
		||||
                    :title="sql"
 | 
			
		||||
                    >{{ sql }}</el-text
 | 
			
		||||
                >
 | 
			
		||||
            </el-col>
 | 
			
		||||
            <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-dialog v-model="conditionDialog.visible" :title="conditionDialog.title" width="420px">
 | 
			
		||||
            <el-row>
 | 
			
		||||
@@ -242,6 +283,7 @@ import { DbDialect, getDbDialect } from '@/views/ops/db/dialect';
 | 
			
		||||
import SvgIcon from '@/components/svgIcon/index.vue';
 | 
			
		||||
import ColumnFormItem from './ColumnFormItem.vue';
 | 
			
		||||
import { useEventListener, useStorage } from '@vueuse/core';
 | 
			
		||||
import { copyToClipboard } from '@/common/utils/string';
 | 
			
		||||
 | 
			
		||||
const props = defineProps({
 | 
			
		||||
    dbId: {
 | 
			
		||||
@@ -290,7 +332,10 @@ const state = reactive({
 | 
			
		||||
        defaultPageSize * 40,
 | 
			
		||||
        defaultPageSize * 80,
 | 
			
		||||
    ],
 | 
			
		||||
    count: 0,
 | 
			
		||||
    setPageNum: 0,
 | 
			
		||||
    total: 0,
 | 
			
		||||
    showTotal: 0,
 | 
			
		||||
    counting: false,
 | 
			
		||||
    selectionDatas: [] as any,
 | 
			
		||||
    condPopVisible: false,
 | 
			
		||||
    columnNameSearch: '',
 | 
			
		||||
@@ -314,7 +359,7 @@ const state = reactive({
 | 
			
		||||
    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(
 | 
			
		||||
    () => props.tableHeight,
 | 
			
		||||
@@ -347,18 +392,19 @@ const onRefresh = async () => {
 | 
			
		||||
    await selectData();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 数据tab修改页数
 | 
			
		||||
 */
 | 
			
		||||
const pageChange = async () => {
 | 
			
		||||
watch(
 | 
			
		||||
    () => state.pageNum,
 | 
			
		||||
    async () => {
 | 
			
		||||
        await selectData();
 | 
			
		||||
};
 | 
			
		||||
    }
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 单表数据信息查询数据
 | 
			
		||||
 */
 | 
			
		||||
const selectData = async () => {
 | 
			
		||||
    state.loading = true;
 | 
			
		||||
    state.setPageNum = state.pageNum;
 | 
			
		||||
    const dbInst = getNowDbInst();
 | 
			
		||||
    const db = props.dbName;
 | 
			
		||||
    const table = props.tableName;
 | 
			
		||||
@@ -371,16 +417,10 @@ const selectData = async () => {
 | 
			
		||||
            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);
 | 
			
		||||
        state.sql = sql;
 | 
			
		||||
        if (state.count > 0) {
 | 
			
		||||
        const colAndData: any = await dbInst.runSql(db, sql);
 | 
			
		||||
        state.datas = colAndData.res;
 | 
			
		||||
        } else {
 | 
			
		||||
            state.datas = [];
 | 
			
		||||
        }
 | 
			
		||||
    } finally {
 | 
			
		||||
        state.loading = false;
 | 
			
		||||
    }
 | 
			
		||||
@@ -392,6 +432,38 @@ const handleSizeChange = async (size: any) => {
 | 
			
		||||
    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 = '';
 | 
			
		||||
// 是否存在列建议
 | 
			
		||||
@@ -586,4 +658,8 @@ const addRow = async () => {
 | 
			
		||||
};
 | 
			
		||||
</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 { SqliteDialect } from '@/views/ops/db/dialect/sqlite_dialect';
 | 
			
		||||
import { MssqlDialect } from '@/views/ops/db/dialect/mssql_dialect';
 | 
			
		||||
import { GaussDialect } from '@/views/ops/db/dialect/gauss_dialect';
 | 
			
		||||
 | 
			
		||||
export interface sqlColumnType {
 | 
			
		||||
    udtName: string;
 | 
			
		||||
@@ -116,6 +117,7 @@ export const DbType = {
 | 
			
		||||
    mysql: 'mysql',
 | 
			
		||||
    mariadb: 'mariadb',
 | 
			
		||||
    postgresql: 'postgres',
 | 
			
		||||
    gauss: 'gauss',
 | 
			
		||||
    dm: 'dm', // 达梦
 | 
			
		||||
    oracle: 'oracle',
 | 
			
		||||
    sqlite: 'sqlite',
 | 
			
		||||
@@ -126,7 +128,7 @@ export const DbType = {
 | 
			
		||||
export const noSchemaTypes = [DbType.mysql, DbType.mariadb, DbType.sqlite];
 | 
			
		||||
 | 
			
		||||
// 有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];
 | 
			
		||||
 | 
			
		||||
@@ -225,6 +227,7 @@ export const getDbDialect = (dbType: string): DbDialect => {
 | 
			
		||||
    registerDbDialect(DbType.mysql, mysqlDialect);
 | 
			
		||||
    registerDbDialect(DbType.mariadb, new MariadbDialect());
 | 
			
		||||
    registerDbDialect(DbType.postgresql, new PostgresqlDialect());
 | 
			
		||||
    registerDbDialect(DbType.gauss, new GaussDialect());
 | 
			
		||||
    registerDbDialect(DbType.dm, new DMDialect());
 | 
			
		||||
    registerDbDialect(DbType.oracle, new OracleDialect());
 | 
			
		||||
    registerDbDialect(DbType.sqlite, new SqliteDialect());
 | 
			
		||||
 
 | 
			
		||||
@@ -14,7 +14,6 @@ import (
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	"github.com/gin-gonic/gin"
 | 
			
		||||
	"github.com/google/uuid"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type DataSyncTask struct {
 | 
			
		||||
@@ -46,13 +45,6 @@ func (d *DataSyncTask) SaveTask(rc *req.Ctx) {
 | 
			
		||||
	task.DataSql = sql
 | 
			
		||||
	form.DataSql = sql
 | 
			
		||||
 | 
			
		||||
	key := task.TaskKey
 | 
			
		||||
	// 判断key为空就生成随机key
 | 
			
		||||
	if key == "" {
 | 
			
		||||
		key = uuid.New().String()
 | 
			
		||||
		task.TaskKey = key
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	rc.ReqParam = form
 | 
			
		||||
	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) {
 | 
			
		||||
	taskId := getTaskId(rc.GinCtx)
 | 
			
		||||
	rc.ReqParam = taskId
 | 
			
		||||
	d.DataSyncTaskApp.RunCronJob(taskId)
 | 
			
		||||
	_ = d.DataSyncTaskApp.RunCronJob(taskId)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (d *DataSyncTask) Stop(rc *req.Ctx) {
 | 
			
		||||
 
 | 
			
		||||
@@ -154,7 +154,7 @@ func (d *dbAppImpl) GetDbConn(dbId uint64, dbName string) (*dbi.DbConn, error) {
 | 
			
		||||
 | 
			
		||||
		checkDb := dbName
 | 
			
		||||
		// 兼容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, "/")
 | 
			
		||||
			if len(ss) > 1 {
 | 
			
		||||
				checkDb = ss[0]
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,7 @@ import (
 | 
			
		||||
	"database/sql"
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"github.com/google/uuid"
 | 
			
		||||
	"mayfly-go/internal/db/dbm/dbi"
 | 
			
		||||
	"mayfly-go/internal/db/domain/entity"
 | 
			
		||||
	"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}$`)
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func (d *dataSyncAppImpl) InjectDbDataSyncTaskRepo(repo repository.DataSyncTask) {
 | 
			
		||||
	d.Repo = repo
 | 
			
		||||
func (app *dataSyncAppImpl) InjectDbDataSyncTaskRepo(repo repository.DataSyncTask) {
 | 
			
		||||
	app.Repo = repo
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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 {
 | 
			
		||||
	var err error
 | 
			
		||||
	if taskEntity.Id == 0 {
 | 
			
		||||
		// 新建时生成key
 | 
			
		||||
		taskEntity.TaskKey = uuid.New().String()
 | 
			
		||||
		err = app.Insert(ctx, taskEntity)
 | 
			
		||||
	} else {
 | 
			
		||||
		err = app.UpdateById(ctx, taskEntity)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	app.AddCronJob(taskEntity)
 | 
			
		||||
	task, err := app.GetById(new(entity.DataSyncTask), taskEntity.Id)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	app.AddCronJob(task)
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -92,9 +100,13 @@ func (app *dataSyncAppImpl) AddCronJob(taskEntity *entity.DataSyncTask) {
 | 
			
		||||
	// 根据状态添加新的任务
 | 
			
		||||
	if taskEntity.Status == entity.DataSyncTaskStatusEnable {
 | 
			
		||||
		scheduler.AddFunByKey(key, taskEntity.TaskCron, func() {
 | 
			
		||||
			if err := app.RunCronJob(taskEntity.Id); err != nil {
 | 
			
		||||
			go func() {
 | 
			
		||||
				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"
 | 
			
		||||
	DbTypeMariadb  DbType = "mariadb"
 | 
			
		||||
	DbTypePostgres DbType = "postgres"
 | 
			
		||||
	DbTypeGauss    DbType = "gauss"
 | 
			
		||||
	DbTypeDM       DbType = "dm"
 | 
			
		||||
	DbTypeOracle   DbType = "oracle"
 | 
			
		||||
	DbTypeSqlite   DbType = "sqlite"
 | 
			
		||||
@@ -43,7 +44,7 @@ func (dbType DbType) QuoteIdentifier(name string) string {
 | 
			
		||||
	switch dbType {
 | 
			
		||||
	case DbTypeMysql, DbTypeMariadb:
 | 
			
		||||
		return quoteIdentifier(name, "`")
 | 
			
		||||
	case DbTypePostgres:
 | 
			
		||||
	case DbTypePostgres, DbTypeGauss:
 | 
			
		||||
		return quoteIdentifier(name, `"`)
 | 
			
		||||
	case DbTypeMssql:
 | 
			
		||||
		return fmt.Sprintf("[%s]", name)
 | 
			
		||||
@@ -56,7 +57,7 @@ func (dbType DbType) RemoveQuote(name string) string {
 | 
			
		||||
	switch dbType {
 | 
			
		||||
	case DbTypeMysql, DbTypeMariadb:
 | 
			
		||||
		return removeQuote(name, "`")
 | 
			
		||||
	case DbTypePostgres:
 | 
			
		||||
	case DbTypePostgres, DbTypeGauss:
 | 
			
		||||
		return removeQuote(name, `"`)
 | 
			
		||||
	default:
 | 
			
		||||
		return removeQuote(name, `"`)
 | 
			
		||||
@@ -69,7 +70,7 @@ func (dbType DbType) QuoteLiteral(literal string) string {
 | 
			
		||||
		literal = strings.ReplaceAll(literal, `\`, `\\`)
 | 
			
		||||
		literal = strings.ReplaceAll(literal, `'`, `''`)
 | 
			
		||||
		return "'" + literal + "'"
 | 
			
		||||
	case DbTypePostgres:
 | 
			
		||||
	case DbTypePostgres, DbTypeGauss:
 | 
			
		||||
		return pq.QuoteLiteral(literal)
 | 
			
		||||
	default:
 | 
			
		||||
		return pq.QuoteLiteral(literal)
 | 
			
		||||
@@ -80,7 +81,7 @@ func (dbType DbType) MetaDbName() string {
 | 
			
		||||
	switch dbType {
 | 
			
		||||
	case DbTypeMysql, DbTypeMariadb:
 | 
			
		||||
		return ""
 | 
			
		||||
	case DbTypePostgres:
 | 
			
		||||
	case DbTypePostgres, DbTypeGauss:
 | 
			
		||||
		return "postgres"
 | 
			
		||||
	case DbTypeDM:
 | 
			
		||||
		return ""
 | 
			
		||||
@@ -93,7 +94,7 @@ func (dbType DbType) Dialect() sqlparser.Dialect {
 | 
			
		||||
	switch dbType {
 | 
			
		||||
	case DbTypeMysql, DbTypeMariadb:
 | 
			
		||||
		return sqlparser.MysqlDialect{}
 | 
			
		||||
	case DbTypePostgres:
 | 
			
		||||
	case DbTypePostgres, DbTypeGauss:
 | 
			
		||||
		return sqlparser.PostgresDialect{}
 | 
			
		||||
	default:
 | 
			
		||||
		return sqlparser.PostgresDialect{}
 | 
			
		||||
@@ -121,7 +122,7 @@ func (dbType DbType) StmtSetForeignKeyChecks(check bool) string {
 | 
			
		||||
		} else {
 | 
			
		||||
			return "SET FOREIGN_KEY_CHECKS = 0;\n"
 | 
			
		||||
		}
 | 
			
		||||
	case DbTypePostgres:
 | 
			
		||||
	case DbTypePostgres, DbTypeGauss:
 | 
			
		||||
		// not currently supported postgres
 | 
			
		||||
		return ""
 | 
			
		||||
	default:
 | 
			
		||||
@@ -133,7 +134,7 @@ func (dbType DbType) StmtUseDatabase(dbName string) string {
 | 
			
		||||
	switch dbType {
 | 
			
		||||
	case DbTypeMysql, DbTypeMariadb:
 | 
			
		||||
		return fmt.Sprintf("USE %s;\n", dbType.QuoteIdentifier(dbName))
 | 
			
		||||
	case DbTypePostgres:
 | 
			
		||||
	case DbTypePostgres, DbTypeGauss:
 | 
			
		||||
		// not currently supported postgres
 | 
			
		||||
		return ""
 | 
			
		||||
	default:
 | 
			
		||||
 
 | 
			
		||||
@@ -16,13 +16,18 @@ import (
 | 
			
		||||
 | 
			
		||||
func init() {
 | 
			
		||||
	dbi.Register(dbi.DbTypePostgres, new(PostgresMeta))
 | 
			
		||||
 | 
			
		||||
	gauss := new(PostgresMeta)
 | 
			
		||||
	gauss.Param = "dbtype=gauss"
 | 
			
		||||
	dbi.Register(dbi.DbTypeGauss, gauss)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type PostgresMeta struct {
 | 
			
		||||
	Param string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (md *PostgresMeta) GetSqlDb(d *dbi.DbInfo) (*sql.DB, error) {
 | 
			
		||||
	driverName := string(d.Type)
 | 
			
		||||
	driverName := "postgres"
 | 
			
		||||
	// SSH Conect
 | 
			
		||||
	if d.SshTunnelMachineId > 0 {
 | 
			
		||||
		// 如果使用了隧道,则使用`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, "&"), " "))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if md.Param != "" && !strings.Contains(dsn, "dbtype") {
 | 
			
		||||
		dsn = fmt.Sprintf("%s %s", dsn, md.Param)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return sql.Open(driverName, dsn)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user