Skip to content

Releases

v0.7.2

Choose a tag to compare

@github-actions github-actions released this 23 Oct 04:05

修 0.7.1 上补全在慢库 / 大库上退化成“只有关键字”的问题。

修复

  • 预取失败被当成“这个库没有表”缓存下来:当每一批表读取都失败(超时、规则报错)时,0.7.1
    仍写入了一份空表列表并当作成功;补全随后只给关键字,直到缓存过期。现在全部失败时不写缓存、
    记录失败,并在输出通道写一行 Completion has no table list for ...,把原因(超时/报错)留在日志里
  • 补全不再为一次按键等整次预取:预取按 schema 串行读取,库里 schema 多、驱动又慢时,一次
    FROM 会等到所有 schema 读完。现在补全最多等 1 秒,先给已经发布的 schema 名和表名,其余继续
    在后台读;缓存过期时也先用旧列表,同时后台刷新
  • 分批结果边读边发布:每读完一个 schema 就更新缓存,而不是全部读完才写入 —— 慢库上补全能
    逐步变得完整,而不是长时间空白
  • schema 列表读不到时不再回退到整库读取:那正是会耗尽桥堆的那条 getTables;现在直接报告
    “没有安全的分批方式”,不读
  • 预取有时间上限:最多 60 秒开始新的一批,避免一次预取长时间占住连接

v0.7.1

Choose a tag to compare

@github-actions github-actions released this 21 Oct 02:41

修复 0.7.0 上两处让基本使用失效的问题,并给元数据缓存加上有效期。

修复

  • 配置了驱动目录却报 “JDBC driver ... is not loaded”:合并时 refreshAll 命令被注册了两次,
    registerCommand 对重复 id 抛异常,整个 activate 在注册命令这一步中断 —— 后面「把驱动 jar
    交给桥」根本没执行。桥能起来、连接菜单也能点,但驱动一个都没加载。删掉重复注册,并让
    check-docs.mjs 校验「同一条命令不得注册两次」,以后这类问题在 npm test 就会失败
  • 桥自动重启后驱动全部丢失:驱动活在桥 JVM 里,而崩溃重启不经过「重启桥」命令。现在桥每次
    进入 ready 都会重新加载驱动;桥一进入 starting/stopped,DriverManager 就丢弃旧列表,
    连接前发现驱动类不在会先重载,桥在连接途中被替换时也会重载并重试一次
  • 驱动注册不再能让激活卡死:driver.register 加 120 秒超时,并在 info 级别留下
    「正在加载 N 个驱动 jar」
  • 大库上的元数据预取会把桥撑爆:整库一次 getTables 的结果会被驱动整个读进堆内存,
    超大 catalog 上足以耗尽堆。补全预取改为按 schema(或按 catalog)分批,并设 20000 张表
    的总预算;每次读取和缓存占用因此都有界
  • metadata.queries 的表规则在预取路径上恢复了作用:分批后每次读取都带 schema,
    规则不再因「${schema} 填不出来」被拒绝而回落到驱动
  • OOM 后不再半死不活:JVM 加 -XX:+ExitOnOutOfMemoryError,堆耗尽时直接退出,
    由已有的自动重启换一个新进程(驱动会随之重新加载)

新增

  • metadata.cacheMinutes(默认 5):树与补全的元数据缓存多少分钟后重新读取;0 表示直到
    断开连接或手动刷新。手动刷新总是立即清空

新增(仅开发)

  • check-docs.mjs 增加重复命令注册校验;新增 prefetchPlan.test.ts、cacheAge.test.ts,
    把「按什么维度分批」与「缓存何时过期」两条规则固定下来

v0.7.0

Choose a tag to compare

@github-actions github-actions released this 20 Oct 11:02

本版同时包含 0.4.1–0.4.4 线上未发布的修复:中文日志、把连接自身的 catalog 带进元数据规则、
表 / 视图列表只读一次、健康报告取完整快照、补齐未注册的命令、限定名补全。逐条说明见仓库
CHANGELOG.md 的 0.4.4 一节。

