Skip to content

M3: Dapper coexistence proof (closes Phase 1)#3

Merged
lgamorim merged 4 commits into
masterfrom
feature/M3-dapper-coexistence
Jul 11, 2026
Merged

M3: Dapper coexistence proof (closes Phase 1)#3
lgamorim merged 4 commits into
masterfrom
feature/M3-dapper-coexistence

Conversation

@lgamorim

@lgamorim lgamorim commented Jul 11, 2026

Copy link
Copy Markdown
Owner

What

Milestone 3 (Phase 1 — Bedrock, final milestone) of the SqlBound roadmap: proof that Dapper and SqlBound genuinely coexist — same connection, same transaction, both namespaces imported, zero ambiguity — as a permanent automated test rather than a one-off demo.

  • SqlBound.IntegrationTests: the first integration test project, referencing Dapper and Microsoft.Data.Sqlite alongside SqlBound. SQLite over SQL Server here — the coexistence proof only depends on the shared ADO.NET abstraction, not on SQL-Server-specific behavior (that's M7's job), and SQLite needs no external service or CI setup.

  • DapperCoexistenceTests: three scenarios, each against a real (isolated, in-memory) SQLite connection:

    • Interleaving SqlSession and Dapper calls on the same open connection.
    • A DbTransaction shared between both libraries: commit persists both libraries' writes.
    • The same shared transaction: rollback discards both libraries' writes — the strongest possible proof of genuine sharing, since if either library weren't truly enlisted in the same transaction, its write would survive the rollback.
    • "Zero ambiguity" is proven by the file compiling with both using Dapper; and (implicitly, via enclosing namespace) SqlBound's types together — not a runtime assertion — since SqlBound deliberately never defines Query*/Execute*/ExecuteScalar* extensions on DbConnection.

    All three passed on the first run against the real provider. SqlSession had previously only been verified against M2's hand-rolled ADO.NET fakes; this is the first confirmation its parameter binding and transaction handling work correctly against a live provider, not just idealized fake behavior.

  • Governance: documented the test/<ProjectName>.IntegrationTests/ convention in architecture.md, alongside the existing .UnitTests/ one.

  • Phase 1 close-out: PackageVersion drops its -preview.1 suffix to the clean 0.1.0, so the v0.1.0 tag (to be applied after this merges) names the exact package this revision produces. Convention recorded in workflow.md: prerelease during a phase's active development, clean version on the commit that gets tagged, new prerelease line starts the next phase.

Why

This is the empirical test of the project's core value proposition — a compile-time-verified SQL library that developers can adopt incrementally without displacing Dapper. Closing Phase 1 here also means the roadmap's Bedrock phase (skeleton, execution core, coexistence) is complete before any codegen work begins in Phase 2.

Reviewer notes

  • Security fix included: scaffolding Microsoft.Data.Sqlite surfaced that it transitively pulls SQLitePCLRaw.lib.e_sqlite3 2.1.11, which has a known high-severity vulnerability (CVE-2025-6965, a SQLite memory-corruption bug fixed upstream in SQLite 3.50.2) that NuGet's audit blocks restore on by default. Pinned directly to 3.53.3 in test/SqlBound.IntegrationTests/SqlBound.IntegrationTests.csproj.
  • Directory.Build.props's test-project condition broadened from EndsWith('.UnitTests') to EndsWith('Tests') so the XML-doc exemption and IsPackable=false apply to .IntegrationTests too.
  • No CI workflow changes were needed — Microsoft.Data.Sqlite restores its native binaries for ubuntu-latest automatically, and dotnet test already runs at the solution level.
  • Post-merge action, not in this PR: tagging master as v0.1.0 and pushing the tag, per the workflow rules — will do that separately with explicit confirmation once this is merged.

Test plan

  • Full local verification: dotnet build (0 warnings), dotnet format --verify-no-changes (clean), dotnet test (31 unit + 3 integration, all passing), dotnet pack (produces SqlBound.0.1.0.nupkg)
  • CI green on this PR

🤖 Generated with Claude Code

lgamorim added 4 commits July 11, 2026 02:47
M3 introduces the first integration test project, needing a real
dependency (a database provider) rather than hand-rolled fakes. Adds
test/<ProjectName>.IntegrationTests/ alongside .UnitTests/ in
architecture.md, and broadens Directory.Build.props' test-project
condition from EndsWith('.UnitTests') to EndsWith('Tests') so the
XML-doc exemption and IsPackable=false apply to it too, without
needing another edit for the next test-suffixed project.
The first integration test project, referencing SqlBound, Dapper, and
Microsoft.Data.Sqlite so the coexistence proof can run against a real
ADO.NET provider instead of the hand-rolled fakes used in the unit
tests. SQLite over SQL Server here: the coexistence proof only depends
on the shared ADO.NET abstraction, not on any SQL-Server-specific
behavior (that's M7's job), and SQLite needs no external service or CI
setup.

Pins SQLitePCLRaw.lib.e_sqlite3 to 3.53.3 directly: Microsoft.Data.Sqlite
10.0.9 transitively pulls 2.1.11, which carries a known high-severity
vulnerability (CVE-2025-6965, a SQLite memory-corruption issue fixed
upstream in SQLite 3.50.2) that NuGet's audit now fails restore on.
Three scenarios against a real SQLite provider, each opening its own
isolated in-memory connection:

- interleaving SqlSession and Dapper calls on the same open connection
- a transaction shared between both libraries: commit persists both
  libraries' writes
- the same shared transaction: rollback discards both libraries' writes

The rollback case is the strongest proof of genuine sharing — if either
library weren't truly enlisted in the same transaction, its write would
survive the rollback. Both namespaces (Dapper, SqlBound) are imported
in the same file with zero method-name ambiguity, proven by compiling
rather than by a runtime assertion, since SqlBound deliberately never
defines Query*/Execute*/ExecuteScalar* extensions on DbConnection.

All three passed on the first run against the real provider — SqlSession
was previously verified only against hand-rolled fakes (M2), and this is
the first confirmation its parameter binding and transaction handling
work correctly against a live ADO.NET provider, not just idealized fake
behavior. This project (and these tests) stay in the suite permanently
so a coexistence regression fails CI.
Bumps PackageVersion from 0.1.0-preview.1 to the clean 0.1.0 so the
v0.1.0 tag applied to this commit after merge matches the version it
actually marks — a tag should name the exact package a revision
produces. Dropping the suffix doesn't overclaim stability: every
0.x version is already "anything may change" under semver, so 0.1.0
promises no more than 0.1.0-preview.1 did.

Records the convention in workflow.md: PackageVersion carries a
prerelease suffix during a phase's active development, and closing
the phase drops it in the same commit that gets tagged. The next
phase's first commit starts the new prerelease line.
@lgamorim lgamorim added this to the M3 — Dapper coexistence milestone Jul 11, 2026
@lgamorim lgamorim merged commit dbf944a into master Jul 11, 2026
2 checks passed
@lgamorim lgamorim deleted the feature/M3-dapper-coexistence branch July 11, 2026 02:09
@lgamorim lgamorim modified the milestones: M3 — Dapper coexistence, Phase 1 — Bedrock (0.1.x) Jul 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant