Skip to content
CAI
Software that uses CAICheck a score

JordanMarr/SqlHydra

56.3

Adequate · 24 September 2026

14.3k

lines of production code

F#

primary language

5

measurements over time

CAI band scale
CAI trend line
CAI lens gauges

What this system is

SqlHydra is a type-safe SQL generation tool for F\# that creates strongly-typed data access code from database schemas. It provides a CLI for introspecting databases across SQL Server, PostgreSQL, SQLite, Oracle, and MySQL, and a query engine that translates LINQ expressions into provider-specific SQL. The system ensures type safety by generating column wrappers for safe data reading and abstracting write operations to exclude read-only fields.

How it got here

2021 — Initial project setup and core engine development

21 changes.

This period established the SqlHydra project foundation, including the initial repository structure, core domain models, and the LINQ-to-SQL query generation engine. It also introduced comprehensive multi-database support for SQL Server, PostgreSQL, SQLite, and Oracle, alongside a robust test suite and build infrastructure targeting .NET 8, 9, and 10.

2022–2026 — multi-database provider expansion

10 changes.

This period focused on expanding the CLI's database support by implementing initial providers for Oracle, MySQL, and SQL Server, alongside significant updates to existing PostgreSQL and SQLite implementations. The work involved standardizing provider interfaces, refining type mappings for modern .NET versions, and enhancing schema introspection capabilities across all supported databases.

Features

Added Azure CLI installation script for Debian-based dev containers

A new library script (azcli-debian.sh) has been added to the devcontainer configuration to automate the installation of the Azure CLI on Debian-based environments. This script handles dependency management, securely imports Microsoft's GPG keys, configures the Azure CLI package repository, and installs the azure-cli package, ensuring the development container has the necessary tools for Azure interactions out of the box.

src/.devcontainer/library-scripts · high confidence

Added Oracle sample database initialization scripts for the dev container

The development container now includes a complete set of SQL scripts to initialize the Oracle database with the OT (Oracle Tutorial) sample schema and data. These files define the database structure (regions, countries, locations, warehouses, employees, products, customers, orders, and inventories) and populate them with sample data, ensuring the local development environment starts with a consistent, pre-configured dataset ready for use.

src/.devcontainer/orcl · high confidence

Added PostgreSQL dev container with AdventureWorks sample database

Developers can now spin up a local PostgreSQL development environment that automatically provisions the AdventureWorks 2014 OLTP sample database. The container image installs necessary tools (Ruby, unzip), converts CSV data formats for PostgreSQL compatibility, and runs initialization scripts to create the database, user, and schema structures, providing a ready-to-use dataset for testing and development.

src/.devcontainer/postgresql · high confidence

Added SQL Server dev container with AdventureWorks sample and extension schemas

The development environment for SQL Server now includes a Docker setup that automatically restores the AdventureWorks sample database and creates a custom \ext\ schema. This schema contains specific tables to support and reproduce fixes for nullable composite keys, full \datetime2\ precision, and \HierarchyId\ data types, ensuring these features are available for testing during development.

src/.devcontainer/mssql · high confidence

CLI now supports DACPAC input and explicit extension loading

The CLI can now generate code from SQL Server Data-tier Application packages (.dacpac) via a new SsdtGenerator, parsing the internal model.xml to extract tables, views, and relationships. Additionally, the extension system has been reworked to require explicit registration in the TOML configuration; the CLI now loads extension DLLs from the target project's build output and fails loudly if a registered extension is missing or contains no implementations, rather than silently skipping them.

src/SqlHydra.Cli · high confidence

Initial MySQL provider implementation for the CLI

Added the MySQL database provider to the CLI, introducing new source files for data type mappings, schema retrieval, and provider registration. This enables users to connect to MySQL databases, automatically map MySQL column types (including legacy and modern date/time handling) to .NET types, and retrieve table schemas for code generation.

src/SqlHydra.Cli/MySql · high confidence

Initial Oracle database provider support

Added a new Oracle database provider to the CLI, enabling schema discovery and type mapping for Oracle databases. This includes a schema provider that queries system tables to extract table and column metadata, a data type mapping module that converts Oracle-specific types (such as NUMBER, VARCHAR2, TIMESTAMP, and BLOB) to .NET types with precision-aware adjustments, and a provider instance that wires these components together for use with the SqlHydra code generation pipeline.

