コード例 #1
0
        public Task <IFdbDatabaseHandler> OpenDatabaseAsync(string databaseName, CancellationToken cancellationToken)
        {
            if (cancellationToken.IsCancellationRequested)
            {
                return(Task.FromCanceled <IFdbDatabaseHandler>(cancellationToken));
            }

            var future = FdbNative.ClusterCreateDatabase(m_handle, databaseName);

            return(FdbFuture.CreateTaskFromHandle(
                       future,
                       (h) =>
            {
                DatabaseHandle database;
                var err = FdbNative.FutureGetDatabase(h, out database);
                if (err != FdbError.Success)
                {
                    database.Dispose();
                    throw Fdb.MapToException(err);
                }
                var handler = new FdbNativeDatabase(database);
                return (IFdbDatabaseHandler)handler;
            },
                       cancellationToken
                       ));
        }
コード例 #2
0
 public Task <Slice> GetAsync(ReadOnlySpan <byte> key, bool snapshot, CancellationToken ct)
 {
     return(FdbFuture.CreateTaskFromHandle(
                FdbNative.TransactionGet(m_handle, key, snapshot),
                (h) => GetValueResultBytes(h),
                ct
                ));
 }
コード例 #3
0
        /// <inheritdoc />
        public Task <string[]> GetAddressesForKeyAsync(ReadOnlySpan <byte> key, CancellationToken ct)
        {
            var future = FdbNative.TransactionGetAddressesForKey(m_handle, key);

            return(FdbFuture.CreateTaskFromHandle(
                       future,
                       (h) => GetStringArrayResult(h),
                       ct
                       ));
        }
コード例 #4
0
        public Task <Slice> GetKeyAsync(KeySelector selector, bool snapshot, CancellationToken ct)
        {
            var future = FdbNative.TransactionGetKey(m_handle, selector, snapshot);

            return(FdbFuture.CreateTaskFromHandle(
                       future,
                       (h) => GetKeyResult(h),
                       ct
                       ));
        }
