From 28f9354d45621d4d18d2a1b3a42097ed3726a72b Mon Sep 17 00:00:00 2001 From: wellwei <96378453+wellwei@users.noreply.github.com> Date: Sun, 9 Aug 2026 02:43:10 +0800 Subject: [PATCH] =?UTF-8?q?feat(pkg):=20add=20compat.sqlite3@3.45.3=20?= =?UTF-8?q?=E2=80=94=20SQLite=20C=20amalgamation=20(most=20widely=20deploy?= =?UTF-8?q?ed=203.45.x=20line)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Shape A (C-source compat): compile the single sqlite3.c amalgamation into a lib, expose sqlite3.h/sqlite3ext.h via include_dirs; shell.c (interactive CLI, needs editline/readline) stays out. - Version 3.45.3 = final maintenance release of the most widely deployed SQLite series (Ubuntu 24.04 LTS ships 3.45.1; CPython 3.11/3.12/3.13 installers ship 3.45.1/3.45.3/3.45.3), chosen over newer series per user request (widely-used, not latest). - GLOBAL = sqlite.org amalgamation zip (sha256 verified twice); no CN mirror (plain-string url fallback — the GitHub sqlite/sqlite mirror does not carry the generated sqlite3.c). - Consumer member tests/examples/sqlite3 asserts sqlite3_libversion()==3.45.3 and exercises open/create/insert/prepared-query end to end; verified cold with the CI-pinned mcpp 2026.8.8.2 (test result ok, 1 passed). - Design doc covers shape decision, version rationale, multi-version support plan (one mcpp block, xpm rows only). --- .agents/docs/2026-08-09-add-sqlite3-plan.md | 114 ++++++++++++++++++ README.md | 2 +- README.zh-CN.md | 2 +- mcpp.toml | 1 + pkgs/c/compat.sqlite3.lua | 60 +++++++++ tests/examples/sqlite3/mcpp.toml | 9 ++ tests/examples/sqlite3/tests/sqlite3_test.cpp | 39 ++++++ 7 files changed, 225 insertions(+), 2 deletions(-) create mode 100644 .agents/docs/2026-08-09-add-sqlite3-plan.md create mode 100644 pkgs/c/compat.sqlite3.lua create mode 100644 tests/examples/sqlite3/mcpp.toml create mode 100644 tests/examples/sqlite3/tests/sqlite3_test.cpp diff --git a/.agents/docs/2026-08-09-add-sqlite3-plan.md b/.agents/docs/2026-08-09-add-sqlite3-plan.md new file mode 100644 index 0000000..5f13369 --- /dev/null +++ b/.agents/docs/2026-08-09-add-sqlite3-plan.md @@ -0,0 +1,114 @@ +# 新增 SQLite 收录(compat.sqlite3,C 源码 compat) + +**日期**: 2026-08-09 +**本仓**: `mcpplibs/mcpp-index` +**参考**: PR #48(cJSON compat)、#50(eigen);skill [`add-mcpp-index-package`](../skills/add-mcpp-index-package/SKILL.md) +**目标**: 收录 SQLite 引擎本体为 `compat.sqlite3`(C 源码 compat 形态),版本 **3.45.3**,用户 +`#include ` 开箱即用;最小示例 `tests/examples/sqlite3/` 走完整冷验证。 + +--- + +## 1. 版本选择:3.45.3(部署最广,而非最新) + +用户要求"选最广泛使用的版本,不追求最新"。调研结论:3.45.x 是当前部署面最广的版本线。 + +| 平台 | SQLite 版本 | +|---|---| +| Ubuntu 24.04 LTS(支持至 2029+) | 3.45.1(安全更新在 3.45.x 线内) | +| CPython 3.11 / 3.12 / 3.13 官方安装器 | 3.45.1 / 3.45.3 / 3.45.3 | +| Debian 13(trixie)/ Debian 12(bookworm) | 3.46.1 / 3.40.1(3.45 处于两者交集) | +| Android 15+ / iOS 18+ 时代生态 | 3.45+ 被普遍视为兼容基准 | + +- **3.45.3** = 3.45.x 线最后一个维护版(含该线安全/稳定性修复),API 与 Ubuntu 24.04 LTS 的 3.45.1 一致,更成熟。 +- 未选最新 3.53.4:新版本线部署面尚未铺开,收录后对消费侧无兼容收益。 +- 后续可加新版本线:xpm 加行即可,mcpp 块不变。 + +## 2. 上游布局与哈希(已实测) + +- GLOBAL:`https://sqlite.org/2024/sqlite-amalgamation-3450300.zip`(HEAD 200 已验证;3.45.1/3.45.2/3.45.3 + 均存在,年路径为发布年)。 +- sha256(两次计算一致):`ea170e73e447703e8359308ca2e4366a3ae0c4304a8665896f068c736781c651`。 +- zip 单层 wrap `sqlite-amalgamation-3450300/`,内含 `sqlite3.c`(9.0 MB)、`shell.c`、`sqlite3.h`、 + `sqlite3ext.h`。glob `*` 吸收 wrap 层。 +- 许可:Public Domain(SPDX 无标准 id,采用 `LicenseRef-Public-Domain` 惯例)。 + +## 3. 形态判定:形态 A(C 源码 compat),无 feature + +- 只编 `sqlite3.c` 进 lib;`shell.c`(交互式 CLI)不编 —— 它依赖 editline/readline。 +- `include_dirs = {"*"}` 暴露 `sqlite3.h` / `sqlite3ext.h`。 +- amalgamation 开箱即编,无需任何 define/config;`c_standard = c11`(与 compat.cjson 对齐)。 +- **无可门控组件**:amalgamation 是单一 TU,可选功能全部由编译期 define 控制(如 + `SQLITE_OMIT_*` / `SQLITE_ENABLE_*`),而当前 mcpp feature 表只能门控 sources、不能携带 define → 不实现 + feature(同 compat.eigen 对 define 类开关的结论)。 +- **无 CN 镜像**:sqlite.org 是 amalgamation 的唯一权威来源(GitHub `sqlite/sqlite` 镜像仓**不含**生成的 + `sqlite3.c`,raw 404 实测);无 `mcpp-res` 写权限 → 采用纯字符串 url 回退(先例:compat.hiredis / + compat.spdlog / compat.redis-plus-plus)。 + +## 4. 描述符与消费者示例 + +- `pkgs/c/compat.sqlite3.lua`:三平台同 url+sha;`sources = {"*/sqlite3.c"}`;target `sqlite3`(kind lib)。 +- `tests/examples/sqlite3/`:`mcpp.toml` 依赖 `compat.sqlite3 = "3.45.3"`;`tests/sqlite3_test.cpp` 断言 + `sqlite3_libversion() == "3.45.3"`,并走 `sqlite3_open(:memory:) → sqlite3_exec 建表/插入 → 预编译语句查询` + 全链路。 +- 根 `mcpp.toml` `[workspace] members` 登记 `tests/examples/sqlite3`(CI 的成员选择与 `--all` 都读它)。 + +## 5. 本地验证(mcpp 2026.8.8.2,与 CI 同版) + +- 环境:`MCPP`/`MCPP_HOME`/`MCPP_VENDORED_XLINGS` 指向 `mcpp-2026.8.8.2-macosx-arm64` 解包根, + `MCPP_INDEX_MIRROR=GLOBAL`;`~/.mcpp/registry` 复制 release 自带 registry。 +- 结果(`$MCPP test -p sqlite3`,冷状态,自动装 llvm@20.1.7 工具链): + `sqlite3_test ... ok (0.27s)` / `test result ok. 1 passed; 0 failed; finished in 104.29s`。 +- 包从 sqlite.org 下载、`sqlite3.c` 编译、链接、运行断言全部通过。 + +## 6. lint(复现 validate.yml) + +- lua 语法 `loadfile(...,'t')` OK;`spec/name/xpm` 必填字段齐全;无前导 v。 +- `check_mirror_urls.lua` OK(纯字符串 url 不施加镜像约束)。 +- `check_package_name.lua` OK;全仓 `check_cross_package_refs.lua` OK。 + +## 7. 后续可选项(不在本 PR 范围) + +- **C++ 封装层**(SQLiteCpp / sqlite_orm):用户已评估 —— 非必要,引擎先行;若后续做,sqlite_orm 为 + header-only 且提供 MIT 双许可,适合独立 PR。 +- **CN 镜像**:获得 `mcpp-res` 写权限后,可将 url 改写为 `{ GLOBAL=…, CN=… }` 表(sha256 不变)。 +- **新版本线**:3.46+/3.50+/3.53+ 作为新 xpm 行追加。 + +## 8. 多版本支持方案(后续可实施,难度低) + +SQLite amalgamation 布局几十年来恒定(每版均为 `sqlite3.c` / `sqlite3.h` / `sqlite3ext.h` / `shell.c`, +同一个 wrap 层),因此**一个 `mcpp` 块通吃所有版本**:`sources` / `include_dirs` / `c_standard` 不变, +加版本 = 三平台各加一行 `xpm` 条目。对比本仓难例(`compat.catch2` v2/v3 形态切换、`compat.redis-plus-plus` +subset/superset 源码并集),SQLite 属最简单一档。 + +### 8.1 URL 数字编码与年路径(唯一需要小心的点) + +版本号 → 数字编码 = 大版本 1 位 + 次版本 2 位 + 补丁 2 位;URL 带**发布年**路径。已实测: + +| 版本 | URL | 备注 | +|---|---|---| +| 3.45.3 | `https://sqlite.org/2024/sqlite-amalgamation-3450300.zip` | 本 PR 收录 | +| 3.46.1 | `https://sqlite.org/2024/sqlite-amalgamation-3460100.zip` | 3.46 → `34601` | +| 3.50.0 | `https://sqlite.org/2025/sqlite-amalgamation-3500000.zip` | 3.50 → `35000`,勿写成 `350` | +| 3.53.4 | `https://sqlite.org/2026/sqlite-amalgamation-3530400.zip` | 年路径随发布年变 | + +### 8.2 加一版的操作步骤 + +1. 下载对应 zip,`tar -tzf` 确认布局仍为四件套(应无变化)。 +2. `sha256sum` 计算两次确认稳定。 +3. 描述符三平台各加一个 `["x.y.z"] = { url=…, sha256=… }` 行(mcpp 块不动)。 +4. 新成员 `tests/examples/sqlite3-/`(或复用既有成员改 pin)做冷验证。 + +### 8.3 测试与 CI 覆盖策略 + +- **每版本一个成员、断言各自 pin 的版本**(先例:`tests/examples/redis-plus-plus` 与 + `redis-plus-plus-v133` 各 pin 一版),不放松 `sqlite3_libversion()` 断言 —— 否则「解析到的确为所 pin + 版本」的证明被削弱。 +- CI 成员选择规则为「描述符变更 → 选中所有 mcpp.toml 引用 `sqlite3` 的成员」,故新增第二成员后,改描述符 + 时两个版本都会被 CI 覆盖。 +- SQLite API 纯增量、文件格式兼容,同一行为测试跨版本通常直接通过;各成员的意义在于证明该版本 + 编译+链接+行为均正常。 + +### 8.4 何时加 + +- 用户侧出现对更新版本线的需求(如新 feature / 新文件格式扩展)时按上述步骤追加; +- 加 CN 镜像(获得 `mcpp-res` 写权限)与加新版本相互独立,互不阻塞。 diff --git a/README.md b/README.md index d4bb706..d639f18 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ Two kinds of packages live here: | Shape | Examples | |------|------| | Native module library (Form A) | [`mcpplibs.xpkg`](pkgs/x/xpkg.lua) · [`mcpplibs.tinyhttps`](pkgs/t/tinyhttps.lua) · [`tensorvia-cpu`](pkgs/t/tensorvia-cpu.lua) · [`ffmpeg`](pkgs/f/ffmpeg.lua) (module layer; sources compiled directly through `compat.ffmpeg`) · [`opencv`](pkgs/o/opencv.lua) (single repository: the module layer and the full OpenCV 5 source build both live in the package, and only this descriptor stays on the index side) · [`mcpplibs.grpc`](pkgs/g/grpc.lua) (gRPC 1.83.0 — the one library here that CANNOT be a compat descriptor: upstream publishes no self-contained source artifact, its tag archive carrying abseil/protobuf/re2/boringssl/zlib as empty submodule placeholders, so [grpc-m](https://github.com/mcpplibs/grpc-m)'s release tarball IS that artifact. It vendors only gRPC's own source and takes the five dependencies from this index, so a consumer that also uses protobuf links one copy rather than two) | -| C-source compat (with `features`) | [`compat.cjson`](pkgs/c/compat.cjson.lua) · [`compat.zlib`](pkgs/c/compat.zlib.lua) · [`compat.hiredis`](pkgs/c/compat.hiredis.lua) (the classic 1.2.0 — a 7-TU C build whose flat tarball headers get `hiredis/`-prefixed wrapper headers via `generated_files`, so consumers write `#include ` exactly like upstream's install layout) | +| C-source compat (with `features`) | [`compat.cjson`](pkgs/c/compat.cjson.lua) · [`compat.zlib`](pkgs/c/compat.zlib.lua) · [`compat.hiredis`](pkgs/c/compat.hiredis.lua) (the classic 1.2.0 — a 7-TU C build whose flat tarball headers get `hiredis/`-prefixed wrapper headers via `generated_files`, so consumers write `#include ` exactly like upstream's install layout) · [`compat.sqlite3`](pkgs/c/compat.sqlite3.lua) (plain C-source, no features: the single `sqlite3.c` amalgamation; 3.45.3, the final maintenance release of the most widely deployed 3.45.x line) | | C++-source compat, one depending on the other | [`compat.abseil`](pkgs/c/compat.abseil.lua) (151 TUs; a wildcard over `absl/**` trimmed by upstream's test/benchmark naming conventions) · [`compat.protobuf`](pkgs/c/compat.protobuf.lua) (the libprotobuf runtime, 79 TUs transcribed from upstream's own `src/file_lists.cmake`; declares `compat.abseil` as a dependency because protobuf's public headers include `absl/…`, and its `gzip` feature defines `HAVE_ZLIB` and pulls `compat.zlib`, while `upb` adds protobuf's 64-TU C runtime out of the same tarball. It also exposes **`protoc`** as a `kind = "bin"` target, so a consumer writing `tools = ["protoc"]` gets the compiler built for its own machine out of the same package it links — making a generator/runtime version mismatch inexpressible) · [`compat.re2`](pkgs/c/compat.re2.lua) (22 TUs, upstream's own `RE2_SOURCES`) · [`compat.redis-plus-plus`](pkgs/c/compat.redis-plus-plus.lua) (redis++ 1.3.13 — the sync client, 17 TUs + `patterns/redlock.cpp`, depends on `compat.hiredis`; the one header CMake would generate, `hiredis_features.h`, is snapshotted via `generated_files`, and the async/TLS TUs are left out so the base build stays a two-package pair. Two versions, one on each side of the source-structure watershed, share this ONE source list: 1.3.13 (modern 17-TU layout) and 1.3.3 (pre-`redis_uri.cpp`/`redlock` 15-TU layout) — the union works because 1.3.3's TUs are a strict subset, so exactly two globs match nothing there (a warning, not an error; same trick as compat.catch2)) | | C++-source compat, zero-dep client + optional components | [`compat.websocket`](pkgs/c/compat.websocket.lua) (IXWebSocket 12.0.1 — a pure RFC 6455 client compiled from upstream's `IXWEBSOCKET_SOURCES` minus the four server TUs, so the **base build has zero external dependencies**: TLS off (the OpenSSL/MbedTLS/AppleSSL TUs aren't built) and `IXWEBSOCKET_USE_ZLIB` unset, so the gzip codec compiles to a no-op. Two optional features add on top: `server` (the four server TUs — `IXWebSocketServer`, `IXSocketServer`, `IXHttpServer`, `IXWebSocketProxyServer` — needing nothing external, and it **implies `zlib`** because upstream's server advertises permessage-deflate by default, which the transport negotiates regardless of the define) and `zlib` (deps `compat.zlib` and turns the codec into real per-message-deflate compression). The default-feature test brings its own minimal RFC 6455 echo server on loopback sockets (handshake, masking, fragmentation and close all exercised offline); a second member, `websocket-features`, runs a real `ix::WebSocketServer` and asserts the compression is observable on the wire — a 64 KiB repeated payload round-trips with `wireSize` = 80) | | header-only (with `features`) | [`compat.eigen`](pkgs/c/compat.eigen.lua) | diff --git a/README.zh-CN.md b/README.zh-CN.md index 2ac39c0..b329f3a 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -35,7 +35,7 @@ mcpp self config --mirror CN # 切换至国内镜像,默认使用 GLOBAL 上 | 形态 | 示例 | |------|------| | 原生模块库(Form A) | [`mcpplibs.xpkg`](pkgs/x/xpkg.lua) · [`mcpplibs.tinyhttps`](pkgs/t/tinyhttps.lua) · [`tensorvia-cpu`](pkgs/t/tensorvia-cpu.lua) · [`ffmpeg`](pkgs/f/ffmpeg.lua)(模块层,源码经 `compat.ffmpeg` 直编) · [`opencv`](pkgs/o/opencv.lua)(单仓库:模块层与 OpenCV 5 全源码构建同在包内,索引侧只留本描述符) · [`mcpplibs.grpc`](pkgs/g/grpc.lua)(gRPC 1.83.0 —— 本索引里唯一**无法**做成 compat 描述符的库:上游不发布任何自包含源码产物,其 tag 归档里 abseil/protobuf/re2/boringssl/zlib 全是空 submodule 占位,因此 [grpc-m](https://github.com/mcpplibs/grpc-m) 的 release tarball 才是那个产物。它只 vendor gRPC 自己的源码,五个依赖全取自本索引,故同时直接使用 protobuf 的消费者链进去的是同一份而非两份)| -| C 源码 compat(含 `features`) | [`compat.cjson`](pkgs/c/compat.cjson.lua) · [`compat.zlib`](pkgs/c/compat.zlib.lua) · [`compat.hiredis`](pkgs/c/compat.hiredis.lua)(经典 1.2.0 —— 7 个 C TU;tarball 平铺头经 `generated_files` 补 `hiredis/` 前缀薄包装头,消费者可写 `#include `,与上游安装布局一致) | +| C 源码 compat(含 `features`) | [`compat.cjson`](pkgs/c/compat.cjson.lua) · [`compat.zlib`](pkgs/c/compat.zlib.lua) · [`compat.hiredis`](pkgs/c/compat.hiredis.lua)(经典 1.2.0 —— 7 个 C TU;tarball 平铺头经 `generated_files` 补 `hiredis/` 前缀薄包装头,消费者可写 `#include `,与上游安装布局一致) · [`compat.sqlite3`](pkgs/c/compat.sqlite3.lua)(纯 C 源码、无 feature:单一 `sqlite3.c` amalgamation;3.45.3,部署最广的 3.45.x 线最后一个维护版) | | C++ 源码 compat(彼此依赖) | [`compat.abseil`](pkgs/c/compat.abseil.lua)(151 TU;对 `absl/**` 取通配后,按上游自身的 test/benchmark 命名约定裁剪) · [`compat.protobuf`](pkgs/c/compat.protobuf.lua)(libprotobuf 运行时,79 TU 逐条转录自上游 `src/file_lists.cmake`;因 protobuf 公开头文件 include 了 `absl/…`,故显式依赖 `compat.abseil`;`gzip` feature 定义 `HAVE_ZLIB` 并拉入 `compat.zlib`,`upb` feature 则从同一个 tarball 里再编出 protobuf 的 64 TU C 运行时;还以 `kind = "bin"` target 暴露 **`protoc`**,消费者写 `tools = ["protoc"]` 即可从「自己链接的那个包」拿到为本机构建的编译器,使生成器与运行时的版本错配无法表达) · [`compat.re2`](pkgs/c/compat.re2.lua)(22 TU,取自上游自身的 `RE2_SOURCES`) · [`compat.redis-plus-plus`](pkgs/c/compat.redis-plus-plus.lua)(redis++ 1.3.13 —— 同步客户端,17 TU + `patterns/redlock.cpp`,依赖 `compat.hiredis`;CMake 唯一会生成的头 `hiredis_features.h` 用 `generated_files` 快照,async/TLS TU 不收,基座保持两包成对。两个版本分处源码结构分水岭两侧,共享同一份源列表:1.3.13(现代 17-TU 布局)与 1.3.3(缺 `redis_uri.cpp`/`redlock` 的 15-TU 旧布局)—— 并集之所以成立,是因为 1.3.3 的 TU 是 1.3.13 的严格子集,恰好两个 glob 在 1.3.3 上零命中(仅警告,非错误;与 compat.catch2 同款手法)) | | C++ 源码 compat(零依赖客户端 + 可选组件) | [`compat.websocket`](pkgs/c/compat.websocket.lua)(IXWebSocket 12.0.1 —— 从上游 `IXWEBSOCKET_SOURCES` 剔掉 4 个 server TU 后直编的纯 RFC 6455 客户端,**基座零外部依赖**:TLS 关闭(OpenSSL/MbedTLS/AppleSSL 三组 TU 均不编),`IXWEBSOCKET_USE_ZLIB` 不定义(gzip codec 编译为 no-op)。两个可选 feature 在基座上叠加:`server`(4 个 server TU —— `IXWebSocketServer`/`IXSocketServer`/`IXHttpServer`/`IXWebSocketProxyServer`,零新增外部依赖,且 **implies `zlib`** —— 因为上游 server 默认就宣称 permessage-deflate,而 transport 的协商不受宏门控)与 `zlib`(依赖 `compat.zlib`,把 codec 变成真正的 permessage-deflate 压缩)。默认构建的测试自带基于 loopback 原始 socket 的最小 RFC 6455 echo server(握手/掩码/分片/关闭全部离线实测);第二个成员 `websocket-features` 跑真实的 `ix::WebSocketServer`,并断言压缩在线路上可观测 —— 64 KiB 重复载荷往返,`wireSize` = 80) | | header-only(含 `features`) | [`compat.eigen`](pkgs/c/compat.eigen.lua) | diff --git a/mcpp.toml b/mcpp.toml index 054476d..945fffc 100644 --- a/mcpp.toml +++ b/mcpp.toml @@ -69,6 +69,7 @@ members = [ "tests/examples/llmapi", "tests/examples/md4c", "tests/examples/spdlog-compiled", + "tests/examples/sqlite3", "tests/examples/tinyhttps", "tests/examples/vulkan", "tests/examples/websocket", diff --git a/pkgs/c/compat.sqlite3.lua b/pkgs/c/compat.sqlite3.lua new file mode 100644 index 0000000..a61a201 --- /dev/null +++ b/pkgs/c/compat.sqlite3.lua @@ -0,0 +1,60 @@ +-- Form B inline descriptor for SQLite — the most widely deployed database +-- engine in the world, distributed as a single C amalgamation. Pure-C source +-- build (same shape as compat.cjson / compat.zlib): compile sqlite3.c into a +-- lib, expose sqlite3.h / sqlite3ext.h via include_dirs. shell.c (the +-- interactive CLI) stays out — it pulls in editline/readline dependencies. +-- The amalgamation builds out of the box with no defines. +-- +-- VERSION. 3.45.3 is the FINAL maintenance release of the 3.45.x series, the +-- most widely deployed SQLite line: Ubuntu 24.04 LTS ships 3.45.1 and CPython +-- 3.11/3.12/3.13 official installers ship 3.45.1/3.45.3/3.45.3. Pinning this +-- mature baseline rather than the newest release keeps consumers +-- API-compatible with the largest installed base; newer series can be added +-- later as extra xpm rows (the mcpp block never changes). +-- +-- No CN mirror: sqlite.org is the authoritative source for the amalgamation +-- (the GitHub sqlite/sqlite mirror does NOT carry the generated sqlite3.c), +-- and plain-string url is the documented fallback without mcpp-res write +-- access (docs/cn-mirror.md; precedent: compat.hiredis / compat.spdlog). +package = { + spec = "1", + namespace = "compat", + name = "sqlite3", + description = "SQLite — self-contained SQL database engine (C amalgamation)", + licenses = {"LicenseRef-Public-Domain"}, + repo = "https://sqlite.org/", + type = "package", + + xpm = { + linux = { + ["3.45.3"] = { + url = "https://sqlite.org/2024/sqlite-amalgamation-3450300.zip", + sha256 = "ea170e73e447703e8359308ca2e4366a3ae0c4304a8665896f068c736781c651", + }, + }, + macosx = { + ["3.45.3"] = { + url = "https://sqlite.org/2024/sqlite-amalgamation-3450300.zip", + sha256 = "ea170e73e447703e8359308ca2e4366a3ae0c4304a8665896f068c736781c651", + }, + }, + windows = { + ["3.45.3"] = { + url = "https://sqlite.org/2024/sqlite-amalgamation-3450300.zip", + sha256 = "ea170e73e447703e8359308ca2e4366a3ae0c4304a8665896f068c736781c651", + }, + }, + }, + + mcpp = { + language = "c++23", + import_std = false, + c_standard = "c11", + -- Tarball root: exposes sqlite3.h and sqlite3ext.h to consumers + -- writing `#include `. + include_dirs = { "*" }, + sources = { "*/sqlite3.c" }, + targets = { ["sqlite3"] = { kind = "lib" } }, + deps = { }, + }, +} diff --git a/tests/examples/sqlite3/mcpp.toml b/tests/examples/sqlite3/mcpp.toml new file mode 100644 index 0000000..bc46866 --- /dev/null +++ b/tests/examples/sqlite3/mcpp.toml @@ -0,0 +1,9 @@ +# SQLite test project: depends on compat.sqlite3 (built from source via this +# repo's own index) and asserts behavior under `mcpp test`. Part of the +# mcpp-index self-referential workspace. +[package] +name = "sqlite3-tests" +version = "0.1.0" + +[dependencies.compat] +sqlite3 = "3.45.3" diff --git a/tests/examples/sqlite3/tests/sqlite3_test.cpp b/tests/examples/sqlite3/tests/sqlite3_test.cpp new file mode 100644 index 0000000..fe4df86 --- /dev/null +++ b/tests/examples/sqlite3/tests/sqlite3_test.cpp @@ -0,0 +1,39 @@ +// Behavioral test for compat.sqlite3 (SQLite 3.45.3, C API): assert the +// resolved library version, then open an in-memory database, create a table, +// insert a row, and read it back through both sqlite3_exec and a prepared +// statement. +#include +#include +#include + +int main() { + // The index pins 3.45.3; prove the resolved package is that version. + assert(std::strcmp(sqlite3_libversion(), "3.45.3") == 0); + + sqlite3* db = nullptr; + assert(sqlite3_open(":memory:", &db) == SQLITE_OK); + assert(db != nullptr); + + // DDL + DML through the convenience API. + char* errmsg = nullptr; + int rc = sqlite3_exec(db, + "CREATE TABLE t(id INTEGER PRIMARY KEY, name TEXT NOT NULL);" + "INSERT INTO t(name) VALUES ('mcpp');", + nullptr, nullptr, &errmsg); + assert(rc == SQLITE_OK); + if (errmsg != nullptr) { sqlite3_free(errmsg); errmsg = nullptr; } + + // Read back through a prepared statement. + sqlite3_stmt* stmt = nullptr; + rc = sqlite3_prepare_v2(db, "SELECT id, name FROM t;", -1, &stmt, nullptr); + assert(rc == SQLITE_OK); + assert(stmt != nullptr); + assert(sqlite3_step(stmt) == SQLITE_ROW); + assert(sqlite3_column_int(stmt, 0) == 1); + assert(std::strcmp(reinterpret_cast(sqlite3_column_text(stmt, 1)), "mcpp") == 0); + assert(sqlite3_step(stmt) == SQLITE_DONE); + sqlite3_finalize(stmt); + + assert(sqlite3_close(db) == SQLITE_OK); + return 0; +}