src/SqlHydra.Cli/Oracle · high confidence

Initial SQL Server database schema for AdventureWorks

The project now includes the initial SQL Server database schema for the AdventureWorks sample database, defined in the AdventureWorks.sqlproj file. This schema establishes the core data model for the SalesLT schema, including tables for Customers, Addresses, Products, Product Categories, Product Models, and Sales Orders (Header and Detail). It also defines necessary constraints, indexes, and a trigger to maintain data integrity, such as automatically updating subtotals in the SalesOrderHeader when SalesOrderDetail records change.

src/AdventureWorks · high confidence

Initial domain model and write-shape abstraction for generated records

The SqlHydra.Domain package introduces the core type definitions for schema introspection and code generation, including records for Tables, Columns, Enums, and the global Config (which now supports options like NullablePropertyType, TableDeclarations, and LeftJoinedViews). It also defines the IWriteOf and IWriteColumns interfaces, which allow generated table records to expose only the columns that are safe to INSERT or UPDATE, automatically excluding database-owned or read-only columns from write operations.

SqlHydra.Domain · high confidence

Initial release of the SqlHydra.Query SQL generation engine

This change introduces the core SqlHydra.Query library, providing the infrastructure to translate LINQ expressions into SQL. It includes the query Intermediate Representation (IR) definitions for SELECT, INSERT, UPDATE, and DELETE operations, a LINQ expression visitor to parse query logic, and an ISqlEmitter interface for database-specific SQL generation. The implementation supports complex query features such as joins, where clauses, aggregates, and left-view records for nullable columns.

SqlHydra.Query · high confidence

Initial repository setup and documentation

The repository has been initialized with core project files including an MIT license, build automation scripts, and configuration for line endings and ignored files. Comprehensive documentation has been added, detailing the SqlHydra library as a type-safe SQL generation tool for F\# that supports SQL Server, PostgreSQL, SQLite, Oracle, and MySQL. The README provides quick-start instructions for installing the CLI tool, generating types from database schemas, and writing strongly-typed queries using the SqlHydra.Query library.

(repo-wide) · high confidence

Initial solution structure for SqlHydra

The SqlHydra solution is introduced, defining the core project layout including SqlHydra.Query, SqlHydra.Domain, SqlHydra.Cli, and a Build project, alongside a Tests project nested under a \_Tests solution folder. The configuration supports Debug, Release, and DebugDocker platforms across various architectures.

src · high confidence

New SQL Server provider implementation with explicit type mappings

The SQL Server database provider has been implemented with explicit support for mapping SQL Server data types to .NET types, including modern .NET 6+ types like DateOnly and TimeOnly for DATE and TIME columns (with legacy DateTime/TimeSpan support available). The provider now handles schema introspection for tables and views, filters out tables with no supported columns, and integrates with the new ISqlHydraDbProvider interface for consistent provider registration.

src/SqlHydra.Cli/SqlServer · high confidence

Sample app now includes examples for Dapper, Dapper.FSharp, and Donald

The sample application has been expanded to demonstrate the HydraReader library alongside other popular data-access tools. New example modules have been added for vanilla Dapper, the Dapper.FSharp query builder, and the Donald library, alongside the existing native reader example. These additions allow users to compare usage patterns and see how Hydra integrates with different ADO.NET wrappers and query styles.

src/SampleApp · high confidence

Behavioural changes

Generated reader classes now use Column wrappers for safer data access

The generated code in SampleApp.AdventureWorks has shifted from direct method calls to a Column-based architecture. Each field is now represented by a RequiredColumn or OptionalColumn type that encapsulates the reader, ordinal lookup, and getter logic. This allows the generated Read() methods to simply invoke .Read() on these column instances, while ReadIfNotNull() checks for nulls via the column's IsNull() method before returning an Option. The diff also shows support for binary columns (RequiredBinaryColumn/OptionalBinaryColumn) and utility extensions for DateOnly and TimeOnly types.

SampleApp · high confidence

Introduce left-view nullability and provider type attributes

The domain layer now supports column-level nullability for left joins by introducing the ILeftViewOf interface, which allows unmatched rows to be represented as None per column rather than wrapping the entire record in an Option. Additionally, the ProviderDbTypeAttribute has been added to explicitly map properties and fields to specific database provider types using their full names.

