Exemplo n.º 1
0
 public Task <string> CreateAsync <T>(
     Expression <Func <T, bool> > predicate = null,
     SubscriptionCreationOptions options    = null,
     string database = null)
 {
     return(CreateAsync(EnsureCriteria(options, predicate), database));
 }
Exemplo n.º 2
0
 /// <summary>
 /// Creates a data subscription in a database. The subscription will expose all documents that match the specified subscription options for a given type.
 /// </summary>
 /// <typeparam name="T">Type of the collection to be proccessed by the subscription</typeparam>
 /// <returns>Created subscription</returns>
 public string Create <T>(SubscriptionCreationOptions <T> options, string database = null)
 {
     return(Create(EnsureCriteria(new SubscriptionCreationOptions
     {
         Name = options.Name,
         ChangeVector = options.ChangeVector
     }, options.Filter, options.Projection), database));
 }
Exemplo n.º 3
0
 /// <summary>
 /// It creates a data subscription in a database. The subscription will expose all documents that match the specified subscription options for a given type.
 /// </summary>
 /// <returns>Created subscription name.</returns>
 public Task <string> CreateAsync <T>(
     Expression <Func <T, bool> > predicate = null,
     SubscriptionCreationOptions options    = null,
     string database         = null,
     CancellationToken token = default)
 {
     return(CreateAsync(EnsureCriteria(options, predicate, null), database, token));
 }
Exemplo n.º 4
0
 /// <summary>
 /// It creates a data subscription in a database. The subscription will expose all documents that match the specified subscription options for a given type.
 /// </summary>
 /// <returns>Created subscription name.</returns>
 public Task <string> CreateAsync <T>(
     Expression <Func <T, bool> > predicate = null,
     SubscriptionCreationOptions options    = null,
     string database         = null,
     CancellationToken token = default)
 {
     return(CreateAsync(CreateSubscriptionOptionsFromGeneric(_store.Conventions, options, predicate, null, includes: null), database, token));
 }
Exemplo n.º 5
0
 /// <summary>
 /// Creates a data subscription in a database. The subscription will expose all documents that match the specified subscription options for a given type.
 /// </summary>
 /// <typeparam name="T">Type of the collection to be processed by the subscription</typeparam>
 /// <returns>Created subscription</returns>
 public string Create <T>(SubscriptionCreationOptions <T> options, string database = null)
 {
     return(Create(CreateSubscriptionOptionsFromGeneric(_store.Conventions, new SubscriptionCreationOptions
     {
         Name = options.Name,
         ChangeVector = options.ChangeVector,
         MentorNode = options.MentorNode
     }, options.Filter, options.Projection, options.Includes), database));
 }
Exemplo n.º 6
0
 /// <summary>
 /// It creates a data subscription in a database. The subscription will expose all documents that match the specified subscription options.
 /// </summary>
 /// <returns>Created subscription name.</returns>
 public Task <string> CreateAsync <T>(
     SubscriptionCreationOptions <T> options, string database = null, CancellationToken token = default)
 {
     return(CreateAsync(EnsureCriteria(new SubscriptionCreationOptions
     {
         Name = options.Name,
         ChangeVector = options.ChangeVector,
         MentorNode = options.MentorNode
     }, options.Filter, options.Projection), database, token));
 }
Exemplo n.º 7
0
 /// <summary>
 /// It creates a data subscription in a database. The subscription will expose all documents that match the specified subscription options.
 /// </summary>
 /// <returns>Created subscription name.</returns>
 public Task <string> CreateAsync <T>(
     SubscriptionCreationOptions <T> options, string database = null, CancellationToken token = default)
 {
     return(CreateAsync(CreateSubscriptionOptionsFromGeneric(_store.Conventions, new SubscriptionCreationOptions
     {
         Name = options.Name,
         ChangeVector = options.ChangeVector,
         MentorNode = options.MentorNode
     }, options.Filter, options.Projection, options.Includes), database, token));
 }
