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 Option
- type Options
- type Storage
- func (db *Storage[T]) BatchGet(ctx context.Context, keys []T, opts ...interface{ GetterOpt(T) }) ([]T, error)
- func (db *Storage[T]) Get(ctx context.Context, key T, opts ...interface{ GetterOpt(T) }) (T, error)
- func (db *Storage[T]) Match(ctx context.Context, key T, opts ...interface{ MatcherOpt(T) }) ([]T, interface{ ... }, error)
- func (db *Storage[T]) MatchKey(ctx context.Context, key dynamo.Thing, opts ...interface{ MatcherOpt(T) }) ([]T, interface{ ... }, error)
- func (db *Storage[T]) Put(ctx context.Context, entity T, opts ...interface{ WriterOpt(T) }) error
- func (db *Storage[T]) Remove(ctx context.Context, key T, opts ...interface{ WriterOpt(T) }) (T, error)
- func (db *Storage[T]) Update(ctx context.Context, entity T, opts ...interface{ WriterOpt(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 ¶
type ConditionExpression[T dynamo.Thing, A any] struct { // contains filtered or unexported fields }
func ClauseFor ¶
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 ¶
func (ce ConditionExpression[T, A]) Between(a, b A) interface{ WriterOpt(T) }
Between attribute condition
name.Between(a, b) ⟼ Field BETWEEN :a AND :b
func (ConditionExpression[T, A]) Contains ¶
func (ce ConditionExpression[T, A]) Contains(val A) interface{ WriterOpt(T) }
Contains attribute condition
name.Contains(x) ⟼ contains(Field, :value)
func (ConditionExpression[T, A]) Eq ¶
func (ce ConditionExpression[T, A]) Eq(val A) interface{ WriterOpt(T) }
Eq is equal condition
name.Eq(x) ⟼ Field = :value
func (ConditionExpression[T, A]) Exists ¶
func (ce ConditionExpression[T, A]) Exists() interface{ WriterOpt(T) }
Exists attribute constrain
name.Exists(x) ⟼ attribute_exists(name)
func (ConditionExpression[T, A]) Ge ¶
func (ce ConditionExpression[T, A]) Ge(val A) interface{ WriterOpt(T) }
Ge is greater or equal constrain
name.Le(x) ⟼ Field >= :value
func (ConditionExpression[T, A]) Gt ¶
func (ce ConditionExpression[T, A]) Gt(val A) interface{ WriterOpt(T) }
Gt is greater than constrain
name.Le(x) ⟼ Field > :value
func (ConditionExpression[T, A]) HasPrefix ¶
func (ce ConditionExpression[T, A]) HasPrefix(val A) interface{ WriterOpt(T) }
HasPrefix attribute condition
name.HasPrefix(x) ⟼ begins_with(Field, :value)
func (ConditionExpression[T, A]) In ¶
func (ce ConditionExpression[T, A]) In(seq ...A) interface{ WriterOpt(T) }
In attribute condition
name.Between(a, b, c) ⟼ Field IN (:a, :b, :c)
func (ConditionExpression[T, A]) Is ¶
func (ce ConditionExpression[T, A]) Is(val string) interface{ WriterOpt(T) }
Is matches either Eq or NotExists if value is not defined
func (ConditionExpression[T, A]) Le ¶
func (ce ConditionExpression[T, A]) Le(val A) interface{ WriterOpt(T) }
Le is less or equal constain
name.Le(x) ⟼ Field <= :value
func (ConditionExpression[T, A]) Lt ¶
func (ce ConditionExpression[T, A]) Lt(val A) interface{ WriterOpt(T) }
Lt is less than constraint
name.Lt(x) ⟼ Field < :value
func (ConditionExpression[T, A]) Ne ¶
func (ce ConditionExpression[T, A]) Ne(val A) interface{ WriterOpt(T) }
Ne is non equal condition
name.Ne(x) ⟼ Field <> :value
func (ConditionExpression[T, A]) NotExists ¶
func (ce ConditionExpression[T, A]) NotExists() interface{ WriterOpt(T) }
NotExists attribute constrain
name.NotExists(x) ⟼ attribute_not_exists(name)
type DynamoDB ¶
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 Option ¶
type Option func(*Options)
Option type to configure the S3
func WithGlobalSecondaryIndex ¶
WithTable defines dynamodb table
func WithHashKey ¶
WithHashKey defines custom name of HashKey, default one is "prefix"
func WithPrefixes ¶
WithPrefixes defines prefixes for CURIEs
func WithService ¶
Configure AWS Service for broker instance
func WithSortKey ¶
WithHashKey defines custom name of SortKey, default one is "suffix"
func WithStrictType ¶
WithTypeSchema demand that storage schema "knows" all type attributes
type Storage ¶
type Storage[T dynamo.Thing] struct {
// contains filtered or unexported fields
}
Storage type
func (*Storage[T]) Match ¶
func (db *Storage[T]) Match(ctx context.Context, key T, opts ...interface{ MatcherOpt(T) }) ([]T, interface{ MatcherOpt(T) }, error)
Match applies a pattern matching to elements in the table
func (*Storage[T]) MatchKey ¶
func (db *Storage[T]) MatchKey(ctx context.Context, key dynamo.Thing, opts ...interface{ MatcherOpt(T) }) ([]T, interface{ MatcherOpt(T) }, error)
Match applies a pattern matching to elements in the table
func (*Storage[T]) Remove ¶
func (db *Storage[T]) Remove(ctx context.Context, key T, opts ...interface{ WriterOpt(T) }) (T, error)
Remove discards the entity from the table
func (*Storage[T]) Update ¶
func (db *Storage[T]) Update(ctx context.Context, entity T, opts ...interface{ WriterOpt(T) }) (T, error)
Update applies a partial patch to entity and returns new values
func (*Storage[T]) UpdateWith ¶
func (db *Storage[T]) UpdateWith(ctx context.Context, expression UpdateItemExpression[T], opts ...interface{ WriterOpt(T) }) (T, error)
Update applies a partial patch to entity using update expression abstraction
type UpdateExpression ¶
type UpdateExpression[T dynamo.Thing, A any] struct { // contains filtered or unexported fields }
func UpdateFor ¶
func UpdateFor[T dynamo.Thing, A any](attr ...string) UpdateExpression[T, A]
func (UpdateExpression[T, A]) Add ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
func (ue UpdateExpression[T, A]) Remove() interface{ UpdateExpression(T) }
Remove attribute
name.Remove() ⟼ REMOVE Field
func (UpdateExpression[T, A]) Set ¶
func (ue UpdateExpression[T, A]) Set(val A) interface{ UpdateExpression(T) }
Set attribute
name.Inc(x) ⟼ SET Field = :value
func (UpdateExpression[T, A]) SetNotExists ¶
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 ¶
func (ue UpdateExpression[T, A]) Union(val A) interface{ UpdateExpression(T) }
Add elements to set
name.Union(x) ⟼ ADD Field :value
type UpdateItemExpression ¶
type UpdateItemExpression[T dynamo.Thing] struct {
// contains filtered or unexported fields
}
func Updater ¶
func Updater[T dynamo.Thing](entity T, opts ...interface{ UpdateExpression(T) }) UpdateItemExpression[T]