/// <summary>Execute the query and return a single element in the expected type</summary> protected virtual async Task <object?> ExecuteSingleInternal(FdbQueryExpression expression, Type resultType, CancellationToken ct) { var generator = CompileSingle(expression); var trans = this.Transaction; bool owned = false; try { if (trans == null) { owned = true; trans = await this.Database !.BeginTransactionAsync(ct); } T result = await generator(trans, ct).ConfigureAwait(false); return(result); } finally { if (owned) { trans?.Dispose(); } } }
/// <summary>Execute the query and return the result asynchronously</summary> /// <typeparam name="R">Type of the expected result. Can be a <typeparamref name="T"/> for singleton queries or a <see cref="List{T}"/> for sequence queries</typeparam> public async Task<R> ExecuteAsync<R>([NotNull] FdbQueryExpression expression, CancellationToken ct) { if (expression == null) throw new ArgumentNullException("ct"); ct.ThrowIfCancellationRequested(); var result = await ExecuteInternal(expression, typeof(R), ct).ConfigureAwait(false); return (R)result; }
/// <summary>Create a new typed query from a query expression</summary> public virtual IFdbAsyncQueryable<R> CreateQuery<R>([NotNull] FdbQueryExpression<R> expression) { if (expression == null) throw new ArgumentNullException("expression"); if (this.Transaction != null) return new FdbAsyncSingleQuery<R>(this.Transaction, expression); else return new FdbAsyncSingleQuery<R>(this.Database, expression); }
private Func<IFdbReadOnlyTransaction, CancellationToken, Task<T>> CompileSingle([NotNull] FdbQueryExpression expression) { //TODO: caching ! var expr = ((FdbQueryExpression<T>)expression).CompileSingle(); //Console.WriteLine("Compiled single as:"); //Console.WriteLine("> " + expr.GetDebugView().Replace("\r\n", "\r\n> ")); return expr.Compile(); }
private Func<IFdbReadOnlyTransaction, IFdbAsyncEnumerable<T>> CompileSequence([NotNull] FdbQueryExpression expression) { #if false //TODO: caching ! Console.WriteLine("Source expression:"); Console.WriteLine("> " + expression.GetDebugView().Replace("\r\n", "\r\n> ")); #endif var expr = ((FdbQuerySequenceExpression<T>) expression).CompileSequence(); #if false Console.WriteLine("Compiled sequence as:"); Console.WriteLine("> " + expr.GetDebugView().Replace("\r\n", "\r\n> ")); #endif return expr.Compile(); }
/// <summary>Create a new typed query from a query expression</summary> public virtual IFdbAsyncQueryable <R> CreateQuery <R>(FdbQueryExpression <R> expression) { if (expression == null) { throw new ArgumentNullException(nameof(expression)); } if (this.Transaction != null) { return(new FdbAsyncSingleQuery <R>(this.Transaction, expression)); } else { return(new FdbAsyncSingleQuery <R>(this.Database !, expression)); } }
/// <summary>Execute the query and return a list of elements in the expected type</summary> protected virtual async Task <object?> ExecuteSequenceInternal(FdbQueryExpression expression, Type resultType, CancellationToken ct) { var generator = CompileSequence(expression); var trans = this.Transaction; bool owned = false; try { if (trans == null) { owned = true; trans = await this.Database !.BeginTransactionAsync(ct); } var enumerable = generator(trans); object result; if (typeof(T[]).IsAssignableFrom(resultType)) { result = await enumerable.ToArrayAsync(ct).ConfigureAwait(false); } else if (typeof(IEnumerable <T>).IsAssignableFrom(resultType)) { result = await enumerable.ToListAsync(ct).ConfigureAwait(false); } else { throw new InvalidOperationException($"Sequence result type {resultType.Name} is not supported"); } return(result); } finally { if (owned) { trans?.Dispose(); } } }
/// <summary>Execute the query and return the result in the expected type</summary> protected virtual Task<object> ExecuteInternal([NotNull] FdbQueryExpression expression, Type resultType, CancellationToken ct) { switch(expression.Shape) { case FdbQueryShape.Single: { if (!expression.Type.IsAssignableFrom(resultType)) throw new InvalidOperationException(String.Format("Return type {0} does not match the sequence type {1}", resultType.Name, expression.Type.Name)); return ExecuteSingleInternal(expression, resultType, ct); } case FdbQueryShape.Sequence: return ExecuteSequenceInternal(expression, resultType, ct); case FdbQueryShape.Void: return Task.FromResult(default(object)); default: throw new InvalidOperationException("Invalid sequence shape"); } }
/// <summary>Execute the query and return the result in the expected type</summary> protected virtual Task <object?> ExecuteInternal(FdbQueryExpression expression, Type resultType, CancellationToken ct) { switch (expression.Shape) { case FdbQueryShape.Single: { if (!expression.Type.IsAssignableFrom(resultType)) { throw new InvalidOperationException($"Return type {resultType.Name} does not match the sequence type {expression.Type.Name}"); } return(ExecuteSingleInternal(expression, resultType, ct)); } case FdbQueryShape.Sequence: return(ExecuteSequenceInternal(expression, resultType, ct)); case FdbQueryShape.Void: return(Task.FromResult(default(object))); default: throw new InvalidOperationException("Invalid sequence shape"); } }
/// <summary>Create a new query from a query expression</summary> public virtual IFdbAsyncQueryable CreateQuery(FdbQueryExpression expression) { // source queries are usually only intended to produce some sort of result throw new NotSupportedException(); }
/// <summary>Async LINQ query that will execute on a specific Transaction instance</summary> protected FdbAsyncQuery([NotNull] IFdbReadOnlyTransaction trans, FdbQueryExpression expression = null) { this.Transaction = trans; this.Expression = expression; }
/// <summary>Async LINQ query that will execute under a retry loop on a specific Database instance</summary> protected FdbAsyncQuery([NotNull] IFdbDatabase db, FdbQueryExpression expression = null) { this.Database = db; this.Expression = expression; }
/// <summary>Async LINQ query that will execute on a specific Transaction instance</summary> public FdbAsyncSingleQuery(IFdbReadOnlyTransaction trans, FdbQueryExpression <T> expression) : base(trans, expression) { }
/// <summary>Async LINQ query that will execute on a specific Transaction instance</summary> public FdbAsyncSequenceQuery(IFdbReadOnlyTransaction trans, FdbQueryExpression expression) : base(trans, expression) { }
/// <summary>Async LINQ query that will execute under a retry loop on a specific Database instance</summary> public FdbAsyncSequenceQuery(IFdbDatabase db, FdbQueryExpression expression) : base(db, expression) { }
/// <summary>Execute the query and return the result in the expected type</summary> protected override Task <object> ExecuteInternal(FdbQueryExpression expression, Type resultType, CancellationToken ct) { throw new InvalidOperationException("You cannot execute this operation on the whole database. Try calling Range() or RangeStartsWith() on this query to read from the database."); }
/// <summary>Execute the query and return the result in the expected type</summary> protected override Task <object> ExecuteInternal(FdbQueryExpression expression, Type resultType, CancellationToken ct) { throw new InvalidOperationException("You cannot execute this operation on the whole index. Try calling Lookup() on this query to lookup specific values from the index."); }
/// <summary>Async LINQ query that will execute under a retry loop on a specific Database instance</summary> public FdbAsyncSingleQuery(IFdbDatabase db, FdbQueryExpression <T> expression) : base(db, expression) { }