Help us shape the future of Go! Take the 2026 Go Developer Survey

engine

package
v1.8.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 11, 2026 License: MIT Imports: 31 Imported by: 0

Documentation

Overview

Package engine 核心引擎层:导出/导入/迁移。 注意:为避免循环依赖,引擎层所需的公共模型定义在本包, 根包 model.go 通过类型别名对外暴露。

SQL 快速生成:按表浏览的行/单元格/过滤条件生成方言正确的可执行 SQL 文本。 复用 cydb 语句构建器 + InlineLiterals(字面量由方言层转义后内联), 生成文本与执行链路(RunParamInsert/RunParamDelete 等)同源转义,即生成即能执行。

Package engine 提供数据库执行核心。本文件为 Web 查询终端提供 SQL 分类 / 危险检测 / LIMIT 护栏 / 查询与执行薄封装。 逻辑与 internal/cli/sqlcmd 保持一致,但不依赖 CLI 交互状态。

SQL 文本通用处理:库引擎无关的纯文本操作,供引擎内部与根包公开 API 共用。

Index

Constants

View Source
const (
	DataEntryCreateTable = 0 // 建表:SQL 为 CREATE TABLE,回滚为 DROP TABLE(仅当表原本不存在时生成)
	DataEntryUpsertData  = 1 // 行数据:按 PK 幂等 upsert(先 DELETE 再 REPLACE),回滚为旧行还原
	DataEntryExecSQL     = 2 // 成对 SQL:Data 中每项为 {"SQL":"...", "rollback":"..."},逐对执行并收集回滚
)

数据包条目类型(JSON 序列化值与 tl-env DataHolder/DataStruc 格式兼容,契约冻结)

View Source
const (
	ErrStoreOpen = errStoreOpen

	ErrStoreMigrate = errStoreMigrate

	ErrStoreRecordNotFound = errStoreRecordNotFound

	ErrCryptoFormat = errCryptoFormat

	ErrCryptoLen = errCryptoLen

	ErrCryptoDecrypt = errCryptoDecrypt
)

错误模板 key 常量(编译期防拼写错误)

View Source
const (
	DetailKindTable     = "table"
	DetailKindView      = "view"
	DetailKindFunction  = "function"
	DetailKindProcedure = "procedure"
)

导出明细类型(ExportDetail.Kind 取值)

View Source
const BackupTablePrefix = "__dqex_bak_"

BackupTablePrefix 重置备份表前缀

View Source
const DefaultBatchSize = 500

DefaultBatchSize 默认批量大小

View Source
const DefaultCompareThreshold = 1000

DefaultCompareThreshold 数据逐行比较默认阈值:行数不超过该值的表逐行比较,超过仅比较行数

View Source
const MaxQueryLimit = 1000

MaxQueryLimit 单次查询返回行数上限(安全护栏,防止拖垮后端)

Variables

View Source
var ErrEmptyDatabase = fmt.Errorf("empty database")

ErrEmptyDatabase 表示目标库内没有任何(非视图)表,可被子层跳过而非致命失败。

Functions

func CancelledMsg

func CancelledMsg(lang string) string

CancelledMsg 返回任务取消文案(按语言渲染,供 service 层终态消息使用)

func CheckDangerous

func CheckDangerous(sql string) (warnings []string, forbidden []string)

CheckDangerous 检测危险/禁止函数,返回 (警告, 禁止)

func ClassifySQL

func ClassifySQL(sql string) bool

ClassifySQL 判断 SQL 是否为写操作(INSERT/UPDATE/DELETE 等)。 与 sqlcmd.classifySQL 保持同一内核。

func CloseAllCliPool

func CloseAllCliPool()

CloseAllCliPool 释放进程级连接池(程序退出时调用)

func Connect

func Connect(info DBConnInfo) (*cydb.DBCli, error)

Connect 根据连接信息建立数据库连接(每次新建,调用方需 Close)

func ConnectDB

func ConnectDB(info DBConnInfo, dbName string) (*cydb.DBCli, error)

ConnectDB 建立到指定库的连接(覆盖连接信息中的库名,每次新建,调用方需 Close)

func ConnectPGWithAnchor

func ConnectPGWithAnchor(info DBConnInfo) (*cydb.DBCli, error)

ConnectPGWithAnchor 连接 PG 系实例:连接未指定库名时依次尝试候选锚点库,返回首个可连上的连接。 每次新建(调用方需 Close),适合健康检测等短生命周期场景;指定了库名则直接连接。

func ConnectPooled

func ConnectPooled(info DBConnInfo, dbName string) (*cydb.DBCli, error)

ConnectPooled 池化获取绑定指定库名的连接,复用同一实例,调用方不要 Close

func CtxWithQueryHooks

func CtxWithQueryHooks(ctx context.Context, hooks *QueryHooks) context.Context

CtxWithQueryHooks 将审计钩子注入 context,随任务传递到引擎执行点

func EnsureDBExists

func EnsureDBExists(info DBConnInfo, dbName string) error

EnsureDBExists 确保指定数据库存在,不存在则自动创建(复用 cydb 各方言实现: MySQL 为 CREATE DATABASE IF NOT EXISTS,PostgreSQL 先查 pg_database 再创建)。 Oracle 的“库”语义为用户/模式,且连接本身已定位到目标 schema,不做自动创建。

func EscapeColumn

func EscapeColumn(dbType, subType, columnName string) string

EscapeColumn 按数据库方言转义列名

func EscapeTable

func EscapeTable(dbType, subType, tableName string) string

EscapeTable 按数据库方言转义表名

func ExportTableExcel

func ExportTableExcel(ctx context.Context, cli *cydb.DBCli, table string, sortSpecs []SortSpec, filters []ColumnFilter, maxRows int) ([]byte, int64, bool, error)

ExportTableExcel 将表数据(应用过滤/排序)导出为 Excel(.xlsx)字节流。 复用 QueryTablePage 拿数据(pageSize=maxRows,一次取回上限内的全部行), 再用 excelize 内存生成单 sheet 数据表(列头加粗 + 冻结首行),不落盘。 maxRows 为导出行数上限(防内存溢出,超限截断并返回已截断标志)。

func GenerateSQL

func GenerateSQL(_ context.Context, cli *cydb.DBCli, p GenSQLParams) (string, error)

GenerateSQL 按参数生成方言正确的 SQL 文本(多条语句以 ;\n 拼接,统一结尾分号)。

func GetCellValue

func GetCellValue(ctx context.Context, cli *cydb.DBCli, table, column string, pkColumns []string, pkValues []any) (any, error)

GetCellValue 按主键 + 列名定位单行单列,返回该单元格完整值(大字段懒加载)。 复用 cydb 语句构建器:表名/列名/主键列按连接方言引用(防标识符注入); 主键值用命名参数绑定(防值注入)。查询不到行时返回 nil。

func GetDatabaseList

func GetDatabaseList(conn DBConnInfo) ([]string, error)

GetDatabaseList 仅返回库(Oracle 为 schema)名列表,不做对象枚举(对象树分级加载第一层)。 连接配置指定库时只返回该库(名称已知无需连接);未指定时枚举全部, 系统库/用户过滤与库枚举 SQL 由方言 GetDatabases 承担(与 GetTableTree 口径一致)。

func GetObjectDDL

func GetObjectDDL(cli *cydb.DBCli, objType ObjectDDLType, name string) (string, error)

GetObjectDDL 获取指定对象(表/视图/函数/存储过程)的创建语句。 复用底层库方言 DDL 能力;表 DDL 已包含该表触发器。

func IsCancelled

func IsCancelled(err error) bool

IsCancelled 判断错误是否为任务取消(engine.MsgError 的 errCancelled key)。 供 service 层在按语言渲染错误后仍能识别取消语义(不依赖中文文案匹配)。

func IsKnownReadOnly

func IsKnownReadOnly(sql string) bool

IsKnownReadOnly 判断语句是否属于已知只读前缀(SELECT/SHOW/USE 等)

func IsSensitiveColumn

func IsSensitiveColumn(column string) bool

IsSensitiveColumn 判断列名是否属于敏感字段(用于结果集脱敏)

func MaskResult

func MaskResult(result *SQLQueryResult)

MaskResult 对查询结果集做脱敏:敏感列的值统一打码(NULL 保留)。 已脱敏的结果集中敏感值以 ****** 呈现,防止前端展示明文密钥/口令。

func NewMsgErr

func NewMsgErr(key string, args ...any) error

NewMsgErr 创建无底层原因的结构化错误

func NewMsgErrf

func NewMsgErrf(key string, cause error, args ...any) error

NewMsgErrf 创建带底层原因的结构化错误(等价原 fmt.Errorf("模板: %w", cause))

func Ping

func Ping(ctx context.Context, cli *cydb.DBCli) (int64, error)