Exemplo n.º 8
0
        private SubscriptionCreationOptions EnsureCriteria <T>(
            SubscriptionCreationOptions criteria,
            Expression <Func <T, bool> > predicate,
            Expression <Func <T, object> > project)
        {
            criteria = criteria ?? new SubscriptionCreationOptions();
            var collectionName = _store.Conventions.GetCollectionName(typeof(T));

            if (criteria.Query == null)
            {
                var tType            = typeof(T);
                var includeRevisions = tType.IsConstructedGenericType && tType.GetGenericTypeDefinition() == typeof(Revision <>);
                if (includeRevisions)
                {
                    collectionName = _store.Conventions.GetCollectionName(tType.GenericTypeArguments[0]);
                }
                if (includeRevisions)
                {
                    criteria.Query = "from " + collectionName + " (Revisions = true)";
                }
                else
                {
                    criteria.Query = "from " + collectionName;
                }
            }
            if (predicate != null)
            {
                var script = predicate.CompileToJavascript(
                    new JavascriptCompilationOptions(
                        JsCompilationFlags.BodyOnly,
                        new JavascriptConversionExtensions.LinqMethodsSupport(),
                        new JavascriptConversionExtensions.BooleanSupport(),
                        new JavascriptConversionExtensions.ReplaceParameterWithThis {
                    Parameter = predicate.Parameters[0]
                },
                        new JavascriptConversionExtensions.DateTimeSupport()
                        ));
                criteria.Query = "declare function predicate () {\r\n\t return " +
                                 script + "\r\n}\r\n" + criteria.Query + "\r\n" +
                                 "where predicate.call(this)";
            }
            if (project != null)
            {
                var script = project.CompileToJavascript(
                    new JavascriptCompilationOptions(
                        JsCompilationFlags.BodyOnly,
                        new JavascriptConversionExtensions.LinqMethodsSupport(),
                        new JavascriptConversionExtensions.DateTimeSupport()
                        ));
                criteria.Query += Environment.NewLine + "select " + script;
            }
            return(criteria);
        }
Exemplo n.º 9
0
        public async Task <string> CreateAsync(SubscriptionCreationOptions options, string database = null)
        {
            if (options == null)
            {
                throw new InvalidOperationException("Cannot create a subscription if options is null");
            }

            if (options.Query == null)
            {
                throw new InvalidOperationException("Cannot create a subscription if the script is null");
            }

            var requestExecutor = _store.GetRequestExecutor(database ?? _store.Database);

            requestExecutor.ContextPool.AllocateOperationContext(out JsonOperationContext context);

            var command = new CreateSubscriptionCommand(options);
            await requestExecutor.ExecuteAsync(command, context).ConfigureAwait(false);

            return(command.Result.Name);
        }
Exemplo n.º 10
0
        /// <summary>
        /// It creates a data subscription in a database. The subscription will expose all documents that match the specified subscription options.
        /// </summary>
        /// <returns>Created subscription name.</returns>
        public async Task <string> CreateAsync(SubscriptionCreationOptions options, string database = null, CancellationToken token = default)
        {
            if (options == null)
            {
                throw new InvalidOperationException("Cannot create a subscription if options is null");
            }

            if (options.Query == null)
            {
                throw new InvalidOperationException("Cannot create a subscription if the script is null");
            }

            database = _store.GetDatabase(database);

            var requestExecutor = _store.GetRequestExecutor(database);

            using (requestExecutor.ContextPool.AllocateOperationContext(out JsonOperationContext context))
            {
                var command = new CreateSubscriptionCommand(_store.Conventions, options);
                await requestExecutor.ExecuteAsync(command, context, sessionInfo : null, token : token).ConfigureAwait(false);

                return(command.Result.Name);
            }
        }