src/SqlHydra.Domain · high confidence

Introduces FAKE-based build system with .NET 8, 9, and 10 support

The project now uses a new FAKE build script (src/Build) to manage the build lifecycle, replacing previous methods. This build system explicitly supports building and testing the SqlHydra.Cli and SqlHydra.Query projects against .NET 8, .NET 9, and .NET 10 frameworks. It includes dedicated targets for restoring dependencies, building the netstandard2.0-based Query project separately, running tests on each supported framework, regenerating AdventureWorks schema tests, packing NuGet packages, and publishing them to NuGet.org using the SQLHYDRA\_NUGET\_KEY environment variable.

src/Build · high confidence

Npgsql provider now supports PostgreSQL network address types and materialized view mappings

The Npgsql provider has been updated to recognize additional PostgreSQL data types, specifically network address types (cidr, inet, macaddr, macaddr8) which now map to their corresponding .NET types (IPNetwork, IPAddress, PhysicalAddress). It also adds support for materialized view column mappings (e.g., int8, float8) and ensures legacy date/time handling is preserved via the isLegacy flag. The provider instance is now defined using the new ISqlHydraDbProvider interface, consolidating configuration for the Npgsql dialect.

src/SqlHydra.Cli/Npgsql · high confidence

PostgreSQL SQL function support now generated from database catalog

The code generation for PostgreSQL SQL functions has been reworked to derive function signatures directly from the \pg\_proc\ system catalog. A new allowlist file (\NpgsqlSqlFn.allowlist\) defines which functions are exposed, while the generator script (\NpgsqlSqlFn.fsx\) queries the database to determine argument types, return types, and strictness (NULL handling). This approach automatically supports niladic functions (like \current\_date\) by treating them as keywords when no catalog row exists, and ensures that function overloads match the actual database schema rather than being hardcoded.

src/SqlHydra.Query/codegen · high confidence

Query builders and hydration pipeline restructured for provider-specific fixes and expression normalization

The query execution layer has been reorganized to improve reliability and cross-version compatibility. A new ExpressionNormalizer module standardizes LINQ expression trees, ensuring consistent behavior across different F\# compiler versions. Provider-specific SQL generation issues are now handled explicitly in the Fixes module, including Oracle multi-insert and identity queries, PostgreSQL identity returns, and SQL Server GUID identity handling. The hydration pipeline has been replaced with a new internal module that centralizes column reading, featuring robust Oracle type conversion fallbacks and support for DateOnly/TimeOnly on .NET 6+. Additionally, dedicated builder files (InsertBuilders, DeleteBuilders) now expose cancellation and timeout controls, and new extension modules provide native SQL functions for MySQL and PostgreSQL.

src/SqlHydra.Query · high confidence

SQLite provider now uses Microsoft.Data.Sqlite and supports legacy type mappings

The SQLite provider implementation has been updated to use Microsoft.Data.Sqlite instead of System.Data.SQLite, changing the default provider and connection types accordingly. Additionally, the provider now exposes a legacy mode that maps 'date' and 'time' columns to System.DateTime instead of the newer System.DateOnly and System.TimeOnly, ensuring compatibility with older schema expectations.

src/SqlHydra.Cli/Sqlite · high confidence

SqlHydra CLI v2.6.0-beta.4: New configuration wizard, explicit extension loading, and improved PostgreSQL/SQLite schema handling

The CLI now includes an interactive configuration wizard to generate new TOML config files, defaulting to \LeftJoinedViews\ enabled and \NullablePropertyType\ set to Option. Extension loading has changed from auto-scanning to requiring explicit opt-in via the TOML file's \type\_mappings\ array. PostgreSQL schema generation now correctly distinguishes base tables from views, supports materialized views (on .NET 8+), and handles database-generated columns. SQLite schema generation has been rewritten to use \Microsoft.Data.Sqlite\ and PRAGMA functions, replacing the previous \System.Data.SQLite\ dependency. The CLI also displays pre-release version information and prints TOML configuration options to the console.

SqlHydra.Cli · high confidence

Test coverage

