/// <summary>Snippet for BatchGetDocuments</summary>
        public async Task BatchGetDocuments()
        {
            // Snippet: BatchGetDocuments(BatchGetDocumentsRequest,CallSettings)
            // Create client
            FirestoreClient firestoreClient = FirestoreClient.Create();
            // Initialize request argument
            BatchGetDocumentsRequest request = new BatchGetDocumentsRequest
            {
                Database  = new DatabaseRootName("[PROJECT]", "[DATABASE]").ToString(),
                Documents = { },
            };

            // Make the request, returning a streaming response
            FirestoreClient.BatchGetDocumentsStream streamingResponse = firestoreClient.BatchGetDocuments(request);

            // Read streaming responses from server until complete
            IAsyncEnumerator <BatchGetDocumentsResponse> responseStream = streamingResponse.ResponseStream;

            while (await responseStream.MoveNext())
            {
                BatchGetDocumentsResponse response = responseStream.Current;
                // Do something with streamed response
            }
            // The response stream has completed
            // End snippet
        }
Ejemplo n.º 2
0
        public async Task GetDocumentSnapshotsAsync_WithFieldMask()
        {
            string docName = "projects/proj/databases/db/documents/col1/doc1";
            var    mock    = new Mock <FirestoreClient> {
                CallBase = true
            };
            var request = new BatchGetDocumentsRequest
            {
                Database  = "projects/proj/databases/db",
                Documents = { docName },
                Mask      = new DocumentMask {
                    FieldPaths = { "a", "b" }
                }
            };
            var responses = new[]
            {
                new BatchGetDocumentsResponse {
                    Missing = docName, ReadTime = CreateProtoTimestamp(1, 2)
                },
            };

            mock.Setup(c => c.BatchGetDocuments(request, It.IsAny <CallSettings>())).Returns(new FakeDocumentStream(responses));
            var db        = FirestoreDb.Create("proj", "db", mock.Object);
            var fieldMask = new FieldMask("a", "b");
            var results   = await db.GetDocumentSnapshotsAsync(new[] { db.Document("col1/doc1") }, transactionId : null, fieldMask, default);

            mock.VerifyAll();
        }
Ejemplo n.º 3
0
        public async Task GetDocumentSnapshotsAsync_Retry()
        {
            string docName = "projects/proj/databases/db/documents/col1/doc1";
            var    mock    = CreateMockClient();

            mock.Object.Settings.Clock     = new FakeClock();
            mock.Object.Settings.Scheduler = new NoOpScheduler();

            var request = new BatchGetDocumentsRequest
            {
                Database  = "projects/proj/databases/db",
                Documents = { docName }
            };

            var responses = new[]
            {
                new BatchGetDocumentsResponse {
                    Missing = docName, ReadTime = CreateProtoTimestamp(1, 2)
                },
            };
            var errorResponses = responses.Where(r => throw new RpcException(new Status(StatusCode.Unavailable, "Bang")));

            mock.SetupSequence(c => c.BatchGetDocuments(request, It.IsAny <CallSettings>()))
            .Returns(new FakeDocumentStream(errorResponses))
            .Returns(new FakeDocumentStream(errorResponses))
            .Returns(new FakeDocumentStream(responses));
            var db      = FirestoreDb.Create("proj", "db", mock.Object);
            var docRef  = db.Document("col1/doc1");
            var results = await db.GetDocumentSnapshotsAsync(new[] { docRef }, transactionId : null, fieldMask : null, default);

            Assert.Equal(1, results.Count);
        }
