/// <summary> /// Adds an operation to delete a document's data in this transaction. /// </summary> /// <param name="documentReference">The document to delete. Must not be null.</param> /// <param name="precondition">Optional precondition for deletion. May be null, in which case the deletion is unconditional.</param> public void Delete(DocumentReference documentReference, Precondition precondition = null) { // Preconditions are validated by WriteBatch. _writes.Delete(documentReference, precondition); }
/// <summary> /// Adds an operation to update a document's data in this transaction. /// </summary> /// <param name="documentReference">A document reference indicating the path of the document to update. Must not be null.</param> /// <param name="field">The dot-separated name of the field to update. Must not be null.</param> /// <param name="value">The new value for the field. May be null.</param> /// <param name="precondition">Optional precondition for updating the document. May be null, which is equivalent to <see cref="Precondition.MustExist"/>.</param> public void Update(DocumentReference documentReference, string field, object value, Precondition precondition = null) { GaxPreconditions.CheckNotNull(field, nameof(field)); Update(documentReference, new Dictionary <string, object> { { field, value } }, precondition); }
/// <summary> /// Adds an operation to update a document's data in this transaction. /// </summary> /// <param name="documentReference">The document to update. Must not be null.</param> /// <param name="updates">The updates to perform on the document, keyed by the field path to update. Fields not present in this dictionary are not updated. Must not be null or empty.</param> /// <param name="precondition">Optional precondition for updating the document. May be null, which is equivalent to <see cref="Precondition.MustExist"/>.</param> public void Update(DocumentReference documentReference, IDictionary <FieldPath, object> updates, Precondition precondition = null) { // Preconditions are validated by WriteBatch. _writes.Update(documentReference, updates, precondition); }
/// <summary> /// Adds an operation to update a document's data in this transaction. /// </summary> /// <param name="documentReference">A document reference indicating the path of the document to update. Must not be null.</param> /// <param name="updates">The updates to perform on the document, keyed by the dot-separated field path to update. Fields not present in this dictionary are not updated. Must not be null or empty.</param> /// <param name="precondition">Optional precondition for updating the document. May be null, which is equivalent to <see cref="Precondition.MustExist"/>.</param> public void Update(DocumentReference documentReference, IDictionary <string, object> updates, Precondition precondition = null) { GaxPreconditions.CheckNotNull(updates, nameof(updates)); Update(documentReference, updates.ToDictionary(pair => FieldPath.FromDotSeparatedString(pair.Key), pair => pair.Value), precondition); }
/// <summary> /// Asynchronously performs a set of updates on the document referred to by this path, with an optional precondition. /// </summary> /// <param name="updates">The updates to perform on the document, keyed by the field path to update. Fields not present in this dictionary are not updated. Must not be null or empty.</param> /// <param name="precondition">Optional precondition for updating the document. May be null, which is equivalent to <see cref="Precondition.MustExist"/>.</param> /// <param name="cancellationToken">A cancellation token to monitor for the asynchronous operation.</param> /// <returns>The write result of the server operation.</returns> public async Task <WriteResult> UpdateAsync(IDictionary <FieldPath, object> updates, Precondition precondition = null, CancellationToken cancellationToken = default) { var batch = Database.StartBatch(); batch.Update(this, updates, precondition); var results = await batch.CommitAsync(cancellationToken).ConfigureAwait(false); return(results[0]); }
/// <summary> /// Adds an update operation that updates just the specified fields paths in the document, with the corresponding values. /// </summary> /// <param name="documentReference">A document reference indicating the path of the document to update. Must not be null.</param> /// <param name="updates">The updates to perform on the document, keyed by the field path to update. Fields not present in this dictionary are not updated. Must not be null or empty.</param> /// <param name="precondition">Optional precondition for updating the document. May be null, which is equivalent to <see cref="Precondition.MustExist"/>.</param> /// <returns>This batch, for the purposes of method chaining.</returns> public WriteBatch Update(DocumentReference documentReference, IDictionary <FieldPath, object> updates, Precondition precondition = null) { GaxPreconditions.CheckNotNull(documentReference, nameof(documentReference)); GaxPreconditions.CheckNotNull(updates, nameof(updates)); GaxPreconditions.CheckArgument(updates.Count != 0, nameof(updates), "Empty set of updates specified"); GaxPreconditions.CheckArgument(precondition?.Exists != true, nameof(precondition), "Cannot specify a must-exist precondition for update"); var serializedUpdates = updates.ToDictionary(pair => pair.Key, pair => ValueSerializer.Serialize(documentReference.Database.SerializationContext, pair.Value)); var expanded = ExpandObject(serializedUpdates); var sentinels = FindSentinels(expanded); // This effectively validates that a delete wasn't part of a map. It could still be a multi-segment field path, but it can't be within something else. var deletePaths = sentinels.Where(sf => sf.IsDelete).Select(sf => sf.FieldPath); GaxPreconditions.CheckArgument(deletePaths.All(fp => updates.ContainsKey(fp)), nameof(updates), "Deletes cannot be nested within update calls"); RemoveSentinels(expanded, sentinels); var nonDeletes = sentinels.Where(sf => !sf.IsDelete).ToList(); AddUpdateWrite(documentReference, expanded, updates.Keys.ToList(), precondition ?? Precondition.MustExist, sentinelFields: nonDeletes); return(this); }
/// <summary> /// Asynchronously performs a set of updates on the document referred to by this path, with an optional precondition. /// </summary> /// <param name="updates">The updates to perform on the document, keyed by the dot-separated field path to update. Fields not present in this dictionary are not updated. Must not be null or empty.</param> /// <param name="precondition">Optional precondition for updating the document. May be null, which is equivalent to <see cref="Precondition.MustExist"/>.</param> /// <param name="cancellationToken">A cancellation token to monitor for the asynchronous operation.</param> /// <returns>The write result of the server operation.</returns> public Task <WriteResult> UpdateAsync(IDictionary <string, object> updates, Precondition precondition = null, CancellationToken cancellationToken = default) { GaxPreconditions.CheckNotNull(updates, nameof(updates)); return(UpdateAsync(updates.ToDictionary(pair => FieldPath.FromDotSeparatedString(pair.Key), pair => pair.Value), precondition, cancellationToken)); }
/// <summary> /// Adds an update operation that updates just the specified fields paths in the document, with the corresponding values. /// </summary> /// <param name="documentReference">A document reference indicating the path of the document to update. Must not be null.</param> /// <param name="updates">The updates to perform on the document, keyed by the field path to update. Fields not present in this dictionary are not updated. Must not be null or empty.</param> /// <param name="precondition">Optional precondition for updating the document. May be null, which is equivalent to <see cref="Precondition.MustExist"/>.</param> /// <returns>This batch, for the purposes of method chaining.</returns> public WriteBatch Update(DocumentReference documentReference, IDictionary <FieldPath, object> updates, Precondition precondition = null) { GaxPreconditions.CheckNotNull(documentReference, nameof(documentReference)); GaxPreconditions.CheckNotNull(updates, nameof(updates)); GaxPreconditions.CheckArgument(updates.Count != 0, nameof(updates), "Empty set of updates specified"); GaxPreconditions.CheckArgument(precondition?.Proto.Exists != true, nameof(precondition), "Cannot specify a must-exist precondition for update"); var serializedUpdates = updates.ToDictionary(pair => pair.Key, pair => ValueSerializer.Serialize(pair.Value)); var expanded = ExpandObject(serializedUpdates); var serverTimestamps = new List <FieldPath>(); var deletes = new List <FieldPath>(); FindSentinels(expanded, FieldPath.Empty, serverTimestamps, deletes); // This effectively validates that a delete wasn't part of a map. It could still be a multi-segment field path, but it can't be within something else. GaxPreconditions.CheckArgument(deletes.All(fp => updates.ContainsKey(fp)), nameof(updates), "Deletes cannot be nested within update calls"); RemoveSentinels(expanded, deletes); RemoveSentinels(expanded, serverTimestamps); AddUpdateWrites(documentReference, expanded, updates.Keys.ToList(), precondition ?? Precondition.MustExist, serverTimestamps, false); return(this); }