SQLCipher 中的 Miscellaneous Extensions:从可加载扩展源码到虚拟表实战指南 数据库关系型数据库嵌入式数据库密码学【免费下载链接】sqlcipherSQLCipher is a standalone fork of SQLite that adds 256 bit AES encryption of database files and other security features.项目地址https://gitcode.com/gh_mirrors/sq/sqlcipher点击查看免费下载本篇指南以 SQLCipher 仓库ext/misc/目录中的官方文档为核心系统讲解该目录下 CSV 虚拟表、generate_series、ZIP 归档读写、unionvtab/swarmvtab 分库虚拟表等轻量级可加载扩展的实现原理与实战用法。读完本文你将掌握如何编译、加载这些扩展理解每个扩展的入口函数、虚拟表机制与典型 SQL 调用方式并能直接在本仓库源码中定位对应实现。一、ext/misc一个单文件可加载扩展的工具箱ext/misc/README.md是 SQLCipher 仓库SQLite 的一个独立分支增加了 256 位 AES 数据库文件加密中杂项扩展目录的官方说明。它的定位非常明确该目录存放了一批小型的、可加载的 SQLite 扩展每个扩展都由单个 C 源文件实现并在文件头部注释中给出完整的功能描述。从源码结构看这批扩展可分为三类虚拟表类csv.c、series.c、unionvtab.c、zipfile.c以及目录中未被 README 单独列出但同样存在的amatch.c、closure.c、completion.c、fileio.c、fuzzer.c、spellfix.c、templatevtab.c、vtablog.c等SQL 函数类rot13.c、shathree.c、sha1.c以及base64.c、base85.c、decimal.c、ieee754.c、percentile.c、regexp.c、uuid.c等库/工具类dbdump.c近似实现命令行.dump的 C 库、appendvfs.c、cksumvfs.c、memstat.c、vfslog.c等 VFS 层组件。所有扩展都遵循 SQLite 可加载扩展的标准约定以#include sqlite3ext.hSQLITE_EXTENSION_INIT1开头导出sqlite3_扩展名_init入口函数如 csv.c 中的sqlite3_csv_init。编译与加载的通用方法请参考 SQLite 官方 loadable extensions 文档sqlite.org/loadext.html下文将给出基于本仓库的具体命令。二、csv.c用虚拟表直接查询 CSV 文件csv.c 实现了一个用于读取逗号分隔值CSV文件的虚拟表是用 SQL 查询文件最直接的例子。2.1 基本用法.load ./csv -- 在 sqlite3 命令行中加载扩展 CREATE VIRTUAL TABLE temp.csv USING csv(filenameFILENAME); SELECT * FROM csv;默认情况下列被命名为c1、c2、c3……列数由 CSV 首行推断通过columnsN参数可显式指定列数通过schema参数可用自定义CREATE TABLE语句定义列名与类型通过data参数可直接把 CSV 文本作为字符串传入无需文件。2.2 带自定义 schema 的示例CREATE VIRTUAL TABLE temp.csv2 USING csv( filename ../http.log, schema CREATE TABLE x(date,ipaddr,url,referrer,userAgent) );2.3 源码实现要点从源码结构看csv 虚拟表的核心是一个CsvReader状态机csv.c它维护输入文件流、字段文本缓冲区、当前行号与缓冲读取位置按字段为单位解析引号转义、逗号分隔与换行。模块还定义了CSV_MXERR 200错误消息上限与CSV_INBUFSZ 1024输入缓冲大小。若以-DSQLITE_TEST编译模块还会启用专用于虚拟表测试的调试特性。仓库的 test/csv01.test 覆盖了该扩展的核心场景包括参数缺省、schema/columns/data组合等。三、series.cgenerate_series 表值函数series.c 实现 PostgreSQL 风格的generate_series()表值函数是用虚拟表实现表值函数的教科书级模板。3.1 行为语义其内部等价于如下虚拟表定义CREATE TABLE generate_series( value, -- 输出列rowid 是该列的别名 start HIDDEN, -- 起始值必填 stop HIDDEN, -- 结束值默认 4294967295即 0xffffffff step HIDDEN -- 步长默认 10 视为 1 );函数参数会被翻译为对隐藏列的等值约束例如下面两对查询完全等价SELECT * FROM generate_series(0,100,5); SELECT * FROM generate_series WHERE start0 AND stop100 AND step5;3.2 典型调用SELECT * FROM generate_series(0,100,5); -- 0,5,10,...,95,100共 21 行 SELECT * FROM generate_series(0,100); -- 0..100步长 1共 101 行 SELECT * FROM generate_series(20) LIMIT 10; -- 20..29共 10 行 SELECT * FROM generate_series(0,-100,-5); -- 0,-5,...,-100共 21 行 SELECT * FROM generate_series(0,-1); -- 空序列3.3 查询优化原理该实现将xCreate置为 NULL因此无法通过CREATE VIRTUAL TABLE ... USING generate_series显式创建而是始终可用的无名虚拟表。xBestIndex会寻找对隐藏列start/stop/step的等值约束命中start与stop时返回较小代价鼓励查询规划器优先确定序列边界缺失边界时使用默认值 0 / 4294967295 / 12024-08-22 起见 series.c 头注释xBestIndex还识别对value列的等值与不等值约束并将其作为序列范围的附加边界因此SELECT value FROM generate_series($SA,$EA) WHERE value BETWEEN $SB AND $EB;逻辑上等价于generate_series(max($SA,$SB), min($EA,$EB))。generate_series的约束边界仅限有符号 64 位整数相关行为在 test/tabfunc01.test 等测试中有覆盖。四、rot13.c自定义 SQL 函数的最小模板rot13.c 实现了极简单的rot13()替换函数官方文档明确推荐它作为编写新自定义 SQL 函数的最佳起点模板。4.1 实现要点核心是一个 10 行左右的单字符转换函数rot13.c对a-z/A-Z的 ASCII 字母向后旋转 13 位并回绕非字母字符保持不变因此rot13(rot13(X)) X恒成立。SQL 层函数rot13func遵循标准sqlite3_context/sqlite3_value约定NULL 输入返回 NULL短文本使用栈上 100 字节临时缓冲长文本才走sqlite3_malloc64堆分配避免频繁小分配。此外它还注册了rot13排序序列collating sequence使x y COLLATE rot13等价于对rot13(x)与rot13(y)做二进制比较。4.2 模板价值从该文件可以学到一个完整 SQL 函数扩展需要的全部骨架SQLITE_EXTENSION_INIT1初始化宏、参数数量校验、类型检查、内存管理与sqlite3_result_text结果回传——这些正是编写任何自定义 SQL 函数包括 SQLCipher 场景下对加密字段做应用层变换的通用范式。五、shathree.csha3 / sha3_query 哈希函数shathree.c 按 NIST FIPS 202 SHA-3 标准实现了三个 SQL 函数sha3(X, SIZE)对输入 X 计算 SHA3 哈希。文本按 UTF-8 字节、BLOB 按原始二进制、数字先转 UTF-8 文本再哈希SIZE可选缺省为 256可取 224 / 256 / 384 / 512sha3_agg(Y, SIZE)聚合函数对全部 Y 输入求哈希。因顺序影响结果官方建议配合ORDER BY使用各数据类型被编码为带类型前缀的字节序列如I8 字节大端整数、Tnnn:文本、Bnnn:BLOB、N表示 NULL因此sha3(1) sha3(1)之类的恒等式成立详见 shathree.c 头注释sha3_query(Z, SIZE)执行 Z 中 SQL 语句产生的所有查询对每行结果额外加前缀R后哈希可用于对查询结果集做完整性校验。该文件命名为shathree.c而非sha3.c是因为 SQLite 默认入口点名称基于源文件名去掉数字生成——若叫sha3.c会与此前sha1.c扩展的入口点冲突README 与源码注释均说明了这一点。文件头部还给出了一组可直接验证的恒等式例如SELECT sha3(hello) sha3(x68656c6c6f); WITH a(x) AS (VALUES(xyzzy)) SELECT sha3_agg(x) sha3(T5:xyzzy) FROM a;六、unionvtab.c 与 swarmvtab.c跨库虚拟表unionvtab.c 同时实现unionvtab与swarmvtab两个虚拟表核心能力是把一张逻辑大表横向切分存储到多个数据库文件再通过单一虚拟表只读访问。二者对源表的要求相同必须是 rowid 表不能是虚拟表、WITHOUT ROWID 表或视图各表列集合、顺序与声明类型完全一致不允许有用户自定义的_rowid_列各表必须持有互不重叠的 rowid 区间。区别在于unionvtab要求所有源表位于主库或用户 ATTACH 的库中swarmvtab则允许源表位于磁盘上任意数据库文件由实现自动打开/关闭文件且支持按需挂载attach on demand。6.1 unionvtab 创建方式CREATE VIRTUAL TABLE name USING unionvtab(sql-statement);该 SQL 语句在虚拟表每次创建或打开时执行为每个源表返回一行每行四列所在数据库名main/temp/ATTACH 名或 NULL 表示按常规方式全库查找、表名、该表可能存储的最小 rowid、最大 rowid。6.2 swarmvtab 新旧两种语法旧语法CREATE VIRTUAL TABLE name USING swarmvtab(sql-statement, callback);其中首列必须是可打开源库文件的路径或 URIcallback可选当文件尚不存在时会被调用。新语法CREATE VIRTUAL TABLE name USING swarmvtab( sql-statement [, options] );合法选项包括missingudf文件缺失时的回调函数、opencloseudf、maxopeninteger最多同时打开的文件数以及任意sql-parametertext-value。SQL 语句除旧语法的 4 列外还可返回第 5 列 context 文本供回调使用。仓库中 test/unionvtab.test、test/unionvtabfault.test 与 test/swarmvtab.test、test/swarmvtab2.test、test/swarmvtab3.test 提供了完整的分库、按需打开与故障注入测试。七、zipfile.c可读可写的 ZIP 归档虚拟表zipfile.c 提供一个能读取并写入 ZIP 归档文件的虚拟表。典型用法SELECT name, sz, datetime(mtime,unixepoch) FROM zipfile($filename);当前实现的明确限制源码头注释列出zipfile.c不支持加密不支持跨多文件spanning归档不支持 zip64 扩展仅支持 zlib 的 inflate/deflate 压缩方法。实现依赖 zlib 库且与 CLI 的sqlite3_stdio.h模块配合时可复用其fopen定义若未包含该头文件则自行定义sqlite3_fopenzipfile.c。相关功能在 test/zipfile.test、test/zipfile2.test、test/zipfilefault.test 中验证。八、dbdump.c可嵌入的 .dump 等价库dbdump.c不是可加载扩展而是一个 C 语言库提供对命令行.dump命令的近似等价实现int sqlite3_db_dump( sqlite3 *db, /* 数据库连接 */ const char *zSchema, /* 模式名main / temp / 任意 ATTACH 库 */ const char *zTable, /* 为 NULL 时导出全部表否则仅导出该表 */ void (*xCallback)(void*, const char*), /* 输出回调签名兼容 fputs() */ void *pArg );其输出为可精确重建原库的 UTF-8 文本 SQL 语句并保留 ROWID 值。回调签名特意设计为与fputs()兼容便于直接接入输出流。若以-DDBDUMP_STANDALONE编译文件会附带main()成为命令行工具用法为dbdump 数据库文件 [schema] [table]。在仓库构建体系中main.mk已将 dbdump 编为独立可执行目标main.mk。九、编译、集成与在 SQLCipher 中使用9.1 可加载扩展的标准编译路径在 SQLCipher 仓库中扩展编译进 CLI/库的方式已固化于 main.mkmain.mk、main.mk、main.mk、main.mk 将csv.c、series.c、unionvtab.c、zipfile.c等列入 CLI 或核心库的编译源main.mk 将series.c、shathree.c、sha1.c编译进测试构建main.mk 在另一组构建目标中同样引入series.c、sha1.c、shathree.c、zipfile.c。即这些扩展既可随构建产物静态集成也可单独编译为.so/.dll动态加载sqlite3 命令行下使用.load ./csv等命令。由于 SQLCipher 是 SQLite 的加密分支其可加载扩展机制与上游一致唯一需要注意的是扩展需链接到 SQLCipher 提供的sqlite3API 之上编译时使用本仓库 src/sqlite3ext.h 与 src/sqlcipher.h 导出的接口。9.2 通用加载流程适用于任一扩展# 编译单个扩展以 rot13 为例 gcc -O2 -fPIC -shared ext/misc/rot13.c -o rot13.so # 在 sqlite3 命令行中加载并使用 sqlite3 test.db sqlite .load ./rot13 sqlite SELECT rot13(Hello, World!);十、总结从文档到源码的完整阅读路径ext/misc/README.md篇幅虽短却精准勾勒出这批扩展的设计哲学——单文件、头注释即文档、以虚拟表和自定义函数两种机制扩展 SQL。在本仓库中每个条目都能找到对应的完整实现与测试证据README 条目实现文件仓库内测试CSV 虚拟表ext/misc/csv.ctest/csv01.test近似 .dump 的库ext/misc/dbdump.cmain.mk 独立目标JSON 处理已内置于 amalgamation核心实现位于 src/json.ctest/json 目录rot13 函数模板ext/misc/rot13.c—generate_series 虚拟表ext/misc/series.ctest/tabfunc01.testsha3 系列函数ext/misc/shathree.c—unionvtab / swarmvtabext/misc/unionvtab.ctest/unionvtab.test、test/swarmvtab.testZIP 归档虚拟表ext/misc/zipfile.ctest/zipfile.test、test/zipfile2.test对于想深入 SQLCipher 扩展机制、或需要为加密数据库编写自定义 SQL 函数与虚拟表的开发者而言ext/misc/是仓库中最值得研读的入门区先读每个文件头部的注释即扩展自带文档再结合xBestIndex、sqlite3_context等接口源码即可快速掌握 SQLite/SQLCipher 扩展开发的完整链路。赞分享数据库关系型数据库嵌入式数据库密码学【免费下载链接】sqlcipherSQLCipher is a standalone fork of SQLite that adds 256 bit AES encryption of database files and other security features.项目地址https://gitcode.com/gh_mirrors/sq/sqlcipher点击查看免费下载相关推荐Pyrite64骨骼蒙皮实战教程6条单骨权重规则与Blender绑定建议Pyrite64骨骼蒙皮实战教程6条单骨权重规则与Blender绑定建议 Pyrite64 是一款基于 libdragon 与 tiny3d 构建的 N64Akka Classic Extensions 扩展机制完全指南从自定义扩展到配置加载与库扩展Akka Classic Extensions 扩展机制完全指南从自定义扩展到配置加载与库扩展 Akka Extensions 是 Akka 提供的官方扩展机后端并发编程异步编程Apache Druid 扩展加载完全指南core extensions、contrib extensions 与 classpath 加载机制Apache Druid 扩展加载完全指南core extensions、contrib extensions 与 classpath 加载机制 导读 Apa数据库数据分析OLAP大数据实时分析数据仓库后端上一篇Anarlog 1.4.4 深度解析分享体验升级与实时会话稳定性修复下一篇Gutenberg ListView 组件完全指南块编辑器层级结构面板的实现原理与开发实践创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考