5using System.Diagnostics;
 
    6using System.Runtime.CompilerServices;
 
    7using System.Linq.Expressions;
 
   12public partial class QuerySource<T>
 
   16    private LookupTable Lookup { 
get => Ctx.LookupTable; }
 
   23        return Chain<T>(q: 
QH.MethodCall(
Query, 
"distinct"));
 
 
   29        return Chain<T>(q: 
QH.MethodCall(
Query, 
"order"));
 
 
   35        return Chain<T>(q: 
QH.MethodCall(
Query, 
"order", SubQuery(keySelector)));
 
 
   41        return Chain<T>(q: 
QH.MethodCall(
Query, 
"order", 
QH.FnCall(
"desc", SubQuery(keySelector))));
 
 
   47        return Chain<T>(q: 
QH.MethodCall(
Query, 
"order", 
QH.Expr(
"desc(x => x)")));
 
 
   51        Chain<T>(q: 
QH.MethodCall(
Query, 
"reverse"));
 
   55        var pl = SelectCall(
Query, selector);
 
 
   60         Chain<T>(q: 
QH.MethodCall(
Query, 
"drop", 
QH.Const(count)));
 
   63         Chain<T>(q: 
QH.MethodCall(
Query, 
"take", 
QH.Const(count)));
 
   66        Chain<T>(q: WhereCall(
Query, predicate));
 
   70    public bool All(Expression<Func<T, bool>> predicate) => Execute<bool>(AllImpl(predicate));
 
   71    public Task<bool> 
AllAsync(Expression<Func<T, bool>> predicate, CancellationToken cancel = 
default) =>
 
   72        ExecuteAsync<bool>(AllImpl(predicate), cancel);
 
   73    private Pipeline AllImpl(Expression<Func<T, bool>> predicate)
 
   75        RequireQueryMode(
"All");
 
   78            q: 
QH.MethodCall(
Query, 
"every", SubQuery(predicate)),
 
   82    public bool Any() => Execute<bool>(AnyImpl(
null));
 
   83    public Task<bool> 
AnyAsync(CancellationToken cancel = 
default) =>
 
   84        ExecuteAsync<bool>(AnyImpl(
null), cancel);
 
   85    public bool Any(Expression<Func<T, bool>> predicate) => Execute<bool>(AnyImpl(predicate));
 
   86    public Task<bool> 
AnyAsync(Expression<Func<T, bool>> predicate, CancellationToken cancel = 
default) =>
 
   87        ExecuteAsync<bool>(AnyImpl(predicate), cancel);
 
   88    private Pipeline AnyImpl(Expression<Func<T, bool>>? predicate) =>
 
   91            q: 
QH.MethodCall(MaybeWhereCall(
Query, predicate), 
"nonEmpty"),
 
   94    public int Count() => Execute<int>(CountImpl(
null));
 
   95    public Task<int> 
CountAsync(CancellationToken cancel = 
default) =>
 
   96        ExecuteAsync<int>(CountImpl(
null), cancel);
 
   97    public int Count(Expression<Func<T, bool>> predicate) => Execute<int>(CountImpl(predicate));
 
   98    public Task<int> 
CountAsync(Expression<Func<T, bool>> predicate, CancellationToken cancel = 
default) =>
 
   99        ExecuteAsync<int>(CountImpl(predicate), cancel);
 
  100    private Pipeline CountImpl(Expression<Func<T, bool>>? predicate) =>
 
  103            q: 
QH.MethodCall(MaybeWhereCall(
Query, predicate), 
"count"),
 
  106    public T 
First() => Execute<T>(FirstImpl(
null));
 
  107    public Task<T> 
FirstAsync(CancellationToken cancel = 
default) =>
 
  108        ExecuteAsync<T>(FirstImpl(
null), cancel);
 
  109    public T 
First(Expression<Func<T, bool>> predicate) => Execute<T>(FirstImpl(predicate));
 
  110    public Task<T> 
FirstAsync(Expression<Func<T, bool>> predicate, CancellationToken cancel = 
default) =>
 
  111        ExecuteAsync<T>(FirstImpl(predicate), cancel);
 
  112    private Pipeline FirstImpl(Expression<Func<T, bool>>? predicate) =>
 
  115            q: 
QH.MethodCall(AbortIfEmpty(MaybeWhereCall(
Query, predicate)), 
"first"));
 
  119        ExecuteAsync<T?>(FirstOrDefaultImpl(
null), cancel);
 
  120    public T? 