Ping 检测数据库连接可用性(SELECT 1),返回耗时(毫秒)。 用于前端连接健康检测:连接断开/数据库不可达时返回错误。

func RunParamDelete

func RunParamDelete(ctx context.Context, cli *cydb.DBCli, p DeleteRowParams) (int64, error)

RunParamDelete 执行整行 DELETE(复用 cydb 语句构建器 + 命名参数绑定,彻底防注入):

  • 表名/主键列由 cydb 的 ss.Delete/cydb.EQ 按连接方言引用(防标识符注入);
  • 主键值通过命名参数(:pk_N)绑定,而非字符串拼接(防值注入)。

生成形如:DELETE FROM `t` WHERE `id` = :pk_0 AND `c` = :pk_1

func RunParamInsert

func RunParamInsert(ctx context.Context, cli *cydb.DBCli, p InsertRowParams) (int64, error)

RunParamInsert 执行 INSERT(复用 cydb 语句构建器 + 命名参数绑定,彻底防注入):

  • 表名/列名由 cydb 的 ss.Insert/Columns 按连接方言引用(防标识符注入);
  • 值通过命名参数(:v_N)绑定,而非字符串拼接(防值注入)。

生成形如:INSERT INTO `t` (`a`,`b`) VALUES (:v_0,:v_1)

func RunParamUpdate

func RunParamUpdate(ctx context.Context, cli *cydb.DBCli, p UpdateCellParams) (int64, error)

RunParamUpdate 执行单元格 UPDATE(复用 cydb 语句构建器 + 命名参数绑定,彻底防注入):

  • 表名/列名由 cydb 的 ss.Update/AssignParam 按连接方言引用(防标识符注入);
  • 值通过命名参数(:set_val / :pk_N)绑定,而非字符串拼接(防值注入)。

生成形如:UPDATE `t` SET `c` = :set_val WHERE `id` = :pk_0

func StripSQLDBPrefix

func StripSQLDBPrefix(isMySQL bool, sql string, knownDBs ...string) string

StripSQLDBPrefix 清除 SQL 中的源库名前缀(`db`. / db.),使外部生成的 SQL 可在目标库上执行。 前缀仅当命中 knownDBs(包内库名/目标库名)时清除,避免误伤别名前缀(t.col); 非 MySQL 方言同时移除全部反引号(MySQL 专有语法,PG/Oracle 上非法)。 已知局限:与库名同形的字符串字面量会被误改(外部 SQL 场景可忽略,与 tl-env 原实现一致)。

Types

type ChangedRow

type ChangedRow struct {
	Key   map[string]any `json:"key"`   // 主键列取值
	Diffs []ValueDiff    `json:"diffs"` // 取值不一致的列
}

ChangedRow 变化行样例:主键取值 + 差异列双侧取值(PK 模式:主键匹配但内容不同)

type ColumnDiff

type ColumnDiff struct {
	Matched    bool             `json:"matched"`
	SourceOnly []ColumnItem     `json:"sourceOnly"` // 源有目标无的列
	TargetOnly []ColumnItem     `json:"targetOnly"` // 目标有源无的列
	Different  []ColumnItemDiff `json:"different"`  // 类型/可空/主键不一致的列
}

ColumnDiff 列级结构差异

type ColumnFilter

type ColumnFilter struct {
	Column string   `json:"column"`
	Op     FilterOp `json:"op"`
	Value  any      `json:"value,omitempty"`
}

ColumnFilter 单列过滤条件(值仅在 isNull/isNotNull 时为空)。

type ColumnItem

type ColumnItem struct {
	Name           string `json:"name"`
	DataType       string `json:"dataType"`                 // 原始类型(GetOrginalDataType),用于展示
	NormalizedType string `json:"normalizedType,omitempty"` // 按方言归一后的类型(写入时固化,diff 优先用此比对)
	Nullable       bool   `json:"nullable"`
	PrimaryKey     bool   `json:"primaryKey"`
}

ColumnItem 单列信息

type ColumnItemDiff

type ColumnItemDiff struct {
	Name   string     `json:"name"`
	Source ColumnItem `json:"source"`
	Target ColumnItem `json:"target"`
}

ColumnItemDiff 不一致列的双侧信息(供前端并排展示)

type CompareDBPair

type CompareDBPair struct {
	SourceDB string `json:"sourceDB" yaml:"sourceDB"` // 源库名(oracle 为 schema)
	TargetDB string `json:"targetDB" yaml:"targetDB"` // 目标库名
}

CompareDBPair 对比的库对(源库 ↔ 目标库)

type CompareDatabaseResult

type CompareDatabaseResult struct {
	SourceDB string               `json:"sourceDB"` // 源库名(oracle 为 schema)
	TargetDB string               `json:"targetDB"` // 目标库名
	Tables   []CompareTableResult `json:"tables"`   // 该库内表级结果
	Summary  CompareSummary       `json:"summary"`  // 该库汇总统计
}

CompareDatabaseResult 单个库对(源库 ↔ 目标库)的对比结果

type CompareOptions

type CompareOptions struct {
	SourceConn    string            `json:"sourceConn" yaml:"sourceConn"`
	TargetConn    string            `json:"targetConn" yaml:"targetConn"`
	Source        *DBConnInfo       `json:"source,omitempty" yaml:"source,omitempty"`
	Target        *DBConnInfo       `json:"target,omitempty" yaml:"target,omitempty"`
	Databases     []CompareDBPair   `json:"databases,omitempty" yaml:"databases,omitempty"` // 库对(源库↔目标库),按索引配对
	DBMapping     map[string]string `json:"dbMapping,omitempty" yaml:"dbMapping,omitempty"` // 源库名→目标库名覆盖映射
	Tables        []string          `json:"tables,omitempty" yaml:"tables,omitempty"`
	Aliases       []TableAlias      `json:"aliases,omitempty" yaml:"aliases,omitempty"`
	StructureOnly bool              `json:"structureOnly" yaml:"structureOnly"` // 仅比结构
	DataOnly      bool              `json:"dataOnly" yaml:"dataOnly"`           // 仅比数据
	Threshold     int               `json:"threshold" yaml:"threshold"`         // 数据逐行比较阈值,默认 1000
	IgnoreColumns []string          `json:"ignoreColumns,omitempty" yaml:"ignoreColumns,omitempty"`
	ForceData     bool              `json:"forceData,omitempty" yaml:"forceData,omitempty"`
	// Lang 任务日志语言(zh/en),默认 zh
	Lang string `json:"lang,omitempty" yaml:"lang,omitempty"`
	// User 任务发起人标识(宿主注入):随 OnTaskStart 透传宿主。运行时注入不入任务配置
	User string `json:"-" yaml:"-"`
}

CompareOptions 对比选项 多库对比:SourceDatabases/TargetDatabases 为要对比的源库/目标库列表(按索引一一配对); DBMapping 提供源库名→目标库名的覆盖映射(未按索引配对时的回退,如 db_prod→db_test); Tables 为 nil 时对比所有选中库的全部表(项为 "库.表" 限定名或裸表名)。 源/目标不同名的同义表通过 Aliases 配对。

type CompareResult

type CompareResult struct {
	Source    string                  `json:"source"`           // 源连接标签
	Target    string                  `json:"target"`           // 目标连接标签
	Databases []CompareDatabaseResult `json:"databases"`        // 每个库对的结果(多库分组)
	Tables    []CompareTableResult    `json:"tables,omitempty"` // 兼容字段:所有库表的扁平汇总(旧数据可读,新写入不再依赖)
	Summary   CompareSummary          `json:"summary"`          // 汇总统计(所有库合计)
}

CompareResult 对比结果(多库分组,序列化落盘为 JSON 报告)

func RunCompare

func RunCompare(ctx context.Context, opts CompareOptions, cb ProgressFunc) (*CompareResult, error)

RunCompare 执行数据库对比(多库):解析库对(按 Databases 索引配对,DBMapping 覆盖), 逐库循环对比表清单/结构/数据,结果按库分组汇总到 CompareResult.Databases。 表按裸表名匹配(大小写不敏感);Aliases 别名配对优先于同名匹配;行数超阈值仅比较行数。

func RunSnapshotCompare

func RunSnapshotCompare(ctx context.Context, snapshot *Snapshot, targetConn *DBConnInfo, opts SnapshotCompareOptions, cb ProgressFunc) (*CompareResult, error)

RunSnapshotCompare 快照 vs 在线库对比(多库):逐库对比,结构对比直接比较快照列定义 vs 在线库列定义, 数据对比走在线库全量查询 + 快照侧行数辅助判断(快照不存全量数据,不做逐行对比)。 库对按 opts.DBMapping(快照库名→目标库名)配对,未指定时同名配对。结果按库分组到 CompareResult.Databases。 注意:每个目标库必须单独建立绑定该库名的 pooled 连接, 否则 GetTableInfo/DirectQuery 会查错库导致结构/数据张冠李戴(非首个快照库的所有列/行数都会失败)。

