Documentation
¶
Index ¶
- func Decode(av types.AttributeValue, val interface{}, coder ...Coder) (err error)
- func Encode(val interface{}, coder ...Coder) (types.AttributeValue, error)
- type CodecOf
- type Coder
- type ConditionExpression
- func (ce ConditionExpression[T, A]) Between(a, b A) interface{ ... }
- func (ce ConditionExpression[T, A]) Contains(val A) interface{ ... }
- func (ce ConditionExpression[T, A]) Eq(val A) interface{ ... }
- func (ce ConditionExpression[T, A]) Exists() interface{ ... }
- func (ce ConditionExpression[T, A]) Ge(val A) interface{ ... }
- func (ce ConditionExpression[T, A]) Gt(val A) interface{ ... }
- func (ce ConditionExpression[T, A]) HasPrefix(val A) interface{ ... }
- func (ce ConditionExpression[T, A]) In(seq ...A) interface{ ... }
- func (ce ConditionExpression[T, A]) Is(val string) interface{ ... }
- func (ce ConditionExpression[T, A]) Le(val A) interface{ ... }
- func (ce ConditionExpression[T, A]) Lt(val A) interface{ ... }
- func (ce ConditionExpression[T, A]) Ne(val A) interface{ ... }
- func (ce ConditionExpression[T, A]) NotExists() interface{ ... }
- type DynamoDB
- type Storage
- func (db *Storage[T]) BatchGet(ctx context.Context, keys []T) ([]T, error)
- func (db *Storage[T]) Get(ctx context.Context, key T) (T, error)
- func (db *Storage[T]) Match(ctx context.Context, key T, opts ...dynamo.MatchOpt) ([]T, dynamo.MatchOpt, error)
- func (db *Storage[T]) MatchKey(ctx context.Context, key dynamo.Thing, opts ...dynamo.MatchOpt) ([]T, dynamo.MatchOpt, error)
- func (db *Storage[T]) Put(ctx context.Context, entity T, opts ...interface{ ConditionExpression(T) }) error
- func (db *Storage[T]) Remove(ctx context.Context, key T, opts ...interface{ ConditionExpression(T) }) (T, error)
- func (db *Storage[T]) Update(ctx context.Context, entity T, opts ...interface{ ConditionExpression(T) }) (T, error)
- func (db *Storage[T]) UpdateWith(ctx context.Context, expression UpdateItemExpression[T], ...) (T, error)
- type UpdateExpression
- func (ue UpdateExpression[T, A]) Add(val A) interface{ ... }
- func (ue UpdateExpression[T, A]) Append(val A) interface{ ... }
- func (ue UpdateExpression[T, A]) Dec(val A) interface{ ... }
- func (ue UpdateExpression[T, A]) Inc(val A) interface{ ... }
- func (ue UpdateExpression[T, A]) Minus(val A) interface{ ... }
- func (ue UpdateExpression[T, A]) Prepend(val A) interface{ ... }
- func (ue UpdateExpression[T, A]) Remove() interface{ ... }
- func (ue UpdateExpression[T, A]) Set(val A) interface{ ... }
- func (ue UpdateExpression[T, A]) SetNotExists(val A) interface{ ... }
- func (ue UpdateExpression[T, A]) Union(val A) interface{ ... }
- type UpdateItemExpression
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Decode ¶
func Decode(av types.AttributeValue, val interface{}, coder ...Coder) (err error)
Decode is a helper function to decode core domain types from Dynamo DB format. The helper ensures compact URI de-serialization from DynamoDB schema.
type MyType struct { ID MyComplexType Name MyComplexType } var ID, Name = dynamo.Codec2[MyType, MyDynamoType, MyDynamoType]("ID", "Name") func (x *MyType) UnmarshalDynamoDBAttributeValue(av types.AttributeValue) error { type tStruct *MyType return dynamo.Decode(av, tStruct(x), ID.Decode((*MyDynamoType)(&x.ID)), Name.Decode((*MyDynamoType)(&x.Name)), ) }
func Encode ¶
func Encode(val interface{}, coder ...Coder) (types.AttributeValue, error)
Encode is a helper function to encode core domain types into struct. The helper ensures compact URI serialization into DynamoDB schema.
type MyType struct { ID MyComplexType Name MyComplexType } var ID, Name = dynamo.Codec2[MyType, MyDynamoType, MyDynamoType]("ID", "Name") func (x MyType) MarshalDynamoDBAttributeValue() (types.AttributeValue, error) { type tStruct MyType return dynamo.Encode(av, tStruct(x), ID.Encode(MyDynamoType(x.ID)), Name.Encode(MyDynamoType(x.Name)), ) }
Types ¶
type CodecOf ¶
CodecOf for struct fields, the type implement Encode/Decode primitives. Codec helps to implement semi-automated encoding/decoding algebraic data type into the format compatible with storage.
Let's consider scenario were application uses complex types that skips implementation of marshal/unmarshal protocols. Here the type MyComplexType needs to be casted to MyDynamoType that knows how to marshal/unmarshal the type.
type MyType struct { ID MyComplexType Name MyComplexType } var ( ID = dynamo.Codec[MyType, MyDynamoType]("ID") Name = dynamo.Codec[MyType, MyDynamoType]("Name") ) func (t MyType) MarshalDynamoDBAttributeValue() (*dynamodb.AttributeValue, error) { type tStruct MyType return dynamo.Encode(tStruct(p), ID.Encode(MyDynamoType(t.ID)), Name.Encode(MyDynamoType(t.Name)), ) }
type Coder ¶
type Coder func(map[string]types.AttributeValue) (map[string]types.AttributeValue, error)
Coder is a function, applies transformation of generic dynamodb AttributeValue
type ConditionExpression ¶ added in v2.4.0
type ConditionExpression[T dynamo.Thing, A any] struct { // contains filtered or unexported fields }
func ClauseFor ¶ added in v2.5.0
func ClauseFor[T dynamo.Thing, A any](attr ...string) ConditionExpression[T, A]
See DynamoDB Conditional Expressions
https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.ConditionExpressions.html
Schema declares type descriptor to express Storage I/O Constrains.
Let's consider a following example:
type Person struct { curie.ID Name string `dynamodbav:"anothername,omitempty"` }
How to define a condition expression on the field Name? Golang struct defines and refers the field by `Name` but DynamoDB stores it under the attribute `anothername`. Struct field dynamodbav tag specifies serialization rules. Golang does not support a typesafe approach to build a correspondence between `Name` ⟷ `anothername`. Developers have to utilize dynamodb attribute name(s) in conditional expression and Golang struct name in rest of the code. It becomes confusing and hard to maintain.
The Schema is helpers to declare builders for conditional expressions. Just declare a global variables next to type definition and use them across the application.
var ( name = dynamo.ClauseFor[Person, string]("Name") addr = dynamo.ClauseFor[Person, Address]() ) name.Eq("Joe Doe") name.NotExists()
func (ConditionExpression[T, A]) Between ¶ added in v2.4.0
func (ce ConditionExpression[T, A]) Between(a, b A) interface{ ConditionExpression(T) }
Between attribute condition
name.Between(a, b) ⟼ Field BETWEEN :a AND :b
func (ConditionExpression[T, A]) Contains ¶ added in v2.4.0
func (ce ConditionExpression[T, A]) Contains(val A) interface{ ConditionExpression(T) }
Contains attribute condition
name.Contains(x) ⟼ contains(Field, :value)
func (ConditionExpression[T, A]) Eq ¶ added in v2.4.0
func (ce ConditionExpression[T, A]) Eq(val A) interface{ ConditionExpression(T) }
Eq is equal condition
name.Eq(x) ⟼ Field = :value
func (ConditionExpression[T, A]) Exists ¶ added in v2.4.0
func (ce ConditionExpression[T, A]) Exists() interface{ ConditionExpression(T) }
Exists attribute constrain
name.Exists(x) ⟼ attribute_exists(name)
func (ConditionExpression[T, A]) Ge ¶ added in v2.4.0
func (ce ConditionExpression[T, A]) Ge(val A) interface{ ConditionExpression(T) }
Ge is greater or equal constrain
name.Le(x) ⟼ Field >= :value
func (ConditionExpression[T, A]) Gt ¶ added in v2.4.0
func (ce ConditionExpression[T, A]) Gt(val A) interface{ ConditionExpression(T) }
Gt is greater than constrain
name.Le(x) ⟼ Field > :value
func (ConditionExpression[T, A]) HasPrefix ¶ added in v2.4.0
func (ce ConditionExpression[T, A]) HasPrefix(val A) interface{ ConditionExpression(T) }
HasPrefix attribute condition
name.HasPrefix(x) ⟼ begins_with(Field, :value)
func (ConditionExpression[T, A]) In ¶ added in v2.4.0
func (ce ConditionExpression[T, A]) In(seq ...A) interface{ ConditionExpression(T) }
In attribute condition
name.Between(a, b, c) ⟼ Field IN (:a, :b, :c)
func (ConditionExpression[T, A]) Is ¶ added in v2.4.0
func (ce ConditionExpression[T, A]) Is(val string) interface{ ConditionExpression(T) }
Is matches either Eq or NotExists if value is not defined
func (ConditionExpression[T, A]) Le ¶ added in v2.4.0
func (ce ConditionExpression[T, A]) Le(val A) interface{ ConditionExpression(T) }
Le is less or equal constain
name.Le(x) ⟼ Field <= :value
func (ConditionExpression[T, A]) Lt ¶ added in v2.4.0
func (ce ConditionExpression[T, A]) Lt(val A) interface{ ConditionExpression(T) }
Lt is less than constraint
name.Lt(x) ⟼ Field < :value
func (ConditionExpression[T, A]) Ne ¶ added in v2.4.0
func (ce ConditionExpression[T, A]) Ne(val A) interface{ ConditionExpression(T) }
Ne is non equal condition
name.Ne(x) ⟼ Field <> :value
func (ConditionExpression[T, A]) NotExists ¶ added in v2.4.0
func (ce ConditionExpression[T, A]) NotExists() interface{ ConditionExpression(T) }
NotExists attribute constrain
name.NotExists(x) ⟼ attribute_not_exists(name)
type DynamoDB ¶ added in v2.2.0
type DynamoDB interface { GetItem(context.Context, *dynamodb.GetItemInput, ...func(*dynamodb.Options)) (*dynamodb.GetItemOutput, error) PutItem(context.Context, *dynamodb.PutItemInput, ...func(*dynamodb.Options)) (*dynamodb.PutItemOutput, error) DeleteItem(context.Context, *dynamodb.DeleteItemInput, ...func(*dynamodb.Options)) (*dynamodb.DeleteItemOutput, error) UpdateItem(context.Context, *dynamodb.UpdateItemInput, ...func(*dynamodb.Options)) (*dynamodb.UpdateItemOutput, error) Query(context.Context, *dynamodb.QueryInput, ...func(*dynamodb.Options)) (*dynamodb.QueryOutput, error) BatchGetItem(context.Context, *dynamodb.BatchGetItemInput, ...func(*dynamodb.Options)) (*dynamodb.BatchGetItemOutput, error) }
DynamoDB declares interface of original AWS DynamoDB API used by the library
type Storage ¶ added in v2.2.0
type Storage[T dynamo.Thing] struct {
// contains filtered or unexported fields
}
Storage type
func (*Storage[T]) Match ¶ added in v2.2.0
func (db *Storage[T]) Match(ctx context.Context, key T, opts ...dynamo.MatchOpt) ([]T, dynamo.MatchOpt, error)
Match applies a pattern matching to elements in the table
func (*Storage[T]) MatchKey ¶ added in v2.5.2
func (db *Storage[T]) MatchKey(ctx context.Context, key dynamo.Thing, opts ...dynamo.MatchOpt) ([]T, dynamo.MatchOpt, error)
Match applies a pattern matching to elements in the table
func (*Storage[T]) Put ¶ added in v2.2.0
func (db *Storage[T]) Put(ctx context.Context, entity T, opts ...interface{ ConditionExpression(T) }) error
Put writes entity
func (*Storage[T]) Remove ¶ added in v2.2.0
func (db *Storage[T]) Remove(ctx context.Context, key T, opts ...interface{ ConditionExpression(T) }) (T, error)
Remove discards the entity from the table
func (*Storage[T]) Update ¶ added in v2.2.0
func (db *Storage[T]) Update(ctx context.Context, entity T, opts ...interface{ ConditionExpression(T) }) (T, error)
Update applies a partial patch to entity and returns new values
func (*Storage[T]) UpdateWith ¶ added in v2.4.0
func (db *Storage[T]) UpdateWith(ctx context.Context, expression UpdateItemExpression[T], opts ...interface{ ConditionExpression(T) }) (T, error)
Update applies a partial patch to entity using update expression abstraction
type UpdateExpression ¶ added in v2.4.0
type UpdateExpression[T dynamo.Thing, A any] struct { // contains filtered or unexported fields }
func UpdateFor ¶ added in v2.5.0
func UpdateFor[T dynamo.Thing, A any](attr ...string) UpdateExpression[T, A]
func (UpdateExpression[T, A]) Add ¶ added in v2.4.1
func (ue UpdateExpression[T, A]) Add(val A) interface{ UpdateExpression(T) }
Add new attribute and increment value
name.Add(x) ⟼ ADD Field :value
func (UpdateExpression[T, A]) Append ¶ added in v2.4.0
func (ue UpdateExpression[T, A]) Append(val A) interface{ UpdateExpression(T) }
Append element to list
name.Inc(x) ⟼ SET Field = list_append (Field, :value)
func (UpdateExpression[T, A]) Dec ¶ added in v2.4.0
func (ue UpdateExpression[T, A]) Dec(val A) interface{ UpdateExpression(T) }
Decrement attribute
name.Inc(x) ⟼ SET Field = Field - :value
func (UpdateExpression[T, A]) Inc ¶ added in v2.4.0
func (ue UpdateExpression[T, A]) Inc(val A) interface{ UpdateExpression(T) }
Increment attribute
name.Inc(x) ⟼ SET Field = Field + :value
func (UpdateExpression[T, A]) Minus ¶ added in v2.6.0
func (ue UpdateExpression[T, A]) Minus(val A) interface{ UpdateExpression(T) }
Delete elements from set
name.Minus(x) ⟼ ADD Field :value
func (UpdateExpression[T, A]) Prepend ¶ added in v2.4.0
func (ue UpdateExpression[T, A]) Prepend(val A) interface{ UpdateExpression(T) }
Prepend element to list
name.Inc(x) ⟼ SET Field = list_append (:value, Field)
func (UpdateExpression[T, A]) Remove ¶ added in v2.4.0
func (ue UpdateExpression[T, A]) Remove() interface{ UpdateExpression(T) }
Remove attribute
name.Remove() ⟼ REMOVE Field
func (UpdateExpression[T, A]) Set ¶ added in v2.4.0
func (ue UpdateExpression[T, A]) Set(val A) interface{ UpdateExpression(T) }
Set attribute
name.Inc(x) ⟼ SET Field = :value
func (UpdateExpression[T, A]) SetNotExists ¶ added in v2.4.1
func (ue UpdateExpression[T, A]) SetNotExists(val A) interface{ UpdateExpression(T) }
Set attribute if not exists
name.Inc(x) ⟼ SET Field = if_not_exists(Field, :value)
func (UpdateExpression[T, A]) Union ¶ added in v2.6.0
func (ue UpdateExpression[T, A]) Union(val A) interface{ UpdateExpression(T) }
Add elements to set
name.Union(x) ⟼ ADD Field :value
type UpdateItemExpression ¶ added in v2.4.0
type UpdateItemExpression[T dynamo.Thing] struct {
// contains filtered or unexported fields
}
func Updater ¶ added in v2.4.0
func Updater[T dynamo.Thing](entity T, opts ...interface{ UpdateExpression(T) }) UpdateItemExpression[T]