CodeLogic.SQLite 4.5.2-preview.68

This is a prerelease version of CodeLogic.SQLite.
There is a newer version of this package available.
See the version list below for details.
dotnet add package CodeLogic.SQLite --version 4.5.2-preview.68
                    
NuGet\Install-Package CodeLogic.SQLite -Version 4.5.2-preview.68
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="CodeLogic.SQLite" Version="4.5.2-preview.68" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="CodeLogic.SQLite" Version="4.5.2-preview.68" />
                    
Directory.Packages.props
<PackageReference Include="CodeLogic.SQLite" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add CodeLogic.SQLite --version 4.5.2-preview.68
                    
#r "nuget: CodeLogic.SQLite, 4.5.2-preview.68"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package CodeLogic.SQLite@4.5.2-preview.68
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=CodeLogic.SQLite&version=4.5.2-preview.68&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=CodeLogic.SQLite&version=4.5.2-preview.68&prerelease
                    
Install as a Cake Tool

CodeLogic.SQLite

NuGet

SQLite database library for CodeLogic with connection pooling, a fluent LINQ-shaped query builder, attribute-driven table sync, and migration tracking. Built on Microsoft.Data.Sqlite.

Install

dotnet add package CodeLogic.SQLite

Quick start

await Libraries.LoadAsync<SQLiteLibrary>();

var sqlite = Libraries.Get<SQLiteLibrary>();

// 1. Sync the table from the entity (CREATE / ALTER to match the class)
await sqlite.TableSync.SyncTableAsync<NoteRecord>("Default");

// 2. CRUD via the repository — every call returns a Result<T>
var repo = sqlite.GetRepository<NoteRecord>("Default");
var insert = await repo.InsertAsync(new NoteRecord { Title = "Hello", Body = "World" });
if (insert.IsSuccess)
    Console.WriteLine($"new rowid = {insert.Value}");

// 3. Fluent queries via the query builder
var notes = await sqlite.GetQueryBuilder<NoteRecord>("Default")
    .Where(n => n.Title.Contains("Hello"))
    .OrderByDescending(n => n.CreatedUtc)
    .Take(20)
    .ToListAsync();

foreach (var note in notes.Value)
    Console.WriteLine(note.Title);

The entity is plain C# annotated with [SQLiteTable] / [SQLiteColumn]:

[SQLiteTable("notes")]
public sealed class NoteRecord
{
    [SQLiteColumn(IsPrimaryKey = true, IsAutoIncrement = true)]
    public long Id { get; set; }

    [SQLiteColumn(ColumnName = "title", IsNotNull = true, IsIndexed = true)]
    public string Title { get; set; } = "";

    [SQLiteColumn(ColumnName = "body")]
    public string Body { get; set; } = "";

    [SQLiteColumn(ColumnName = "created_utc")]
    public DateTime CreatedUtc { get; set; } = DateTime.UtcNow;
}

Only properties marked with [SQLiteColumn] are mapped — unannotated properties are ignored for schema, reads, and writes. The connection id defaults to "Default" on every entry point, so GetRepository<NoteRecord>() is equivalent to GetRepository<NoteRecord>("Default").

What's in the box

Library entry points

Member Purpose
GetRepository<T>(connectionId = "Default") CRUD + raw SQL for an entity
GetQueryBuilder<T>(connectionId = "Default") fluent query builder
TableSync SyncTableAsync<T>, SyncTablesAsync, SyncNamespaceAsync
MigrationTracker inspect applied schema migrations
ConnectionManager named connection pool (active/pooled counts, test)
HealthCheckAsync() per-database connectivity check (Healthy / Degraded / Unhealthy)

All data operations return CodeLogic Result / Result<T> — check .IsSuccess and read .Value, or inspect .Error. They do not throw on query failure.

Repository

GetRepository<T>() exposes:

Method Result
InsertAsync(entity) Result<long> — new rowid; auto-increment PK is written back to the entity
UpsertAsync(entity) INSERT OR REPLACE
UpdateAsync(entity) update by primary key
DeleteAsync(id) delete by single PK
GetByIdAsync(id) Result<T?>
GetByKeysAsync(ct, params keys) composite-PK lookup
DeleteByKeysAsync(ct, params keys) composite-PK delete
GetAllAsync(limit = 1000) Result<List<T>>
FindAsync(predicate) Result<List<T>> from a LINQ WHERE
CountAsync() Result<long>
GetPagedAsync(page, pageSize, orderBy?, desc?) Result<PagedResult<T>>
RawQueryAsync(sql, params?) Result<List<T>> — raw SELECT mapped to entities
RawExecuteAsync(sql, params?) Result<int> — raw non-query, rows affected
var repo = sqlite.GetRepository<NoteRecord>();

