KBUBComm.Database
1.4.2
dotnet add package KBUBComm.Database --version 1.4.2
NuGet\Install-Package KBUBComm.Database -Version 1.4.2
<PackageReference Include="KBUBComm.Database" Version="1.4.2" />
<PackageVersion Include="KBUBComm.Database" Version="1.4.2" />
<PackageReference Include="KBUBComm.Database" />
paket add KBUBComm.Database --version 1.4.2
#r "nuget: KBUBComm.Database, 1.4.2"
#:package KBUBComm.Database@1.4.2
#addin nuget:?package=KBUBComm.Database&version=1.4.2
#tool nuget:?package=KBUBComm.Database&version=1.4.2
KBUBComm.Database
Typed protected object-backed configuration and local database storage layer for .NET applications and services.
This is not a general ORM. It is a POCO-first model store:
- define normal C# classes
- mark the root with
[DBModel] - open
DatabaseConnection<TModel> - mutate
databaseConnection.Model - call
SyncAsync()for commit-style persistence - call
WriteAsync()/MutateAsync()for immediate persistence
Package contents
The NuGet package includes:
- package icon metadata
- package README metadata
- embedded MIT license file
- neutral sample defaults with no organization-specific wording
Compatibility policy
Version 1.4.2 is a backward-compatible hardening release.
Existing public APIs from 1.4.1 are preserved. The release adds optional helper APIs for diagnostics, backup/export, and secret-reference validation. Existing callers using OpenAsync, WriteAsync, MutateAsync, SyncAsync, list helpers, Secrets.SetAsync, Secrets.GetAsync, and Secrets.RotateAsync do not need call-site changes.
SQLite provider
The package uses:
Microsoft.Data.Sqlite.CoreSQLitePCLRaw.bundle_e_sqlite3
The SQLite bundle is initialized explicitly by the SQLite provider before opening connections. This keeps the package self-contained for normal .NET applications without requiring app callers to remember SQLite provider initialization.
Basic use
DatabaseConnection<DemoBridgeDbModel> databaseConnection =
await DatabaseConnection<DemoBridgeDbModel>.OpenAsync(
new DatabaseConnectionOptions
{
DatabaseName = "DemoStatusBridge",
StoragePath = databasePath,
EncryptionMode = DatabaseEncryptionMode.LocalUserProtected,
ChangedBy = Environment.UserName,
ChangeReason = "Initial setup"
});
await databaseConnection.WriteAsync(
model => model.ConnectionSettings.OpcUaPort,
4840);
await databaseConnection.AddDistinctToListAsync(
model => model.ConnectionSettings.ClientIpWhitelist,
"10.10.20.15");
await databaseConnection.MutateAsync(
model => model.OpcAndPathSettings.CustomTagsToMonitor,
tags =>
{
if (!tags.Contains("DEMO.CONTROLLER.HEARTBEAT", StringComparer.OrdinalIgnoreCase))
{
tags.Add("DEMO.CONTROLLER.HEARTBEAT");
}
});
Commit-style changes
databaseConnection.SetAuditContext(Environment.UserName, "Updated bridge settings");
databaseConnection.Model.ConnectionSettings.OpcUaPort = 4840;
databaseConnection.Model.ConnectionSettings.EndpointIp = "127.0.0.1";
IReadOnlyList<DatabaseChange> pendingChanges = databaseConnection.GetPendingChanges();
DatabaseSyncResult syncResult = await databaseConnection.SyncAsync();
Immediate scalar write
DatabaseSyncResult writeResult = await databaseConnection.WriteAsync(
model => model.ConnectionSettings.ReaderPort,
55231);
Immediate list mutation
DatabaseSyncResult addResult = await databaseConnection.AddDistinctToListAsync(
model => model.ConnectionSettings.ClientIpWhitelist,
"10.10.20.15");
DatabaseSyncResult removeResult = await databaseConnection.RemoveFromListAsync(
model => model.ConnectionSettings.ClientIpWhitelist,
"10.10.20.15");
Secrets
Use [DBSecret] only for recoverable outbound secrets, not user login passwords.
SecretRef secretRef = await databaseConnection.Secrets.SetAsync(
"Demo.Reader.Password",
passwordValue,
Environment.UserName);
databaseConnection.Model.Credentials.ReaderPassword = secretRef;
await databaseConnection.SyncAsync();
string password = await databaseConnection.Secrets.GetAsync(
databaseConnection.Model.Credentials.ReaderPassword);
Diagnostics-safe status
Use GetStatusAsync() to show database state in app diagnostics without exposing protected values, secret values, password hashes, or raw config payloads.
DatabaseStatusSnapshot status = await databaseConnection.GetStatusAsync();
Console.WriteLine(status.DatabasePath);
Console.WriteLine(status.SchemaVersion);
Console.WriteLine(status.ModelValueCount);
Console.WriteLine(status.SecretCount);
DatabaseStatusSnapshot.IsDiagnosticsSafe is always true for the built-in SQLite provider because it reports only paths, counts, provider/version labels, schema metadata, and file metadata.
Backup/export
Use BackupAsync() to create a consistent SQLite backup with VACUUM INTO.
DatabaseBackupResult backup = await databaseConnection.BackupAsync(
Path.Combine(backupFolder, "settings-backup.db"),
overwriteExisting: true);
The source database remains open/usable. The backup file is a standalone SQLite database copy.
Secret-reference validation
Use ValidateSecretReferencesAsync() to check [DBSecret] properties currently present on the model.
SecretReferenceValidationResult result = await databaseConnection.ValidateSecretReferencesAsync();
foreach (SecretReferenceValidationIssue issue in result.Issues)
{
Console.WriteLine($"{issue.Severity}: {issue.ValuePath} - {issue.Message}");
}
Empty secret references are warnings because optional secrets may intentionally be blank. References to missing stored secrets are errors.
Attributes
[DBModel("Name")]marks the root model.[DBName("Name")]overrides the inferred path segment.[DBIgnore]skips a property.[DBProtected]protects a persisted field value.[DBSecret]stores aSecretRefas a protected secret reference.
Current limitations
- SQLite provider only.
- No SQLCipher full-file encryption yet.
[DBProtected]and[DBSecret]use DPAPI on Windows.DatabaseEncryptionMode.NonerequiresAllowPlainTextProtectionForDevelopment = true.- Automatic property change tracking is intentionally not implemented. Use
SyncAsync()orWriteAsync()/MutateAsync(). - User login passwords need a separate password-hashing user manager. Do not store login passwords with
[DBSecret].
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. 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. |
-
net8.0
- Microsoft.Data.Sqlite.Core (>= 10.0.9)
- SQLitePCLRaw.bundle_e_sqlite3 (>= 3.0.3)
- System.Security.Cryptography.ProtectedData (>= 10.0.8)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
1.4.2 adds backward-compatible SQLite initialization hardening, diagnostics-safe status snapshots, backup/export helpers, and SecretRef validation helpers.