Ejemplo n.º 4
0
        public async Task GetAllSnapshotsAsync_ServerError()
        {
            string docName1 = "projects/proj/databases/db/documents/col1/doc1";
            string docName2 = "projects/proj/databases/db/documents/col2/doc2";
            var    mock     = CreateMockClient();
            var    request  = new BatchGetDocumentsRequest
            {
                Database  = "projects/proj/databases/db",
                Documents = { docName1, docName2 }
            };
            // The server only returns information about docName1, not docName2
            var responses = new[]
            {
                new BatchGetDocumentsResponse {
                    Missing = docName1, ReadTime = CreateProtoTimestamp(1, 2)
                },
            };

            mock.Setup(c => c.BatchGetDocuments(request, It.IsAny <CallSettings>())).Returns(new FakeDocumentStream(responses));
            var db      = FirestoreDb.Create("proj", "db", mock.Object);
            var docRef1 = db.Document("col1/doc1");
            var docRef2 = db.Document("col2/doc2");

            await Assert.ThrowsAsync <InvalidOperationException>(async() => await db.GetAllSnapshotsAsync(new[] { docRef1, docRef2 }));
        }
        public async Task GetDocumentSnapshotsAsync_WithTransaction()
        {
            // This test is about checking the transaction is copied...
            var    transactionId = ByteString.CopyFrom(1, 2, 3, 4);
            string docName       = "projects/proj/databases/db/documents/col1/doc1";
            var    mock          = new Mock <FirestoreClient> {
                CallBase = true
            };
            var request = new BatchGetDocumentsRequest
            {
                Database    = "projects/proj/databases/db",
                Documents   = { docName },
                Transaction = transactionId
            };
            var responses = new[]
            {
                new BatchGetDocumentsResponse {
                    Missing = docName, ReadTime = CreateProtoTimestamp(1, 2)
                },
            };

            mock.Setup(c => c.BatchGetDocuments(request, It.IsAny <CallSettings>())).Returns(new FakeDocumentStream(responses));
            var db      = FirestoreDb.Create("proj", "db", mock.Object);
            var results = await db.GetDocumentSnapshotsAsync(new[] { db.Document("col1/doc1") }, transactionId, default);

            mock.VerifyAll();
        }
