From 7dd4a688694e8a2696a32e0cbf4efc460d0c6652 Mon Sep 17 00:00:00 2001 From: Christophe Chevalier Date: Sat, 16 Apr 2022 18:20:02 +0200 Subject: [PATCH] Expose GetApiVersion() on database and transaction context, and use this for all api version checks --- .../Core/IFdbDatabaseHandler.cs | 2 +- FoundationDB.Client/FdbDatabase.cs | 3 +++ FoundationDB.Client/FdbOperationContext.cs | 5 +++++ FoundationDB.Client/FdbTransaction.cs | 4 +--- .../FdbTransactionExtensions.cs | 22 +++++++++---------- FoundationDB.Client/IFdbDatabase.cs | 3 +++ .../Native/FdbNativeDatabase.cs | 2 +- 7 files changed, 25 insertions(+), 16 deletions(-) diff --git a/FoundationDB.Client/Core/IFdbDatabaseHandler.cs b/FoundationDB.Client/Core/IFdbDatabaseHandler.cs index 2d1935af3..c2a8b87fb 100644 --- a/FoundationDB.Client/Core/IFdbDatabaseHandler.cs +++ b/FoundationDB.Client/Core/IFdbDatabaseHandler.cs @@ -46,7 +46,7 @@ public interface IFdbDatabaseHandler : IDisposable IFdbTransactionHandler CreateTransaction(FdbOperationContext context); - int GetSelectedApiVersion(); + int GetApiVersion(); int GetMaxApiVersion(); diff --git a/FoundationDB.Client/FdbDatabase.cs b/FoundationDB.Client/FdbDatabase.cs index 2f1ecb35c..a916931f5 100644 --- a/FoundationDB.Client/FdbDatabase.cs +++ b/FoundationDB.Client/FdbDatabase.cs @@ -143,6 +143,9 @@ public static FdbDatabase Create(IFdbDatabaseHandler handler, FdbDirectoryLayer /// Internal handler internal IFdbDatabaseHandler Handler => m_handler; + /// Return the currently enforced API version for this database instance. + public int GetApiVersion() => m_handler.GetApiVersion(); + #endregion #region Transaction Management... diff --git a/FoundationDB.Client/FdbOperationContext.cs b/FoundationDB.Client/FdbOperationContext.cs index fb9d285e1..5e5c40552 100644 --- a/FoundationDB.Client/FdbOperationContext.cs +++ b/FoundationDB.Client/FdbOperationContext.cs @@ -1316,8 +1316,13 @@ internal void ReleaseTransaction(FdbTransaction trans) Interlocked.CompareExchange(ref this.Transaction, null, trans); } + /// Return the underlying native handler for this transaction + /// This is only intended for testing or troubleshooting purpose! public IFdbTransactionHandler GetTransactionHandler() => this.Transaction?.Handler ?? throw new InvalidOperationException("Transaction has already been disposed"); + /// Return the currently enforced API version for the database attached to this transaction. + public int GetApiVersion() => this.Database.GetApiVersion(); + public void Dispose() { this.Abort = true; diff --git a/FoundationDB.Client/FdbTransaction.cs b/FoundationDB.Client/FdbTransaction.cs index fca32c200..17ec75a91 100644 --- a/FoundationDB.Client/FdbTransaction.cs +++ b/FoundationDB.Client/FdbTransaction.cs @@ -861,9 +861,7 @@ static void ExecuteLogged(FdbTransaction self, ReadOnlySpan key, ReadOnlyS /// An error with code if the type of mutation is not supported by this API level. private void EnsureMutationTypeIsSupported(FdbMutationType mutation) { - var dbHandler = this.Database.Handler; - int selectedApiVersion = dbHandler.GetSelectedApiVersion(); - + int selectedApiVersion = this.Database.GetApiVersion(); if (selectedApiVersion < 200) { // mutations were not available at this time diff --git a/FoundationDB.Client/FdbTransactionExtensions.cs b/FoundationDB.Client/FdbTransactionExtensions.cs index 3dbf1d85f..a34c56b20 100644 --- a/FoundationDB.Client/FdbTransactionExtensions.cs +++ b/FoundationDB.Client/FdbTransactionExtensions.cs @@ -53,7 +53,7 @@ public static class FdbTransactionExtensions public static TTransaction WithReadAccessToSystemKeys(this TTransaction trans) where TTransaction : IFdbReadOnlyTransaction { - trans.SetOption(Fdb.ApiVersion >= 300 ? FdbTransactionOption.ReadSystemKeys : FdbTransactionOption.AccessSystemKeys); + trans.SetOption(trans.Context.GetApiVersion() >= 300 ? FdbTransactionOption.ReadSystemKeys : FdbTransactionOption.AccessSystemKeys); //TODO: cache this into a local variable ? return trans; } @@ -1030,9 +1030,9 @@ private static int GetVersionStampOffset(ReadOnlySpan buffer, ReadOnlySpan } [Pure, MethodImpl(MethodImplOptions.NoInlining)] - private static Exception FailVersionStampNotSupported() + private static Exception FailVersionStampNotSupported(int apiVersion) { - return new NotSupportedException($"VersionStamps are not supported at API version {Fdb.ApiVersion}. You need to select at least API Version 400 or above."); + return new NotSupportedException($"VersionStamps are not supported at API version {apiVersion}. You need to select at least API Version 400 or above."); } /// Set the of the in the database, with the replaced by the resolved version at commit time. @@ -1059,10 +1059,10 @@ public static void SetVersionStampedKey(this IFdbTransaction trans, ReadOnlySpan trans.CreateVersionStamp().WriteTo(token); var offset = GetVersionStampOffset(key, token, nameof(key)); - int apiVer = Fdb.ApiVersion; + int apiVer = trans.Context.Database.GetApiVersion(); if (apiVer < 400) { // introduced in 400 - throw FailVersionStampNotSupported(); + throw FailVersionStampNotSupported(apiVer); } if (apiVer < 520) @@ -1108,10 +1108,10 @@ public static void SetVersionStampedKey(this IFdbTransaction trans, ReadOnlySpan Contract.Positive(stampOffset); if (stampOffset > key.Length - 10) throw new ArgumentException("The VersionStamp overflows past the end of the key.", nameof(stampOffset)); - int apiVer = Fdb.ApiVersion; + int apiVer = trans.Context.GetApiVersion(); if (apiVer < 400) { // introduced in 400 - throw FailVersionStampNotSupported(); + throw FailVersionStampNotSupported(apiVer); } if (apiVer < 520) @@ -1154,10 +1154,10 @@ public static void SetVersionStampedValue(this IFdbTransaction trans, ReadOnlySp Contract.NotNull(trans); if (value.Length < 10) throw new ArgumentException("The value must be at least 10 bytes long.", nameof(value)); - int apiVer = Fdb.ApiVersion; + int apiVer = trans.Context.GetApiVersion(); if (apiVer < 400) { // introduced in 400 - throw FailVersionStampNotSupported(); + throw FailVersionStampNotSupported(apiVer); } if (apiVer < 520) @@ -1207,10 +1207,10 @@ public static void SetVersionStampedValue(this IFdbTransaction trans, ReadOnlySp Contract.Positive(stampOffset); if (stampOffset > key.Length - 10) throw new ArgumentException("The VersionStamp overflows past the end of the value.", nameof(stampOffset)); - int apiVer = Fdb.ApiVersion; + int apiVer = trans.Context.GetApiVersion(); if (apiVer < 400) { // introduced in 400 - throw FailVersionStampNotSupported(); + throw FailVersionStampNotSupported(apiVer); } if (apiVer < 520) diff --git a/FoundationDB.Client/IFdbDatabase.cs b/FoundationDB.Client/IFdbDatabase.cs index 109d1e0d1..64af63508 100644 --- a/FoundationDB.Client/IFdbDatabase.cs +++ b/FoundationDB.Client/IFdbDatabase.cs @@ -104,6 +104,9 @@ public interface IFdbDatabase : IFdbRetryable, IDisposable /// } ValueTask BeginTransactionAsync(FdbTransactionMode mode, CancellationToken ct, FdbOperationContext? context = null); + /// Return the currently enforced API version for this database instance. + int GetApiVersion(); + } } diff --git a/FoundationDB.Client/Native/FdbNativeDatabase.cs b/FoundationDB.Client/Native/FdbNativeDatabase.cs index 927412a9c..94ea6e0b9 100644 --- a/FoundationDB.Client/Native/FdbNativeDatabase.cs +++ b/FoundationDB.Client/Native/FdbNativeDatabase.cs @@ -150,7 +150,7 @@ private static async ValueTask CreateDatabaseLegacyAsync(st public bool IsClosed => m_handle.IsClosed; - public int GetSelectedApiVersion() => Fdb.ApiVersion; + public int GetApiVersion() => Fdb.ApiVersion; public int GetMaxApiVersion() => FdbNative.GetMaxApiVersion();