- 数据库
- 数据库客户端
- 桌面应用
- 后端
【免费下载链接】dbgate
Database manager for MySQL, PostgreSQL, SQL Server, MongoDB, SQLite and others. Runs under Windows, Linux, Mac or as web application
导读
DbGate 是一个支持 MySQL、PostgreSQL、SQL Server、MongoDB、SQLite 等数十种数据库的统一管理工具,其多引擎架构之所以能保持清晰一致,关键在于一个独立的纯类型包——dbgate-types。本文以 packages/types/README.md 为骨架,逐一拆解数据库结构(dbinfo)、SQL 方言(dialect)、SQL 生成器(dumper)、引擎驱动(engines)、查询结果(query)与插件扩展(extensions)六大类型域,并结合仓库源码说明这些类型契约如何被真实驱动与工具链消费。读完本文,你将掌握 DbGate 类型系统各文件的作用边界、核心接口字段语义,以及如何基于这些类型开发自己的引擎驱动或插件。
一、定位与安装:一个只有类型、没有运行时的包
dbgate-types是 DbGate 的 TypeScript 类型定义包,正如其 README 所述:"Typescript definitions for DbGate app"。它的存在让不同引擎驱动(MySQL、PostgreSQL、Redis、Cassandra、DuckDB……)在编译期共享同一套结构描述,避免每个插件各自定义一份"表结构"或"驱动接口"。
从 packages/types/package.json 可以看到几个关键设计特征:
"types": "index.d.ts":类型入口指向index.d.ts,所有子模块通过它聚合导出;"main": "":没有运行时 JavaScript 实现,是纯粹的声明文件包;"typeScriptVersion": "2.8":声明了对较老 TS 版本的兼容。
安装方式即 README 给出的命令:
yarn add --dev dbgate-types作为开发期依赖安装即可,因为发布产物是类型声明,不影响最终运行。需要注意:README 中列出了 6 个核心类型文件,而实际的 packages/types/index.d.ts 通过export * from聚合导出了 10 个模块(engines、dbinfo、query、dialect、dumper、dbtypes、extensions、alter-processor、appdefs、filter-type、test-engines),比 README 清单更完整,下文会逐一覆盖。
二、dbinfo.d.ts:数据库结构描述的公共骨架
dbinfo.d.ts 是整个类型系统的基础,定义了 DbGate 眼中"一个数据库长什么样"。核心设计思想是:所有对象都继承NamedObjectInfo,统一携带pureName(对象名)与可选的schemaName(模式名)。
表与列
TableInfo聚合了表的全部要素:columns(列数组)、primaryKey(主键)、foreignKeys(外键)、indexes(索引)、uniques(唯一约束)、checks(检查约束),以及tableEngine、tableRowCount等物理信息。ColumnInfo则完整描述一列:
export interface ColumnInfo extends NamedObjectInfo { columnName: string; notNull?: boolean; autoIncrement?: boolean; dataType: string; displayedDataType?: string; precision?: number; scale?: number; length?: number; computedExpression?: string; isPersisted?: boolean; defaultValue?: string; columnComment?: string; isUnsigned?: boolean; hasAutoValue?: boolean; // ... }这些字段映射了不同数据库的列特征:precision/scale/length对应数值与字符类型的尺寸,computedExpression对应生成列,isUnsigned/isZerofill是 MySQL 特有标志,defaultConstraint用于 SQL Server 的命名默认约束。
约束体系
约束通过ConstraintInfo统一建模,constraintType收窄为六种:'primaryKey' | 'foreignKey' | 'sortingKey' | 'index' | 'check' | 'unique'。其中ForeignKeyInfo额外带有refSchemaName、refTableName与updateAction/deleteAction(级联行为),IndexInfo携带isUnique、indexType与 SQL Server 过滤索引的filterDefinition,CheckInfo直接保存definition表达式。
非关系型对象:集合、过程与触发器
DbGate 不仅管理关系型数据库,还通过CollectionInfo描述 Cassandra 这类文档/宽列存储:partitionKey(分区键)、clusterKey(分区内聚簇键)、uniqueKey与autoValueColumns共同构成集合的键体系。ProcedureInfo/FunctionInfo通过CallableObjectInfo携带parameters,参数模式由ParameterMode = 'IN' | 'OUT' | 'INOUT' | 'RETURN'限定;TriggerInfo用联合类型刻画触发时机(BEFORE/AFTER/INSTEAD OF/每行/语句级)与eventType(INSERT/UPDATE/DELETE/TRUNCATE)。
整个数据库与"精简版"变体
DatabaseInfo继承DatabaseInfoObjects,后者把tables、collections、views、matviews、procedures、functions、triggers、schedulerEvents全部收拢——这正是 packages/tools/src/database-info-alter-processor.ts 中this.db.tables.push(...)、this.db[obj.objectTypeField]等操作的直接依据。文件末尾还提供了ColumnInfoTiny/TableInfoTiny/DatabaseInfoTiny等紧凑变体,用单字母字段(n表示 name、t表示 type)压缩结构体积,用于 JSON 序列化传输场景。
三、engines.d.ts:引擎驱动必须实现的完整契约
engines.d.ts 定义了EngineDriver<TClient, TDataBase>接口——这是每个数据库插件后端最核心的契约。在真实插件中,它被以 JSDoc 形式显式引用,例如 plugins/dbgate-plugin-mysql/src/backend/drivers.js 第 80 行的/** @type {import('dbgate-types').EngineDriver} */,为纯 JavaScript 插件提供类型提示与约束。
生命周期:连接、查询与关闭
驱动必须实现的最基本方法包括:
connect({ server, port, user, password, database, connectionDefinition }): Promise<DatabaseHandle>; close(dbhan): Promise<any>; query(dbhan, sql, options?): Promise<QueryResult>; stream(dbhan, sql, options: StreamOptions); readQuery(dbhan, sql, structure?): Promise<StreamResult>; writeQueryFromStream(dbhan, sql): Promise<StreamResult>; writeTable(dbhan, name, options: WriteTableOptions): Promise<StreamResult>;其中DatabaseHandle是驱动与底层客户端库之间的桥接:client持有原生连接对象(如 mysql2 的 Connection),database记录当前库名,feedback用于回传消息。StreamOptions定义了recordset/row/error/done/info等回调,支撑查询结果的分块流式传输;StreamResult则允许返回单个stream.Readable或可读/可写流的组合。
能力开关:用布尔字段声明"支持什么"
EngineDriver中包含大量能力声明字段,前端 UI 与后端流程据此自动调整行为,例如:
supportsTransactions/implicitTransactions:是否支持事务、是否无需显式 BEGIN TRANSACTION;supportsEditableQueryResults:查询结果是否可直接编辑;supportsDatabaseUrl:连接是否可用 URL 表示(如mongodb://);supportsNativeBackup/supportsNodejsBackup:备份走原生命令行工具还是 Node.js 实现;supportsServerSummary:是否支持进程/变量/数据库汇总面板;singleConnectionOnly:是否只允许单连接;premiumOnly:是否仅专业版可用。
这些开关直接决定了 packages/web 前端界面中哪些按钮、标签页、表单选项对当前引擎可见,也是连接表单动态渲染(showConnectionField/showConnectionTab)的依据。
结构分析:analyseFull 与 analyseIncremental
驱动通过analyseFull(dbhan, serverVersion)返回完整DatabaseInfo,通过analyseIncremental在已有结构上增量补齐,配合analyseSingleObject/analyseSingleTable支持按需加载单个对象。incrementalAnalysis的能力由supportsIncrementalAnalysis声明。此外getVersion、listDatabases、listSchemas等服务于连接树的构建。
集合操作、脚本与杂项
CollectionOperationInfo用可辨识联合类型描述 create/drop/rename/clone 集合四种操作;readCollection/updateCollection/getCollectionUpdateScript支撑 NoSQL 集合浏览与编辑;getQuerySplitterOptions按用途(stream/script/editor/import)提供 SQL 拆分规则;getScriptTemplates提供建表/建视图等脚本模板;createSaveChangeSetScript让驱动有机会覆盖默认的变更集 SQL 生成逻辑。
四、dialect.d.ts:SQL 方言的能力差异描述
packages/tools/src/SqlDumper.ts 导入的类型表明,SqlDumper的构造器接收EngineDriver并读取driver.dialect。方言描述对象 dialect.d.ts 用大量布尔开关刻画"这家数据库的 SQL 长什么样":
- 分页风格:
rangeSelect(LIMIT/OFFSET)、topRecords(TOP n)、rowNumberOverPaging、offsetFetchRangeSyntax(SQL Server OFFSET…FETCH)、offsetFirstSkipSyntax(Mongo 风格 skip 在前); - 标识符与字符串:
quoteIdentifier(s)定义标识符引号规则(反引号 vs 双引号)、stringEscapeChar定义字符串转义符、maxIdentifierLength限制标识符长度; - 结构变更能力:
createColumn/dropColumn/changeColumn/createIndex/createForeignKey/createPrimaryKey/renameTable等一长串布尔开关,决定表编辑器允许哪些操作; - 兼容性开关:
requireFromDual(Oracle 的FROM DUAL)、userDatabaseNamePrefix(Oracle 的c##)、upperCaseAllDbObjectNames、disableAutoIncrement、defaultValueBeforeNullability(默认值在 NOT NULL 之前还是之后); - 数据类型:
predefinedDataTypes列出可选类型集合,fallbackDataType是兜底类型,defaultNewTableColumns给出新建表时的默认列。
getTableFormOptions(intent)根据newTableForm/editTableForm/sqlCreateTable/sqlAlterTable四种场景返回表选项列表,createColumnViewExpression则用于在 SQL 树层面生成列视图/过滤表达式。
五、dumper.d.ts 与 alter-processor.d.ts:SQL 生成与结构变更的统一抽象
SqlDumper:跨引擎的 SQL 命令生成器
README 对 dumper 的定义是"dump SQL commands independed on DB engine"。 dumper.d.ts 中的SqlDumper接口同时继承AlterProcessor,提供了一组 DSL 式方法:
putRaw(s); // 直接追加原始文本 put(format, ...args); // 格式化追加(含关键字大小写转换) putCmd(format, ...args);// 追加一条命令 putValue(value, dataType?); // 追加字面量值(字符串、数字、日期、二进制) putCollection(delimiter, collection, lambda); // 用分隔符拼接集合 transform(type, dumpExpr); // 对日期/时间做 GROUP:YEAR 等变换真实的类实现在 packages/tools/src/SqlDumper.ts:SqlDumper implements AlterProcessor,其putValue方法把null渲染为^null占位符、布尔值渲染为1/0、日期渲染为 ISO 字符串,并把$binary.base64形式的二进制数据转换为^null占位。文件开头还展示了keywordsCase静态开关——生成的关键字可整体大写或小写,以满足不同库的审美与规则。
AlterProcessor:把"结构变更"变成操作序列
alter-processor.d.ts 定义的AlterProcessor是结构与 SQL 之间的桥梁,方法覆盖建/删表、增/改/删列、增/改/删约束、重命名表/对象/列/约束、重建表(recreateTable)、创建/删除 SQL 对象,以及fillPreloadedRows(用预载行填充表)。
它有两个重要实现:一个是 packages/tools/src/alterPlan.ts 中收集变更操作并在run(processor)时逐一派发的计划对象(runAlterOperation(op, processor));另一个是 packages/tools/src/database-info-alter-processor.ts 中的DatabaseInfoAlterProcessor,它把createTable实现为this.db.tables.push(table)、dropColumn实现为从table.columns中移除匹配列——即"把变更计划作用到内存数据库结构"上,用于预览变更结果;而SqlDumper则把同样的操作渲染成真实 SQL。这种"同一套操作接口,两种执行目标"的设计,是 DbGate 表结构编辑器"预览 SQL 再执行"特性的底层支撑。
六、query.d.ts:查询结果与结构化过滤条件
query.d.ts 定义了查询结果与过滤条件的标准形态。QueryResult很轻量:rows?(数据行数组)、columns?(QueryResultColumn[],含columnName、notNull、isPrimaryKey、dataType、tableName、sourceColumnName等元数据)、rowsAffected?。
更值得注意的是它内置了一套与具体数据库无关的"过滤条件 AST"——FilterCondition是可辨识联合类型,由BinaryCondition(=、!=、<>、<、<=、>、>=)、AndCondition/OrCondition(组合)、NullCondition(isNull/isNotNull)、NotCondition、LikeCondition、PredicateCondition(exists/emptyArray 等)、InCondition组合而成。FullQueryOptions则把condition、sort、limit、skip打包成一个完整的分页查询参数对象,被前端数据网格与数据导出流程共用。
这套 AST 的实际消费方是 packages/filterparser 的parseFilter与filterTool,它们把用户输入的过滤表达式解析成FilterCondition,再由各引擎翻译为原生查询。
七、filter-type.d.ts:过滤器行为的能力描述
filter-type.d.ts 定义了FilterBehaviour——它不是过滤条件本身,而是"某种数据类型支持哪些过滤操作"的能力矩阵:supportEquals、supportStringInclusion、supportNullTesting、supportSqlCondition、supportEmptyArrayTesting、allowStringToken、allowNumberDualTesting、passBooleans等开关,决定了过滤输入框中哪些运算符可选。
EngineDriver要求驱动实现FilterBehaviourProvider.getFilterBehaviour(dataType, standardFilterBehaviours),后者传入标准行为集。标准集定义在 packages/tools/src/filterBehaviours.ts:numberFilterBehaviour、stringFilterBehaviour、logicalFilterBehaviour、datetimeFilterBehaviour、mongoFilterBehaviour、firestoreFilterBehaviours、evalFilterBehaviour七种,并聚合为standardFilterBehaviours字典。以mongoFilterBehaviour为例,它开启了数组存在性测试、ObjectId 测试与passBooleans,与 Mongo 的查询语义一一对应。
八、extensions.d.ts、appdefs.d.ts 与 test-engines.d.ts:插件、应用与测试
extensions:插件系统的四种注册物
extensions.d.ts 定义了ExtensionsDirectory,它是插件运行时注册表的静态形态,包含四类成员:
plugins: PluginDefinition[]——插件本体(包名 + manifest + content);fileFormats: FileFormatDefinition[]——文件格式定义(storageType、extension、readerFunc/writerFunc,如 CSV、JSONL、Excel);quickExports: QuickExportDefinition[]——快速导出格式;drivers: EngineDriver[]——插件贡献的引擎驱动。
FileFormatDefinition的addFileToSourceList/getDefaultOutputName/getOutputParams钩子,让文件格式能参与导入向导的源选择与目标命名流程。
appdefs:业务"应用"的静态描述
appdefs.d.ts 描述的是 DbGate 的"应用"(Application)概念——一组面向特定业务场景的虚拟外键、字典描述与查询文件。ApplicationDefinition包含appid、applicationName、usageRules(通过服务主机/库名/表名/列名的正则或列表精确圈定适用数据库)、virtualReferences(虚拟外键)、dictionaryDescriptions(字典字段描述)与files(内置查询/命令)。前端 packages/web/src/utility/appTools.ts 第 1 行即import type { ApplicationDefinition, DatabaseInfo, StoredConnection } from 'dbgate-types',其filterAppsForDatabase函数逐条执行usageRules的匹配逻辑,决定当前数据库应该显示哪些应用。
test-engines:跨引擎集成测试的驱动清单
test-engines.d.ts 定义了TestEngineInfo与TestObjectInfo,为仓库的跨引擎集成测试提供类型化配置:包括连接参数(engine/server/databaseUrl/port)、海量的skip*能力开关(skipOnCI、skipIndexes、skipTriggers、skipDataReplicator、skipDeploy……)、dumpChecks(执行 SQL 并断言结果)、parameters/triggers/schedulerEvents的建/删脚本与期望结构,以及objects中成对的 create/drop 测试对象。
真实使用见 integration-tests/engines.js:文件顶部即以/** @type {import('dbgate-types').TestEngineInfo} */标注各引擎配置(如 MySQL 的dumpFile: 'data/chinook-mysql.sql'、binaryDataType: 'blob'、dumpChecks: [{ sql: 'select count(*) as res from genre', res: '25' }]),并以create1/create2/drop1/drop2成对定义过程、调度事件等对象的测试脚本。
九、如何基于 dbgate-types 开发一个驱动
综合以上契约,开发一个新引擎驱动的最小骨架可概括为四步(参照 plugins/dbgate-plugin-mysql/src/backend/drivers.js 与各插件目录dbgate-plugin-*的组织方式):
- 实现
EngineDriver:先声明engine、title、defaultPort、databaseEngineTypes与能力开关,再实现connect/query/stream/close生命周期;JS 实现可用/** @type {import('dbgate-types').EngineDriver} */获得编译期检查; - 提供
dialect:按引擎语法填写分页风格、标识符引号、DDL 能力开关与predefinedDataTypes; - 提供
createDumper:返回基于SqlDumper的 SQL 生成器,或复用 packages/tools/src/SqlDumper.ts 的通用实现并覆写差异点; - 实现
analyseFull等分析方法:返回符合DatabaseInfo的结构,并实现getFilterBehaviour以启用对应的过滤能力。
整个过程都由dbgate-types的类型声明兜底,保证所有插件对上层应用暴露一致的接口面。
结语
dbgate-types虽然只有 12 个.d.ts文件、没有任何运行时代码,却是 DbGate 多引擎架构的"宪法":dbinfo定义世界模型,engines定义能力契约,dialect与dumper/alter-processor定义 SQL 生成规则,query与filter-type定义数据交互形态,extensions/appdefs/test-engines定义生态与质量保障。无论你是想为 DbGate 贡献新驱动、开发插件,还是研究其架构设计,从研读这些类型文件入手都是最高效的路径。
- 数据库
- 数据库客户端
- 桌面应用
- 后端
【免费下载链接】dbgate
Database manager for MySQL, PostgreSQL, SQL Server, MongoDB, SQLite and others. Runs under Windows, Linux, Mac or as web application
相关推荐
changesets 类型系统全解:@changesets/types 的类型契约与生态应用
changesets 类型系统全解:@changesets/types 的类型契约与生态应用 导读 @changesets/types 是 changesets
开发工具CLIMAX Pipelines Modeling Types 全解析:Max 推理管线的类型体系与协议契约
MAX Pipelines Modeling Types 全解析:Max 推理管线的类型体系与协议契约 导读 max.pipelines.modeling.ty
人工智能大模型编程语言编译器标准库算子库模型推理服务模型量化Crawlee 类型系统全解:读懂 @crawlee/types 的公开 API 契约
Crawlee 类型系统全解:读懂 @crawlee/types 的公开 API 契约 导读 Crawlee 是面向 Node.js 的网页抓取与浏览器自动化库
后端网页爬虫
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考