Ejemplo n.º 6
0
        /// <summary>Snippet for BatchGetDocuments</summary>
        public async Task BatchGetDocumentsRequestObject()
        {
            // Snippet: BatchGetDocuments(BatchGetDocumentsRequest, CallSettings)
            // Create client
            FirestoreClient firestoreClient = FirestoreClient.Create();
            // Initialize request argument(s)
            BatchGetDocumentsRequest request = new BatchGetDocumentsRequest
            {
                Database    = "",
                Documents   = { "", },
                Mask        = new DocumentMask(),
                Transaction = ByteString.Empty,
            };

            // Make the request, returning a streaming response
            FirestoreClient.BatchGetDocumentsStream response = firestoreClient.BatchGetDocuments(request);

            // Read streaming responses from server until complete
            // Note that C# 8 code can use await foreach
            AsyncResponseStream <BatchGetDocumentsResponse> responseStream = response.GetResponseStream();

            while (await responseStream.MoveNextAsync())
            {
                BatchGetDocumentsResponse responseItem = responseStream.Current;
                // Do something with streamed response
            }
            // The response stream has completed
            // End snippet
        }
        public async Task SnapshotAllAsync()
        {
            string docName1 = "projects/proj/databases/db/documents/col1/doc1";
            string docName2 = "projects/proj/databases/db/documents/col2/doc2";
            var    mock     = new Mock <FirestoreClient> {
                CallBase = true
            };
            var request = new BatchGetDocumentsRequest
            {
                Database = "projects/proj/databases/db",
                // Note that we request docName2 twice, as per the caller's request:
                // the library doesn't perform any elision.
                Documents = { docName1, docName2, docName2 }
            };
            var responses = new[]
            {
                // Deliberately not in the requested order
                new BatchGetDocumentsResponse
                {
                    Found = new Document
                    {
                        Name   = docName2, CreateTime = CreateProtoTimestamp(0, 1), UpdateTime = CreateProtoTimestamp(0, 2),
                        Fields = { { "Name", CreateValue("Test") } }
                    },
                    ReadTime = CreateProtoTimestamp(1, 3)
                },
                new BatchGetDocumentsResponse {
                    Missing = docName1, ReadTime = CreateProtoTimestamp(1, 2)
                },
            };

            mock.Setup(c => c.BatchGetDocuments(request, It.IsAny <CallSettings>())).Returns(new FakeDocumentStream(responses));
            var db      = FirestoreDb.Create("proj", "db", mock.Object);
            var docRef1 = db.Document("col1/doc1");
            var docRef2 = db.Document("col2/doc2");
            var results = await db.SnapshotAllAsync(new[] { docRef1, docRef2, docRef2 });

            Assert.Equal(3, results.Count);
            // Note that this is the first result from the request, not the first from the response -
            // the method returns them in request order, not response order.
            var snapshot1 = results[0];

            Assert.False(snapshot1.Exists);
            Assert.Equal(new Timestamp(1, 2), snapshot1.ReadTime);
            Assert.Equal(docRef1, snapshot1.Reference);

            var snapshot2 = results[1];

            Assert.True(snapshot2.Exists);
            Assert.Equal(new Timestamp(0, 1), snapshot2.CreateTime);
            Assert.Equal(new Timestamp(0, 2), snapshot2.UpdateTime);
            Assert.Equal(new Timestamp(1, 3), snapshot2.ReadTime);
            Assert.Equal(docRef2, snapshot2.Reference);
            Assert.Equal("Test", snapshot2.GetField <string>("Name"));

            // The third result element is just a reference to the same snapshot.
            Assert.Same(results[1], results[2]);
            mock.VerifyAll();
        }
        public async Task GetDocumentSnapshotsAsync()
        {
            string docName1 = "projects/proj/databases/db/documents/col1/doc1";
            string docName2 = "projects/proj/databases/db/documents/col2/doc2";
            var    mock     = new Mock <FirestoreClient> {
                CallBase = true
            };
            var request = new BatchGetDocumentsRequest
            {
                Database  = "projects/proj/databases/db",
                Documents = { docName1, docName2 }
            };
            var responses = new[]
            {
                // Deliberately not in the requested order
                new BatchGetDocumentsResponse
                {
                    Found = new Document
                    {
                        Name   = docName2, CreateTime = CreateProtoTimestamp(0, 1), UpdateTime = CreateProtoTimestamp(0, 2),
                        Fields = { { "Name", CreateValue("Test") } }
                    },
                    ReadTime = CreateProtoTimestamp(1, 3)
                },
                new BatchGetDocumentsResponse {
                    Missing = docName1, ReadTime = CreateProtoTimestamp(1, 2)
                },
            };

            mock.Setup(c => c.BatchGetDocuments(request, It.IsAny <CallSettings>())).Returns(new FakeDocumentStream(responses));
            var db      = FirestoreDb.Create("proj", "db", mock.Object);
            var docRef1 = db.Document("col1/doc1");
            var docRef2 = db.Document("col2/doc2");
            var results = await db.GetDocumentSnapshotsAsync(new[] { docRef1, docRef2 }, null, default);

            Assert.Equal(2, results.Count);
            // Note that this is the second result, not the first - we get them back in response order, not request order.
            // (If we need to ensure request order, that can be done as a separate method layered on this one.)
            var snapshot1 = results[1];

            Assert.False(snapshot1.Exists);
            Assert.Equal(new Timestamp(1, 2), snapshot1.ReadTime);
            Assert.Equal(docRef1, snapshot1.Reference);

            var snapshot2 = results[0];

            Assert.True(snapshot2.Exists);
            Assert.Equal(new Timestamp(0, 1), snapshot2.CreateTime);
            Assert.Equal(new Timestamp(0, 2), snapshot2.UpdateTime);
            Assert.Equal(new Timestamp(1, 3), snapshot2.ReadTime);
            Assert.Equal(docRef2, snapshot2.Reference);
            Assert.Equal("Test", snapshot2.GetField <string>("Name"));
            mock.VerifyAll();
        }
        /// <summary>
        /// Fetches document snapshots from the server, based on an optional transaction ID.
        /// </summary>
        /// <param name="documents">The document references to fetch. Must not be null, or contain null references.</param>
        /// <param name="transactionId">A transaction ID, or null to not include any transaction ID.</param>
        /// <param name="fieldMask">The field mask to use to restrict which fields are retrieved. May be null, in which
        /// case no field mask is applied, and the complete documents are retrieved.</param>
        /// <param name="cancellationToken">A cancellation token for the operation.</param>
        /// <returns>The document snapshots, in the order they are provided in the response. (This may not be the order of <paramref name="documents"/>.)</returns>
        internal async Task <IList <DocumentSnapshot> > GetDocumentSnapshotsAsync(IEnumerable <DocumentReference> documents, ByteString transactionId, FieldMask fieldMask, CancellationToken cancellationToken)
        {
            GaxPreconditions.CheckNotNull(documents, nameof(documents));
            var request = new BatchGetDocumentsRequest
            {
                Database  = RootPath,
                Documents = { documents.Select(ExtractPath) },
                Mask      = fieldMask?.ToProto()
            };

            if (transactionId != null)
            {
                request.Transaction = transactionId;
            }
            var stream = Client.BatchGetDocuments(request, CallSettings.FromCancellationToken(cancellationToken));

            using (var responseStream = stream.ResponseStream)
            {
                List <DocumentSnapshot> snapshots = new List <DocumentSnapshot>();

                // Note: no need to worry about passing the cancellation token in here, as we've passed it into the overall call.
                // If the token is cancelled, the call will be aborted.
                while (await responseStream.MoveNext().ConfigureAwait(false))
                {
                    var response = responseStream.Current;
                    var readTime = Timestamp.FromProto(response.ReadTime);
                    switch (response.ResultCase)
                    {
                    case BatchGetDocumentsResponse.ResultOneofCase.Found:
                        snapshots.Add(DocumentSnapshot.ForDocument(this, response.Found, readTime));
                        break;

                    case BatchGetDocumentsResponse.ResultOneofCase.Missing:
                        snapshots.Add(DocumentSnapshot.ForMissingDocument(this, response.Missing, readTime));
                        break;

                    default:
                        throw new InvalidOperationException($"Unknown response type: {response.ResultCase}");
                    }
                }
                return(snapshots);
            }

            string ExtractPath(DocumentReference documentReference)
            {
                GaxPreconditions.CheckArgument(documentReference != null, nameof(documents), "DocumentReference sequence must not contain null elements.");
                return(documentReference.Path);
            }
        }