var page  = await repo.GetPagedAsync(page: 1, pageSize: 20, orderBy: "created_utc", desc: true);
var byTag = await repo.FindAsync(n => n.Title.StartsWith("draft"));
var raw   = await repo.RawQueryAsync(
    "SELECT * FROM notes WHERE title LIKE @q",
    new() { ["@q"] = "%hello%" });

Always bind values via named parameters — never interpolate user input into the SQL.

Fluent query builder

GetQueryBuilder<T>() chains LINQ-shaped clauses and translates them to SQL.

Capability Shape
Filter .Where(x => x.Status == "active" && x.Age >= 18) (multiple calls AND together)
Sort .OrderBy, .OrderByDescending, .ThenBy, .ThenByDescending
Paging .Limit / .Take, .Offset / .Skip, .ToPagedListAsync
Projection .Select(x => new { x.Id, x.Title }) — restricts the SELECT column list
Grouping .GroupBy(x => x.Category)

Terminal operations (each returns a Result):

Method Result
ToListAsync() Result<List<T>>
FirstOrDefaultAsync() Result<T?>
ToPagedListAsync(page, pageSize) Result<PagedResult<T>>
CountAsync() Result<long> over the current WHERE
SumAsync(x => x.Col) / MaxAsync / MinAsync Result<TResult> aggregate
DeleteAsync() Result<int> — bulk delete by predicate
UpdateAsync(Dictionary<string, object?>) Result<int> — bulk update by predicate
var qb = sqlite.GetQueryBuilder<NoteRecord>();

var total = await qb.Where(n => n.Title.Contains("hello")).CountAsync();

var page = await sqlite.GetQueryBuilder<NoteRecord>()
    .Where(n => n.CreatedUtc >= since)
    .OrderByDescending(n => n.CreatedUtc)
    .ToPagedListAsync(page: 1, pageSize: 20);

// Bulk predicate mutations
await sqlite.GetQueryBuilder<NoteRecord>()
    .Where(n => n.CreatedUtc < cutoff)
    .DeleteAsync();

await sqlite.GetQueryBuilder<NoteRecord>()
    .Where(n => n.Title == "")
    .UpdateAsync(new() { ["title"] = "(untitled)" });

Attribute-driven schema sync

Entity classes are the source of truth. TableSync.SyncTableAsync<T>() creates or alters the SQLite table to match the class; SyncTablesAsync and SyncNamespaceAsync batch-sync many types.

Attribute Purpose
[SQLiteTable("name")] table name (defaults to the class name)
[SQLiteColumn] ColumnName, DataType, Size, IsPrimaryKey, IsAutoIncrement, IsIndexed, IsUnique, IsNotNull, DefaultValue
[SQLiteIndex(cols...)] class-level named index; IsUnique, Name
[SQLiteForeignKey(table, column)] FK with OnDelete / OnUpdate (ForeignKeyAction: NoAction, Restrict, SetNull, SetDefault, Cascade)

SQLiteDataType values: INTEGER, REAL, TEXT, BLOB, NUMERIC, DATETIME, DATE, BOOLEAN, UUID. When omitted the type is inferred from the property type. bool, DateTime, DateTimeOffset, Guid, and enum are converted automatically on read and write.

[SQLiteTable("orders")]
[SQLiteIndex("customer_id", "created_utc", Name = "ix_orders_customer")]
public sealed class OrderRecord
{
    [SQLiteColumn(IsPrimaryKey = true, IsAutoIncrement = true)]
    public long Id { get; set; }

    [SQLiteColumn(ColumnName = "customer_id", IsNotNull = true)]
    [SQLiteForeignKey("customers", "id", OnDelete = ForeignKeyAction.Cascade)]
    public long CustomerId { get; set; }

    [SQLiteColumn(ColumnName = "total", DataType = SQLiteDataType.NUMERIC)]
    public decimal Total { get; set; }

    [SQLiteColumn(ColumnName = "created_utc")]
    public DateTime CreatedUtc { get; set; } = DateTime.UtcNow;
}

Observability

Queries are logged when the runtime is in development mode, and any query that runs longer than the per-database SlowQueryThresholdMs is logged as a warning.

Configuration

Auto-generated on first run under data/codelogic/Libraries/CL.SQLite/config.sqlite.json. The config is a map of named databases — each key is a connection id you pass to GetRepository / GetQueryBuilder / SyncTableAsync.

