/// <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 }
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(); }
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); }
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(); }
/// <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); } }
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)); }
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)); }
partial void Modify_BatchGetDocumentsRequest(ref BatchGetDocumentsRequest request, ref CallSettings settings) => ApplyResourcePrefixHeader(ref settings, request.Database);
/// <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); } }
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"); }