func RunSnapshotCompareWithConn

func RunSnapshotCompareWithConn(ctx context.Context, snapshot *Snapshot, targetConn *DBConnInfo, opts SnapshotCompareOptions, cb ProgressFunc) (*CompareResult, error)

RunSnapshotCompareWithConn 快照对比的便捷入口:以连接配置构建多库 pooled 连接后执行对比 (不再统一 Connect 成单一 cli;原因见 RunSnapshotCompare)

type CompareSummary

type CompareSummary struct {
	Total         int `json:"total"`         // 配对总数
	Matched       int `json:"matched"`       // 完全一致
	SourceOnly    int `json:"sourceOnly"`    // 仅源有
	TargetOnly    int `json:"targetOnly"`    // 仅目标有
	StructureDiff int `json:"structureDiff"` // 结构差异
	DataDiff      int `json:"dataDiff"`      // 数据差异(含仅计数不一致)
}

CompareSummary 对比汇总计数

type CompareTableResult

type CompareTableResult struct {
	Name       string      `json:"name"`                 // 展示名:同名取表名,别名配对为 "源表 ↔ 目标表"
	SourceName string      `json:"sourceName,omitempty"` // 源侧实际表名
	TargetName string      `json:"targetName,omitempty"` // 目标侧实际表名
	SourceDB   string      `json:"sourceDB,omitempty"`   // 源侧库名(oracle 为 schema),多库展示用
	TargetDB   string      `json:"targetDB,omitempty"`   // 目标侧库名,多库展示用
	Status     string      `json:"status"`
	Columns    *ColumnDiff `json:"columns,omitempty"` // 结构差异(DataOnly 时为 nil)
	Data       *DataDiff   `json:"data,omitempty"`    // 数据差异(StructureOnly 时为 nil)
}

CompareTableResult 单表(配对)对比结果 Status: source_only=仅源有 / target_only=仅目标有 / both=两侧均有

type Contributor

type Contributor struct {
	// Type 类型标识,同时是 zip 包内目录名(如 flow/panel/rule/datatable),须为安全目录名
	Type string `json:"type" yaml:"type"`
	// Title 展示名(进度/日志用),空则回退 Type
	Title string `json:"title,omitempty" yaml:"title,omitempty"`
	// Export 导出回调:生成文件写入 req.Dir,返回清单(文件路径相对 req.Dir);nil 视为非法注册
	Export func(ctx context.Context, req ContributorRequest) (*ContributorResult, error) `json:"-" yaml:"-"`
	// Import 导入回调:从 req.Dir 读回业务对象;nil 表示仅导出(导入包中该目录被跳过)
	Import func(ctx context.Context, req ContributorImportRequest) error `json:"-" yaml:"-"`
	// IDs 本次任务要导出的业务对象 ID(任务配置层携带;Client 注册的模板留空)
	IDs []string `json:"ids,omitempty" yaml:"ids,omitempty"`
}

Contributor 业务对象贡献者(代理层扩展点)。

导出/导入的编排(任务目录、进度、zip 打包、清单)由 dqex 统一负责; 宿主业务对象(如流程/面板/规则/数据表)的"取数"与"回写"通过回调代理给宿主实现:

  • Export:把 IDs 指定的业务对象写入 req.Dir(zip 任务目录下 <Type>/), 可输出任意格式(SQL/JSON/YAML),随后与库 SQL 一并打包;
  • Import:从 req.Dir 读回业务对象(可为 nil,表示该类型仅支持导出)。

回调契约:Export/Import 运行在任务执行 goroutine 上,回调内阻塞会暂停进度推送; 取消统一由 req 内携带的 ctx 控制;回调内不得再回调 dqex 的 Client 方法。

type ContributorImportRequest

type ContributorImportRequest struct {
	// Key 任务目标连接 connKey(宿主据此路由到对应环境的业务配置)
	Key string
	// Conn 目标库连接(即本次导入的目标连接)
	Conn *DBConnInfo
	// DB 目标库名(连接配置库)
	DB string
	// Dir 业务对象目录(解压后 <Type>/)
	Dir string
}

ContributorImportRequest 导入回调请求

type ContributorRequest

type ContributorRequest struct {
	// Key 任务连接 connKey(如 env:prod/db:biz):业务对象策略是环境级的,
	// 宿主据此路由到对应环境的业务配置(回调无 Key 时宿主无法区分多环境)
	Key string
	// Conn 业务对象所在库连接(即本次导出的源连接;宿主可自行建连或忽略)
	Conn *DBConnInfo
	// DB 业务库名(连接配置库;多库导出时为连接默认库,宿主自定义语义)
	DB string
	// IDs 要导出的业务对象 ID 列表(来自任务配置层)
	IDs []string
	// Dir 写入目录(任务目录下 <Type>/,已存在)
	Dir string
}

ContributorRequest 导出回调请求

type ContributorResult

type ContributorResult struct {
	// Files 生成的文件清单(相对 Dir)
	Files []string
	// Count 导出的业务对象数(进度/日志展示用)
	Count int
}

ContributorResult 导出回调结果

type CreateSnapshotOptions

type CreateSnapshotOptions struct {
	IncludeSamples bool // 是否保存前 N 行采样数据
	SampleLimit    int  // 采样行数上限,默认 10
	// Lang 任务日志语言(zh/en),默认 zh
	Lang string
}

CreateSnapshotOptions 创建快照选项

type DBConnInfo

type DBConnInfo struct {
	def.DBConnection `json:",inline" yaml:",inline"`
}

DBConnInfo 应用层连接信息。 def.DBConnection 已包含 SubType 字段:它不是版本号,而是“使用该类型兼容模式的具体数据库产品” (如 mysql 兼容的 "oceanbase"/"mariadb"、postgresql 兼容的 "gaussdb"/"kingbase"、oracle 兼容的 "dameng"), 供方言层按产品语法差异生成 SQL;空值或等于类型名表示原生标准库。 此处内嵌复用,JSON/YAML 序列化时字段平铺。

type DBSchema

type DBSchema struct {
	Name    string              `json:"name"`
	Tables  []string            `json:"tables"`
	Objects map[string][]string `json:"objects,omitempty"`
}

DBSchema 一个库内的 schema(PG 系)及其表与对象清单 (PG 系对象树按 库 → schema → 分组 → 对象 分层;MySQL/Oracle 不使用)

func GetSchemaObjects

func GetSchemaObjects(conn DBConnInfo, db, schema string) (*DBSchema, error)

GetSchemaObjects 返回单 schema 的对象清单(对象树分级第三层,PG 系,一次往返)

type DBSelection

type DBSelection struct {
	DB      string   `json:"db" yaml:"db"`
	Tables  []string `json:"tables,omitempty" yaml:"tables,omitempty"`
	Objects []string `json:"objects,omitempty" yaml:"objects,omitempty"`
}

type DBTables

type DBTables struct {
	Name   string   `json:"name"`
	Tables []string `json:"tables"`
	// Schemas 库内 schema 清单(PG 系按 schema 分层时填充;MySQL/Oracle 为空)
	Schemas []DBSchema `json:"schemas,omitempty"`
	// Objects 库内对象:_views/_functions/_procedures → 对象名(枚举失败的类型不返回)
	Objects map[string][]string `json:"objects,omitempty"`
}

DBTables 一个数据库(Oracle 为 schema)及其表与对象清单

func GetDbObjects

func GetDbObjects(conn DBConnInfo, db string) (*DBTables, error)

GetDbObjects 返回单库对象清单(对象树分级第二层,MySQL/Oracle 无 schema 层): 复用 GetTableTree 单库逻辑(指定库名后返回首元素)

func GetTableTree

func GetTableTree(conn DBConnInfo) ([]DBTables, error)

GetTableTree 获取 "库 → 表" 树形结构。 conn.DBName 非空时只返回该库;为空时遍历所有库(Oracle 遍历 schema)。

type DataApplyResult

type DataApplyResult struct {
	Stmts         int64    // 执行的语句数(DDL/REPLACE/成对 SQL)
	RollbackSQL   []string // 回滚 SQL(按执行顺序排列,整体回放即恢复到应用前状态)
	SkippedTables []string // 跳过的表(无主键等无法精确回滚的场景,宿主侧告警)
	Unrollback    []string // 执行了但无法生成精确回滚的语句(宿主侧告警;见 tryColumnRollback)
}

DataApplyResult 数据包应用结果

func ApplyDataPackage

func ApplyDataPackage(ctx context.Context, cli *cydb.DBCli, pkg *DataPackage, connKey string) (*DataApplyResult, error)

