internal async Task <bool> AnyOrNoneAsync(bool any)
        {
            // Optimized code path for Any/None where we can be smart and only ask for 1 from the db

            // we can use the EXACT streaming mode with Limit = 1, and it will work if TargetBytes is 0
            if ((this.TargetBytes ?? 0) != 0 || (this.Mode != FdbStreamingMode.Iterator && this.Mode != FdbStreamingMode.Exact))
            {             // fallback to the default implementation
                if (any)
                {
                    return(await FdbAsyncEnumerable.AnyAsync(this, this.Transaction.Cancellation));
                }
                else
                {
                    return(await FdbAsyncEnumerable.NoneAsync(this, this.Transaction.Cancellation));
                }
            }

            //BUGBUG: do we need special handling if OriginalRange != Range ? (weird combinations of Take/Skip and Reverse)

            var options = new FdbRangeOptions()
            {
                Limit       = 1,
                TargetBytes = 0,
                Mode        = FdbStreamingMode.Exact,
                Reverse     = this.Reversed
            };

            var tr      = this.Snapshot ? this.Transaction.Snapshot : this.Transaction;
            var results = await tr.GetRangeAsync(this.Begin, this.End, options, 0).ConfigureAwait(false);

            return(any ? !results.IsEmpty : results.IsEmpty);
        }
        internal async Task <T> HeadAsync(bool single, bool orDefault)
        {
            // Optimized code path for First/Last/Single variants where we can be smart and only ask for 1 or 2 results from the db

            // we can use the EXACT streaming mode with Limit = 1|2, and it will work if TargetBytes is 0
            if ((this.TargetBytes ?? 0) != 0 || (this.Mode != FdbStreamingMode.Iterator && this.Mode != FdbStreamingMode.Exact))
            {             // fallback to the default implementation
                return(await FdbAsyncEnumerable.Head(this, single, orDefault, this.Transaction.Cancellation).ConfigureAwait(false));
            }

            var options = new FdbRangeOptions()
            {
                Limit       = single ? 2 : 1,
                TargetBytes = 0,
                Mode        = FdbStreamingMode.Exact,
                Reverse     = this.Reversed
            };

            //BUGBUG: do we need special handling if OriginalRange != Range ? (weird combinations of Take/Skip and Reverse)

            var tr      = this.Snapshot ? this.Transaction.Snapshot : this.Transaction;
            var results = await tr.GetRangeAsync(this.Begin, this.End, options, 0).ConfigureAwait(false);

            if (results.IsEmpty)
            {             // no result
                if (!orDefault)
                {
                    throw new InvalidOperationException("The range was empty");
                }
                return(default(T));
            }

            if (single && results.Count > 1)
            {             // there was more than one result
                throw new InvalidOperationException("The range contained more than one element");
            }

            // we have a result
            return(this.Transform(results.First));
        }
 /// <summary>Execute an action on each key/value pair of the range results</summary>
 public Task ForEachAsync([NotNull] Action <T> action)
 {
     return(FdbAsyncEnumerable.ForEachAsync(this, action, this.Transaction.Cancellation));
 }
 /// <summary>Return the number of elements in the range, by reading them</summary>
 /// <remarks>This method has to read all the keys and values, which may exceed the lifetime of a transaction. Please consider using <see cref="Fdb.System.EstimateCountAsync"/> when reading potentially large ranges.</remarks>
 public Task <int> CountAsync()
 {
     return(FdbAsyncEnumerable.CountAsync(this, this.Transaction.Cancellation));
 }
 public IFdbAsyncEnumerable <T> Where([NotNull] Func <T, bool> predicate)
 {
     return(FdbAsyncEnumerable.Where(this, predicate));
 }
 public Task <T[]> ToArrayAsync()
 {
     return(FdbAsyncEnumerable.ToArrayAsync(this, this.Transaction.Cancellation));
 }
 public Task <List <T> > ToListAsync()
 {
     return(FdbAsyncEnumerable.ToListAsync(this, this.Transaction.Cancellation));
 }
Beispiel #8
0
 /// <summary>Execute an action on each key/value pair of the range results</summary>
 public Task ForEachAsync([NotNull] Action <T> action)
 {
     // ReSharper disable once InvokeAsExtensionMethod
     return(FdbAsyncEnumerable.ForEachAsync(this, action, this.Transaction.Cancellation));
 }
Beispiel #9
0
 /// <summary>Return the number of elements in the range, by reading them</summary>
 /// <remarks>This method has to read all the keys and values, which may exceed the lifetime of a transaction. Please consider using <see cref="Fdb.System.EstimateCountAsync"/> when reading potentially large ranges.</remarks>
 public Task <int> CountAsync()
 {
     // ReSharper disable once InvokeAsExtensionMethod
     return(FdbAsyncEnumerable.CountAsync(this, this.Transaction.Cancellation));
 }
 /// <summary>Return an async sequence that will return the results of this query</summary>
 public IFdbAsyncEnumerable <T> ToEnumerable(FdbAsyncMode mode = FdbAsyncMode.Default)
 {
     return(FdbAsyncEnumerable.Create((_) => GetEnumerator(this, mode)));
 }