コード例 #5
0
 public Task <(FdbValueCheckResult Result, Slice Actual)> CheckValueAsync(ReadOnlySpan <byte> key, Slice expected, bool snapshot, CancellationToken ct)
 {
     return(FdbFuture.CreateTaskFromHandle(
                FdbNative.TransactionGet(m_handle, key, snapshot),
                (h) =>
     {
         if (TryPeekValueResultBytes(h, out var actual))
         {                         // key exists
             return !expected.IsNull && expected.Span.SequenceEqual(actual) ? (FdbValueCheckResult.Success, expected) : (FdbValueCheckResult.Failed, Slice.Copy(actual));
         }
コード例 #6
0
        private static async ValueTask <IFdbDatabaseHandler> CreateDatabaseLegacyAsync(string?clusterFile, CancellationToken ct)
        {
            // In legacy API versions, you first had to create "cluster" handle and then obtain a database handle that that cluster.
            // The API is async, but the future always completed inline...

            ClusterHandle? cluster  = null;
            DatabaseHandle?database = null;

            try
            {
                cluster = await FdbFuture.CreateTaskFromHandle(
                    FdbNative.CreateCluster(clusterFile),
                    h =>
                {
                    var err = FdbNative.FutureGetCluster(h, out var handle);
                    if (Fdb.Failed(err))
                    {
                        throw Fdb.MapToException(err) !;
                    }

                    return(handle);
                },
                    ct).ConfigureAwait(false);

                database = await FdbFuture.CreateTaskFromHandle(
                    FdbNative.ClusterCreateDatabase(cluster, "DB"),
                    h =>
                {
                    var err = FdbNative.FutureGetDatabase(h, out var handle);
                    if (Fdb.Failed(err))
                    {
                        throw Fdb.MapToException(err) !;
                    }

                    return(handle);
                },
                    ct).ConfigureAwait(false);

                return(new FdbNativeDatabase(database, clusterFile, cluster));
            }
            catch (Exception)
            {
                database?.Dispose();
                cluster?.Dispose();
                throw;
            }
        }
コード例 #7
0
        public Task <long> GetReadVersionAsync(CancellationToken ct)
        {
            var future = FdbNative.TransactionGetReadVersion(m_handle);

            return(FdbFuture.CreateTaskFromHandle(future,
                                                  (h) =>
            {
                var err = FdbNative.FutureGetVersion(h, out long version);
#if DEBUG_TRANSACTIONS
                Debug.WriteLine("FdbTransaction[" + m_id + "].GetReadVersion() => err=" + err + ", version=" + version);
#endif
                Fdb.DieOnError(err);
                return version;
            },
                                                  ct
                                                  ));
        }
コード例 #8
0
        /// <summary>Asynchronously fetch a new page of results</summary>
        /// <returns>True if Chunk contains a new page of results. False if all results have been read.</returns>
        public Task <FdbRangeChunk> GetRangeAsync(KeySelector begin, KeySelector end, FdbRangeOptions options, int iteration, bool snapshot, CancellationToken ct)
        {
            Contract.Requires(options != null);

            bool reversed = options.Reverse ?? false;
            var  future   = FdbNative.TransactionGetRange(m_handle, begin, end, options.Limit ?? 0, options.TargetBytes ?? 0, options.Mode ?? FdbStreamingMode.Iterator, iteration, snapshot, reversed);

            return(FdbFuture.CreateTaskFromHandle(
                       future,
                       (h) =>
            {
                var mode = options.Read ?? FdbReadMode.Both;
                KeyValuePair <Slice, Slice>[] items;
                bool hasMore;
                Slice first, last;
                switch (mode)
                {
                case FdbReadMode.Both:
                    {
                        items = GetKeyValueArrayResult(h, out hasMore, out first, out last);
                        break;
                    }

                case FdbReadMode.Keys:
                    {
                        items = GetKeyValueArrayResultKeysOnly(h, out hasMore, out first, out last);
                        break;
                    }

                case FdbReadMode.Values:
                    {
                        items = GetKeyValueArrayResultValuesOnly(h, out hasMore, out first, out last);
                        break;
                    }

                default:
                    {
                        throw new InvalidOperationException();
                    }
                }
                return new FdbRangeChunk(items, hasMore, iteration, reversed, mode, first, last);
            },
                       ct
                       ));
        }
コード例 #9
0
        /// <summary>Asynchronously fetch a new page of results</summary>
        /// <returns>True if Chunk contains a new page of results. False if all results have been read.</returns>
        public Task <FdbRangeChunk> GetRangeAsync(KeySelector begin, KeySelector end, FdbRangeOptions options, int iteration, bool snapshot, CancellationToken ct)
        {
            Contract.Requires(options != null);

            bool reversed = options.Reverse ?? false;
            var  future   = FdbNative.TransactionGetRange(m_handle, begin, end, options.Limit ?? 0, options.TargetBytes ?? 0, options.Mode ?? FdbStreamingMode.Iterator, iteration, snapshot, reversed);

            return(FdbFuture.CreateTaskFromHandle(
                       future,
                       (h) =>
            {
                // TODO: quietly return if disposed
                var chunk = GetKeyValueArrayResult(h, out bool hasMore);
                return new FdbRangeChunk(hasMore, chunk, iteration, reversed);
            },
                       ct
                       ));
        }
コード例 #10
0
        public static Task <IFdbClusterHandler> CreateClusterAsync(string clusterFile, CancellationToken ct)
        {
            var future = FdbNative.CreateCluster(clusterFile);

            return(FdbFuture.CreateTaskFromHandle(future,
                                                  (h) =>
            {
                var err = FdbNative.FutureGetCluster(h, out ClusterHandle cluster);
                if (err != FdbError.Success)
                {
                    cluster.Dispose();
                    throw Fdb.MapToException(err);
                }
                var handler = new FdbNativeCluster(cluster);
                return (IFdbClusterHandler)handler;
            },
                                                  ct
                                                  ));
        }
コード例 #11
0
        /// <summary>Asynchronously fetch a new page of results</summary>
        /// <returns>True if Chunk contains a new page of results. False if all results have been read.</returns>
        public Task <FdbRangeChunk> GetRangeAsync(KeySelector begin, KeySelector end, int limit, bool reversed, int targetBytes, FdbStreamingMode mode, FdbReadMode read, int iteration, bool snapshot, CancellationToken ct)
        {
            var future = FdbNative.TransactionGetRange(m_handle, begin, end, limit, targetBytes, mode, iteration, snapshot, reversed);

            return(FdbFuture.CreateTaskFromHandle(
                       future,
                       (h) =>
            {
                KeyValuePair <Slice, Slice>[] items;
                bool hasMore;
                Slice first, last;
                switch (read)
                {
                case FdbReadMode.Both:
                    {
                        items = GetKeyValueArrayResult(h, out hasMore, out first, out last);
                        break;
                    }

                case FdbReadMode.Keys:
                    {
                        items = GetKeyValueArrayResultKeysOnly(h, out hasMore, out first, out last);
                        break;
                    }

                case FdbReadMode.Values:
                    {
                        items = GetKeyValueArrayResultValuesOnly(h, out hasMore, out first, out last);
                        break;
                    }

                default:
                    {
                        throw new InvalidOperationException();
                    }
                }
                return new FdbRangeChunk(items, hasMore, iteration, reversed, read, first, last);
            },
                       ct
                       ));
        }
コード例 #12
0
        /// <inheritdoc />
        public Task <long> GetApproximateSizeAsync(CancellationToken ct)
        {
            // API was introduced in 6.2
            if (Fdb.ApiVersion < 620)
            {
                throw new NotSupportedException($"The GetApproximateSize method is only available for version 6.2 or greater. Your application has selected API version {Fdb.ApiVersion} which is too low. You willl need to select API version 620 or greater.");
            }
            //TODO: for lesser version, maybe we could return our own estimation?

            var future = FdbNative.TransactionGetReadVersion(m_handle);

            return(FdbFuture.CreateTaskFromHandle(future,
                                                  (h) =>
            {
                var err = FdbNative.FutureGetInt64(h, out long size);
#if DEBUG_TRANSACTIONS
                Debug.WriteLine("FdbTransaction[" + m_id + "].GetApproximateSize() => err=" + err + ", size=" + size);
#endif
                Fdb.DieOnError(err);
                return size;
            },
                                                  ct
                                                  ));
        }
コード例 #13
0
        public Task OnErrorAsync(FdbError code, CancellationToken ct)
        {
            var future = FdbNative.TransactionOnError(m_handle, code);

            return(FdbFuture.CreateTaskFromHandle <object?>(future, (h) => { ResetInternal(); return null; }, ct));
        }
コード例 #14
0
        /// <summary>
        /// Attempts to commit the sets and clears previously applied to the database snapshot represented by this transaction to the actual database.
        /// The commit may or may not succeed – in particular, if a conflicting transaction previously committed, then the commit must fail in order to preserve transactional isolation.
        /// If the commit does succeed, the transaction is durably committed to the database and all subsequently started transactions will observe its effects.
        /// </summary>
        /// <returns>Task that succeeds if the transaction was committed successfully, or fails if the transaction failed to commit.</returns>
        /// <remarks>As with other client/server databases, in some failure scenarios a client may be unable to determine whether a transaction succeeded. In these cases, CommitAsync() will throw CommitUnknownResult error. The OnErrorAsync() function treats this error as retryable, so retry loops that don’t check for CommitUnknownResult could execute the transaction twice. In these cases, you must consider the idempotence of the transaction.</remarks>
        public Task CommitAsync(CancellationToken ct)
        {
            var future = FdbNative.TransactionCommit(m_handle);

            return(FdbFuture.CreateTaskFromHandle <object?>(future, (h) => null, ct));
        }
コード例 #15
0
        public Task <VersionStamp> GetVersionStampAsync(CancellationToken ct)
        {
            var future = FdbNative.TransactionGetVersionStamp(m_handle);

            return(FdbFuture.CreateTaskFromHandle <VersionStamp>(future, GetVersionStampResult, ct));
        }
コード例 #16
0
        public Task <Slice> GetAsync(Slice key, bool snapshot, CancellationToken ct)
        {
            var future = FdbNative.TransactionGet(m_handle, key, snapshot);

            return(FdbFuture.CreateTaskFromHandle(future, (h) => GetValueResultBytes(h), ct));
        }