Categorygithub.com/nguyengg/go-aws-commons/ddb
package
0.2.2
Repository: https://github.com/nguyengg/go-aws-commons.git
Documentation: pkg.go.dev

# Packages

No description provided by the author
No description provided by the author

# README

DynamoDB goodies

Go Reference

This module adds optimistic locking and auto-generated timestamps by modifying the expressions being created as part of a DynamoDB service call.

Usage

Get with:

go get github.com/nguyengg/go-aws-commons/ddb
package main

import (
	"context"
	"time"

	"github.com/aws/aws-sdk-go-v2/service/dynamodb/types"
	"github.com/nguyengg/go-aws-commons/ddb"
)

type Item struct {
	Id           string    `dynamodbav:"id,hashkey" tableName:"my-table"`
	Sort         string    `dynamodbav:"sort,sortkey"`
	Version      int64     `dynamodbav:"version,version"`
	CreatedTime  time.Time `dynamodbav:"createdTime,createdTime,unixtime"`
	ModifiedTime time.Time `dynamodbav:"modifiedTime,modifiedTime,unixtime"`
}

func main() {
	ctx := context.TODO()

	// ddbfns.Put and ddbfns.Update is smart enough to add condition expression for me.
	item := Item{
		Id:   "hello",
		Sort: "world",
		// Since version has zero value, ddbfns.Put and ddbfns.Put will add a condition expression that's basically
		// `attribute_not_exists (id)`, and increment the version's value in the request for me.
		Version: 0,
		// Since these timestamps have zero value, they will be updated to the same time.Now in the request for me.
		CreatedTime:  time.Time{},
		ModifiedTime: time.Time{},
	}

	// my original item is never mutated by ddbfns.
	// Instead, the map[string]AttributeValue sent to DynamoDB is the one that is modified along with its
	// the request's ConditionExpression, ExpressionAttributeNames, and ExpressionAttributeValues.
	_, _ = ddb.Put(ctx, item)

	// If the version is not at zero value, ddbfns.Put and ddbfns.Update knows to add `#version = :old_value` instead.
	item = Item{
		Id:   "hello",
		Sort: "world",
		// Since version has non-zero value, ddbfns.Put and ddbfns.Put will add `#version = 3` instead, and increment
		// the version's value in the request for me.
		Version: 3,
		// In ddbfns.Update, only ModifiedTime is updated with a `SET #modifiedTime = :now`.
		ModifiedTime: time.Time{},
	}

	// Update requires me to specify at least one update expression. Here's an example of how to return updated values
	// as well.
	_, _ = ddb.Update(ctx, Item{Id: "hello", Sort: " world", Version: 3}, func(options *ddb.UpdateOptions) {
		options.
			Set("anotherField", "notes").
			// by passing a struct pointer to WithReturnValues, ddbfns will unmarshall the response to
			// this struct so that item will have updated attribute values.
			WithReturnValues(types.ReturnValueAllNew, &item)
	})

	// ddbfns.Delete will only use the version attribute, and it does not care if the attribute has zero value or not
	// (i.e. you can't attempt to delete an item that doesn't exist).
	_, _ = ddb.Delete(ctx, Item{
		Id: "hello",
		// Even if the version's value was 0, `SET #version = :old_value` is used regardless.
		Version: 3,
	})

	// ddbfns.Get accepts a key which can be struct or struct pointer, and an optional struct pointer argument to
	// unmarshal the response of the GetItem request.
	item = Item{}
	_, _ = ddb.Get(ctx, Item{Id: "hello", Sort: "world"}, &item)
}