Ejemplo n.º 10
0
        public async Task GetDocumentSnapshotsAsync_UnknownResponseCase()
        {
            string docName = "projects/proj/databases/db/documents/col1/doc1";
            var    mock    = CreateMockClient();
            var    request = new BatchGetDocumentsRequest
            {
                Database  = "projects/proj/databases/db",
                Documents = { docName },
            };
            var responses = new[] { new BatchGetDocumentsResponse {
                                        ReadTime = CreateProtoTimestamp(1, 2)
                                    } };

            mock.Setup(c => c.BatchGetDocuments(request, It.IsAny <CallSettings>())).Returns(new FakeDocumentStream(responses));
            var db = FirestoreDb.Create("proj", "db", mock.Object);
            await Assert.ThrowsAsync <InvalidOperationException>(() => db.GetDocumentSnapshotsAsync(new[] { db.Document("col1/doc1") }, transactionId: null, fieldMask: null, default));
        }
Ejemplo n.º 11
0
        public override BatchGetDocumentsStream BatchGetDocuments(BatchGetDocumentsRequest request, CallSettings callSettings = null)
        {
            string transaction = request.ConsistencySelectorCase == BatchGetDocumentsRequest.ConsistencySelectorOneofCase.Transaction ?
                                 request.Transaction.ToStringUtf8() : "no transaction";
            // Fake documents that show which transaction was being used.
            var responses = request.Documents.Select(path => new BatchGetDocumentsResponse
            {
                Found = new Document
                {
                    Name       = path,
                    CreateTime = CreateProtoTimestamp(0, 0),
                    UpdateTime = CreateProtoTimestamp(0, 0),
                    Fields     = { { "transaction", CreateValue(transaction) } }
                },
                ReadTime = GetNextTimestamp()
            });

            return(new FakeDocumentStream(responses));
        }
Ejemplo n.º 12
0
 partial void Modify_BatchGetDocumentsRequest(ref BatchGetDocumentsRequest request, ref CallSettings settings) =>
 ApplyResourcePrefixHeader(ref settings, request.Database);