Exemplo n.º 11
0
        private SubscriptionCreationOptions EnsureCriteria <T>(
            SubscriptionCreationOptions criteria,
            Expression <Func <T, bool> > predicate,
            Expression <Func <T, object> > project)
        {
            criteria = criteria ?? new SubscriptionCreationOptions();
            var collectionName = _store.Conventions.GetCollectionName(typeof(T));

            if (criteria.Query == null)
            {
                var tType            = typeof(T);
                var includeRevisions = tType.IsConstructedGenericType && tType.GetGenericTypeDefinition() == typeof(Revision <>);
                if (includeRevisions)
                {
                    collectionName = _store.Conventions.GetCollectionName(tType.GenericTypeArguments[0]);
                }
                if (includeRevisions)
                {
                    criteria.Query = "from " + collectionName + " (Revisions = true)";
                }
                else
                {
                    criteria.Query = "from " + collectionName;
                }
                criteria.Query += " as doc";
            }
            if (predicate != null)
            {
                var script = predicate.CompileToJavascript(
                    new JavascriptCompilationOptions(
                        JsCompilationFlags.BodyOnly,
                        JavascriptConversionExtensions.MathSupport.Instance,
                        new JavascriptConversionExtensions.DictionarySupport(),
                        JavascriptConversionExtensions.LinqMethodsSupport.Instance,
                        new JavascriptConversionExtensions.SubscriptionsWrappedConstantSupport(_store.Conventions),
                        new JavascriptConversionExtensions.ConstSupport(_store.Conventions),
                        new JavascriptConversionExtensions.ReplaceParameterWithNewName(predicate.Parameters[0], "this"),
                        JavascriptConversionExtensions.ToStringSupport.Instance,
                        new JavascriptConversionExtensions.DateTimeSupport(),
                        JavascriptConversionExtensions.InvokeSupport.Instance,
                        JavascriptConversionExtensions.NullCoalescingSupport.Instance,
                        JavascriptConversionExtensions.NestedConditionalSupport.Instance,
                        JavascriptConversionExtensions.StringSupport.Instance
                        ));

                criteria.Query = $"declare function predicate() {{ return {script} }}{Environment.NewLine}" +
                                 $"{criteria.Query}{Environment.NewLine}" +
                                 "where predicate.call(doc)";
            }
            if (project != null)
            {
                var script = project.CompileToJavascript(
                    new JavascriptCompilationOptions(
                        JsCompilationFlags.BodyOnly,
                        JavascriptConversionExtensions.MathSupport.Instance,
                        new JavascriptConversionExtensions.DictionarySupport(),
                        JavascriptConversionExtensions.LinqMethodsSupport.Instance,
                        new JavascriptConversionExtensions.ConstSupport(_store.Conventions),
                        JavascriptConversionExtensions.ToStringSupport.Instance,
                        new JavascriptConversionExtensions.DateTimeSupport(),
                        JavascriptConversionExtensions.InvokeSupport.Instance,
                        JavascriptConversionExtensions.NullCoalescingSupport.Instance,
                        JavascriptConversionExtensions.StringSupport.Instance,
                        JavascriptConversionExtensions.NestedConditionalSupport.Instance,
                        new JavascriptConversionExtensions.ReplaceParameterWithNewName(project.Parameters[0], "doc"),
                        JavascriptConversionExtensions.CounterSupport.Instance,
                        JavascriptConversionExtensions.CompareExchangeSupport.Instance
                        ));
                criteria.Query += Environment.NewLine + "select " + script;
            }
            return(criteria);
        }