3 commits adding/updating tests in src/Tests/TestData; Added .NET 8 integration and unit tests for Npgsql, SqlServer, and Oracle providers; Added Npgsql test suite for .NET 8, 9, and 10; Added Oracle test suite with generated schemas and integration tests; Added SQL Server tests for .NET 9 and .NET 10; Added SQLite integration and unit tests for .NET 8, 9, and 10; Added unit tests for schema filtering, extension loading, and TOML configuration; Expanded test infrastructure for multi-database and multi-framework validation.

Dependencies

Upgrade to .NET 10 and update core dependencies

SqlHydra.Cli and SqlHydra.Query now target .NET 10 alongside .NET 8 and 9, with the build tooling (src/Build) and sample app also targeting net10.0. This release updates key database drivers to their latest major versions—Npgsql to 9.0.3, Microsoft.Data.SqlClient to 5.2.1, and Microsoft.Data.Sqlite to 10.0.5—and upgrades FSharp.Core to 10.1.201 for .NET 10 targets. The test suite has been expanded to run against .NET 8, 9, and 10, and the build system now uses Fake 5.22.0 and Nuke 6.0.1.

(dependencies) · high confidence

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

How this codebase got here

Score

  • CAI 50 → 56 (+6.0)
  • Rubric changed (rubric-2026.08.19 → rubric-2026.09.15) — scores are not directly comparable.

Lenses

  • Code Health 79 → 74 (-4.9)
  • Architecture 100 → 100 (+0.0)
  • Maturity 61 → 63 (+1.1)
  • Readiness 25 → 42 (+17.1)
  • Security 83 → 68 (-15.4)

Resolved (49)

  • Dependency hygiene not measured — no packages were read
  • Duplicated block (11 lines × 2) (src/SqlHydra.Cli/MySql/MySqlSchemaProvider.fs)
  • Duplicated block (11 lines × 2) (src/SqlHydra.Cli/SchemaFilters.fs)
  • Duplicated block (11 lines × 2) (src/SqlHydra.Cli/SqlServer/SqlServerSchemaProvider.fs)
  • Duplicated block (11 lines × 2) (src/SqlHydra.Query/SelectBuilders.fs)
  • Duplicated block (12 lines × 2) (src/SqlHydra.Cli/SqlServer/SqlServerSchemaProvider.fs)
  • Duplicated block (12 lines × 2) (src/SqlHydra.Query/SelectBuilders.fs)
  • Duplicated block (13 lines × 2) (src/SampleApp/DapperExample.fs)
  • Duplicated block (13 lines × 2) (src/SqlHydra.Query/SelectBuilders.fs)
  • Duplicated block (14 lines × 2) (src/SqlHydra.Cli/MySql/MySqlDataTypes.fs)
  • Duplicated block (14 lines × 2) (src/SqlHydra.Query/SqlEmitters.fs)
  • Duplicated block (16 lines × 4) (src/SqlHydra.Cli/SqlServer/SqlServerSchemaProvider.fs)
  • Duplicated block (17 lines × 2) (src/SqlHydra.Cli/SqlServer/SqlServerDataTypes.fs)
  • Duplicated block (5 lines × 2) (src/SqlHydra.Query/LinqExpressionVisitors.fs)
  • Duplicated block (5 lines × 2) (src/SqlHydra.Query/NpgsqlExtensions.fs)
  • Duplicated block (5 lines × 3) (src/SqlHydra.Query/SqlServerExtensions.fs)
  • Duplicated block (6 lines × 2) (src/SqlHydra.Query/InsertBuilders.fs)
  • Duplicated block (6 lines × 2) (src/SqlHydra.Query/LinqExpressionVisitors.fs)
  • Duplicated block (6 lines × 2) (src/SqlHydra.Query/LinqExpressionVisitors.fs)
  • Duplicated block (6 lines × 2) (src/SqlHydra.Query/NpgsqlExtensions.fs)
  • …and 29 more