FirstOrDefault(Expression<Func<T, bool>> predicate) => Execute<T?>(FirstOrDefaultImpl(predicate));
 
  121    public Task<T?> 
FirstOrDefaultAsync(Expression<Func<T, bool>> predicate, CancellationToken cancel = 
default) =>
 
  122        ExecuteAsync<T?>(FirstOrDefaultImpl(predicate), cancel);
 
  123    private Pipeline FirstOrDefaultImpl(Expression<Func<T, bool>>? predicate) =>
 
  126            q: 
QH.MethodCall(MaybeWhereCall(
Query, predicate), 
"first"),
 
  130    public T 
Last() => Execute<T>(LastImpl(
null));
 
  131    public Task<T> 
LastAsync(CancellationToken cancel = 
default) =>
 
  132        ExecuteAsync<T>(LastImpl(
null), cancel);
 
  133    public T 
Last(Expression<Func<T, bool>> predicate) => Execute<T>(LastImpl(predicate));
 
  134    public Task<T> 
LastAsync(Expression<Func<T, bool>> predicate, CancellationToken cancel = 
default) =>
 
  135        ExecuteAsync<T>(LastImpl(predicate), cancel);
 
  136    private Pipeline LastImpl(Expression<Func<T, bool>>? predicate) =>
 
  139            q: 
QH.MethodCall(AbortIfEmpty(MaybeWhereCall(
Query, predicate)), 
"last"));
 
  143        ExecuteAsync<T?>(LastOrDefaultImpl(
null), cancel);
 
  144    public T? 
LastOrDefault(Expression<Func<T, bool>> predicate) => Execute<T?>(LastOrDefaultImpl(predicate));
 
  145    public Task<T?> 
LastOrDefaultAsync(Expression<Func<T, bool>> predicate, CancellationToken cancel = 
default) =>
 
  146        ExecuteAsync<T?>(LastOrDefaultImpl(predicate), cancel);
 
  147    private Pipeline LastOrDefaultImpl(Expression<Func<T, bool>>? predicate) =>
 
  150            q: 
QH.MethodCall(MaybeWhereCall(
Query, predicate), 
"last"),
 
  154    public long LongCount() => Execute<long>(LongCountImpl(
null));
 
  156        ExecuteAsync<long>(LongCountImpl(
null), cancel);
 
  157    public long LongCount(Expression<Func<T, bool>> predicate) => Execute<long>(LongCountImpl(predicate));
 
  158    public Task<long> 
LongCountAsync(Expression<Func<T, bool>> predicate, CancellationToken cancel = 
default) =>
 
  159        ExecuteAsync<long>(LongCountImpl(predicate), cancel);
 
  160    private Pipeline LongCountImpl(Expression<Func<T, bool>>? predicate) =>
 
  163            q: 
QH.MethodCall(MaybeWhereCall(
Query, predicate), 
"count"),
 
  166    private static readonly 
Query _maxReducer = 
QH.Expr(
"(a, b) => if (a >= b) a else b");
 
  168    public T 
Max() => Execute<T>(MaxImpl<T>(
null));
 
  169    public Task<T> 
MaxAsync(CancellationToken cancel = 
default) =>
 
  170        ExecuteAsync<T>(MaxImpl<T>(
null), cancel);
 
  171    public R 
Max<R>(Expression<Func<T, R>> selector) => Execute<R>(MaxImpl(selector));
 
  172    public Task<R> 
MaxAsync<R>(Expression<Func<T, R>> selector, CancellationToken cancel = 
default) =>
 
  173        ExecuteAsync<R>(MaxImpl(selector), cancel);
 
  174    private Pipeline MaxImpl<R>(Expression<Func<T, R>>? selector, [CallerMemberName] 
string callerName = 
"")
 
  176        RequireQueryMode(callerName);
 
  179            q: 
QH.MethodCall(MaybeMap(AbortIfEmpty(
Query), selector), 
"reduce", _maxReducer),
 
  183    private static readonly 
Query _minReducer = 
QH.Expr(
"(a, b) => if (a <= b) a else b");
 
  185    public T 
Min() => Execute<T>(MinImpl<T>(
null));
 
  186    public Task<T> 
MinAsync(CancellationToken cancel = 
default) => ExecuteAsync<T>(MinImpl<T>(
null), cancel);
 
  187    public R 
Min<R>(Expression<Func<T, R>> selector) => Execute<R>(MinImpl(selector));
 
  188    public Task<R> 