Exemplo n.º 12
0
        internal static SubscriptionCreationOptions CreateSubscriptionOptionsFromGeneric <T>(
            DocumentConventions conventions,
            SubscriptionCreationOptions criteria,
            Expression <Func <T, bool> > predicate,
            Expression <Func <T, object> > project,
            Action <ISubscriptionIncludeBuilder <T> > includes)
        {
            criteria ??= new SubscriptionCreationOptions();
            var           collectionName = conventions.GetCollectionName(typeof(T));
            StringBuilder queryBuilder;

            if (criteria.Query != null)
            {
                queryBuilder = new StringBuilder(criteria.Query);
            }
            else
            {
                queryBuilder = new StringBuilder();
                var tType            = typeof(T);
                var includeRevisions = tType.IsConstructedGenericType && tType.GetGenericTypeDefinition() == typeof(Revision <>);
                if (includeRevisions)
                {
                    collectionName = conventions.GetCollectionName(tType.GenericTypeArguments[0]);
                }

                queryBuilder.Append("from '");
                StringExtensions.EscapeString(queryBuilder, collectionName);
                queryBuilder.Append('\'');
                if (includeRevisions)
                {
                    queryBuilder.Append(" (Revisions = true)");
                }

                criteria.Query = queryBuilder.Append(" as doc").ToString();
            }

            if (predicate != null)
            {
                var script = predicate.CompileToJavascript(
                    new JavascriptCompilationOptions(
                        JsCompilationFlags.BodyOnly,
                        JavascriptConversionExtensions.MathSupport.Instance,
                        new JavascriptConversionExtensions.DictionarySupport(),
                        JavascriptConversionExtensions.LinqMethodsSupport.Instance,
                        new JavascriptConversionExtensions.SubscriptionsWrappedConstantSupport(conventions),
                        new JavascriptConversionExtensions.ConstSupport(conventions),
                        new JavascriptConversionExtensions.ReplaceParameterWithNewName(predicate.Parameters[0], "this"),
                        JavascriptConversionExtensions.ToStringSupport.Instance,
                        JavascriptConversionExtensions.DateTimeSupport.Instance,
                        JavascriptConversionExtensions.TimeSpanSupport.Instance,
                        JavascriptConversionExtensions.InvokeSupport.Instance,
                        JavascriptConversionExtensions.NullCoalescingSupport.Instance,
                        JavascriptConversionExtensions.NestedConditionalSupport.Instance,
                        JavascriptConversionExtensions.StringSupport.Instance,
                        new JavascriptConversionExtensions.IdentityPropertySupport(conventions)
                        ));

                queryBuilder
                .Insert(0, $"declare function predicate() {{ return {script} }}{Environment.NewLine}")
                .AppendLine()
                .Append("where predicate.call(doc)");
            }

            if (project != null)
            {
                var script = project.CompileToJavascript(
                    new JavascriptCompilationOptions(
                        JsCompilationFlags.BodyOnly,
                        JavascriptConversionExtensions.MathSupport.Instance,
                        new JavascriptConversionExtensions.DictionarySupport(),
                        JavascriptConversionExtensions.LinqMethodsSupport.Instance,
                        new JavascriptConversionExtensions.ConstSupport(conventions),
                        JavascriptConversionExtensions.ToStringSupport.Instance,
                        JavascriptConversionExtensions.DateTimeSupport.Instance,
                        JavascriptConversionExtensions.TimeSpanSupport.Instance,
                        JavascriptConversionExtensions.InvokeSupport.Instance,
                        JavascriptConversionExtensions.NullCoalescingSupport.Instance,
                        JavascriptConversionExtensions.StringSupport.Instance,
                        JavascriptConversionExtensions.NestedConditionalSupport.Instance,
                        new JavascriptConversionExtensions.ReplaceParameterWithNewName(project.Parameters[0], "doc"),
                        new JavascriptConversionExtensions.IdentityPropertySupport(conventions),
                        JavascriptConversionExtensions.CounterSupport.Instance,
                        JavascriptConversionExtensions.CompareExchangeSupport.Instance,
                        new JavascriptConversionExtensions.LoadSupport(),
                        JavascriptConversionExtensions.MemberInit.Instance
                        ));

                queryBuilder
                .AppendLine()
                .Append("select ")
                .Append(script);
            }

            if (includes != null)
            {
                var builder = new IncludeBuilder <T>(conventions);
                includes(builder);

                var numberOfIncludesAdded = 0;

                if (builder.DocumentsToInclude?.Count > 0)
                {
                    queryBuilder
                    .AppendLine()
                    .Append("include ");

                    foreach (var inc in builder.DocumentsToInclude)
                    {
                        var include = "doc." + inc;

                        if (numberOfIncludesAdded > 0)
                        {
                            queryBuilder.Append(",");
                        }

                        if (IncludesUtil.RequiresQuotes(include, out var escapedInclude))
                        {
                            queryBuilder
                            .Append("'")
                            .Append(escapedInclude)
                            .Append("'");
                        }
                        else
                        {
                            queryBuilder.Append(QueryToken.IsKeyword(include) ? $"'{include}'" : include);
                        }

                        numberOfIncludesAdded++;
                    }
                }

                if (builder.AllCounters)
                {
                    if (numberOfIncludesAdded == 0)
                    {
                        queryBuilder
                        .AppendLine()
                        .Append("include ");
                    }

                    var token = CounterIncludesToken.All(string.Empty);
                    token.WriteTo(queryBuilder);

                    numberOfIncludesAdded++;
                }
                else if (builder.CountersToInclude?.Count > 0)
                {
                    if (numberOfIncludesAdded == 0)
                    {
                        queryBuilder
                        .AppendLine()
                        .Append("include ");
                    }

                    foreach (var counterName in builder.CountersToInclude)
                    {
                        if (numberOfIncludesAdded > 0)
                        {
                            queryBuilder.Append(",");
                        }

                        var token = CounterIncludesToken.Create(string.Empty, counterName);
                        token.WriteTo(queryBuilder);

                        numberOfIncludesAdded++;
                    }
                }

                if (builder.TimeSeriesToInclude != null)
                {
                    foreach (var timeSeriesRange in builder.TimeSeriesToInclude)
                    {
                        if (numberOfIncludesAdded == 0)
                        {
                            queryBuilder
                            .AppendLine()
                            .Append("include ");
                        }

                        if (numberOfIncludesAdded > 0)
                        {
                            queryBuilder.Append(",");
                        }

                        var token = TimeSeriesIncludesToken.Create(string.Empty, timeSeriesRange);
                        token.WriteTo(queryBuilder);

                        numberOfIncludesAdded++;
                    }
                }
            }

            criteria.Query = queryBuilder.ToString();
            return(criteria);
        }