新增

  • 共享服务鉴权:--listen <port> --token <secret> 开启共享密钥鉴权,每个请求帧必须携带
    token,否则返回 UNAUTHORIZED(常量时间比较,防时序侧信道)。保护共享桥不被任意可达端口的
    客户端驱动、也防 system.shutdown 被滥用。
  • 连接归属隔离:连接记住打开它的租户(connection.open 的 tenantId),后续
    query.execute / metadata.* / connection.close / 事务等操作必须携带同一 tenantId,否则
    返回 FORBIDDEN。一个租户不能使用或关闭另一个租户的连接;connection.list 会带出 tenantId。
  • 桥版本 0.3.0 -> 0.4.0。

v0.4.0

Choose a tag to compare

@github-actions github-actions released this 30 Sep 02:00

这一版的主题是把元数据读取交给用户写的 SQL,并且让你看得见它在做什么。前几轮反馈里最重要的一条
是“有些库展开一张表要等几分钟”—— 而慢的不是 SQL,是围着它的 DatabaseMetaData 读取。所以这一版做两件事:
凡是能换成用户自己写的语句的读取都开出来(现在覆盖模式/表/列/索引/目录/表类型六种,外加 DDL),以及
把“跑的是哪条语句、花在哪个调用、哪张表上”落到日志与健康报告里。

新增

  • 连接树上显示表/视图的中文名。数据库给了表注释时,注释跟在表名后面(orders 订单),悬浮提示里
    是完整注释和附加字段。标签仍是物理名 —— 那才是要写进 SQL 的东西。树的筛选也匹配注释,
    于是输入“订单”能找到 orders(之前只比名称,中文名等于白写)
  • 元数据规则可以带回表注释和任意附加字段。别名成 REMARKS / TABLE_COMMENT / COMMENT 的列被
    认作表注释(多列都有值时按此顺序取),它随后出现在树上、参与筛选、并可作为 ${remark} 用于自定义
    动作与 DDL 规则;select 出来的其它列不再被丢弃,按你 select 的顺序(不是字母序)显示在节点的
    悬浮提示里,形如 EST_ROWS: 12000。这才是这个设置真正可扩展的地方:目录表里有用的字段,
    不用等插件认识那个库
  • 示例规则新增 MySQL 一档,PostgreSQL/openGauss 的例子改用 pg_catalog —— 比 information_schema
    快得多,而且只有它能取到表注释,也就是中文 schema 上人真正认得的那个名字
  • metadata.queries 现在也能替掉列与索引的读取(kind: "columns" / "indexes")。之前只有
    schemas/tables 能自定义,而真正让树变慢的恰恰是每张表一次的 getColumns:展开一张表、
    补全缓存填充、Show Columns 各算一次。列规则能表达树会显示的每一件事(COLUMN_NAME、TYPE_NAME、
    COLUMN_SIZE/DECIMAL_DIGITS、IS_NULLABLE、COLUMN_DEF、REMARKS、ORDINAL_POSITION、
    IS_PRIMARY_KEY、IS_AUTOINCREMENT、IS_GENERATEDCOLUMN),索引规则是 INDEX_NAME、
    NON_UNIQUE、COLUMN_NAME、ORDINAL_POSITION、ASC_OR_DESC、TYPE_NAME、CARDINALITY;
    没给的字段取诚实默认(类型 → UNKNOWN、可空性 → 未知(显示 ?)、JDBC 类型 → OTHER、
    序号 → 结果行序),而不是编一个
  • 字面量占位符 ${tableLiteral} / ${schemaLiteral} / ${catalogLiteral} /
    ${namePatternLiteral}:自带单引号并转义值里的引号。这些值是数据,自己往引号里塞的名字
    遇到一张叫 it's 的表就变成了另一条语句。示例里全部改成 = ${tableLiteral}
  • catalogs 与 tableTypes 也开了(原来只剩这两个读取不能自定义)。它们各是一次性的小结果、
    平时不慢,所以理由是"万一你那个驱动在这里返回了没用的东西":目录列表把连不上的库也列出来、
    表类型一个都不给。两者都不需要占位符(跑到它们时还不知道能按什么过滤),tableTypes 的
    kind 大小写都认(存下来的是规范拼写),名字列表会去重、空白条目按"没给"处理
  • 新增 columns 示例(PostgreSQL/openGauss 走 pg_attribute + format_type + col_description,
    MySQL 走 information_schema.columns)与 MySQL 的 indexes 示例。PG 的索引例子故意不给:
    列出索引的列需要 unnest ... WITH ORDINALITY 或 LATERAL,而这正是那些较老的
    PostgreSQL 兼容库(本功能最想服务的对象)没有的语法,当示例发出去就会在它们上面报错