MinAsync<R>(Expression<Func<T, R>> selector, CancellationToken cancel = 
default) =>
 
  189        ExecuteAsync<R>(MinImpl(selector), cancel);
 
  190    private Pipeline MinImpl<R>(Expression<Func<T, R>>? selector, [CallerMemberName] 
string callerName = 
"")
 
  192        RequireQueryMode(callerName);
 
  195            q: 
QH.MethodCall(MaybeMap(AbortIfEmpty(
Query), selector), 
"reduce", _minReducer),
 
  199    public T 
Single() => Execute<T>(SingleImpl(
null));
 
  200    public Task<T> 
SingleAsync(CancellationToken cancel = 
default) => ExecuteAsync<T>(SingleImpl(
null), cancel);
 
  201    public T 
Single(Expression<Func<T, bool>> predicate) => Execute<T>(SingleImpl(predicate));
 
  202    public Task<T> 
SingleAsync(Expression<Func<T, bool>> predicate, CancellationToken cancel = 
default) =>
 
  203        ExecuteAsync<T>(SingleImpl(predicate), cancel);
 
  204    private Pipeline SingleImpl(Expression<Func<T, bool>>? predicate) =>
 
  207            q: 
QH.MethodCall(AbortIfEmpty(Singularize(MaybeWhereCall(
Query, predicate))), 
"first"));
 
  210    public Task<T> 
SingleOrDefaultAsync(CancellationToken cancel = 
default) => ExecuteAsync<T>(SingleOrDefaultImpl(
null), cancel);
 
  211    public T 
SingleOrDefault(Expression<Func<T, bool>> predicate) => Execute<T>(SingleOrDefaultImpl(predicate));
 
  212    public Task<T> 
SingleOrDefaultAsync(Expression<Func<T, bool>> predicate, CancellationToken cancel = 
default) =>
 
  213        ExecuteAsync<T>(SingleOrDefaultImpl(predicate), cancel);
 
  214    private Pipeline SingleOrDefaultImpl(Expression<Func<T, bool>>? predicate) =>
 
  217            q: 
QH.MethodCall(Singularize(MaybeWhereCall(
Query, predicate)), 
"first"),
 
  221    private static readonly 
Query _sumReducer = 
QH.Expr(
"(a, b) => a + b");
 
  223    public int Sum(Expression<Func<T, int>> selector) => Execute<int>(SumImpl<int>(selector));
 
  224    public Task<int> 
SumAsync(Expression<Func<T, int>> selector, CancellationToken cancel = 
default) =>
 
  225        ExecuteAsync<int>(SumImpl<int>(selector), cancel);
 
  226    public long Sum(Expression<Func<T, long>> selector) => Execute<long>(SumImpl<long>(selector));
 
  227    public Task<long> 
SumAsync(Expression<Func<T, long>> selector, CancellationToken cancel = 
default) =>
 
  228        ExecuteAsync<long>(SumImpl<long>(selector), cancel);
 
  229    public double Sum(Expression<Func<T, double>> selector) => Execute<double>(SumImpl<double>(selector));
 
  230    public Task<double> 
SumAsync(Expression<Func<T, double>> selector, CancellationToken cancel = 
default) =>
 
  231        ExecuteAsync<double>(SumImpl<double>(selector), cancel);
 
  232    private Pipeline SumImpl<R>(Expression<Func<T, R>> selector)
 
  234        RequireQueryMode(
"Sum");
 
  235        var seed = (typeof(R) == typeof(
int) || typeof(R) == typeof(
long)) ?
 
  238        var mapped = 
QH.MethodCall(
Query, 
"map", SubQuery(selector));
 
  241            q: 
QH.MethodCall(mapped, 
"fold", seed, _sumReducer),
 
  247    private void RequireQueryMode([CallerMemberName] 
string callerName = 
"")
 
  253                $
"Query is not pure: Earlier `Select` could not be translated to pure FQL.");
 
  257    private R Execute<R>(Pipeline pl)
 
  261            var res = ExecuteAsync<R>(pl);
 
  265        catch (AggregateException ex)
 
  267            throw TranslateException(ex.InnerExceptions.First());
 
  271    private async Task<R> ExecuteAsync<R>(Pipeline pl, CancellationToken cancel = 
default)
 
  275            return await pl.GetExec(Ctx).Result<R>(queryOptions: 
null, cancel: cancel);
 
  277        catch (AggregateException ex)
 
  279            throw TranslateException(ex.InnerExceptions.First());
 
  283    private QuerySource<R> Chain<R>(
 
  289        LambdaExpression? proj = 
null) =>
 
  290        new QuerySource<R>(Ctx, CopyPipeline(mode, q, deser, ety, enull, proj));
 
  292    private Pipeline CopyPipeline(
 
  298        LambdaExpression? proj = 
null)
 
  300        if (deser is not 
null) Debug.Assert(ety is not 
null);
 
  302        var mode0 = mode ?? Pipeline.Mode;
 
  303        var q0 = q ?? Pipeline.Query;
 
  306        var (ety0, enull0, deser0, proj0) = ety is not 
