Class EntityWriteExtensions
- Namespace
- DynaSharp
- Assembly
- DynaSharp.dll
The clauses of a write of an entity that its write rules ask for: IfVersion and IgnoreVersion for an entity with a VersionAttribute, and
StoreKeyInputs for an update that may create the item. These are extension methods so that a write of a table without a schema, which has neither, does not offer them.
public static class EntityWriteExtensions
- Inheritance
-
EntityWriteExtensions
- Inherited Members
Examples
var cart = await carts.Get(Cart.Keys.Of("bob")).Consistent().ItemAsync(ct);
await carts.Update(Cart.Keys.Of("bob")).Set(Cart.Attrs.Lines, lines).IfVersion(cart!.Revision).SendAsync(ct);
Methods
IfVersion<T>(DeleteCommand<T>, long)
Deletes only if the item has this version. If the item has another version, sending throws ConditionalCheckFailedException.
public static DeleteCommand<T> IfVersion<T>(this DeleteCommand<T> command, long version) where T : IDynamoDbEntity<T>
Parameters
commandDeleteCommand<T>The command.
versionlongThe version last read.
Returns
- DeleteCommand<T>
The command, which replaces this one.
Type Parameters
TThe entity. A table without a schema has no version, so it does not compile.
Remarks
Required for a versioned entity. A key does not carry a version, so a delete by a key of an entity with a VersionAttribute needs this or IgnoreVersion<T>(DeleteCommand<T>); a delete of an entity takes the version from it, and this checks another one in its place. RetryOnConflictAsync<TResult>(Func<CancellationToken, ValueTask<TResult>>, CancellationToken) repeats code that reads the version again.
Version 0 stands for an item that does not exist, so it renders attribute_not_exists on the partition key, and the delete fails on any item under the key. With
Allow it looks at the version attribute instead, and deletes an item without one or with 0 in it.
Exceptions
- ArgumentOutOfRangeException
versionis negative, or MaxValue.- InvalidOperationException
Thas no VersionAttribute.
IfVersion<T>(UpdateCommand<T>, long)
Updates only if the item has this version, and stores the next one, which Version returns. If the item has another version, sending throws ConditionalCheckFailedException.
public static UpdateCommand<T> IfVersion<T>(this UpdateCommand<T> command, long version) where T : IDynamoDbEntity<T>
Parameters
commandUpdateCommand<T>The command.
versionlongThe version last read.
Returns
- UpdateCommand<T>
The command, which replaces this one.
Type Parameters
TThe entity. A table without a schema has no version, so it does not compile.
Remarks
Required for a versioned entity. A key does not carry a version, so an update of an entity with a VersionAttribute needs this or IgnoreVersion<T>(UpdateCommand<T>). Nothing is read or retried by itself: RetryOnConflictAsync<TResult>(Func<CancellationToken, ValueTask<TResult>>, CancellationToken) is how to ask for that, around code that reads the version again.
Version 0 stands for an item that does not exist, so it renders attribute_not_exists on the partition key and fails on any item under the key, also on one without a version
attribute, which IgnoreVersion<T>(UpdateCommand<T>) writes to. With Allow it looks at the version attribute instead, and writes to an item
without one or with 0 in it.
Exceptions
- ArgumentOutOfRangeException
versionis negative, or MaxValue, which has no next one.- InvalidOperationException
Thas no VersionAttribute.
IgnoreVersion<T>(DeleteCommand<T>)
Lets the delete go out without the check.
public static DeleteCommand<T> IgnoreVersion<T>(this DeleteCommand<T> command) where T : IDynamoDbEntity<T>
Parameters
commandDeleteCommand<T>The command.
Returns
- DeleteCommand<T>
The command, which replaces this one.
Type Parameters
TThe entity.
IgnoreVersion<T>(PutCommand<T>)
Writes the entity without the check of its version, for imports, migrations and an item written without a version, and still stores the next version, as a checked put does: Version is the version of the entity plus one. Conditions of your own stay, it holds wherever it stands in the chain, and on an entity without a VersionAttribute it changes nothing.
public static PutCommand<T> IgnoreVersion<T>(this PutCommand<T> command) where T : IDynamoDbEntity<T>
Parameters
commandPutCommand<T>The command.
Returns
- PutCommand<T>
The command, which replaces this one.
Type Parameters
TThe entity. A table without a schema has no version, so it does not compile.
Remarks
The version still advances. Every write of a versioned entity stores a new version, also one without the check: an update adds 1 to the stored version,
SET #v = if_not_exists(#v, :zero) + :one, so an item without one, or a new item, gets version 1, and a put or a batch stores the version of its entity plus one, as a checked put does. A writer
that holds a copy read before this write then fails with ConditionalCheckFailedException, or in a transaction with TransactionCanceledException, instead of overwriting it.
What this write itself overwrites is not checked: it wins over whatever another writer stored since, so it suits a change that does not depend on what was read, such as an Add to a counter.
Taking over an item without a version. Such an item reads as version 0, and a checked put at 0 fails with ConditionalCheckFailedException, because 0 says that no item has the key.
orders.Put(order).IgnoreVersion() of the entity as it was read stores version 1, and the next write is an ordinary one. For a table that keeps such items, Allow is the better answer.
The last version. An entity at the last version its property holds throws OverflowException at Put(T), because it has no next one.
IgnoreVersion<T>(UpdateCommand<T>)
Lets the update go out without the check of the version, and still stores the next version, so that a copy read before it fails its next checked write. Version is null, because the update does not know the version it advanced from.
public static UpdateCommand<T> IgnoreVersion<T>(this UpdateCommand<T> command) where T : IDynamoDbEntity<T>
Parameters
commandUpdateCommand<T>The command.
Returns
- UpdateCommand<T>
The command, which replaces this one.
Type Parameters
TThe entity.
Remarks
The version still advances. Every write of a versioned entity stores a new version, also one without the check: an update adds 1 to the stored version,
SET #v = if_not_exists(#v, :zero) + :one, so an item without one, or a new item, gets version 1, and a put or a batch stores the version of its entity plus one, as a checked put does. A writer
that holds a copy read before this write then fails with ConditionalCheckFailedException, or in a transaction with TransactionCanceledException, instead of overwriting it.
What this write itself overwrites is not checked: it wins over whatever another writer stored since, so it suits a change that does not depend on what was read, such as an Add to a counter.
Setting the version yourself. An update that sets, adds to or removes the version attribute by its own action keeps that action, and the version is not advanced besides it.
IfVersion(n) after this checks n and stores n + 1; before it, this throws.
Exceptions
- InvalidOperationException
The update already has
IfVersion, whose condition cannot be taken back.
StoreKeyInputs<T>(UpdateCommand<T>)
Stores the inputs of the key of the table as attributes of the item, as a Put does, for an update that may create the item: without it, an item an update created holds the
key alone.
public static UpdateCommand<T> StoreKeyInputs<T>(this UpdateCommand<T> command) where T : IDynamoDbEntity<T>
Parameters
commandUpdateCommand<T>The command.
Returns
- UpdateCommand<T>
The command, which replaces this one.
Type Parameters
TThe entity. A table without a schema has no key inputs, so it does not compile.
Remarks
What is written. SET #userId = if_not_exists(#userId, :v) per input, after the actions of the update and the keys of its indexes and before the discriminator. An item that
exists keeps what it has, so this goes with IfExists(), IfNotExists() and a version alike. The value goes through the converter of the property and is the value, not the
text of the key, and an action of the update on the attribute by a path given as a string takes precedence.
Why. A read of the entity restores the inputs from the key, but Select of such an input and a filter on it find nothing in an item that holds the key alone. A plain key
and a key made of one property over its own attribute are their attribute, and a KeyOnlyAttribute has none, so an entity with nothing else changes nothing here.
A key given as strings. A template that cuts a value off, such as a timestamp in {At:yyyy-MM-dd}, gives it back only from a key the generator built, so a key given as
strings throws for it when the update ends.