Exemplo n.º 13
0
 /// <summary>
 /// Creates a data subscription in a database. The subscription will expose all documents that match the specified subscription options for a given type.
 /// </summary>
 /// <typeparam name="T">Type of the collection to be processed by the subscription</typeparam>
 /// <returns>Created subscription</returns>
 public string Create <T>(Expression <Func <T, bool> > predicate = null,
                          SubscriptionCreationOptions options    = null,
                          string database = null)
 {
     return(Create(EnsureCriteria(options, predicate, null), database));
 }
Exemplo n.º 14
0
 /// <summary>
 /// Create a data subscription in a database. The subscription will expose all documents that match the specified subscription options for a given type.
 /// </summary>
 /// <param name="options"></param>
 /// <param name="database"></param>
 /// <returns>Subscription object</returns>
 public string Create(SubscriptionCreationOptions options, string database = null)
 {
     return(AsyncHelpers.RunSync(() => CreateAsync(options, database)));
 }
Exemplo n.º 15
0
 /// <summary>
 /// Creates a data subscription in a database. The subscription will expose all documents that match the specified subscription options for a given type.
 /// </summary>
 /// <typeparam name="T">Type of the collection to be processed by the subscription</typeparam>
 /// <returns>Created subscription</returns>
 public string Create <T>(Expression <Func <T, bool> > predicate = null,
                          SubscriptionCreationOptions options    = null,
                          string database = null)
 {
     return(Create(CreateSubscriptionOptionsFromGeneric(_store.Conventions, options, predicate, null, includes: null), database));
 }
