public void Constructor_should_create_a_valid_instance()
        {
            var subject = new AggregateToCollectionOperation(_collectionNamespace, _pipeline, _messageEncoderSettings);

            subject.CollectionNamespace.Should().Be(_collectionNamespace);
            subject.Pipeline.Should().HaveCount(2);
            subject.MessageEncoderSettings.Should().BeEquivalentTo(_messageEncoderSettings);
        }
Esempio n. 2
0
        // methods
        public override async Task <IAsyncCursor <TResult> > AggregateAsync <TResult>(PipelineDefinition <TDocument, TResult> pipeline, AggregateOptions options, CancellationToken cancellationToken)
        {
            var renderedPipeline = Ensure.IsNotNull(pipeline, nameof(pipeline)).Render(_documentSerializer, _settings.SerializerRegistry);

            options = options ?? new AggregateOptions();

            var last = renderedPipeline.Documents.LastOrDefault();

            if (last != null && last.GetElement(0).Name == "$out")
            {
                var operation = new AggregateToCollectionOperation(
                    _collectionNamespace,
                    renderedPipeline.Documents,
                    _messageEncoderSettings)
                {
                    AllowDiskUse             = options.AllowDiskUse,
                    BypassDocumentValidation = options.BypassDocumentValidation,
                    MaxTime = options.MaxTime
                };

                await ExecuteWriteOperationAsync(operation, cancellationToken).ConfigureAwait(false);

                var outputCollectionName = last.GetElement(0).Value.AsString;

                var findOperation = new FindOperation <TResult>(
                    new CollectionNamespace(_collectionNamespace.DatabaseNamespace, outputCollectionName),
                    renderedPipeline.OutputSerializer,
                    _messageEncoderSettings)
                {
                    BatchSize = options.BatchSize,
                    MaxTime   = options.MaxTime
                };

                // we want to delay execution of the find because the user may
                // not want to iterate the results at all...
                var deferredCursor = new DeferredAsyncCursor <TResult>(
                    ct => ExecuteReadOperation(findOperation, ReadPreference.Primary, ct),
                    ct => ExecuteReadOperationAsync(findOperation, ReadPreference.Primary, ct));
                return(await Task.FromResult <IAsyncCursor <TResult> >(deferredCursor).ConfigureAwait(false));
            }
            else
            {
                var aggregateOperation = new AggregateOperation <TResult>(
                    _collectionNamespace,
                    renderedPipeline.Documents,
                    renderedPipeline.OutputSerializer,
                    _messageEncoderSettings)
                {
                    AllowDiskUse = options.AllowDiskUse,
                    BatchSize    = options.BatchSize,
                    MaxTime      = options.MaxTime,
                    ReadConcern  = _settings.ReadConcern,
                    UseCursor    = options.UseCursor
                };
                return(await ExecuteReadOperationAsync(aggregateOperation, cancellationToken).ConfigureAwait(false));
            }
        }
        public void AllowDiskUse_should_have_the_correct_value()
        {
            var subject = new AggregateToCollectionOperation(_collectionNamespace, _pipeline, _messageEncoderSettings);

            subject.AllowDiskUse.Should().Be(null);

            subject.AllowDiskUse = true;

            subject.AllowDiskUse.Should().Be(true);
        }
        public void BypassDocumentValidation_should_have_the_correct_value()
        {
            var subject = new AggregateToCollectionOperation(_collectionNamespace, _pipeline, _messageEncoderSettings);

            subject.BypassDocumentValidation.Should().Be(null);

            subject.BypassDocumentValidation = true;

            subject.BypassDocumentValidation.Should().Be(true);
        }
        public void Constructor_should_create_a_valid_instance()
        {
            var subject = new AggregateToCollectionOperation(_collectionNamespace, __pipeline, _messageEncoderSettings);

            subject.CollectionNamespace.Should().BeSameAs(_collectionNamespace);
            subject.Pipeline.Should().Equal(__pipeline);
            subject.MessageEncoderSettings.Should().BeSameAs(_messageEncoderSettings);

            subject.AllowDiskUse.Should().NotHaveValue();
            subject.BypassDocumentValidation.Should().NotHaveValue();
            subject.Collation.Should().BeNull();
            subject.MaxTime.Should().NotHaveValue();
            subject.WriteConcern.Should().BeNull();
        }