ApplyDataPackage 在单库连接上应用数据包,并生成行级回滚 SQL。 回滚语义:基于应用时点的旧值快照,适用于"紧随导入的撤销",不适用于长期 revert。 connKey 用于审计钩子归属。无主键表的数据条目跳过并记录在 SkippedTables。 事务语义按方言:PG/gaussdb/kingbase 的 DDL 可回滚(真单事务);MySQL 系与 Oracle 的 DDL 隐式提交,事务仅覆盖数据语句(建表失败时已建的表不随事务撤销,需回滚产物兜底)。

type DataDiff

type DataDiff struct {
	Mode           string           `json:"mode"`
	SourceRows     int64            `json:"sourceRows"`
	TargetRows     int64            `json:"targetRows"`
	Equal          bool             `json:"equal"`                // count 模式:行数相等;rows 模式:无差异
	KeyColumns     []string         `json:"keyColumns,omitempty"` // 有无判断依据的主键列(PK 模式);空=无主键整行比较
	Missing        int              `json:"missing,omitempty"`    // 源有目标无的行数(rows 模式)
	Extra          int              `json:"extra,omitempty"`      // 目标有源无的行数(rows 模式)
	Changed        int              `json:"changed,omitempty"`    // 主键匹配但内容不同的行数(PK 模式)
	MissingSamples []map[string]any `json:"missingSamples,omitempty"`
	ExtraSamples   []map[string]any `json:"extraSamples,omitempty"`
	ChangedSamples []ChangedRow     `json:"changedSamples,omitempty"` // 变化行样例(主键值 + 差异列双侧取值)
	SampleColumns  []string         `json:"sampleColumns,omitempty"`  // 采样行列序(按源表列定义顺序),供前端按序渲染
	SkippedReason  string           `json:"skippedReason,omitempty"`  // 未逐行比较的原因说明
}

DataDiff 数据差异 Mode: rows=逐行比较 / count=仅比较行数(超阈值)

type DataEntry

type DataEntry struct {
	Type        int                      `json:"type"`
	Table       string                   `json:"table,omitempty"`
	PK          []string                 `json:"pk,omitempty"`
	SQL         string                   `json:"sql,omitempty"`
	RollbackSQL string                   `json:"rollback_sql,omitempty"`
	Data        []map[string]interface{} `json:"data,omitempty"`
}

DataEntry 数据包条目(对应 tl-env DataStruc,JSON 字段名兼容)

type DataPackage

type DataPackage struct {
	DB       string         `json:"db"`
	Entries  []*DataEntry   `json:"datas"`
	MapIndex map[string]int `json:"index"`
	// contains filtered or unexported fields
}

DataPackage 数据交换包:dqex 数据格式契约(JSON 结构与 tl-env DataHolder 兼容, 格式冻结后写入 docs/library.md)。适用于业务配置类中小数据量的精确导入与回滚, 不适用于大批量数据(整包驻留内存)。

func LoadDataPackage

func LoadDataPackage(data []byte) (*DataPackage, error)

LoadDataPackage 从 JSON 字节解析数据包。 使用 UseNumber:数字解码为 json.Number(string kind)而非 float64——雪花 ID 等 超过 float64 尾数精度(2^53)的整数主键往返不失真,且不会以科学计数法进入回滚 SQL 的 IN 匹配;json.Number 经 %v 输出原文,参数化写入时由 database/sql 转为 string 落库(数字列隐式转换),行为安全。 datas 数组中的 null 条目(外部不可信输入)直接丢弃,防止应用时 nil 解引用 panic。

func LoadDataPackageFile

func LoadDataPackageFile(path string) (*DataPackage, error)

LoadDataPackageFile 从 .json 文件加载数据包(顶层无 "datas"/"db" 字段时视为非数据包格式)

func (*DataPackage) Add

func (p *DataPackage) Add(table string, entry DataEntry)

Add 追加条目:同表**同类型**数据合并到既有条目;同表不同类型(建表 type=0 与 数据 type=1)为独立条目,按添加顺序应用(先建表后写数据)。 合并索引按 (表,类型) 复合键——MapIndex 单键在"先建表后写数据"的默认导出路径下 恒指向 type=0 条目,数据条目将无法合并(每行独立成条,JSON 膨胀)。 MapIndex 契约不变:仍指向该表首个条目(兼容 tl-env 格式)。 直接构造 DataPackage(未经 LoadDataPackage)时索引为 nil,此处懒初始化兜底

func (*DataPackage) GetTable

func (p *DataPackage) GetTable(table string) (*DataEntry, bool)

GetTable 取表对应条目

type DataPrepareRequest

type DataPrepareRequest struct {
	// Key 目标连接 connKey(宿主据此路由 env 级业务上下文)
	Key string
	// DB 目标库名(注册键相同)
	DB string
	// Package 待应用的数据包(宿主可原地修改)
	Package *DataPackage
}

DataPrepareRequest 数据前置处理请求

type DataPreparer

type DataPreparer func(ctx context.Context, req DataPrepareRequest) (context.Context, *DataPackage, error)

DataPreparer 数据前置处理器(代理层,按目标库名注册):导入 .json 数据包应用前 回调宿主执行业务策略(如流程/表单版本合并),可直接修改包内容后返回。 返回值:新 ctx(可为 nil,引擎回退原 ctx;派生的值/取消能力传播到后续数据包应用流程)、 修改后的包(nil 表示沿用入参)、错误。 回调契约与 Contributor 一致:运行在任务 goroutine,取消由 ctx 控制。

type DeleteRowParams

type DeleteRowParams struct {
	Table     string   // 表名(不含库前缀)
	PKColumns []string // 主键列名(可复合主键)
	PKValues  []any    // 主键值,与 PKColumns 顺序一致
}

DeleteRowParams 删除整行参数:表名、主键列及值(用于 WHERE 等值定位)。

type DictionaryOptions

type DictionaryOptions struct {
	SourceConn string        `json:"sourceConn" yaml:"sourceConn"` // 已保存连接名(与 Source 二选一)
	Source     *DBConnInfo   `json:"source,omitempty" yaml:"source,omitempty"`
	OutputDir  string        `json:"outputDir" yaml:"outputDir"`                       // 导出根目录,默认数据目录下 exports/
	TaskName   string        `json:"taskName" yaml:"taskName"`                         // 用于生成产物文件名
	Databases  []string      `json:"databases" yaml:"databases"`                       // 指定库(空=连接配置的库)
	Tables     []string      `json:"tables" yaml:"tables"`                             // 指定表(nil=全部,空数组=不导出)
	Selections []DBSelection `json:"selections,omitempty" yaml:"selections,omitempty"` // 结构化库→表选择(优先于 Databases/Tables)
	Compress   bool          `json:"compress" yaml:"compress"`                         // 是否打包 zip,默认 true
	Lang       string        `json:"lang,omitempty" yaml:"lang,omitempty"`             // 产物文案语言(zh/en),默认 zh
	// User 任务发起人标识(宿主注入):随 OnTaskStart 透传宿主。运行时注入不入任务配置
	User string `json:"-" yaml:"-"`
}

DictionaryOptions 数据字典导出选项:按选定库表生成单个 .xlsx 数据字典(总览 + 每库字段明细)

type ExportDesc

type ExportDesc struct {
	Database   string              `json:"database"`          // 数据库名
	ExportTime string              `json:"exportTime"`        // 导出时间
	DBType     string              `json:"dbType"`            // 数据库类型(mysql/postgresql/oracle)
	Mode       string              `json:"mode"`              // 导出模式:schema+data / schemaOnly / dataOnly
	Tables     []ExportDescTable   `json:"tables,omitempty"`  // 表列表(含行数、条件)
	Objects    map[string][]string `json:"objects,omitempty"` // 对象:_views/_functions/_procedures → 名称列表
}

ExportDesc 导出描述文件(.desc)内容,与 .sql 文件同名,JSON 格式 导入时直接读取此文件即可获取导出元信息,无需解析 SQL 内容

type ExportDescTable

type ExportDescTable struct {
	Name    string   `json:"name"`
	Rows    int64    `json:"rows"`
	Query   string   `json:"query,omitempty"`   // 完整 SELECT(按条件导出时记录)
	Where   string   `json:"where,omitempty"`   // Deprecated: 旧版导出文件的 WHERE 条件
	Columns []string `json:"columns,omitempty"` // Deprecated: 旧版导出文件的导出列
}

ExportDescTable 导出描述中的表信息 Where/Columns 为旧版导出文件字段,仅读取兼容(展示旧文件用),新导出一律只写 Query

type ExportDetail