New (87)

  • Banned license: MySql.Data
  • Documentation: no architecture or design documentation (README.md)
  • Documentation: no installation or build instructions (README.md)
  • Duplicated block (10–11 lines × 2) (src/SqlHydra.Cli/Npgsql/NpgsqlSchemaProvider.fs)
  • Duplicated block (11 lines × 2) (src/SqlHydra.Cli/MySql/MySqlSchemaProvider.fs)
  • Duplicated block (11 lines × 2) (src/SqlHydra.Cli/MySql/MySqlSchemaProvider.fs)
  • Duplicated block (11 lines × 2) (src/SqlHydra.Query/LinqExpressionVisitors.fs)
  • Duplicated block (11–12 lines × 2) (src/SqlHydra.Query/SqlEmitterBase.fs)
  • Duplicated block (12 lines × 3) (src/SampleApp/DapperExample.fs)
  • Duplicated block (12 lines × 5) (src/SqlHydra.Cli/MySql/MySqlSchemaProvider.fs)
  • Duplicated block (12 lines × 5) (src/SqlHydra.Cli/MySql/MySqlSchemaProvider.fs)
  • Duplicated block (13 lines × 3) (src/SqlHydra.Cli/MySql/MySqlSchemaProvider.fs)
  • Duplicated block (13–14 lines × 2) (src/SqlHydra.Cli/MySql/MySqlSchemaProvider.fs)
  • Duplicated block (16 lines × 2) (src/SampleApp/DapperExample.fs)
  • Duplicated block (16 lines × 2) (src/SqlHydra.Cli/MySql/MySqlSchemaProvider.fs)
  • Duplicated block (16 lines × 3) (src/SqlHydra.Cli/MySql/MySqlDataTypes.fs)
  • Duplicated block (18 lines × 3) (src/SqlHydra.Query/SelectBuilders.fs)
  • Duplicated block (19 lines × 2) (src/SqlHydra.Query/LinqExpressionVisitors.fs)
  • Duplicated block (20 lines × 2) (src/SqlHydra.Query/SelectBuilders.fs)
  • Duplicated block (2–18 lines × 3) (src/SqlHydra.Query/NpgsqlExtensions.fs)
  • …and 67 more

Changes since last survey

  • 57 commits — 54 feature/other, 3 fixes

By area

  • src/SqlHydra.Query — 21 commits
  • (repo) — 16 commits
  • src/Tests — 8 commits
  • (root) — 5 commits
  • .github/workflows — 4 commits
  • src/SqlHydra.Cli — 3 commits

Notable commits

  • fix: Fix where comparisons against SQL functions silently emitting IS NULL
  • fix: Merge main (BASE TABLE typing fix, #155) into xmin-system-column
  • fix: Merge pull request #163 from michaelglass/fix/extension-dll-not-copied
  • change: 5.0: Remove Diff.fs and bump versions to 5.0.0
  • change: Add NuGet Trusted Publishing workflow
  • change: Allow SQL functions in on' join predicates
  • change: Apply the table filters to PostgreSQL materialized views
  • change: Bind Some and None when a SQL function is compared to a value
  • change: CI: build before regenerating, the sqlite tomls load an extension from Tests.dll
  • change: CI: skip build-and-test for markdown-only changes
  • change: CI: wait for the databases to be ready, and test net10.0
  • change: CLAUDE.md: document Trusted Publishing and the regen-on-version-bump gotcha
  • change: Catch NotImplementedException, not everything, in the eval fall-throughs
  • change: Column-level nullability for leftJoin via generated left-view records (#153)
  • change: Document the option twins where IntelliSense shows them
  • change: Escape embedded single quotes in SQL string literals
  • change: Generate the PostgreSQL SqlFn from pg_proc
  • change: Generate the niladic keywords too, and let PostgreSQL say which they are
  • change: Generated records say what they write
  • change: Give Oracle the same niladic tests PostgreSQL has
  • …and 37 more

Architecture

  • Containers 0 added · 0 removed · contexts 5 added · 0 removed · edges 4 added · 0 removed

Added bounded contexts (5)

  • SampleApp
  • SqlHydra.Cli
  • SqlHydra.Domain
  • SqlHydra.Query
  • Tests

Added dependency edges (4)

  • SqlHydra.Cli → SqlHydra.Domain (coupling)
  • SqlHydra.Query → SqlHydra.Domain
  • Tests → SqlHydra.Cli
  • Tests → SqlHydra.Domain (coupling)

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

Survey your own repository

JordanMarr/SqlHydra was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.

About this page

  • The score is its most recent published measurement, taken on 24 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
  • Measured at commit 5e5b1f30b4842b9d39afabbc4a913a31562ef581 — the exact code this score is about.
  • Scored under rubric-2026.09.15 — the same rubric and the same method as every other entry in this index.
  • Measured by watchdog.canine.dev using codehealth-analyzer preprod-923689c465cf.