Esempio n. 6
0
        // methods
        public async Task <IAsyncEnumerable <TResult> > AggregateAsync <TResult>(AggregateModel <TResult> model, TimeSpan?timeout, CancellationToken cancellationToken)
        {
            Ensure.IsNotNull(model, "model");

            var pipeline = model.Pipeline.Select(x => ConvertToBsonDocument(x)).ToList();

            var last = pipeline.LastOrDefault();

            if (last != null && last.GetElement(0).Name == "$out")
            {
                var operation = new AggregateToCollectionOperation(
                    _collectionNamespace,
                    pipeline,
                    _messageEncoderSettings)
                {
                    AllowDiskUse = model.AllowDiskUse,
                    MaxTime      = model.MaxTime
                };

                await ExecuteWriteOperation(operation, timeout, cancellationToken);

                var outputCollectionName = last.GetElement(0).Value.AsString;
                var findOperation        = new FindOperation <TResult>(
                    new CollectionNamespace(_collectionNamespace.DatabaseNamespace, outputCollectionName),
                    model.ResultSerializer ?? _settings.SerializerRegistry.GetSerializer <TResult>(),
                    _messageEncoderSettings)
                {
                    BatchSize = model.BatchSize,
                    MaxTime   = model.MaxTime
                };

                return(await Task.FromResult <IAsyncEnumerable <TResult> >(new AsyncCursorAsyncEnumerable <TResult>(
                                                                               () => ExecuteReadOperation(findOperation, timeout, cancellationToken),
                                                                               null)));
            }
            else
            {
                var operation = CreateAggregateOperation <TResult>(model, pipeline);

                return(await Task.FromResult <IAsyncEnumerable <TResult> >(new AsyncCursorAsyncEnumerable <TResult>(
                                                                               () => ExecuteReadOperation(operation, timeout, cancellationToken),
                                                                               null)));
            }
        }
Esempio n. 7
0
        public async Task <IAsyncCursor <TResult> > AggregateAsync <TResult>(IEnumerable <object> pipeline, AggregateOptions <TResult> options, CancellationToken cancellationToken)
        {
            Ensure.IsNotNull(pipeline, "pipeline");

            options = options ?? new AggregateOptions <TResult>();
            var pipelineDocuments = pipeline.Select(x => ConvertToBsonDocument(x)).ToList();

            var last = pipelineDocuments.LastOrDefault();

            if (last != null && last.GetElement(0).Name == "$out")
            {
                var operation = new AggregateToCollectionOperation(
                    _collectionNamespace,
                    pipelineDocuments,
                    _messageEncoderSettings)
                {
                    AllowDiskUse = options.AllowDiskUse,
                    MaxTime      = options.MaxTime
                };

                await ExecuteWriteOperation(operation, cancellationToken).ConfigureAwait(false);

                var outputCollectionName = last.GetElement(0).Value.AsString;
                var resultSerializer     = ResolveResultSerializer(options.ResultSerializer);

                var findOperation = new FindOperation <TResult>(
                    new CollectionNamespace(_collectionNamespace.DatabaseNamespace, outputCollectionName),
                    resultSerializer,
                    _messageEncoderSettings)
                {
                    BatchSize = options.BatchSize,
                    MaxTime   = options.MaxTime
                };

                // we want to delay execution of the find because the user may
                // not want to iterate the results at all...
                return(await Task.FromResult <IAsyncCursor <TResult> >(new DeferredAsyncCursor <TResult>(ct => ExecuteReadOperation(findOperation, ReadPreference.Primary, ct))).ConfigureAwait(false));
            }
            else
            {
                var operation = CreateAggregateOperation <TResult>(options, pipelineDocuments);
                return(await ExecuteReadOperation(operation, cancellationToken).ConfigureAwait(false));
            }
        }