变更

  • 自定义动作与 DDL 规则的占位符新增 ${remark}(表注释;在列上是列注释),以及元数据规则带回来的
    任何附加字段
    —— 别名 EST_ROWS 就是 ${EST_ROWS}。${remark} 和 ${column} 一样填不出来就跳过
    模板
    ,而不是当成空串:按中文名查对象的语句少了这个名字,查出来的就是别的东西。附加字段里与
    占位符重名的(table、schema 这种)会被丢掉,否则一条奇怪的规则就能改掉所有模板指向的表
  • 这些值都从节点上直接取,不再为了拿一个界面上已经显示出来的注释而多跑一次查询
  • 每条元数据规则跑的到底是哪条 SQL,现在看得出来:命中规则时输出通道写一行(规则名 + 占位符已
    填好的语句),没命中而回落驱动时写一行 debug。规则是用户写的 SQL、却是插件选中的,而设置里那条
    语句并不是发给数据库的那条(占位符被填过) —— 所以它和别的语句一样要能被查出来
  • 导出时因 export.csv.quoting = never 而留下的「有字段没加引号」提示,除了弹窗还写进
    DB Client 输出通道 —— 弹窗几秒就消失,而这件事关系到已经落盘的文件,日志里还带着完整路径
  • 列注释的读取不再每次都付费。注释是结果里每张表一次 getColumns 换来的,而这正是几个慢库
    上「查询慢」的真正原因,所以:① 只有会显示注释的调用才去读(结果网格、表预览、DDL 结果、导出表头),
    树与补全的元数据读取一律不读;② 读到的结果按「连接 + URL + 表」在会话内缓存(LRU,上限 512 张表,
    空结果也缓存 —— 不然"这张表没有注释"会变成每次查询都重来一次慢调用);③ 新增
    result.columnRemarks(默认 true),关掉后结果与导出只显示物理列名,一次元数据调用都不发
  • 健康报告新增「元数据调用」:按 tables/columns/schemas/indexes/ddl 统计次数、总耗时、
    平均耗时与失败数,并列出最慢的几次读取及其对象(columns public.orders 12.3 s)。原来的
    查询指标只回答「这条语句跑了多久」—— 而当时间根本没花在语句上时(慢驱动的 getColumns 是几
    分钟的目录查询),看上去就像数据库慢。现在能把那笔开销指到具体的调用和具体的表上,也才有得选:
    换掉它(metadata.queries)或关掉它(result.columnRemarks)。统计在每个元数据读取的唯一
    入口
    采集,所以新增的读取不可能漏掉

