☰
dbgate-types 全解析:DbGate 数据库管理器的 TypeScript 类型系统与驱动契约
2026/10/15 16:56:38 网站建设 项目流程
  • 数据库
  • 数据库客户端
  • 桌面应用
  • 后端

【免费下载链接】dbgate

Database manager for MySQL, PostgreSQL, SQL Server, MongoDB, SQLite and others. Runs under Windows, Linux, Mac or as web application

项目地址:https://gitcode.com/gh_mirrors/db/dbgate
点击查看免费下载

导读

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-*的组织方式):

  1. 实现EngineDriver:先声明engine、title、defaultPort、databaseEngineTypes与能力开关,再实现connect/query/stream/close生命周期;JS 实现可用/** @type {import('dbgate-types').EngineDriver} */获得编译期检查;
  2. 提供dialect:按引擎语法填写分页风格、标识符引号、DDL 能力开关与predefinedDataTypes;
  3. 提供createDumper:返回基于SqlDumper的 SQL 生成器,或复用 packages/tools/src/SqlDumper.ts 的通用实现并覆写差异点;
  4. 实现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

项目地址:https://gitcode.com/gh_mirrors/db/dbgate
点击查看免费下载

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询