{
  "databases": {
    "Default": {
      "enabled": true,
      "databasePath": "database.db",
      "connectionTimeoutSeconds": 30,
      "commandTimeoutSeconds": 120,
      "skipTableSync": false,
      "cacheMode": "default",
      "useWAL": true,
      "enableForeignKeys": true,
      "maxPoolSize": 10,
      "slowQueryThresholdMs": 500
    }
  }
}
Field Default Purpose
enabled true disable a database without removing it
databasePath database.db absolute, or relative to the library data directory
connectionTimeoutSeconds 30 connection open timeout
commandTimeoutSeconds 120 per-command timeout
skipTableSync false turn off automatic schema sync for this database
cacheMode default default / private / shared
useWAL true Write-Ahead Logging — better concurrency, recommended
enableForeignKeys true enforce FK constraints
maxPoolSize 10 max pooled connections
slowQueryThresholdMs 500 slow-query warning threshold

A database with enabled: false is skipped at startup; if no database is enabled the library initializes in a disabled state and the health check reports healthy-but-disabled.

Documentation

Requirements

License

MIT — see LICENSE

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
4.6.72 48 6/20/2026
4.6.69-preview 38 6/20/2026
4.5.2 109 5/24/2026
4.5.2-preview.68 63 6/20/2026
4.5.1 107 5/24/2026
4.5.1-preview.56 62 5/24/2026
4.4.2-preview.53 60 5/24/2026
4.4.1 105 5/24/2026
4.0.5 103 5/15/2026
4.0.4 113 5/9/2026
4.0.3 104 5/9/2026
4.0.1 115 4/19/2026
3.3.1 113 4/18/2026
3.3.0 104 4/18/2026
3.2.11 106 4/18/2026
3.2.10 106 4/18/2026
3.2.9 109 4/18/2026
3.2.8 107 4/18/2026
3.2.7 103 4/18/2026
3.2.6 110 4/18/2026
Loading failed

# CL.SQLite — Changelog

All notable changes to **CodeLogic.SQLite** are documented here. Versions follow
[Semantic Versioning](https://semver.org/).

## [4.5.2] — 2026-06-20

### Documentation

- Corrected the README to match the shipping API: the query builder is obtained
 via `GetQueryBuilder<T>()` (there is no `sqlite.Query<T>()`), all data
 operations return `Result` / `Result<T>`, and entities require
 `[SQLiteTable]` / `[SQLiteColumn]` annotations. The previous Quick Start no
 longer compiled.
- Documented the configuration as the real `databases` map (per-named-database
 `databasePath`, `useWAL`, `cacheMode`, `maxPoolSize`, `slowQueryThresholdMs`,
 timeouts, `skipTableSync`, `enableForeignKeys`), replacing the inaccurate
 `connections` array with `journalMode`/`poolSize`.
- Documented previously undocumented user-facing surface that already shipped:
 the full query builder (`Select`, `GroupBy`, `Sum`/`Max`/`Min`, predicate
 `DeleteAsync`/`UpdateAsync`, `ToPagedListAsync`), repository `UpsertAsync`,
 composite-key (`GetByKeysAsync`/`DeleteByKeysAsync`), `GetPagedAsync`, raw SQL
 (`RawQueryAsync`/`RawExecuteAsync`), attribute-driven schema sync
 (`SyncTableAsync`/`SyncTablesAsync`/`SyncNamespaceAsync` with
 `[SQLiteIndex]`/`[SQLiteForeignKey]`), and the `MigrationTracker`. No code
 changes — documentation only.

## [4.5.0] — 2026-05-24

### Changed

- **Unified versioning.** All CodeLogic.Libs now share a single version line
 controlled by `version.txt` in the repo root. This is a version alignment
 release — no functional changes to this library.
## [4.0.4] — 2026-04-16

### Changed

- README + manifest refresh for the v4 baseline. No functional changes vs 4.0.3.
- `LibraryManifest.Version` now reads from assembly metadata.

## [4.0.3] — 2026-04-16

### Fixed

- Added missing `<param name="connectionId">` XML doc tags so the public API
 no longer trips doc-warning gates.

## [4.0.2] — 2026-04-09

### Changed

- Annotated SQLite configuration with `[ConfigField]` for the admin UI surface.
- Aligned with the v4 baseline across all libraries.

## [4.0.0] — 2026-04-09

Major rewrite. Republished as v4.0.0 to reset the version line under the
unified v4 baseline. Embedded-DB sibling of CL.MySQL2 with the same
repository pattern and attribute-driven schema sync.

### Notes

- The MySQL2 4.0 query-builder rewrite (projection pushdown, SQL aggregation,
 smart-cache pools) has not been ported to CL.SQLite yet — repository
 CRUD only.
- Earlier history is retained in the
 [git log](https://github.com/Media2A/CodeLogic.Libs/commits/main/CL.SQLite).