新增(仅开发,不影响扩展行为)

  • scripts/check-i18n.mjs:界面文案以英文原文为键,漏译不会报错,只会让中文用户在一句中文里
    看到一句英文 —— 这是只有那个语言的用户才会先看见的错。脚本扫 src/** 与 media/** 里的每个
    t('...') 字面量(连同 'a' + 'b' 拼接与转义),要求目录里都有条目;读不出来的调用必须列进白名单,
    白名单里还要写清它可能产生哪几个键,否则白名单会退化成一句谁都看不懂的 eslint-disable。
    目录里多余的键只警告不失败。已接入 npm test(npm run checks = 文档 + 文案)
  • CommentCacheTests:3 项针对列注释缓存的测试 —— 空结果必须被记住(否则每次查询都要重新付出
    那笔慢调用)、超出上限时丢的是最久没用过的那条、没读过的表不能假装知道
  • MetadataMetricsTests:5 项针对元数据计时的测试 —— 按调用名汇总、按总耗时而不是次数排序
    (一百次 1 毫秒的调用不该盖过一次 5 秒的)、失败与成功分开计、只记住最慢的 20 次且汇总不受上限影响
  • 示例规则真的在真库上跑过了:PostgreSQL 16 与 MariaDB 11 各起一个容器,建一张带注释、主键、
    serial/auto_increment 与索引的表,把每个示例按占位符展开后丢进去。两个库里 columns 示例都带回了
    主键与注释、IS_AUTOINCREMENT 也都对(nextval / extra LIKE '%auto_increment%'),indexes 示例
    把 NON_UNIQUE 的 0/1 与 index_type 都带了回来 —— 这些是单元测试没法证明的部分
  • 新增一项测试把示例与读取端钉在一起:列/索引示例里每个 AS 别名 都必须是读取端真正会读的名字
    (直接拿 COLUMN_ROW_COLUMNS / INDEX_ROW_COLUMNS 对照)。服务器能告诉你语句跑得通,但告诉不了你
    插件读不读这个别名 —— 一个写成 IS_PK 的规则会安静地少一个主键图标。表规则不参与这项检查:
    那里的额外列是特性(EST_ROWS 会被保留并显示)

v0.2.0

Choose a tag to compare

@github-actions github-actions released this 23 Sep 01:27

修复

  • -- @connection 指令不生效,且每次绑定都会多插一行。扩展写入的是
    -- @connection: 名称(带冒号),而解析只认不带冒号的写法,于是指令永远解析不到 ——
    每次执行都会再问一次连接,每次回答都再插一行。两种写法现在都认,写入与解析放在同一处,
    并用往返测试钉住
  • 「Run again」重跑的是该面板第一次执行的 SQL。复用的面板没有更新回调,重跑处理器停留在
    面板创建时捕获的那条语句 —— 新建查询文件时就是模板里的 SELECT 1
  • 从查询历史插入/删除完全没反应。两个命令都用 asNode() 收窄参数,而历史条目没有
    kind 字段,于是拿到 undefined 后静默返回
  • 导出结果时报「结果已不可用」。桥在连接关闭或磁盘预算用尽后会丢弃缓存结果,而面板能活得
    比它久。现在遇到这种情况会重跑语句再导出,而不是丢一个死胡同给用户
  • 保存脚本后执行按钮消失。新建查询是 untitled 文档,存成非 .sql 文件名会被重新判定语言,
    editorLangId == sql 条件随之失效,连带快捷键和 SQL 补全一起消失。菜单改用扩展自己的上下文
    键(同时认带指令的文档),保存后若语言退化为纯文本则恢复为 SQL
  • 结果网格滚动时不断重绘导致难以滚动。每帧重建 tbody 会改变表格高度,可能再触发滚动事件,
    渲染自己喂自己。现在记住已渲染的窗口,窗口未变就不重建;表头高度改为重建时测量一次,
    行位置不再偏移
  • 连接模板的用户覆盖真正生效了。文件里一直写着"可以把副本放到
    <globalStorage>/templates/connection-templates.json,按 id 合并",但代码从未读过那个路径 ——
    是"打算这么做"被当成"已经这么做"写进了文档。现在实现了,并支持用 disabled 移除内置条目

新增

  • 取 DDL 的 SQL 可以自己写(ddl.queries)。很多数据库本来就能直接给出建表语句,而且比"从 JDBC
    元数据重建"更准 —— 重建看不到存储子句、表空间、引擎选项,也看不到驱动报成 OTHER 的类型。规则按连接
    URL 的 glob 匹配,第一条命中生效;没有命中才回到内置重建,所以默认行为不变。示例:
    DESC ${qualified}(Hive)、SELECT pg_get_tabledef('${qualified}')(PostgreSQL)、
    SHOW CREATE TABLE ${quotedQualified}(MySQL)。结果按数据库返回的样子展示:单单元格开成文本,
    否则开结果网格
  • 占位符显式区分原始名与加引号名。这是必须的而不是洁癖:pg_get_tabledef('${quotedQualified}')
    会去找一张名字里带引号的表 —— 不报语法错,只是找不到。现在 ${qualified} 是原始名(用于字符串
    字面量、Hive 的 DESC),${quotedQualified} 才加引号。这个改动同时作用于自定义动作
  • 自定义 SQL 动作(actions 设置):在表、视图、列上按自己的模板跑 SQL。填不上的占位符会阻止
    执行而不是变成空串(LIKE '%%' 那种静默错配比直接拒绝危险得多);语句在已绑定连接的编辑器里打开,
    而不是静默执行
  • 连接改用单页表单,带「测试联通」按钮。必须测试通过才能保存:存一个连不上的连接,问题要到
    第一次查询时才暴露。测试走桥的独立探测通道(开完即关,不进连接池),所以测一个已经连着的连接
    不会干扰它。字段里的 JDBC URL 会随驱动选择自动预填(仅在为空时,不覆盖已填内容)
  • 内置 DDL 生成器的风格选项:ddl.ifNotExists、ddl.indent、ddl.includeIndexes、
    ddl.quoteIdentifiers。有规则匹配时这些不生效
  • query.maxRows:可配置的取数行数上限(0 表示不限),命中上限会标记为截断
  • 表树筛选:按名称过滤表、视图、列、索引,生效时视图描述显示 filter: 关键字
  • result.openIn:结果面板位置,默认 below(上下分屏)
  • 每条 SQL 上方的 Run 按钮(code lens),可用 query.codeLens 关闭
  • 脚本参数变量:${V_DATE} 形式的占位符,打开脚本时下方自动弹出参数面板,
    执行前替换;变量样式可用 variables.pattern 自定义正则。有变量未填值则拒绝执行并指出是哪个

v0.1.1

Choose a tag to compare

@github-actions github-actions released this 22 Sep 05:38

扩展的行为与 0.1.0 完全相同。 这一版只修正了随包发布的文档,并让构建产物可复现。
如果你已经在用 0.1.0,从功能角度看没有升级的必要。

发这一版的原因是:0.1.0 的 VSIX 是从 tag 所在提交构建的,而下面这些文档修正发生在那之后,
所以 v0.1.0 里那份 README.md 是旧的。

修复

  • README 列出的连接模板与实际不符:删去并不存在的 ClickHouse,补上遗漏的 MariaDB 与 GaussDB
  • README 把命令面板的调用路径写成 Open DB Client: ...,而命令实际贡献在 DB Client 分类下,
    用户照着输是找不到的
  • README 里本地打包的产物名漏了版本号

新增(仅开发,不影响扩展行为)

  • scripts/check-docs.mjs: 校验 README 中的设置名、命令面板标签、快捷键、视图、链接锚点与
    CHANGELOG 小节是否与 package.json 一致,并接入 npm test。这类错误不会让构建失败,
    但用户一用就会撞上
  • 打包 bridge.jar 时不再用构建时刻作为 ZIP 条目时间戳,改用提交时间(CI 经
    SOURCE_DATE_EPOCH 传入)。这样时间戳不再是变量,同一个 JDK 下重建即可得到相同的 jar

一致性说明

下面是直接下载两个 Release 的 VSIX 逐项比对得到的结论,不是估计:

文件 与 0.1.0 的关系
out/extension.js 逐字节相同
media/result/main.js 逐字节相同
resources/bridge.jar 83 个条目内容完全相同;仅 ZIP 条目时间戳不同(0.1.0 未固定时间戳)
README.md 有差异 —— 这正是本版存在的理由

关于 jar 的可复现性:它以同一个 JDK 为前提。用不同版本的 javac 编译,生成的字节码并不保证
一致 —— 实测用 JDK 21 重建 0.1.1,时间戳可以完全对上,但类文件字节与 Created-By 行都不同。

v0.1.0

Choose a tag to compare

@github-actions github-actions released this 22 Sep 01:50

首个版本。

新增

连接

  • 通过用户自备的 JDBC 驱动连接任意数据库,不绑定数据库类型
  • 驱动获取:从 Maven Central 按坐标下载 / 添加本地 jar / 指向已有目录
  • 驱动发现读取 jar 内的 META-INF/services/java.sql.Driver,也支持手动指定驱动类名
  • 连接管理:新建、编辑、复制、删除、测试、连接、断开;连接池可在重新连接时复用
  • 密码存入 VS Code SecretStorage
  • 连接模板(MySQL / PostgreSQL / openGauss / Oracle / SQL Server / ClickHouse / Hive /
    SQLite / Transwarp / Custom),只预填 URL 前缀与驱动类名,不含方言逻辑
  • 通过状态栏或 -- @connection <名称> 注释指令把 SQL 文件绑定到连接
  • 数据库树:目录 → schema → 表/视图 → 列/索引,单层结构自动折叠

查询

  • 执行选中内容、光标处语句或整个文件;支持一次执行多条语句
  • 破坏性语句执行前二次确认
  • 长查询可取消(调用 Statement.cancel() 真正下发到数据库)
  • 结果集不经过进程间通信:桥直接落盘,界面按 200 行一页读取,支持虚拟滚动
  • 值转换:超大整数与 BigDecimal 转字符串避免精度丢失,超长文本截断,二进制显示为占位符
  • 磁盘结果缓存按 LRU 淘汰,默认上限 512 MiB
  • 查询历史,保留最近 500 条,可插回编辑器

SQL 智能补全

  • 表名补全与列名补全,支持别名/表名限定
  • INSERT INTO t ( 处补列而非补表
  • 关键字与代码片段补全
  • 补全在扩展进程内计算,不消耗 IPC 往返;元数据按需加载并 LRU 缓存

导出

  • 四种格式:CSV(CRLF + 可选 UTF-8 BOM)、JSON、Excel .xlsx、INSERT 语句
  • 可从查询结果导出,也可不查询直接导出整张表
  • xlsx 手写 OOXML,支持大表自动拆多 sheet,不引入 Apache POI
  • 导出不设行数上限;写失败时删除半成品文件

表结构

  • 查看列(类型、长度、可空、默认值、注释)与索引(是否唯一)
  • 根据元数据生成 CREATE TABLE 语句

健康监控

  • 状态栏实时显示连接数与堆占用
  • Markdown 健康报告:JVM 堆/线程/运行时长、每个连接的池借还情况、运行中查询数、
    结果缓存占用与淘汰数、已加载驱动
  • 指标仅来自 JDK JMX,不依赖任何第三方库,也不采集数据库服务端指标

说明

  • Java 桥零外部依赖,由 javac + jar 直接构建(无需 Maven/Gradle),产物约 144 KiB
  • 不实现任何数据库方言;跨库行为差异通过 JDBC 能力探测(DatabaseMetaData /
    supportsXxx())处理
  • 代码中不含任何驱动 jar

已知限制

  • SQL 补全不做子查询与 CTE 作用域
  • 结果网格只读,不能在网格内编辑数据
  • 不支持 SSH 隧道
  • 健康监控不含数据库服务端指标