/// <summary> /// Update a document in DynamoDB, with a hash-and-range primary key to identify /// the document, and using the specified config. /// </summary> /// <param name="doc">Attributes to update.</param> /// <param name="hashKey">Hash key element of the document.</param> /// <param name="rangeKey">Range key element of the document.</param> /// <param name="config">Configuration to use.</param> /// <returns>Null or updated attributes, depending on config.</returns> /// <seealso cref="Amazon.DynamoDB.DocumentModel.UpdateItemOperationConfig"/> public Document UpdateItem(Document doc, Primitive hashKey, Primitive rangeKey, UpdateItemOperationConfig config) { return UpdateHelper(doc, MakeKey(hashKey, rangeKey), config, false); }
internal Document UpdateHelper(Document doc, Key key, UpdateItemOperationConfig config, bool isAsync) { var currentConfig = config ?? new UpdateItemOperationConfig(); // If the keys have been changed, treat entire document as having changed bool haveKeysChanged = HaveKeysChanged(doc); bool updateChangedAttributesOnly = !haveKeysChanged; var attributeUpdates = doc.ToAttributeUpdateMap(updateChangedAttributesOnly); foreach (var keyName in this.keyNames) { attributeUpdates.Remove(keyName); } UpdateItemRequest req = new UpdateItemRequest { TableName = TableName, Key = key, AttributeUpdates = attributeUpdates.Count == 0 ? new Dictionary<string,AttributeValueUpdate>() : attributeUpdates, ReturnValues = EnumToStringMapper.Convert(currentConfig.ReturnValues) }; req.BeforeRequestEvent += isAsync ? new RequestEventHandler(UserAgentRequestEventHandlerAsync) : new RequestEventHandler(UserAgentRequestEventHandlerSync); if (currentConfig.Expected != null) req.Expected = currentConfig.Expected.ToExpectedAttributeMap(); var resp = DDBClient.UpdateItem(req); var returnedAttributes = resp.UpdateItemResult.Attributes; doc.CommitChanges(); Document ret = null; if (currentConfig.ReturnValues != ReturnValues.None) { ret = Document.FromAttributeMap(returnedAttributes); } return ret; }
/// <summary> /// Initiates the asynchronous execution of the UpdateItem operation. /// <seealso cref="Amazon.DynamoDB.DocumentModel.Table.UpdateItem"/> /// </summary> /// <param name="doc">Attributes to update.</param> /// <param name="hashKey">Hash key element of the document.</param> /// <param name="rangeKey">Range key element of the document.</param> /// <param name="config">Configuration to use.</param> /// <param name="callback">An AsyncCallback delegate that is invoked when the operation completes.</param> /// <param name="state">A user-defined state object that is passed to the callback procedure. Retrieve this object from within the callback /// procedure using the AsyncState property.</param> /// <returns>An IAsyncResult that can be used to poll or wait for results, or both; this value is also needed when invoking EndUpdateItem /// operation.</returns> public IAsyncResult BeginUpdateItem(Document doc, Primitive hashKey, Primitive rangeKey, UpdateItemOperationConfig config, AsyncCallback callback, object state) { return DynamoDBAsyncExecutor.BeginOperation(() => UpdateHelper(doc, MakeKey(hashKey, rangeKey), config, true), callback, state); }
/// <summary> /// Update a document in DynamoDB, using specified config. /// </summary> /// <param name="doc">Document to update.</param> /// <param name="config">Configuration to use.</param> /// <returns>Null or updated attributes, depending on config.</returns> /// <seealso cref="Amazon.DynamoDB.DocumentModel.UpdateItemOperationConfig"/> public Document UpdateItem(Document doc, UpdateItemOperationConfig config) { return UpdateHelper(doc, MakeKey(doc), config, false); }
private Document UpdateHelper(Document doc, Key key, UpdateItemOperationConfig config) { var currentConfig = config ?? new UpdateItemOperationConfig(); var attributeUpdates = doc.ToAttributeUpdateMap(true); foreach (var keyName in this.keyNames) { if (keyName != null) { attributeUpdates.Remove(keyName); } } UpdateItemRequest req = new UpdateItemRequest { TableName = TableName, Key = key, AttributeUpdates = attributeUpdates, ReturnValues = EnumToStringMapper.Convert(currentConfig.ReturnValues) }; req.BeforeRequestEvent += new RequestEventHandler(this.UserAgentRequestEventHandler); if (currentConfig.Expected != null) req.Expected = currentConfig.Expected.ToExpectedAttributeMap(); var resp = DDBClient.UpdateItem(req); doc.CommitChanges(); Document ret = null; if (currentConfig.ReturnValues != ReturnValues.None) { ret = Document.FromAttributeMap(resp.UpdateItemResult.Attributes); } return ret; }
/// <summary> /// Update a document in DynamoDB, with a hash primary key to identify the /// document, and using the specified config. /// </summary> /// <param name="doc">Attributes to update.</param> /// <param name="hashKey">Hash key element of the document.</param> /// <param name="config">Configuration to use.</param> /// <returns>Null or updated attributes, depending on config.</returns> /// <seealso cref="Amazon.DynamoDB.DocumentModel.UpdateItemOperationConfig"/> public Document UpdateItem(Document doc, Primitive hashKey, UpdateItemOperationConfig config) { return UpdateHelper(doc, MakeKey(hashKey, null), config); }
internal Document UpdateHelper(Document doc, Key key, UpdateItemOperationConfig config, bool isAsync) { var currentConfig = config ?? new UpdateItemOperationConfig(); var attributeUpdates = doc.ToAttributeUpdateMap(true); foreach (var keyName in this.keyNames) { attributeUpdates.Remove(keyName); } ReturnValues currentReturnValue = currentConfig.ReturnValues; bool keysOnlyUpdate = attributeUpdates.Count == 0; // If there are no non-key attributes, make an Update call with AllNewAttributes // return value. If no attributes returned, the item doesn't exist yet, so // make a Put call. if (keysOnlyUpdate) { currentReturnValue = ReturnValues.AllNewAttributes; } UpdateItemRequest req = new UpdateItemRequest { TableName = TableName, Key = key, AttributeUpdates = attributeUpdates, ReturnValues = EnumToStringMapper.Convert(currentReturnValue) }; req.BeforeRequestEvent += isAsync ? new RequestEventHandler(UserAgentRequestEventHandlerAsync) : new RequestEventHandler(UserAgentRequestEventHandlerSync); if (currentConfig.Expected != null) req.Expected = currentConfig.Expected.ToExpectedAttributeMap(); var resp = DDBClient.UpdateItem(req); var returnedAttributes = resp.UpdateItemResult.Attributes; doc.CommitChanges(); if (keysOnlyUpdate) { if (returnedAttributes == null || returnedAttributes.Count == 0) { // if only keys were specified and no attributes are returned, we must issue a Put return CallKeysOnlyPut(key, currentConfig, isAsync); } else { // update was called with AllNewAttributes, item exists // return correct set of attributes // [None] is handled at the end // [AllNewAttributes, AllOldAttributes] are equivalent in this case, no-op // [UpdatedNewAttributes, UpdatedOldAttributes] must return no attributes switch (currentConfig.ReturnValues) { case ReturnValues.UpdatedNewAttributes: case ReturnValues.UpdatedOldAttributes: returnedAttributes = new Dictionary<string,AttributeValue>(); break; } } } Document ret = null; if (currentConfig.ReturnValues != ReturnValues.None) { ret = Document.FromAttributeMap(returnedAttributes); } return ret; }
// Creates a PutItemOperationConfig for the keys-only Put operation private PutItemOperationConfig CreateKeysOnlyPutConfig(Key key, UpdateItemOperationConfig config) { // configure the expected document Document expected = new Document(); expected[this.HashKeyName] = null; if (this.RangeKeyIsDefined) { expected[this.RangeKeyName] = null; } // create the PutItemOperationConfig var putConfig = new PutItemOperationConfig { Expected = expected, ReturnValues = ReturnValues.None }; return putConfig; }
// calls Put, but returns like Update private Document CallKeysOnlyPut(Key key, UpdateItemOperationConfig config, bool isAsync) { // configure the keys-only Document Document doc = CreateKeysOnlyDocument(key); // configure the put operation PutItemOperationConfig putConfig = CreateKeysOnlyPutConfig(key, config); // call put PutItemHelper(doc, putConfig, isAsync); /* New item created, return Update-appropriate response. For update, when no item exists: [None] - returns null, [AllOld, UpdatedNew, UpdatedOld] - return no attributes [AllNew] - returns all attributes */ Document response; switch (config.ReturnValues) { case ReturnValues.None: response = null; break; case ReturnValues.AllNewAttributes: response = doc; break; default: response = new Document(); break; } return response; }