Exemplo n.º 16
0
        internal static SubscriptionCreationOptions CreateSubscriptionOptionsFromGeneric <T>(
            DocumentConventions conventions,
            SubscriptionCreationOptions criteria,
            Expression <Func <T, bool> > predicate,
            Expression <Func <T, object> > project,
            Action <ISubscriptionIncludeBuilder <T> > includes)
        {
            criteria ??= new SubscriptionCreationOptions();
            var collectionName = conventions.GetCollectionName(typeof(T));

            if (criteria.Query == null)
            {
                var tType            = typeof(T);
                var includeRevisions = tType.IsConstructedGenericType && tType.GetGenericTypeDefinition() == typeof(Revision <>);
                if (includeRevisions)
                {
                    collectionName = conventions.GetCollectionName(tType.GenericTypeArguments[0]);
                }

                var builder = new StringBuilder("from '");
                StringExtensions.EscapeString(builder, collectionName);
                builder.Append('\'');
                if (includeRevisions)
                {
                    builder.Append(" (Revisions = true)");
                }

                criteria.Query = builder.Append(" as doc").ToString();
            }

            if (predicate != null)
            {
                var script = predicate.CompileToJavascript(
                    new JavascriptCompilationOptions(
                        JsCompilationFlags.BodyOnly,
                        JavascriptConversionExtensions.MathSupport.Instance,
                        new JavascriptConversionExtensions.DictionarySupport(),
                        JavascriptConversionExtensions.LinqMethodsSupport.Instance,
                        new JavascriptConversionExtensions.SubscriptionsWrappedConstantSupport(conventions),
                        new JavascriptConversionExtensions.ConstSupport(conventions),
                        new JavascriptConversionExtensions.ReplaceParameterWithNewName(predicate.Parameters[0], "this"),
                        JavascriptConversionExtensions.ToStringSupport.Instance,
                        JavascriptConversionExtensions.DateTimeSupport.Instance,
                        JavascriptConversionExtensions.InvokeSupport.Instance,
                        JavascriptConversionExtensions.NullCoalescingSupport.Instance,
                        JavascriptConversionExtensions.NestedConditionalSupport.Instance,
                        JavascriptConversionExtensions.StringSupport.Instance
                        ));

                criteria.Query = $"declare function predicate() {{ return {script} }}{Environment.NewLine}" +
                                 $"{criteria.Query}{Environment.NewLine}" +
                                 "where predicate.call(doc)";
            }

            if (project != null)
            {
                var script = project.CompileToJavascript(
                    new JavascriptCompilationOptions(
                        JsCompilationFlags.BodyOnly,
                        JavascriptConversionExtensions.MathSupport.Instance,
                        new JavascriptConversionExtensions.DictionarySupport(),
                        JavascriptConversionExtensions.LinqMethodsSupport.Instance,
                        new JavascriptConversionExtensions.ConstSupport(conventions),
                        JavascriptConversionExtensions.ToStringSupport.Instance,
                        JavascriptConversionExtensions.DateTimeSupport.Instance,
                        JavascriptConversionExtensions.InvokeSupport.Instance,
                        JavascriptConversionExtensions.NullCoalescingSupport.Instance,
                        JavascriptConversionExtensions.StringSupport.Instance,
                        JavascriptConversionExtensions.NestedConditionalSupport.Instance,
                        new JavascriptConversionExtensions.ReplaceParameterWithNewName(project.Parameters[0], "doc"),
                        JavascriptConversionExtensions.CounterSupport.Instance,
                        JavascriptConversionExtensions.CompareExchangeSupport.Instance
                        ));
                criteria.Query += Environment.NewLine + "select " + script;
            }

            if (includes != null)
            {
                var builder = new IncludeBuilder <T>(conventions);
                includes(builder);

                var numberOfIncludesAdded = 0;

                if (builder.DocumentsToInclude?.Count > 0)
                {
                    criteria.Query += Environment.NewLine + "include ";

                    foreach (var inc in builder.DocumentsToInclude)
                    {
                        var include = "doc." + inc;

                        if (numberOfIncludesAdded > 0)
                        {
                            criteria.Query += ",";
                        }

                        if (IncludesUtil.RequiresQuotes(include, out var escapedInclude))
                        {
                            criteria.Query += $"'{escapedInclude}'";
                        }
                        else
                        {
                            criteria.Query += include;
                        }

                        numberOfIncludesAdded++;
                    }
                }

                if (builder.AllCounters)
                {
                    if (numberOfIncludesAdded == 0)
                    {
                        criteria.Query += Environment.NewLine + "include ";
                    }

                    criteria.Query += $"counters()";

                    numberOfIncludesAdded++;
                }
                else if (builder.CountersToInclude?.Count > 0)
                {
                    if (numberOfIncludesAdded == 0)
                    {
                        criteria.Query += Environment.NewLine + "include ";
                    }

                    foreach (var counterName in builder.CountersToInclude)
                    {
                        if (numberOfIncludesAdded > 0)
                        {
                            criteria.Query += ",";
                        }

                        if (IncludesUtil.RequiresQuotes(counterName, out var escapedCounterName))
                        {
                            criteria.Query += $"counters({escapedCounterName})";
                        }
                        else
                        {
                            criteria.Query += $"counters({counterName})";
                        }

                        numberOfIncludesAdded++;
                    }
                }
            }

            return(criteria);
        }