Esempio n. 8
0
        protected override void Given()
        {
            Require.MinimumServerVersion("2.6.0");

            _subject = new AggregateToCollectionOperation(
                CollectionNamespace,
                new[]
            {
                BsonDocument.Parse("{$match: {x: { $gt: 3}}}"),
                BsonDocument.Parse("{$out: \"awesome\"}")
            },
                MessageEncoderSettings);

            Insert(new[]
            {
                BsonDocument.Parse("{_id: 1, x: 1}"),
                BsonDocument.Parse("{_id: 2, x: 2}"),
                BsonDocument.Parse("{_id: 3, x: 3}"),
                BsonDocument.Parse("{_id: 4, x: 4}"),
                BsonDocument.Parse("{_id: 5, x: 5}"),
                BsonDocument.Parse("{_id: 6, x: 6}"),
            });
        }
        public async Task Executing_with_matching_documents_using_all_options()
        {
            var subject = new AggregateToCollectionOperation(_collectionNamespace, _pipeline, _messageEncoderSettings)
            {
                AllowDiskUse = true,
                MaxTime = TimeSpan.FromSeconds(20)
            };

            await ExecuteOperationAsync(subject);

            var result = await ReadAllFromCollectionAsync(new CollectionNamespace(_databaseNamespace, "awesome"));

            result.Should().NotBeNull();
            result.Should().HaveCount(2);
        }
        public void CreateCommand_should_create_the_correct_command(
            [Values(null, false, true)] bool? allowDiskUse,
            [Values(null, false, true)] bool? bypassDocumentValidation,
            [Values(null, 2000)] int? maxTime,
            [Values("3.0.0", "3.1.3")] string serverVersionString)
        {
            var subject = new AggregateToCollectionOperation(_collectionNamespace, _pipeline, _messageEncoderSettings)
            {
                AllowDiskUse = allowDiskUse,
                BypassDocumentValidation = bypassDocumentValidation,
                MaxTime = maxTime.HasValue ? TimeSpan.FromMilliseconds(maxTime.Value) : (TimeSpan?)null,
            };
            var serverVersion = SemanticVersion.Parse(serverVersionString);

            var expectedResult = new BsonDocument
            {
                { "aggregate", _collectionNamespace.CollectionName },
                { "pipeline", new BsonArray(subject.Pipeline) },
                { "allowDiskUse", () => allowDiskUse.Value, allowDiskUse.HasValue },
                { "bypassDocumentValidation", () => bypassDocumentValidation.Value, bypassDocumentValidation.HasValue && SupportedFeatures.IsBypassDocumentValidationSupported(serverVersion) },
                { "maxTimeMS", () => maxTime.Value, maxTime.HasValue }
            };

            var result = subject.CreateCommand(serverVersion);

            result.Should().Be(expectedResult);
        }
        public void CreateCommand_should_return_expected_result()
        {
            var subject = new AggregateToCollectionOperation(_collectionNamespace, __pipeline, _messageEncoderSettings);

            var result = subject.CreateCommand(null);

            var expectedResult = new BsonDocument
            {
                { "aggregate", _collectionNamespace.CollectionName },
                { "pipeline", new BsonArray(__pipeline) }
            };
            result.Should().Be(expectedResult);
        }
        public void Execute_should_throw_when_a_write_concern_error_occurs(
            [Values(false, true)]
            bool async)
        {
            RequireServer.Check().Supports(Feature.AggregateOut, Feature.CommandsThatWriteAcceptWriteConcern).ClusterType(ClusterType.ReplicaSet);
            EnsureTestData();
            var subject = new AggregateToCollectionOperation(_collectionNamespace, __pipeline, _messageEncoderSettings)
            {
                WriteConcern = new WriteConcern(9)
            };

            var exception = Record.Exception(() => ExecuteOperation(subject, async));

            exception.Should().BeOfType<MongoWriteConcernException>();
        }
        public void AllowDiskUse_get_and_set_should_work(
            [Values(null, false, true)]
            bool? value)
        {
            var subject = new AggregateToCollectionOperation(_collectionNamespace, __pipeline, _messageEncoderSettings);

            subject.AllowDiskUse = value;
            var result = subject.AllowDiskUse;

            result.Should().Be(value);
        }
        public void CreateCommand_should_return_expected_result_when_BypassDocumentValidation_is_set(
            [Values(null, false, true)]
            bool? bypassDocumentValidation,
            [Values(false, true)]
            bool useServerVersionSupportingBypassDocumentValidation)
        {
            var subject = new AggregateToCollectionOperation(_collectionNamespace, __pipeline, _messageEncoderSettings)
            {
                BypassDocumentValidation = bypassDocumentValidation
            };
            var serverVersion = Feature.BypassDocumentValidation.SupportedOrNotSupportedVersion(useServerVersionSupportingBypassDocumentValidation);

            var result = subject.CreateCommand(serverVersion);

            var expectedResult = new BsonDocument
            {
                { "aggregate", _collectionNamespace.CollectionName },
                { "pipeline", new BsonArray(__pipeline) },
                { "bypassDocumentValidation", () => bypassDocumentValidation.Value, bypassDocumentValidation != null && Feature.BypassDocumentValidation.IsSupported(serverVersion) }
            };
            result.Should().Be(expectedResult);
        }
        public void Execute_should_return_expected_result_when_MaxTime_is_set(
            [Values(null, 1000)]
            int? milliseconds,
            [Values(false, true)]
            bool async)
        {
            RequireServer.Check().Supports(Feature.AggregateOut);
            EnsureTestData();
            var maxTime = milliseconds == null ? (TimeSpan?)null : TimeSpan.FromMilliseconds(milliseconds.Value);
            var subject = new AggregateToCollectionOperation(_collectionNamespace, __pipeline, _messageEncoderSettings)
            {
                MaxTime = maxTime
            };

            ExecuteOperation(subject, async);
            var result = ReadAllFromCollection(new CollectionNamespace(_databaseNamespace, "awesome"), async);

            result.Should().NotBeNull();
            result.Should().HaveCount(1);
        }
        public void Collation_get_and_set_should_work(
            [Values(null, "en_US")]
            string locale)
        {
            var subject = new AggregateToCollectionOperation(_collectionNamespace, __pipeline, _messageEncoderSettings);
            var value = locale == null ? null : new Collation(locale);

            subject.Collation = value;
            var result = subject.Collation;

            result.Should().BeSameAs(value);
        }
        public void MaxTime_should_have_the_correct_value()
        {
            var subject = new AggregateToCollectionOperation(_collectionNamespace, _pipeline, _messageEncoderSettings);

            subject.MaxTime.Should().Be(null);

            subject.MaxTime = TimeSpan.FromSeconds(2);

            subject.MaxTime.Should().Be(TimeSpan.FromSeconds(2));
        }
        public void CreateCommand_should_return_expected_result_when_WriteConcern_is_set(
            [Values(null, 1, 2)]
            int? w,
            [Values(false, true)]
            bool isWriteConcernSupported)
        {
            var writeConcern = w.HasValue ? new WriteConcern(w.Value) : null;
            var subject = new AggregateToCollectionOperation(_collectionNamespace, __pipeline, _messageEncoderSettings)
            {
                WriteConcern = writeConcern
            };
            var serverVersion = Feature.CommandsThatWriteAcceptWriteConcern.SupportedOrNotSupportedVersion(isWriteConcernSupported);

            var result = subject.CreateCommand(serverVersion);

            var expectedResult = new BsonDocument
            {
                { "aggregate", _collectionNamespace.CollectionName },
                { "pipeline", new BsonArray(__pipeline) },
                { "writeConcern", () => writeConcern.ToBsonDocument(), writeConcern != null && isWriteConcernSupported }
            };
            result.Should().Be(expectedResult);
        }
        public void Execute_should_return_expected_result_when_BypassDocumentValidation_is_set(
            [Values(null, false, true)]
            bool? bypassDocumentValidation,
            [Values(false, true)]
            bool async)
        {
            RequireServer.Check().Supports(Feature.AggregateOut);
            EnsureTestData();
            var subject = new AggregateToCollectionOperation(_collectionNamespace, __pipeline, _messageEncoderSettings)
            {
                BypassDocumentValidation = bypassDocumentValidation
            };

            ExecuteOperation(subject, async);
            var result = ReadAllFromCollection(new CollectionNamespace(_databaseNamespace, "awesome"), async);

            result.Should().NotBeNull();
            result.Should().HaveCount(1);
        }
        public void CreateCommand_should_return_expected_result_when_MaxTime_is_set(
            [Values(null, 1, 2)]
            int? milliseconds)
        {
            var maxTime = milliseconds == null ? (TimeSpan?)null : TimeSpan.FromMilliseconds(milliseconds.Value);
            var subject = new AggregateToCollectionOperation(_collectionNamespace, __pipeline, _messageEncoderSettings)
            {
                MaxTime = maxTime
            };

            var result = subject.CreateCommand(null);

            var expectedResult = new BsonDocument
            {
                { "aggregate", _collectionNamespace.CollectionName },
                { "pipeline", new BsonArray(__pipeline) },
                { "maxTimeMS", () => milliseconds.Value, milliseconds != null }
            };
            result.Should().Be(expectedResult);
        }
        public void CreateCommand_should_throw_when_Collation_is_set_but_not_supported()
        {
            var subject = new AggregateToCollectionOperation(_collectionNamespace, __pipeline, _messageEncoderSettings)
            {
                Collation = new Collation("en_US")
            };

            var exception = Record.Exception(() => subject.CreateCommand(Feature.Collation.LastNotSupportedVersion));

            exception.Should().BeOfType<NotSupportedException>();
        }
        public void CreateCommand_should_return_expected_result_when_Collation_is_set(
            [Values(null, "en_US")]
            string locale)
        {
            var collation = locale == null ? null : new Collation(locale);
            var subject = new AggregateToCollectionOperation(_collectionNamespace, __pipeline, _messageEncoderSettings)
            {
                Collation = collation
            };

            var result = subject.CreateCommand(Feature.Collation.FirstSupportedVersion);

            var expectedResult = new BsonDocument
            {
                { "aggregate", _collectionNamespace.CollectionName },
                { "pipeline", new BsonArray(__pipeline) },
                { "collation", () => collation.ToBsonDocument(), collation != null }
            };
            result.Should().Be(expectedResult);
        }
        public void CreateCommand_should_create_the_correct_command(
            [Values(null, false, true)] bool? allowDiskUse,
            [Values(null, 2000)] int? maxTime)
        {
            var subject = new AggregateToCollectionOperation(_collectionNamespace, _pipeline, _messageEncoderSettings)
            {
                AllowDiskUse = allowDiskUse,
                MaxTime = maxTime.HasValue ? TimeSpan.FromMilliseconds(maxTime.Value) : (TimeSpan?)null,
            };

            var expectedResult = new BsonDocument
            {
                { "aggregate", _collectionNamespace.CollectionName },
                { "pipeline", new BsonArray(subject.Pipeline) },
                { "allowDiskUse", () => allowDiskUse.Value, allowDiskUse.HasValue },
                { "maxTimeMS", () => maxTime.Value, maxTime.HasValue }
            };

            var result = subject.CreateCommand();

            result.Should().Be(expectedResult);
        }
        public void WriteConcern_get_and_set_should_work(
            [Values(1, 2)]
            int w)
        {
            var subject = new AggregateToCollectionOperation(_collectionNamespace, __pipeline, _messageEncoderSettings);
            var value = new WriteConcern(w);

            subject.WriteConcern = value;
            var result = subject.WriteConcern;

            result.Should().BeSameAs(value);
        }
        public void Executing_with_matching_documents_using_all_options(
            [Values(false, true)]
            bool async)
        {
            var subject = new AggregateToCollectionOperation(_collectionNamespace, _pipeline, _messageEncoderSettings)
            {
                AllowDiskUse = true,
                MaxTime = TimeSpan.FromSeconds(20)
            };

            ExecuteOperation(subject, async);

            var result = ReadAllFromCollection(new CollectionNamespace(_databaseNamespace, "awesome"), async);

            result.Should().NotBeNull();
            result.Should().HaveCount(2);
        }
        public void CreateCommand_should_return_expected_result_when_AllowDiskUse_is_set(
            [Values(null, false, true)]
            bool? allowDiskUse)
        {
            var subject = new AggregateToCollectionOperation(_collectionNamespace, __pipeline, _messageEncoderSettings)
            {
                AllowDiskUse = allowDiskUse
            };

            var result = subject.CreateCommand(null);

            var expectedResult = new BsonDocument
            {
                { "aggregate", _collectionNamespace.CollectionName },
                { "pipeline", new BsonArray(__pipeline) },
                { "allowDiskUse", () => allowDiskUse.Value, allowDiskUse != null }
            };
            result.Should().Be(expectedResult);
        }
        public void BypassDocumentValidation_get_and_set_should_work(
            [Values(null, false, true)]
            bool? value)
        {
            var subject = new AggregateToCollectionOperation(_collectionNamespace, __pipeline, _messageEncoderSettings);

            subject.BypassDocumentValidation = value;
            var result = subject.BypassDocumentValidation;

            result.Should().Be(value);
        }
        public void Execute_should_return_expected_result_when_Collation_is_set(
            [Values(false, true)]
            bool caseSensitive,
            [Values(false, true)]
            bool async)
        {
            RequireServer.Check().Supports(Feature.AggregateOut, Feature.Collation);
            EnsureTestData();
            var pipeline = new[]
            {
                BsonDocument.Parse("{ $match : { x : \"x\" } }"),
                BsonDocument.Parse("{ $out : \"awesome\" }")
            };
            var collation = new Collation("en_US", caseLevel: caseSensitive, strength: CollationStrength.Primary);
            var subject = new AggregateToCollectionOperation(_collectionNamespace, pipeline, _messageEncoderSettings)
            {
                Collation = collation
            };

            ExecuteOperation(subject, async);
            var result = ReadAllFromCollection(new CollectionNamespace(_databaseNamespace, "awesome"), async);

            result.Should().NotBeNull();
            result.Should().HaveCount(caseSensitive ? 1 : 2);
        }
        public void Execute_should_throw_when_Collation_is_set(
            [Values(false, true)]
            bool async)
        {
            RequireServer.Check().Supports(Feature.AggregateOut).DoesNotSupport(Feature.Collation);
            var subject = new AggregateToCollectionOperation(_collectionNamespace, __pipeline, _messageEncoderSettings)
            {
                Collation = new Collation("en_US")
            };

            var exception = Record.Exception(() => ExecuteOperation(subject, async));

            exception.Should().BeOfType<NotSupportedException>();
        }
        public void MaxTime_get_and_set_should_work(
            [Values(null, 1L)]
            long? milliseconds)
        {
            var subject = new AggregateToCollectionOperation(_collectionNamespace, __pipeline, _messageEncoderSettings);
            var value = milliseconds == null ? (TimeSpan?)null : TimeSpan.FromMilliseconds(milliseconds.Value);

            subject.MaxTime = value;
            var result = subject.MaxTime;

            result.Should().Be(value);
        }