fix(auth.apikeys): stamp schema version 2 to match donor gateway DBs; bump 0.1.2
The store was extracted from MxAccessGateway, whose deployed gateway-auth.db is at schema_version=2. The library capped at 1 and threw on a newer on-disk version -> gateway would fail to boot. Final schema is byte-identical since v1; stamp 2 so existing deployed DBs interoperate (no key re-issuance). +2 tests.
This commit is contained in:
@@ -5,7 +5,7 @@
|
|||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<LangVersion>latest</LangVersion>
|
<LangVersion>latest</LangVersion>
|
||||||
<Version>0.1.1</Version>
|
<Version>0.1.2</Version>
|
||||||
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
|
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
|||||||
@@ -5,8 +5,15 @@ namespace ZB.MOM.WW.Auth.ApiKeys.Sqlite;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static class SqliteAuthSchema
|
public static class SqliteAuthSchema
|
||||||
{
|
{
|
||||||
/// <summary>The schema version this build creates and supports.</summary>
|
/// <summary>
|
||||||
public const int CurrentVersion = 1;
|
/// The schema version this build creates and supports. This is <c>2</c>, not <c>1</c>,
|
||||||
|
/// to match the deployed databases of the donor (MxAccessGateway) this store was
|
||||||
|
/// extracted from: that store reached its final shape via a v1→v2 history and stamps
|
||||||
|
/// <c>version = 2</c> on disk. The final schema has been byte-identical since v1, so a
|
||||||
|
/// single-shot create stamped as 2 interoperates with existing <c>gateway-auth.db</c>
|
||||||
|
/// files (the migrator only refuses an on-disk version <em>newer</em> than this).
|
||||||
|
/// </summary>
|
||||||
|
public const int CurrentVersion = 2;
|
||||||
|
|
||||||
/// <summary>Name of the single-row table tracking the applied schema version.</summary>
|
/// <summary>Name of the single-row table tracking the applied schema version.</summary>
|
||||||
public const string SchemaVersionTable = "schema_version";
|
public const string SchemaVersionTable = "schema_version";
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ public sealed class SqliteAuthStoreMigrator(AuthSqliteConnectionFactory connecti
|
|||||||
$"Auth database schema version {existingVersion} is newer than supported version {SqliteAuthSchema.CurrentVersion}.");
|
$"Auth database schema version {existingVersion} is newer than supported version {SqliteAuthSchema.CurrentVersion}.");
|
||||||
}
|
}
|
||||||
|
|
||||||
await ApplyVersionOneAsync(connection, transaction, cancellationToken).ConfigureAwait(false);
|
await ApplySchemaAsync(connection, transaction, cancellationToken).ConfigureAwait(false);
|
||||||
await WriteSchemaVersionAsync(connection, transaction, cancellationToken).ConfigureAwait(false);
|
await WriteSchemaVersionAsync(connection, transaction, cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
await transaction.CommitAsync(cancellationToken).ConfigureAwait(false);
|
await transaction.CommitAsync(cancellationToken).ConfigureAwait(false);
|
||||||
@@ -78,7 +78,10 @@ public sealed class SqliteAuthStoreMigrator(AuthSqliteConnectionFactory connecti
|
|||||||
: Convert.ToInt32(version, CultureInfo.InvariantCulture);
|
: Convert.ToInt32(version, CultureInfo.InvariantCulture);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async Task ApplyVersionOneAsync(
|
// Single-shot create of the final schema (all DDL is CREATE ... IF NOT EXISTS, so it is
|
||||||
|
// idempotent against an already-provisioned database). The applied version is stamped
|
||||||
|
// separately by WriteSchemaVersionAsync.
|
||||||
|
private static async Task ApplySchemaAsync(
|
||||||
SqliteConnection connection,
|
SqliteConnection connection,
|
||||||
SqliteTransaction transaction,
|
SqliteTransaction transaction,
|
||||||
CancellationToken cancellationToken)
|
CancellationToken cancellationToken)
|
||||||
|
|||||||
@@ -34,6 +34,27 @@ public sealed class SqliteMigratorTests : IDisposable
|
|||||||
Assert.Equal(1, await CountSchemaVersionRowsAsync());
|
Assert.Equal(1, await CountSchemaVersionRowsAsync());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void CurrentVersion_Is2_ToMatchDonorGatewayDeployedSchema() =>
|
||||||
|
// The store was extracted from MxAccessGateway, whose deployed gateway-auth.db is
|
||||||
|
// stamped version 2. The library must stamp 2 (not reset to 1) so it does not refuse
|
||||||
|
// those existing databases on first boot. Locking this invariant.
|
||||||
|
Assert.Equal(2, SqliteAuthSchema.CurrentVersion);
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task MigrateAsync_AgainstExistingVersion2Db_DoesNotThrow_AndStaysAt2()
|
||||||
|
{
|
||||||
|
// The deployed-gateway scenario: a database already provisioned at version 2.
|
||||||
|
var migrator = new SqliteAuthStoreMigrator(Factory);
|
||||||
|
await migrator.MigrateAsync(CancellationToken.None);
|
||||||
|
await SetVersionAsync(2);
|
||||||
|
|
||||||
|
await migrator.MigrateAsync(CancellationToken.None); // must not throw
|
||||||
|
|
||||||
|
Assert.Equal(2, await ReadVersionAsync());
|
||||||
|
Assert.True(await TableExistsAsync(SqliteAuthSchema.ApiKeysTable));
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task MigrateAsync_FutureSchemaVersion_Throws()
|
public async Task MigrateAsync_FutureSchemaVersion_Throws()
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user