Exemplo n.º 17
0
        private SubscriptionCreationOptions EnsureCriteria <T>(
            SubscriptionCreationOptions criteria,
            Expression <Func <T, bool> > predicate,
            Expression <Func <T, object> > project,
            Action <ISubscriptionIncludeBuilder <T> > includes)
        {
            criteria = criteria ?? new SubscriptionCreationOptions();
            var collectionName = _store.Conventions.GetCollectionName(typeof(T));

            if (criteria.Query == null)
            {
                var tType            = typeof(T);
                var includeRevisions = tType.IsConstructedGenericType && tType.GetGenericTypeDefinition() == typeof(Revision <>);
                if (includeRevisions)
                {
                    collectionName = _store.Conventions.GetCollectionName(tType.GenericTypeArguments[0]);
                }
                if (includeRevisions)
                {
                    criteria.Query = "from " + collectionName + " (Revisions = true)";
                }
                else
                {
                    criteria.Query = "from " + collectionName;
                }
                criteria.Query += " as doc";
            }

            if (predicate != null)
            {
                var script = predicate.CompileToJavascript(
                    new JavascriptCompilationOptions(
                        JsCompilationFlags.BodyOnly,
                        JavascriptConversionExtensions.MathSupport.Instance,
                        new JavascriptConversionExtensions.DictionarySupport(),
                        JavascriptConversionExtensions.LinqMethodsSupport.Instance,
                        new JavascriptConversionExtensions.SubscriptionsWrappedConstantSupport(_store.Conventions),
                        new JavascriptConversionExtensions.ConstSupport(_store.Conventions),
                        new JavascriptConversionExtensions.ReplaceParameterWithNewName(predicate.Parameters[0], "this"),
                        JavascriptConversionExtensions.ToStringSupport.Instance,
                        JavascriptConversionExtensions.DateTimeSupport.Instance,
                        JavascriptConversionExtensions.InvokeSupport.Instance,
                        JavascriptConversionExtensions.NullCoalescingSupport.Instance,
                        JavascriptConversionExtensions.NestedConditionalSupport.Instance,
                        JavascriptConversionExtensions.StringSupport.Instance
                        ));

                criteria.Query = $"declare function predicate() {{ return {script} }}{Environment.NewLine}" +
                                 $"{criteria.Query}{Environment.NewLine}" +
                                 "where predicate.call(doc)";
            }

            if (project != null)
            {
                var script = project.CompileToJavascript(
                    new JavascriptCompilationOptions(
                        JsCompilationFlags.BodyOnly,
                        JavascriptConversionExtensions.MathSupport.Instance,
                        new JavascriptConversionExtensions.DictionarySupport(),
                        JavascriptConversionExtensions.LinqMethodsSupport.Instance,
                        new JavascriptConversionExtensions.ConstSupport(_store.Conventions),
                        JavascriptConversionExtensions.ToStringSupport.Instance,
                        JavascriptConversionExtensions.DateTimeSupport.Instance,
                        JavascriptConversionExtensions.InvokeSupport.Instance,
                        JavascriptConversionExtensions.NullCoalescingSupport.Instance,
                        JavascriptConversionExtensions.StringSupport.Instance,
                        JavascriptConversionExtensions.NestedConditionalSupport.Instance,
                        new JavascriptConversionExtensions.ReplaceParameterWithNewName(project.Parameters[0], "doc"),
                        JavascriptConversionExtensions.CounterSupport.Instance,
                        JavascriptConversionExtensions.CompareExchangeSupport.Instance
                        ));
                criteria.Query += Environment.NewLine + "select " + script;
            }

            if (includes != null)
            {
                var builder = new IncludeBuilder <T>(_store.Conventions);
                includes(builder);

                if (builder.DocumentsToInclude != null && builder.DocumentsToInclude.Count > 0)
                {
                    criteria.Query += Environment.NewLine + "include ";

                    var first = true;
                    foreach (var inc in builder.DocumentsToInclude)
                    {
                        var include = "doc." + inc;
                        if (first == false)
                        {
                            criteria.Query += ",";
                        }
                        first = false;

                        if (IncludesUtil.RequiresQuotes(include, out var escapedInclude))
                        {
                            criteria.Query += $"'{escapedInclude}'";
                        }
                        else
                        {
                            criteria.Query += include;
                        }
                    }
                }
            }

            return(criteria);
        }