null ?
 
  307            (ety, enull, deser, proj) :
 
  309             Pipeline.ElemNullable,
 
  310             Pipeline.ElemDeserializer,
 
  311             proj ?? Pipeline.ProjectExpr);
 
  313        return new Pipeline(mode0, q0, ety0, enull0, deser0, proj0);
 
  320        QH.Expr(
@"({ let s = (").Concat(setq).Concat(
@") 
  321            if (s.isEmpty()) abort(['empty']) 
  327          let s = (").Concat(setq).Concat(
@").take(2).toArray() 
  328          if (s.length > 1) abort(['not single']) 
  332    private Exception TranslateException(Exception ex) =>
 
  338                    "empty" => 
new InvalidOperationException(
"Empty set"),
 
  339                    "not single" => 
new InvalidOperationException(
"Set contains more than one element"),
 
  345    private Query MaybeWhereCall(
Query callee, Expression? predicate, [CallerMemberName] 
string callerName = 
"") =>
 
  346        predicate is 
null ? callee : WhereCall(callee, predicate, callerName);
 
  348    private Query MaybeMap(
Query setq, Expression? selector) =>
 
  349        selector is 
null ? setq : 
QH.MethodCall(setq, 
"map", SubQuery(selector));
 
  351    private Query SubQuery(Expression expr) =>
 
  352        new SubQuerySwitch(Ctx.LookupTable).Apply(expr);
 
  354    private Query WhereCall(
Query callee, Expression predicate, [CallerMemberName] 
string callerName = 
"")
 
  356        RequireQueryMode(callerName);
 
  357        return QH.MethodCall(callee, 
"where", SubQuery(predicate));
 
  360    private Pipeline SelectCall(
Query callee, Expression proj, [CallerMemberName] 
string callerName = 
"")
 
  362        var lambda = Expressions.UnwrapLambda(proj);
 
  363        Debug.Assert(lambda is not 
null, $
"lambda is {proj.NodeType}");
 
  364        Debug.Assert(lambda.Parameters.Count() == 1);
 
  369            Debug.Assert(Pipeline.ProjectExpr is not 
null);
 
  370            var prev = Pipeline.ProjectExpr;
 
  371            var pbody = Expression.Invoke(lambda, 
new Expression[] { prev.Body });
 
  372            var plambda = Expression.Lambda(pbody, prev.Parameters);
 
  374            return CopyPipeline(proj: plambda);
 
  379        var lparam = lambda.Parameters.First()!;
 
  380        var analysis = 
new ProjectionAnalysisVisitor(MappingCtx, lparam);
 
  381        analysis.Visit(lambda.Body);
 
  385        if (lambda.Body is MemberExpression mexpr && mexpr.Expression == lparam)
 
  387            Debug.Assert(!analysis.Escapes);
 
  388            var info = MappingCtx.
GetInfo(lparam.Type);
 
  389            var access = analysis.Accesses.First();
 
  390            var field = Lookup.FieldLookup(access, lparam);
 
  391            Debug.Assert(field is not 
null);
 
  394                q: 
QH.MethodCall(callee, 
"map", 
QH.Expr($
".{field.Name}")),
 
  395                deser: field.Deserializer,
 
  399        if (analysis.Escapes)
 
  405            var accesses = analysis.Accesses.OrderBy(f => f.Name).ToArray();
 
  406            var fields = accesses.Select(a => Lookup.FieldLookup(a, lparam)!);
 
  409            var accs = fields.Select(f => 
QH.Expr($
"x.{f.Name}"));
 
  410            var pquery = 
QH.Expr(
"x => ").Concat(
QH.Array(accs));
 
  413            var deser = 
new ProjectionDeserializer(fields.Select(f => f.Deserializer));
 
  414            var ety = typeof(
object?[]);
 
  417            var pparam = Expression.Parameter(typeof(
object?[]), 
"x");
 
  418            var rewriter = 
new ProjectionRewriteVisitor(lparam, accesses, pparam);
 
  419            var pbody = rewriter.Visit(lambda.Body);
 
  420            var plambda = Expression.Lambda(pbody, pparam);
 
  423                q: 
QH.MethodCall(callee, 
"map", pquery),
 
Fauna.Linq.IntermediateQueryHelpers QH
 
Represents an exception that occurs when the FQL abort function is called. This exception captures th...
 
object? GetData()
Retrieves the deserialized data associated with the abort operation as an object.
 
Task< int > CountAsync(CancellationToken cancel=default)
 
Task< T?> FirstOrDefaultAsync(Expression< Func< T, bool > > predicate, CancellationToken cancel=default)
 
Task< bool > AllAsync(Expression< Func< T, bool > > predicate, CancellationToken cancel=default)
 
Task< long > SumAsync(Expression< Func< T, long > > selector, CancellationToken cancel=default)
 
Task< T > SingleOrDefaultAsync(Expression< Func< T, bool > > predicate, CancellationToken cancel=default)
 
Task< T > FirstAsync(CancellationToken cancel=default)
 
Task< T > FirstAsync(Expression< Func< T, bool > > predicate, CancellationToken cancel=default)
 
double Sum(Expression< Func< T, double > > selector)
 
T SingleOrDefault(Expression< Func< T, bool > > predicate)
 
Task< T > MinAsync(CancellationToken cancel=default)
 
bool Any(Expression< Func< T, bool > > predicate)
 
Task< T?> FirstOrDefaultAsync(CancellationToken cancel=default)
 
Task< int > SumAsync(Expression< Func< T, int > > selector, CancellationToken cancel=default)
 
Task< int > CountAsync(Expression< Func< T, bool > > predicate, CancellationToken cancel=default)
 
IQuerySource< T > OrderByDescending< K >(Expression< Func< T, K > > keySelector)
 
R Min< R >(Expression< Func< T, R > > selector)
 
Task< T > LastAsync(Expression< Func< T, bool > > predicate, CancellationToken cancel=default)
 
T? FirstOrDefault(Expression< Func< T, bool > > predicate)
 
T First(Expression< Func< T, bool > > predicate)
 
Task< T > LastAsync(CancellationToken cancel=default)
 
IQuerySource< T > Reverse()
 
Task< R > MinAsync< R >(Expression< Func< T, R > > selector, CancellationToken cancel=default)
 
IQuerySource< T > Skip(int count)
 
Task< T > SingleOrDefaultAsync(CancellationToken cancel=default)
 
IQuerySource< T > Where(Expression< Func< T, bool > > predicate)
 
IQuerySource< T > OrderDescending()
 
bool All(Expression< Func< T, bool > > predicate)
 
Task< R > MaxAsync< R >(Expression< Func< T, R > > selector, CancellationToken cancel=default)
 
IQuerySource< T > Order()
 
long LongCount(Expression< Func< T, bool > > predicate)
 
Task< T?> LastOrDefaultAsync(Expression< Func< T, bool > > predicate, CancellationToken cancel=default)
 
int Sum(Expression< Func< T, int > > selector)
 
IQuerySource< T > Take(int count)
 
Task< T > SingleAsync(CancellationToken cancel=default)
 
T Single(Expression< Func< T, bool > > predicate)
 
IQuerySource< T > Distinct()
 
Task< long > LongCountAsync(CancellationToken cancel=default)
 
Task< double > SumAsync(Expression< Func< T, double > > selector, CancellationToken cancel=default)
 
Task< T?> LastOrDefaultAsync(CancellationToken cancel=default)
 
Task< T > SingleAsync(Expression< Func< T, bool > > predicate, CancellationToken cancel=default)
 
T? LastOrDefault(Expression< Func< T, bool > > predicate)
 
Task< bool > AnyAsync(Expression< Func< T, bool > > predicate, CancellationToken cancel=default)
 
T Last(Expression< Func< T, bool > > predicate)
 
IQuerySource< T > OrderBy< K >(Expression< Func< T, K > > keySelector)
 
Task< T > MaxAsync(CancellationToken cancel=default)
 
Task< long > LongCountAsync(Expression< Func< T, bool > > predicate, CancellationToken cancel=default)
 
long Sum(Expression< Func< T, long > > selector)
 
IQuerySource< R > Select< R >(Expression< Func< T, R > > selector)
 
Task< bool > AnyAsync(CancellationToken cancel=default)
 
R Max< R >(Expression< Func< T, R > > selector)
 
int Count(Expression< Func< T, bool > > predicate)
 
MappingInfo GetInfo(Type ty)
 
Represents the abstract base class for constructing FQL queries.