Skip to content

Add the data provider packages, dialects and system migrations - #2737

Merged
pournasserian merged 3 commits into
mainfrom
feat/2689-data-providers-a66630
Nov 2, 2026
Merged

pournasserian merged 3 commits into
mainfrom
feat/2689-data-providers-a66630

Conversation

@pournasserian

@pournasserian pournasserian commented Nov 2, 2026 •

Copy link
Copy Markdown
Member

Closes #2689

Adds the provider seam and the three data provider packages, so that core has one code path and provider-specific SQL stays out of it. FluentCMS.Core gets IJsonSqlDialect, IJobClaimDialect, IDataProvider, SystemDbContext and a minimal AddFluentCms with FluentCmsBuilder. FluentCMS.Data.Sqlite is complete and tested. FluentCMS.Data.PostgreSql and FluentCMS.Data.SqlServer have their wiring, conventions, dialects and first system migration, are marked experimental in their package description, and have never run on a database; #2711 validates and completes them.

Dependencies: Npgsql.EntityFrameworkCore.PostgreSQL 10.0.3 and Microsoft.EntityFrameworkCore.SqlServer 10.0.14 (new). System.Security.Cryptography.Pkcs 10.0.14 (new), a direct reference in the SQL Server package, because Microsoft.Data.SqlClient otherwise brings 9.0.11, which has known vulnerabilities (GHSA-2fmv-rv2c-59x7, GHSA-846f-f764-76mx) that fail the restore. Microsoft.EntityFrameworkCore.Design 10.0.14 (already in Directory.Packages.props) is added to the provider projects as a private asset, so it is not in their packages.

Acceptance

Under the scope change on the issue, the items that name all three providers apply to SQLite until #2711.

  • FluentCMS.Data.Tests runs the same test suite against all three providers in CI. SQLite only. PostgreSQL and SQL Server have offline tests (column types, GIN index, pending model changes, SQL text), with no CI matrix.
  • JSON filters from spec section 4.4 translate on all providers with identical results. SQLite only for results. PostgreSQL and SQL Server are checked for translation only, so identical results are not verified.
  • SQL Server tests cover 2019 (nvarchar JSON) and 2025 (native json) paths. Not done: both column types are asserted offline, and nothing has run on a server. Left to Validate and complete the PostgreSQL and SQL Server providers #2711.
  • A host that references no provider fails startup with a clear FCMS13xx error. FCMS1302, thrown by AddFluentCms.

Verification

On Windows, after merging main: dotnet build -c Release -warnaserror, dotnet test -c Release (916 tests, 915 passed, 1 existing skip), dotnet pack -c Release, and dotnet ef migrations has-pending-model-changes for each provider.

What later issues must do

Interpretations beyond the specification

  • Claim semantics. Spec 4.12 gives only the locking. These are choices: status values pending and running; order priority DESC, run_at, id; a claim sets running, takes the lease and adds one to attempts; attempts < max_attempts is required; and an expired lease is claimable, which goes beyond the spec's WHERE lease_until IS NULL, so that a job returns after its worker dies.
  • SQLite claim is a read, then a guarded update, not one UPDATE ... RETURNING. With a rollback journal, RETURNING commits on a step that Microsoft.Data.Sqlite does not retry, and concurrent claimers got database is locked. The tests run both journal modes.
  • SQLite claim row ids. Ids are matched as the uppercase text EF stores, so cms_job must be written through EF.
  • Numbers on SQLite compare as REAL. A decimal past double precision can compare equal to a neighbouring value; PostgreSQL and SQL Server compare exactly.
  • SQL Server integers. TRY_CONVERT(bigint, ...) does not match a JSON 12.0, while SQLite and PostgreSQL do. Only a value not written by the integer field type looks like that.
  • Dates inside JSON compare as text, so equality is on the exact ISO 8601 string.
  • Every comparison checks the JSON type, on all three. ScalarEquals compares only a value of its own type, ScalarContains matches only JSON text, and ArrayContains matches only text elements of an array, so that results do not depend on how a provider renders another type. On SQLite this adds a json_type guard, because json_extract gives 1 for true and an array or object as its JSON text. ADR 0001's SQL has no such guard.
  • PostgreSQL uses @> for equality rather than a function comparison, because it keeps the JSON type, does not throw on an unexpected shape and is what a GIN index serves.
  • SQL Server text compares under Latin1_General_100_BIN2, to match the case-sensitive providers, and uses OPENJSON rather than JSON_VALUE, which loses the JSON type.
  • SQL Server native json is opt-in through UseSqlServer(connectionString, nativeJson: true). The generated migration uses nvarchar(max), so a host choosing native JSON has no matching migration until Validate and complete the PostgreSQL and SQL Server providers #2711 decides how to handle it.
  • The missing-provider error is thrown by AddFluentCms, before the host is built, rather than at host start. A second provider fails with FCMS1303.
  • dotnet-ef is a global tool in the documented steps; no tool manifest is added.

@pournasserian
pournasserian merged commit 1623707 into main Nov 2, 2026
5 checks passed
@pournasserian
pournasserian deleted the feat/2689-data-providers-a66630 branch November 2, 2026 15:34
@pournasserian pournasserian mentioned this pull request Nov 2, 2026
4 tasks done
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.

Data provider packages for PostgreSQL, SQLite and SQL Server

1 participant