Ejemplo n.º 13
0
        /// <summary>
        /// Fetches document snapshots from the server, based on an optional transaction ID.
        /// </summary>
        /// <param name="documents">The document references to fetch. Must not be null, or contain null references.</param>
        /// <param name="transactionId">A transaction ID, or null to not include any transaction ID.</param>
        /// <param name="fieldMask">The field mask to use to restrict which fields are retrieved. May be null, in which
        /// case no field mask is applied, and the complete documents are retrieved.</param>
        /// <param name="cancellationToken">A cancellation token for the operation.</param>
        /// <returns>The document snapshots, in the order they are provided in the response. (This may not be the order of <paramref name="documents"/>.)</returns>
        internal async Task <IList <DocumentSnapshot> > GetDocumentSnapshotsAsync(IEnumerable <DocumentReference> documents, ByteString transactionId, FieldMask fieldMask, CancellationToken cancellationToken)
        {
            GaxPreconditions.CheckNotNull(documents, nameof(documents));
            var request = new BatchGetDocumentsRequest
            {
                Database  = RootPath,
                Documents = { documents.Select(ExtractPath) },
                Mask      = fieldMask?.ToProto()
            };

            if (transactionId != null)
            {
                request.Transaction = transactionId;
            }

            var clock        = Client.Settings.Clock ?? SystemClock.Instance;
            var scheduler    = Client.Settings.Scheduler ?? SystemScheduler.Instance;
            var callSettings = _batchGetCallSettings.WithCancellationToken(cancellationToken);

            // This is the function that we'll retry. We can't use the built-in retry functionality, because it's not a unary gRPC call.
            // (We could potentially simulate a unary call, but it would be a little odd to do so.)
            // Note that we perform a "whole request" retry. In theory we could collect some documents, then see an error, and only
            // request the remaining documents. Given how rarely we retry anyway in practice, that's probably not worth doing.
            Func <BatchGetDocumentsRequest, CallSettings, Task <List <DocumentSnapshot> > > function = async(req, settings) =>
            {
                var stream = Client.BatchGetDocuments(req, settings);
                using (var responseStream = stream.ResponseStream)
                {
                    List <DocumentSnapshot> snapshots = new List <DocumentSnapshot>();

                    // Note: no need to worry about passing the cancellation token in here, as we've passed it into the overall call.
                    // If the token is cancelled, the call will be aborted.
                    while (await responseStream.MoveNext().ConfigureAwait(false))
                    {
                        var response = responseStream.Current;
                        var readTime = Timestamp.FromProto(response.ReadTime);
                        switch (response.ResultCase)
                        {
                        case BatchGetDocumentsResponse.ResultOneofCase.Found:
                            snapshots.Add(DocumentSnapshot.ForDocument(this, response.Found, readTime));
                            break;

                        case BatchGetDocumentsResponse.ResultOneofCase.Missing:
                            snapshots.Add(DocumentSnapshot.ForMissingDocument(this, response.Missing, readTime));
                            break;

                        default:
                            throw new InvalidOperationException($"Unknown response type: {response.ResultCase}");
                        }
                    }
                    return(snapshots);
                }
            };

            var retryingTask = RetryHelper.Retry(function, request, callSettings, clock, scheduler);

            return(await retryingTask.ConfigureAwait(false));

            string ExtractPath(DocumentReference documentReference)
            {
                GaxPreconditions.CheckArgument(documentReference != null, nameof(documents), "DocumentReference sequence must not contain null elements.");
                return(documentReference.Path);
            }
        }
Ejemplo n.º 14
0
        public async System.Threading.Tasks.Task FSBatchGetDocuments()
        {
            FirestoreTestUtils.ColoredConsoleWrite(ConsoleColor.Green, "\n:: Batch Retrieve Documents ::\n");
            FirestoreTestUtils.ColoredConsoleWrite(ConsoleColor.White, "\nAvailable Docments:\n");
            ListDocuments();

            var batchGetDocumentsRequest = new BatchGetDocumentsRequest();

            batchGetDocumentsRequest.Database = Parent;

            while (true)
            {
                FirestoreTestUtils.ColoredConsoleWrite(ConsoleColor.Yellow, "\n\nEnter Collection [cities]: ");
                string collectionId = Console.ReadLine();
                if (collectionId == "")
                {
                    collectionId = "cities";
                }

                FirestoreTestUtils.ColoredConsoleWrite(ConsoleColor.Yellow, "\nEnter Document Name (blank when finished): ");
                string documentName = Console.ReadLine();
                if (documentName != "")
                {
                    Document doc = null;
                    try
                    {
                        doc = GetDocument(documentName, collectionId);
                    }
                    catch (Grpc.Core.RpcException e)
                    {
                        if (e.Status.StatusCode == Grpc.Core.StatusCode.NotFound)
                        {
                            FirestoreTestUtils.ColoredConsoleWrite(ConsoleColor.Red, "ERROR: Document " + documentName + " not found, ignoring ...");
                        }
                        continue;
                    }
                    batchGetDocumentsRequest.Documents.Add(doc.Name);
                }
                else
                {
                    break;
                }
            }

            var batchGetDocumentsResponse = new BatchGetDocumentsResponse();

            try
            {
                var ret               = FsClient.BatchGetDocuments(batchGetDocumentsRequest);
                var responseStream    = ret.ResponseStream;
                var cancellationToken = new System.Threading.CancellationToken();
                while (await responseStream.MoveNext(cancellationToken))
                {
                    batchGetDocumentsResponse = responseStream.Current;
                    Utils.ReadDocument(batchGetDocumentsResponse.Found);
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("{0} Exception caught.", e);
                return;
            }
            FirestoreTestUtils.ColoredConsoleWrite(ConsoleColor.Green, "\nSuccessfully batch retrieved documents!\n");
        }