type ExportDetail struct {
	Database string            // 库名(引擎枚举的库名;Oracle 为 schema(user))
	Kind     string            // 明细类型:DetailKindTable/View/Function/Procedure
	Name     string            // 引擎实际表/对象名(PG 系表名可能为 "schema.table" 限定形式)
	Rows     int64             // 导出行数(仅 table;对象恒为 0)
	Query    string            // 条件取数归一化后的完整 SELECT(仅 table 条件导出时非空)
	Ddl      string            // 建表/对象 DDL(DataOnly 或获取失败时为空)
	Comment  string            // 表注释(仅 table;元数据不可得时为空)
	Columns  []TableColumnInfo // 列明细(仅 table,名称/类型/可空/主键/默认值/注释等;DataOnly 或元数据不可得时为空)
}

ExportDetail 导出明细回调条目:单表/单对象导出完成时同步通知宿主, 供清单/审计等旁路采集使用(宿主根据回调数据与自身上下文自行处理)。

type ExportFormat

type ExportFormat string

ExportFormat 导出产物格式

const (
	FormatSQL  ExportFormat = "sql"  // SQL 文本(默认,现行行为)
	FormatJSON ExportFormat = "json" // DataPackage 数据包(按 PK 组织行数据)
)

type ExportOptions

type ExportOptions struct {
	SourceConn string           `json:"sourceConn" yaml:"sourceConn"` // 已保存连接名(与 Source 二选一)
	Source     *DBConnInfo      `json:"source,omitempty" yaml:"source,omitempty"`
	OutputDir  string           `json:"outputDir" yaml:"outputDir"`                       // 导出根目录,默认数据目录下 exports/
	TaskName   string           `json:"taskName" yaml:"taskName"`                         // 用于生成 zip 文件名
	Databases  []string         `json:"databases" yaml:"databases"`                       // 指定库(空=连接配置的库)
	Tables     []string         `json:"tables" yaml:"tables"`                             // 指定表(nil=全部,空数组=不导出)
	Objects    []string         `json:"objects" yaml:"objects"`                           // 指定对象,格式 _views/名称(nil=全部,空数组=不导出)
	Selections []DBSelection    `json:"selections,omitempty" yaml:"selections,omitempty"` // 结构化库→表/对象选择(优先于 Databases/Tables/Objects)
	Conditions []TableCondition `json:"conditions" yaml:"conditions"`
	SchemaOnly bool             `json:"schemaOnly" yaml:"schemaOnly"` // 仅导出结构
	DataOnly   bool             `json:"dataOnly" yaml:"dataOnly"`     // 仅导出数据
	BatchSize  int              `json:"batchSize" yaml:"batchSize"`
	Compress   bool             `json:"compress" yaml:"compress"` // 是否打包 zip,默认 true
	// SingleTransaction 一致性快照导出(等同 mysqldump --single-transaction):
	// 全程在同一事务内读取,跨表数据处于同一时间点,避免运行中库导出出不一致状态
	SingleTransaction bool `json:"singleTransaction" yaml:"singleTransaction"`
	// Gzip 将 SQL 文件 gzip 压缩为 .sql.gz(导入侧透明解压;与 Compress 同时开启时 zip 内为 .sql.gz)
	Gzip bool `json:"gzip" yaml:"gzip"`
	// CompatCollation 兼容排序规则:将 MySQL 8.0 特有排序规则(如 utf8mb4_0900_ai_ci)
	// 替换为 MySQL 5.7 兼容的 utf8mb4_unicode_ci,使导出 SQL 可在低版本 MySQL 上执行。
	// 仅对 MySQL 导出的建表 DDL 生效(表级和列级 COLLATE)。
	CompatCollation bool `json:"compatCollation" yaml:"compatCollation"`
	// Lang 任务日志/产物文案语言(zh/en),默认 zh
	Lang string `json:"lang,omitempty" yaml:"lang,omitempty"`
	// User 任务发起人标识(宿主注入,如 X-DQEX-User 登录名):随 OnTaskStart 透传宿主。
	// 运行时注入不入任务配置。
	User string `json:"-" yaml:"-"`
	// Contributors 业务对象贡献者(代理层):宿主注册回调,编排由 dqex 负责。
	// 仅需 Type + IDs(配置层可序列化),Export/Import 回调为空时由服务层按 Type
	// 匹配 Client 注册的模板补齐(未注册报错)。
	Contributors []Contributor `json:"contributors,omitempty" yaml:"contributors,omitempty"`
	// Format 产物格式:FormatSQL(默认,SQL 文本)或 FormatJSON(DataPackage 数据包,
	// 每库一个 <db>.json,支持精确回滚导入)。json 格式适用于业务配置类中小表数据。
	Format ExportFormat `json:"format,omitempty" yaml:"format,omitempty"`
	// OnDetail 导出明细回调(可选):每张表/每个对象导出完成时同步调用,fire-and-forget——
	// 无返回值,回调行为(panic/耗时)由宿主自负,不影响导出主流程。
	// 导出循环为单 goroutine 顺序调用,宿主侧无需加锁;每表恰好回调一次
	// (skip/无数据表 Rows=0),对象在 DDL 写入成功后回调。
	OnDetail func(ExportDetail) `json:"-" yaml:"-"`
}

ExportOptions 导出选项

type ExportResult

type ExportResult struct {
	OutputPath  string // 最终产物路径(zip 或目录)
	OutputDir   string // 导出明细目录
	TotalTables int
	TotalRows   int64
}

ExportResult 导出结果

func RunDictionary

func RunDictionary(ctx context.Context, opts DictionaryOptions, cb ProgressFunc) (*ExportResult, error)

RunDictionary 生成数据字典:选定库表 → 单个 .xlsx(总览 + 每库字段明细)→ 可选 zip 打包

产物组织(面向整体交付物):

  • Sheet "总览"(固定第一个):封面标题区 + 全实例表清单(库名/表名/注释/列数), 表名经定义名称超链接精确跳转到所属库明细 sheet 的对应表分区
  • 每库一个明细 sheet:首行全局列头(冻结 + 筛选),表与表之间以分组标题行分隔, 斑马纹按表分区重置,主键列高亮

func RunExport

func RunExport(ctx context.Context, opts ExportOptions, cb ProgressFunc) (*ExportResult, error)

RunExport 执行导出:多库多表 → {outputDir}/{taskName}_{时间}/库名.sql → 可选 zip 打包

每个数据库导出为单个 SQL 文件,文件内按以下顺序组织:

  1. 建表语句(CREATE TABLE,含触发器——底层库方言的 GetCreateTableSql 已一并返回)
  2. 视图(CREATE VIEW)
  3. 函数(CREATE FUNCTION)
  4. 存储过程(CREATE PROCEDURE)

表之间按外键依赖拓扑排序,确保导入时被引用表先创建。全部内容在单个文件内, 可直接体现依赖顺序;前置/收尾语句(如 SET FOREIGN_KEY_CHECKS)包裹整个文件。

type FilterOp

type FilterOp string

FilterOp 列过滤操作符(前端 FilterOp 与后端严格对齐,后端枚举白名单校验防注入)。

const (
	FilterEq          FilterOp = "eq"          // 等于
	FilterNeq         FilterOp = "neq"         // 不等于
	FilterContains    FilterOp = "contains"    // 包含(LIKE %v%)
	FilterNotContains FilterOp = "notContains" // 不包含(NOT LIKE %v%)
	FilterStartsWith  FilterOp = "startsWith"  // 开头是(LIKE v%)
	FilterEndsWith    FilterOp = "endsWith"    // 结尾是(LIKE %v)
	FilterGt          FilterOp = "gt"          // 大于
	FilterGte         FilterOp = "gte"         // 大于等于
	FilterLt          FilterOp = "lt"          // 小于
	FilterLte         FilterOp = "lte"         // 小于等于
	FilterIsNull      FilterOp = "isNull"      // 为空
	FilterIsNotNull   FilterOp = "isNotNull"   // 非空
)

type GenSQLKind

type GenSQLKind string

GenSQLKind 快速生成 SQL 的类型(白名单校验,防止前端被篡改后传入未知类型)。

const (
	GenSQLInsert         GenSQLKind = "insert"         // 行/多行 INSERT(跳过自增列)
	GenSQLUpdate         GenSQLKind = "update"         // 单行 UPDATE(SET 非主键列,WHERE 主键)
	GenSQLDelete         GenSQLKind = "delete"         // 单行 DELETE(WHERE 主键)
	GenSQLSelectByPK     GenSQLKind = "selectByPk"     // 单行 SELECT(WHERE 主键)
	GenSQLSelectByFilter GenSQLKind = "selectByFilter" // 按当前过滤条件 + 排序 SELECT
	GenSQLWhereCell      GenSQLKind = "whereCell"      // 单元格等于值条件 SELECT
)

type GenSQLParams

type GenSQLParams struct {
	Table       string         `json:"table"`       // 表名(不含库前缀)
	Kind        GenSQLKind     `json:"kind"`        // 生成类型
	Columns     []string       `json:"columns"`     // 列清单(与 Rows 列序一致;whereCell 时仅 1 个 = 条件列名)
	Rows        [][]any        `json:"rows"`        // 行数据(insert 支持多行;其余取首行;whereCell 时 [[值]])
	PKColumns   []string       `json:"pkColumns"`   // 主键列名(update/delete/selectByPk)
	SkipColumns []string       `json:"skipColumns"` // 跳过的列(insert 的自增列)
	Filters     []ColumnFilter `json:"filters"`     // 过滤条件(selectByFilter)
	SortSpecs   []SortSpec     `json:"sortSpecs"`   // 排序(selectByFilter)
}

GenSQLParams 快速生成 SQL 请求参数。 行数据/主键值/单元格值均来自表浏览当前页展示数据;生成仅产出文本、不执行。

type ImportFileInfo

type ImportFileInfo struct {
	Type      string                 `json:"type"` // sql / json / zip
	Size      int64                  `json:"size"`
	Databases []string               `json:"databases"`
	Descs     map[string]*ExportDesc `json:"descs,omitempty"`   // 库名 → 导出描述(如有)
	Entries   int                    `json:"entries,omitempty"` // 条目数(json 数据包格式)
}

ImportFileInfo 导入文件预览信息

func InspectImportFile

func InspectImportFile(path string) (*ImportFileInfo, error)

InspectImportFile 预览导入文件信息(不解压执行) 如果存在同名 .desc 描述文件,会读取其中的元信息(表列表、对象、条件等)

type ImportOptions

type ImportOptions struct {
	TargetConn string      `json:"targetConn" yaml:"targetConn"`
	Target     *DBConnInfo `json:"target,omitempty" yaml:"target,omitempty"`
	InputPath  string      `json:"inputPath" yaml:"inputPath"` // 支持 .sql 单文件 或 .zip 包
	ResetMode  ResetMode   `json:"resetMode" yaml:"resetMode"` // 重置模式: "" / "truncate" / "drop"
	Backup     bool        `json:"backup" yaml:"backup"`       // 重置前在目标库创建备份表(默认 true,仅 reset != none 时生效)
	BatchSize  int         `json:"batchSize" yaml:"batchSize"`
	TempDir    string      `json:"-" yaml:"-"` // 任务处理临时目录(zip 解压),空=系统临时目录;运行时注入不入任务配置
	// CompatCollation 兼容排序规则:将 SQL 文件中的 MySQL 8.0 特有排序规则(如 utf8mb4_0900_ai_ci)
	// 替换为 MySQL 5.7 兼容的 utf8mb4_unicode_ci。仅对 MySQL 目标的导入生效。
	CompatCollation bool `json:"compatCollation" yaml:"compatCollation"`
	// Lang 任务日志语言(zh/en),默认 zh
	Lang string `json:"lang,omitempty" yaml:"lang,omitempty"`
	// User 任务发起人标识(宿主注入):随 OnTaskStart 透传宿主。运行时注入不入任务配置
	User string `json:"-" yaml:"-"`
	// Contributors 业务对象贡献者(代理层):zip 包内含 <Type>/ 目录时回调 Import 读回。
	// 仅需 Type(+可选 IDs),回调为空时由服务层按 Type 匹配注册模板补齐。
	Contributors []Contributor `json:"contributors,omitempty" yaml:"contributors,omitempty"`
	// Rollback 生成精确回滚 SQL 产物(.json 数据导入按旧行快照生成;.sql 导入无行级
	// 语义仅失败自动回滚,不生成产物)。产物写入输入文件同目录 <名称>.rollback.sql。
	Rollback bool `json:"rollback" yaml:"rollback"`
	// DataPreparers 数据前置处理器(代理层,按目标库名注册):导入 .json 数据包前
	// 回调宿主做版本合并等业务策略(对应 tl-env PreProcess 语义),可修改包内容。
	// 运行时注入不入任务配置。
	DataPreparers map[string]DataPreparer `json:"-" yaml:"-"`
}

ImportOptions 导入选项

type ImportResult

type ImportResult struct {
	TotalDatabases int
	TotalStmts     int64    // 执行的 SQL 语句数
	RollbackPath   string   // 精确回滚 SQL 产物路径(仅 .json 数据导入且 Rollback=true 时非空;多库 zip 按库分文件,此为首个产物路径,其余经任务日志输出)
	SkippedTables  []string // 跳过的表(无主键,无法精确导入/回滚)
	Unrollback     []string // 执行了但无法生成精确回滚的语句(宿主侧告警)
}

ImportResult 导入结果

func RunImport

func RunImport(ctx context.Context, opts ImportOptions, cb ProgressFunc) (*ImportResult, error)

RunImport 执行导入:支持 .sql 单文件、.json 数据包(DataPackage,支持精确回滚) 与 .zip 包(每个 库名.sql / 库名.json 即一个库的导出;含 <Type>/ 目录时回调贡献者)

type InsertRowParams

type InsertRowParams struct {
	Table   string   // 表名(不含库前缀)
	Columns []string // 要写入的列名(与 Values 顺序一致)
	Values  []any    // 对应列的值(nil 表示 NULL)
}

InsertRowParams 新增行参数:表名、目标列名与值(列值映射)。 自增主键列通常不在 columns 中(由数据库生成),仅传用户显式填写的列。

type MigrateOptions

type MigrateOptions struct {
	SourceConn string      `json:"sourceConn" yaml:"sourceConn"`
	TargetConn string      `json:"targetConn" yaml:"targetConn"`
	Source     *DBConnInfo `json:"source,omitempty" yaml:"source,omitempty"`
	Target     *DBConnInfo `json:"target,omitempty" yaml:"target,omitempty"`
	Tables     []string    `json:"tables" yaml:"tables"`   // 指定表(nil=全部,空数组=不迁移)
	Objects    []string    `json:"objects" yaml:"objects"` // 指定对象,格式 _views/名称(nil=全部,空数组=不迁移;仅同类型生效)
	// Selections 结构化源库→表/对象选择(与 Tables/Objects 二选一,非空时优先)。
	// 多库迁移逐库执行:目标库为连接配置库(未配置时与源库同名)
	Selections []DBSelection    `json:"selections,omitempty" yaml:"selections,omitempty"`
	Conditions []TableCondition `json:"conditions" yaml:"conditions"`
	SchemaOnly bool             `json:"schemaOnly" yaml:"schemaOnly"`
	DataOnly   bool             `json:"dataOnly" yaml:"dataOnly"`
	ResetMode  ResetMode        `json:"resetMode" yaml:"resetMode"` // 重置模式: "" / "truncate" / "drop"
	Backup     bool             `json:"backup" yaml:"backup"`       // 重置前在目标库创建备份表(默认 true)
	BatchSize  int              `json:"batchSize" yaml:"batchSize"`
	// CompatCollation 兼容排序规则:将 MySQL 8.0 特有排序规则(如 utf8mb4_0900_ai_ci)
	// 替换为 MySQL 5.7 兼容的 utf8mb4_unicode_ci。
	// 仅对 MySQL 同类型迁移的建表 DDL 生效(表级和列级 COLLATE)。
	CompatCollation bool `json:"compatCollation" yaml:"compatCollation"`
	// Lang 任务日志/产物文案语言(zh/en),默认 zh
	Lang string `json:"lang,omitempty" yaml:"lang,omitempty"`
	// User 任务发起人标识(宿主注入):随 OnTaskStart 透传宿主。运行时注入不入任务配置
	User string `json:"-" yaml:"-"`
}

MigrateOptions 迁移选项

type MigrateResult

type MigrateResult struct {
	TotalTables int
	TotalRows   int64
}

MigrateResult 迁移结果

func RunMigrate

func RunMigrate(ctx context.Context, opts MigrateOptions, cb ProgressFunc) (*MigrateResult, error)

RunMigrate 执行迁移:源库 → 目标库。 结构化选择(Selections)时逐库迁移:每库独立连接源侧,目标库为连接配置库(未配置时与源库同名,不存在自动创建); 旧格式(Tables/Objects)保持单库(源连接配置库)。Oracle 的“库”语义为 schema。 两种模式的数据均以行数据为媒介(源库流式 SELECT → 批量 BatchReplace),不经过 SQL 文本。 同类型:表结构用源库原生 DDL(触发器随建表语句一并迁移),表迁移完成后追加迁移视图/函数/存储过程; 跨类型:仅迁表(结构由源库标准化 TableInfo + 目标方言 MigrationDialect 自动转换), 触发器/视图/函数/存储过程为源库方言对象,不迁移

type MsgError

type MsgError struct {
	Key   string // 错误注册表模板 key
	Args  []any  // 模板参数
	Cause error  // 底层原因(原 ": %w" 包装),可为 nil
}

MsgError 结构化业务错误

func AsMsgErr

func AsMsgErr(err error) *MsgError

AsMsgErr 提取错误链中的 *MsgError(无则返回 nil)

func (*MsgError) Error

func (e *MsgError) Error() string

func (*MsgError) Msg

func (e *MsgError) Msg(lang string) string

Msg 按指定语言渲染错误文本(含底层原因)

func (*MsgError) Unwrap

func (e *MsgError) Unwrap() error

type ObjectDDLType

type ObjectDDLType string

ObjectDDLType 可供查询创建语句的对象类型(对应用户可见的 DDL 对象)

const (
	ObjectDDLTable     ObjectDDLType = "table"
	ObjectDDLView      ObjectDDLType = "view"
	ObjectDDLFunction  ObjectDDLType = "function"
	ObjectDDLProcedure ObjectDDLType = "procedure"
)

type Progress

type Progress struct {
	State        string   `json:"state"` // idle/running/done/error/cancelled
	TaskID       string   `json:"taskID"`
	TotalUnits   int      `json:"totalUnits"` // 工作单元总数(表 + 视图/函数/存储过程等对象)
	CurrentTable string   `json:"currentTable"`
	Phase        string   `json:"phase,omitempty"` // 当前表所处阶段:schema=结构(DDL)/ data=数据(行导出);空=未细分(对象/收尾等)
	DoneUnits    int      `json:"doneUnits"`
	TotalRows    int64    `json:"totalRows"`
	DoneRows     int64    `json:"doneRows"`
	Percent      float64  `json:"percent"`
	Message      string   `json:"message"`
	MsgSeq       int      `json:"msgSeq"`               // 事件序号:每次 log() 追加新事件时递增;节流快照不变。宿主据此区分"新事件"与"快照刷新",无需比对消息文本
	OutputPath   string   `json:"outputPath,omitempty"` // 导出完成后的文件路径
	DurationMs   int64    `json:"durationMs,omitempty"` // 任务总耗时(仅终态回放时由执行历史填充,实时推送时前端自行计时)
	Logs         []string `json:"logs"`
}

Progress 任务进度信息

type ProgressFunc

type ProgressFunc func(Progress)

ProgressFunc 进度回调

type QueryHooks

type QueryHooks struct {
	// OnQuery 语句执行完成回调:stmt 为语句文本(超长截断至 4096 字节,截断点回退至
	// UTF-8 字符边界;宿主自行做摘要/脱敏);
	// costMs 为执行耗时(毫秒);rowsAffected 写操作为受影响行数,查询为返回行数。
	// 失败语句同样回调(rowsAffected = -1),宿主可据此记录失败审计。
	OnQuery func(ctx context.Context, connKey, stmt string, costMs int64, rowsAffected int64)
}

QueryHooks SQL 审计钩子:宿主在每次语句执行后收到回调,用于合规审计/慢查询采集。 注册方式:宿主经 Client 选项注入(见根包 WithQueryHooks),引擎经 context 传递到执行点。 回调契约:同步调用、不得阻塞(审计耗时直接累加到语句响应时间);回调内不得再回调 Client 方法;多任务并行时 OnQuery 会被多 goroutine 并发调用,宿主回调需自行保证并发安全。

type ResetMode

type ResetMode string

ResetMode 重置数据模式

const (
	ResetNone     ResetMode = ""         // 不重置,直接追加(默认)
	ResetTruncate ResetMode = "truncate" // 清空表(TRUNCATE),保留表结构
	ResetDrop     ResetMode = "drop"     // 删除重建(DROP + CREATE)
)

type SQLQueryResult

type SQLQueryResult struct {
	Columns      []string `json:"columns"`
	Rows         [][]any  `json:"rows"`
	RowCount     int      `json:"rowCount"`
	AffectedRows int64    `json:"affectedRows"`
	Elapsed      int64    `json:"elapsedMs"` // 毫秒
	SQL          string   `json:"sql"`
	IsWrite      bool     `json:"isWrite"`
	Warnings     []string `json:"warnings"`
	Error        string   `json:"error,omitempty"`   // 执行失败原因(非空时视为失败结果,正常返回给前端展示)
	Skipped      bool     `json:"skipped,omitempty"` // 未执行:因前面语句失败而跳过的语句(仅占位,无结果)
}

SQLQueryResult 查询/执行结果(Web 查询终端使用)

func RunSQLExec

func RunSQLExec(ctx context.Context, cli *cydb.DBCli, sql string) (*SQLQueryResult, error)

RunSQLExec 执行写操作 SQL(INSERT/UPDATE/DELETE/DDL)。 调用方(Web handler)必须已完成危险语句拦截与写操作确认。

func RunSQLQuery

func RunSQLQuery(ctx context.Context, cli *cydb.DBCli, sql string, limit, offset int, mode string) (*SQLQueryResult, error)

RunSQLQuery 执行查询类 SQL(SELECT/SHOW 等),自动追加 LIMIT 上限保护。 返回结果及耗时;写操作直接报错(写操作请走 RunSQLExec)。

mode 控制执行模式:

  • "transform"(默认):解析重构 + 自动补 LIMIT 上限(无 LIMIT 才补,已含则原样);
  • "raw":原始 SQL 直传,不做转换/限制(用于解析重构异常时的兜底,由用户自行负责行数)。

无论何种模式,危险函数与写操作始终拦截(安全底线不因 raw 而关闭)。

func RunSQLScript

func RunSQLScript(ctx context.Context, cli *cydb.DBCli, sql string, limit, offset int, mode string, connKey string) ([]*SQLQueryResult, error)

RunSQLScript 批量执行多语句 SQL(Navicat 式):按分号分割,逐条判断读写, 读语句走查询(含 LIMIT 护栏与方言重构),写语句走执行,返回结果集数组(顺序与语句一致)。

失败策略:语句级失败时停止后续执行(避免依赖后续语句错乱),但保留已成功的结果集, 并在失败语句的对应位置插入错误占位结果(Error 非空),后续语句逐个插入「未执行」占位 (Skipped=true)——前端在多结果集 tab 上定位显示,而非整体失败丢弃全部结果。 错误占位携带失败语句原文(SQL 字段),不依赖「第 N 条」序号。

语句分割复用底层库 cydb.SplitSQLStatements(正确处理字符串/引号/三种注释内的分号)。 写操作的安全确认由调用方(Web handler / 前端)在进入本函数前完成; 本函数仍会对每条语句做危险函数拦截(安全底线)。 RunSQLScript 批量执行多语句脚本:按分号分割,逐条判断读写并执行,返回结果集数组。 connKey 用于审计钩子归属(QueryHooks 经 ctx 注册时逐语句回调 OnQuery)。

type SchemaSummary

type SchemaSummary struct {
	Name       string `json:"name"`
	TableCount int    `json:"tableCount"` // 表数量(视图/函数等不计入,展开后见明细)
}

SchemaSummary 库内 schema 概要(对象树分级第二层,PG 系)

func GetDbSchemas

func GetDbSchemas(conn DBConnInfo, db string) ([]SchemaSummary, error)

GetDbSchemas 返回库的 schema 列表(含表计数,PG 系,一次往返); 非 PG 系返回空列表(前端走 GetDbObjects 加载库对象)。 实现下沉方言层 GetSchemaSummaries,系统 schema 黑名单由方言一处维护。

type Snapshot

type Snapshot struct {
	ID          string             `json:"id"`
	Name        string             `json:"name"`
	Description string             `json:"description,omitempty"`
	ConnID      string             `json:"connId"`    // 来源连接 ID(允许连接被删除后快照仍可读)
	ConnLabel   string             `json:"connLabel"` // 冗余连接名称
	DBType      string             `json:"dbType"`
	CreatedAt   int64              `json:"createdAt"` // unix 秒
	TableCount  int                `json:"tableCount"`
	TotalRows   int64              `json:"totalRows"`
	Databases   []SnapshotDatabase `json:"databases"`        // 多库快照
	DBName      string             `json:"dbName,omitempty"` // 兼容字段(单库旧快照),新写入不再使用
	Tables      []SnapshotTable    `json:"tables,omitempty"` // 兼容字段(单库旧快照)
}

Snapshot 快照完整数据(单个快照文件内容,与索引分离以减少列表加载开销) 支持覆盖多库:Databases 为各库快照,根上的 DBName/Tables 仅作单库兼容读取(v1 旧文件)

func CreateSnapshot

func CreateSnapshot(ctx context.Context, conn *DBConnInfo, name, description string, opts CreateSnapshotOptions, cb ProgressFunc) (*Snapshot, error)

CreateSnapshot 连接数据库并创建快照:读取所有表结构 + 行数 + 可选采样。 作用域为单个库(Oracle 为 schema),通过 conn 的 DBName/Schema 确定。

func LoadSnapshot

func LoadSnapshot(path string) (*Snapshot, error)

LoadSnapshot 从 JSON 文件加载快照完整数据

type SnapshotColumn

type SnapshotColumn struct {
	Name           string `json:"name"`
	DataType       string `json:"dataType"`                 // 原始类型
	NormalizedType string `json:"normalizedType,omitempty"` // 按快照库方言归一后的类型(写入时固化)
	Nullable       bool   `json:"nullable"`
	PrimaryKey     bool   `json:"primaryKey"`
	Position       int    `json:"position"`
}

SnapshotColumn 列快照

type SnapshotCompareOptions

type SnapshotCompareOptions struct {
	SnapshotID string            `json:"snapshotId"`
	TargetConn string            `json:"targetConn"`
	Target     *DBConnInfo       `json:"target,omitempty"`
	DBMapping  map[string]string `json:"dbMapping,omitempty"` // 快照库名→目标库名映射(默认同名)
	Tables     []string          `json:"tables,omitempty"`    // 限定对比的表,nil=全部("库.表" 或裸名)
	// Lang 任务日志语言(zh/en),默认 zh
	Lang string `json:"lang,omitempty"`
	// User 任务发起人标识(宿主注入):随 OnTaskStart 透传宿主。运行时注入不入任务配置
	User string `json:"-"`
}

SnapshotCompareOptions 快照对比选项

type SnapshotDatabase

type SnapshotDatabase struct {
	DBName     string          `json:"dbName"`
	TableCount int             `json:"tableCount"`
	TotalRows  int64           `json:"totalRows"`
	Tables     []SnapshotTable `json:"tables"`
}

SnapshotDatabase 单库快照

type SnapshotInfo

type SnapshotInfo struct {
	ID          string   `json:"id"`
	Name        string   `json:"name"`
	Description string   `json:"description,omitempty"`
	ConnID      string   `json:"connId"`
	ConnLabel   string   `json:"connLabel"`
	DBNames     []string `json:"dbNames"`
	DBName      string   `json:"dbName,omitempty"` // 兼容字段
	DBType      string   `json:"dbType"`
	TableCount  int      `json:"tableCount"`
	TotalRows   int64    `json:"totalRows"`
	CreatedAt   int64    `json:"createdAt"` // unix 秒
}

SnapshotInfo 快照摘要(索引文件条目,不包含表详情) DBNames 为多库列表;DBName 兼容字段(单库旧快照)

type SnapshotTable

type SnapshotTable struct {
	Name       string           `json:"name"`
	RowCount   int64            `json:"rowCount"`
	Columns    []SnapshotColumn `json:"columns"`
	PrimaryKey []string         `json:"primaryKey,omitempty"`
	RowSamples []map[string]any `json:"rowSamples,omitempty"` // 前 N 行采样(创建时可选)
}

SnapshotTable 单表快照

type SortSpec

type SortSpec struct {
	Column string `json:"column"`
	Order  string `json:"order"` // "asc" | "desc"
}

SortSpec 单列排序规格(多列排序:按切片顺序叠加 ORDER BY,优先级从高到低)。

type TableAlias

type TableAlias struct {
	Source        string   `json:"source" yaml:"source"`
	Target        string   `json:"target" yaml:"target"`
	IgnoreColumns []string `json:"ignoreColumns,omitempty" yaml:"ignoreColumns,omitempty"` // 表级忽略列(列名大小写不敏感)
}

TableAlias 表级对比配置:源表 ↔ 目标表(不同名但逻辑对应,Target 空=同名匹配), Source 支持限定名 "库.表",用于多库场景下精确配置某个库的同名表。 并可单独指定该表数据对比的忽略列(与全局忽略列合并生效)

type TableColumnInfo

type TableColumnInfo struct {
	Name          string `json:"name"`
	DataType      string `json:"dataType"`             // 原始数据类型(如 varchar(255), int, timestamp)
	Nullable      bool   `json:"nullable"`             // 是否允许 NULL
	PrimaryKey    bool   `json:"primaryKey,omitempty"` // 是否主键
	Default       string `json:"default,omitempty"`    // 默认值
	AutoIncrement bool   `json:"autoIncrement,omitempty"`
	Unique        bool   `json:"unique,omitempty"`  // 是否唯一约束(非主键)
	Indexed       bool   `json:"indexed,omitempty"` // 是否有普通索引(非主键/非唯一)
	Comment       string `json:"comment,omitempty"` // 列注释(可能为空)
}

TableColumnInfo 表列信息(JSON 返回给前端用于条件编辑辅助)

func GetTableColumns

func GetTableColumns(conn DBConnInfo, tableName string) ([]TableColumnInfo, error)

GetTableColumns 获取指定表的列信息(名称/类型/可空/主键/默认值/注释,复用池化连接)。

type TableCondition

type TableCondition struct {
	TableName string        `json:"tableName" yaml:"tableName"`
	DataMode  TableDataMode `json:"dataMode,omitempty" yaml:"dataMode,omitempty"` // 数据导出模式
	Query     string        `json:"query,omitempty" yaml:"query,omitempty"`       // 完整 SELECT 语句(仅 dataMode=condition 时生效)
	Where     string        `json:"where,omitempty" yaml:"where,omitempty"`       // Deprecated: 旧版 WHERE 条件,仅读取兼容
	Columns   []string      `json:"columns,omitempty" yaml:"columns,omitempty"`   // Deprecated: 旧版导出列,仅读取兼容
}

TableCondition 表级数据过滤条件:统一为完整 SELECT(Query)。 Where/Columns 为旧版配置字段,仅读取兼容(归一化拼装为 SELECT,见 conditionQuery),不再写入新值。

type TableDataMode

type TableDataMode string

TableDataMode 表数据导出模式

const (
	TableDataModeAll       TableDataMode = ""          // 默认:导出所有数据
	TableDataModeSkip      TableDataMode = "skip"      // 不导出数据
	TableDataModeCondition TableDataMode = "condition" // 根据条件导出数据
)

type TableMeta

type TableMeta struct {
	Comment string            // 表注释(可能为空)
	Columns []TableColumnInfo // 列信息(含列注释)
}

TableMeta 表级元数据(表注释 + 列信息,供 AI 上下文等场景一次取全)。

func GetTableMeta

func GetTableMeta(conn DBConnInfo, tableName string) (TableMeta, error)

GetTableMeta 获取指定表的元数据(表注释 + 列信息含注释,复用池化连接)。

type TablePageResult

type TablePageResult struct {
	Columns        []string `json:"columns"`
	Rows           [][]any  `json:"rows"`
	Total          int64    `json:"total"`
	Page           int      `json:"page"`
	PageSize       int      `json:"pageSize"`
	ExcludeColumns []string `json:"excludeColumns,omitempty"` // 被省略的大字段列名(值为 NULL,前端渲染占位)
}

TablePageResult 表数据分页查询结果(对象树数据浏览专用), 一次返回当前页数据与全表总行数,避免前端再发一次 COUNT(*) 造成审计冗余。

func QueryTablePage

func QueryTablePage(ctx context.Context, cli *cydb.DBCli, table string, page, pageSize int, sortSpecs []SortSpec, excludeColumns []string, filters []ColumnFilter) (*TablePageResult, error)

QueryTablePage 分页查询单表数据并返回全表总行数(对象树数据浏览专用)。 table 为已校验的表名(调用方负责白名单/反引号转义);sortSpecs 非空时按顺序叠加 ORDER BY(多列排序)。 excludeColumns 为需要省略的大字段列名(二进制/超长文本),这些列在列表查询时用 NULL 占位, 前端据此渲染「点击加载」占位,避免一次传输大量无意义数据;点击单元格时再按需单独取值。 总数与数据通过 cydb 的 QueryPagedResult 一次获取(内部自动做 COUNT,忽略 ORDER BY/LIMIT/OFFSET), 与数据查询共用同一连接,杜绝前端二次 COUNT 的审计冗余与并发漂移。

filters 为列过滤条件(AND 叠加),复用 cydb 条件构建器(值参数化绑定 + LIKE 自动转义), 不手写 SQL 拼接;列名通过 GetTableInfo 白名单校验(失败时降级为仅结构化转义,不阻塞查询)。

type UpdateCellParams

type UpdateCellParams struct {
	Table     string   // 表名(不含库前缀)
	SetColumn string   // 目标列名
	SetValue  any      // 目标列新值(nil 表示 SET NULL)
	PKColumns []string // 主键列名(可复合主键)
	PKValues  []any    // 主键值,与 PKColumns 顺序一致
}

UpdateCellParams 单元格更新参数:表名、目标列、主键列及值(用于 WHERE 等值定位)。

type ValueDiff

type ValueDiff struct {
	Column string `json:"column"`
	Source any    `json:"source"`
	Target any    `json:"target"`
}

ValueDiff 单列取值差异

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL