dynago

package module
v1.4.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 2, 2016 License: MIT Imports: 13 Imported by: 11

README

Dynago

Build Status GoDoc

Dynago is a DynamoDB client API for Go.

Key design tenets of Dynago:

  • Most actions are done via chaining to build filters and conditions
  • objects are completely safe for passing between goroutines (even queries and the like)
  • To make understanding easier via docs, we use Amazon's naming wherever possible.

Installation

Install using go get:

go get gopkg.in/underarmour/dynago.v1

Docs are at http://godoc.org/gopkg.in/underarmour/dynago.v1

Example

Run a query:

client := dynago.NewAwsClient(region, accessKey, secretKey)

query := client.Query(table).
	KeyConditionExpression("UserId = :uid", dynago.P(":uid", 42)).
	FilterExpression("NumViews > :views").
	Param(":views", 50).
	Desc()

result, err := query.Execute()
if err != nil {
	// do something
}
for _, row := range result.Items {
	fmt.Printf("Name: %s, Views: %d", row["Name"], row["NumViews"])
}

Type Marshaling

Dynago lets you use go types instead of having to understand a whole lot about dynamo's internal type system.

Example:

doc := dynago.Document{
	"name": "Bob",
	"age": 45,
	"height": 2.1,
	"address": dynago.Document{
		"city": "Boston",
	},
	"tags": dynago.StringSet{"male", "middle_aged"},
}
client.PutItem("person", doc).Execute()
  • Strings use golang string
  • Numbers can be input as int (int64, uint64, etc) or float64 but always are returned as dynago.Number to not lose precision.
  • Maps can be either map[string]interface{} or dynago.Document
  • Opaque binary data can be put in []byte
  • String sets, number sets, binary sets are supported using dynago.StringSet dynago.NumberSet dynago.BinarySet
  • Lists are supported using dynago.List
  • time.Time is only accepted if it's a UTC time, and is marshaled to a dynamo string in iso8601 compact format. It comes back as a string, an can be got back using GetTime() on Document.

Debugging

Dynago can dump request or response information for you to use in debugging. Simply set dynago.Debug with the necessary flags:

dynago.Debug = dynago.DebugRequests | dynago.DebugResponses

If you would like to change how the debugging is printed, please set dynago.DebugFunc to your preference.

Version Compatibility

Dynago follows Semantic Versioning via the gopkg.in interface, and within the v1 chain, we will not break the existing API or behaviour of existing code using Dynago. We will add new methods and features, but it again should not break code.

Additional resources

The past, and the future

Dynago currently implements all of its support for the underlying DynamoDB API encoding, AWS signing/authentication, etc. This happened in part because the existing libraries out there at the time of writing used deprecated API's and complicated methods, and it was actually cleaner at the time to support the API by fresh implementation.

AWS-SDK-Go exists as of June 2015 and has a very up to date API, but the API is via bare structs which minimally wrap protocol-level details of DynamoDB, resulting in it being very verbose for writing applications (dealing with DynamoDB's internal type system is boilerplatey). Once Amazon has brought it out of developer preview, the plan is to have Dynago use it as the underlying protocol and signature implementation, but keep providing Dynago's clean and simple API for building queries and marshaling datatypes in DynamoDB.

Documentation

Overview

Dynago is a DynamoDB client API for Go.

Dynago differs from other Dynamo clients for Go in that it tries to mirror DynamoDB's core API closely: Most methods, attributes, and names are made following Dynamo's own naming conventions. This allows it to be clear which API is being accessed and allows finding complementary docs on Amazon's side easier.

Filter Chaining

A key design concept is the use of chaining to build filters and conditions, similar to some ORM frameworks. This allows using sub-features like conditional puts, expression post-filtering, and so on to be clearer, because this means a conditional put is simply a PutItem with a condition expression tacked on.

query := client.Query("Table").
    KeyConditionExpression("Foo = :foo", dynago.Param{":foo", 42}).
    Limit(40).Desc()
result, err := query.Execute()

All the various item-based query actions are evaluated when you call the Execute() method on a filter chain.

Type Marshaling

Dynago tries to marshal to/from Go types where possible:

  • Strings use golang string
  • Numbers can be input as int, int64, float64, etc but always are returned as dynago.Number to not lose precision.
  • Maps can be either map[string]interface{} or dynago.Document
  • Opaque binary data can be put in []byte
  • String sets, number sets, binary sets are supported using dynago.StringSet, dynago.NumberSet, dynago.BinarySet
  • Lists are supported using dynago.List
  • time.Time is only accepted if it's a UTC time, and is marshaled to a dynamo string in iso8601 compact format. It comes back as a string, an can be unmarshaled back using GetTime on document.

Query Parameters

Nearly all the operations on items allow using DynamoDB's expression language to do things like query filtering, attribute projection, and so on. In order to provide literal values, queries are parametric, just like many SQL engines:

SET Foo = Foo + :incr
REMOVE Person.#n

DynamoDB has two fields it uses for parameters: ExpressionAttributeNames for name aliases, and ExpressionAttributeValues for parametric values. For simplicity, in the Dynago library both of those are serviced by Param. This is okay because parameters and aliases are non-ambiguous in that the former are named e.g. ":foo" and the latter "#foo".

So a conditional PutItem might look like:

client.PutItem(table, item).
    ConditionExpression("Foo.#n = :fooName").
    Param("#n", "Name").Param(":fooName", "Bob").
    Execute()

In this case, we only execute the query if the value at document path Foo.Name was the string value "Bob". Note we used the "Param" helper for setting both values.

There are also helpers that let you set multiple parameters, or inline with expressions:

query.FilterExpression("#foo > :foo", Param{":foo", 45}, Param{"#foo", "Foo"})
-or-
query.Params(Param{":foo", 45}, Param{"#foo", "Foo"})
-or-
query.Params(Document{":foo":45, "#foo": "Foo"})
Example
package main

import (
	"fmt"
	"gopkg.in/underarmour/dynago.v1"
)

var region, accessKey, secretKey, table string

func main() {
	client := dynago.NewAwsClient(region, accessKey, secretKey)

	query := client.Query(table).
		FilterExpression("NumViews > :views").
		Param(":views", 50).
		Desc()

	result, err := query.Execute()
	if err != nil {
		// do something
	}
	for _, row := range result.Items {
		fmt.Printf("Name: %s, Views: %d", row["Name"], row["NumViews"])
	}
}

func main(client *dynago.Client) {
	type MyStruct struct {
		Id          int64
		Name        string
		Description string
		Tags        []string
		Address     struct {
			City  string
			State string
		}
	}

	var data MyStruct

	doc := dynago.Document{
		// Basic fields like numbers and strings get marshaled automatically
		"Id":          data.Id,
		"Name":        data.Name,
		"Description": data.Description,
		// StringSet is compatible with []string so we can simply cast it
		"Tags": dynago.StringSet(data.Tags),
		// We don't automatically marshal structs, nest it in a document
		"Address": dynago.Document{
			"City":  data.Address.City,
			"State": data.Address.State,
		},
	}

	client.PutItem("Table", doc).Execute()
}
Output:

Index

Examples

Constants

View Source
const (
	ErrorUnknown codes.ErrorCode = iota

	ErrorConditionFailed        // Conditional put/update failed; condition not met
	ErrorCollectionSizeExceeded // Item collection (local secondary index) too large
	ErrorThroughputExceeded     // Exceeded provisioned throughput for table or shard
	ErrorNotFound               // Resource referenced by key not found
	ErrorInternalFailure        // Internal server error
	ErrorAuth                   // Encapsulates various authorization errors
	ErrorInvalidParameter       // Encapsulates many forms of invalid input errors
	ErrorServiceUnavailable     // Amazon service unavailable
	ErrorThrottling             // Amazon is throttling us, try later
	ErrorResourceInUse          // Tried to create existing table, delete a table in CREATING state, etc.

	// DynamoDB Streams-specific errors
	ErrorExpiredIterator // Iterator is no longer valid
	ErrorTrimmedData     // Attempted to access data older than 24h
)

Variables

View Source
var DebugFunc func(format string, v ...interface{}) = func(format string, v ...interface{}) {
	log.Printf("Dynago DEBUG: "+format, v...)
}

DebugFunc is set to control the target of debug output.

Functions

This section is empty.

Types

type AwsExecutor

type AwsExecutor struct {
	// Underlying implementation that makes requests for this executor. It
	// is called to make every request that the executor makes. Swapping the
	// underlying implementation is not thread-safe and therefore not
	// recommended in production code.
	Requester AwsRequester
}

AwsExecutor is the underlying implementation of making requests to DynamoDB.

func NewAwsExecutor

func NewAwsExecutor(endpoint, region, accessKey, secretKey string) *AwsExecutor

Create an AWS executor with a specified endpoint and AWS parameters.

func (*AwsExecutor) BatchGetItem added in v1.2.1

func (e *AwsExecutor) BatchGetItem(b *BatchGet) (result *BatchGetResult, err error)

BatchGetItem gets multiple keys.

func (*AwsExecutor) BatchWriteItem

func (e *AwsExecutor) BatchWriteItem(b *BatchWrite) (result *BatchWriteResult, err error)

BatchWriteItem executes multiple puts/deletes in a single roundtrip.

func (*AwsExecutor) DeleteItem

func (e *AwsExecutor) DeleteItem(d *DeleteItem) (res *DeleteItemResult, err error)

func (*AwsExecutor) GetItem

func (e *AwsExecutor) GetItem(g *GetItem) (result *GetItemResult, err error)

GetItem gets a single item.

func (*AwsExecutor) MakeRequestUnmarshal

func (e *AwsExecutor) MakeRequestUnmarshal(method string, document interface{}, dest interface{}) (err error)

Make a request to the underlying requester, marshaling document as JSON, and if the requester doesn't error, unmarshaling the response back into dest.

This method is mostly exposed for those implementing custom executors or prototyping new functionality.

func (*AwsExecutor) PutItem

func (e *AwsExecutor) PutItem(p *PutItem) (res *PutItemResult, err error)

PutItem on this executor.

func (*AwsExecutor) Query

func (e *AwsExecutor) Query(q *Query) (result *QueryResult, err error)

Query execution logic

func (*AwsExecutor) Scan

func (e *AwsExecutor) Scan(s *Scan) (result *ScanResult, err error)

Scan operation

func (*AwsExecutor) SchemaExecutor

func (e *AwsExecutor) SchemaExecutor() SchemaExecutor

Return a SchemaExecutor making requests on this Executor.

func (*AwsExecutor) UpdateItem

func (e *AwsExecutor) UpdateItem(u *UpdateItem) (result *UpdateItemResult, err error)

UpdateItem on this executor.

type AwsRequester

type AwsRequester interface {
	MakeRequest(target string, body []byte) ([]byte, error)
}

type BatchConsumedCapacity added in v1.4.1

type BatchConsumedCapacity []ConsumedCapacity

Represents multiple consumed capacity responses.

func (BatchConsumedCapacity) GetTable added in v1.4.1

func (b BatchConsumedCapacity) GetTable(tableName string) *ConsumedCapacity

Get the batch consumed capacity for this table.

type BatchGet added in v1.2.1

type BatchGet struct {
	// contains filtered or unexported fields
}

BatchGet allows getting multiple items by key from a table.

func (BatchGet) ConsistentRead added in v1.3.1

func (b BatchGet) ConsistentRead(table string, consistent bool) *BatchGet

ConsistentRead enables strongly consistent reads per-table.

Consistent read is scoped to each table, so must be called for each table in this BatchGet for which you want consistent reads.

func (*BatchGet) Execute added in v1.2.1

func (b *BatchGet) Execute() (result *BatchGetResult, err error)

Execute this batch get.

func (BatchGet) Get added in v1.2.1

func (b BatchGet) Get(table string, keys ...Document) *BatchGet

Get queues some gets for a table. Can be called multiple times to queue up gets for multiple tables.

func (BatchGet) ProjectionExpression added in v1.2.1

func (b BatchGet) ProjectionExpression(table string, expression string, params ...Params) *BatchGet

ProjectionExpression allows the client to specify attributes returned for a table.

Projection expression is scoped to each table, and must be called for each table on which you want a ProjectionExpression.

func (BatchGet) ReturnConsumedCapacity added in v1.4.1

func (b BatchGet) ReturnConsumedCapacity(consumedCapacity CapacityDetail) *BatchGet

ReturnConsumedCapacity enables capacity reporting on this BatchGet

type BatchGetResult added in v1.2.1

type BatchGetResult struct {
	// Responses to the Batch Get query which were resolved.
	// Note that the order of documents is not guaranteed to be the same as
	// the order of documents requested in building this query.
	Responses map[string][]Document // table name -> list of items.

	// Unprocessed keys are keys which for some reason could not be retrieved.
	// This could be because of response size exceeding the limit or the
	// provisioned throughput being exceeded on one or more tables in this request.
	UnprocessedKeys BatchGetTableMap // Table name -> keys and settings

	ConsumedCapacity BatchConsumedCapacity
}

BatchGetResult is the result of a batch get.

type BatchGetTableEntry added in v1.2.1

type BatchGetTableEntry struct {
	Keys []Document

	ProjectionExpression string `json:",omitempty"`
	ConsistentRead       bool   `json:",omitempty"`
	// contains filtered or unexported fields
}

type BatchGetTableMap added in v1.2.1

type BatchGetTableMap map[string]*BatchGetTableEntry

type BatchWrite

type BatchWrite struct {
	// contains filtered or unexported fields
}

BatchWrite allows writing many items in a single roundtrip to DynamoDB.

func (BatchWrite) Delete

func (b BatchWrite) Delete(table string, keys ...Document) *BatchWrite

Delete queues some number of deletes for a table.

func (*BatchWrite) Execute

func (b *BatchWrite) Execute() (*BatchWriteResult, error)

Execute the writes in this batch.

func (BatchWrite) Put

func (b BatchWrite) Put(table string, items ...Document) *BatchWrite

Put queues up some number of puts to a table.

func (BatchWrite) ReturnConsumedCapacity added in v1.4.1

func (b BatchWrite) ReturnConsumedCapacity(consumedCapacity CapacityDetail) *BatchWrite

ReturnConsumedCapacity enables capacity reporting on this Query.

type BatchWriteResult

type BatchWriteResult struct {
	UnprocessedItems BatchWriteTableMap
	ConsumedCapacity BatchConsumedCapacity
}

BatchWriteResult explains what happened in a batch write.

type BatchWriteTableEntry

type BatchWriteTableEntry struct {
	DeleteRequest *batchDelete `json:",omitempty"`
	PutRequest    *batchPut    `json:",omitempty"`
}

BatchWriteTableEntry is a single write or delete request.

func (*BatchWriteTableEntry) SetDelete

func (e *BatchWriteTableEntry) SetDelete(key Document)

SetDelete sets this table entry as a delete request

func (*BatchWriteTableEntry) SetPut

func (e *BatchWriteTableEntry) SetPut(item Document)

SetPut sets this table entry as a put request

type BatchWriteTableMap

type BatchWriteTableMap map[string][]*BatchWriteTableEntry

BatchWriteTableMap describes writes where the key is the table and the value is the unprocessed items.

func (BatchWriteTableMap) GetDeleteKeys

func (m BatchWriteTableMap) GetDeleteKeys(table string) (deletes []Document)

GetDeleteKeys is a convenience method to get delete keys in this batch write map for a specific table

func (BatchWriteTableMap) GetPuts

func (m BatchWriteTableMap) GetPuts(table string) (puts []Document)

GetPuts is a convenience method to get all put documents in this batch write map for a specific table

type BinarySet

type BinarySet [][]byte

BinarySet stores a set of binary blobs in dynamo.

While implemented as a list in Go, DynamoDB does not preserve ordering on set types and so may come back in a different order on retrieval. Use dynago.List if ordering is important.

type Capacity added in v1.4.1

type Capacity struct {
	CapacityUnits float64
}

type CapacityDetail

type CapacityDetail string

CapacityDetail describes what kind of ConsumedCapacity response to get.

const (
	CapacityIndexes CapacityDetail = "INDEXES"
	CapacityTotal   CapacityDetail = "TOTAL"
	CapacityNone    CapacityDetail = "NONE"
)

Define all the ways you can request consumed capacity.

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client is the primary start point of interaction with Dynago.

Client is concurrency safe, and completely okay to be used in multiple threads/goroutines, as are the operations involving chaining on the client.

func NewAwsClient

func NewAwsClient(region string, accessKey string, secretKey string) *Client

NewAwsClient is a shortcut to create a new dynamo client set up for AWS executor.

region is the AWS region, e.g. us-east-1. accessKey is your amazon access key ID. secretKey is your amazon secret key ID.

func NewClient

func NewClient(executor Executor) *Client

NewClient creates a new client from an executor.

For most use cases other than testing and mocking, you should be able to use NewAwsClient which is a shortcut for this

func (*Client) BatchGet added in v1.2.1

func (c *Client) BatchGet() *BatchGet

A BatchGet allows you to get up to 100 keys, in parallel, even across multiple tables, in a single operation.

func (*Client) BatchWrite

func (c *Client) BatchWrite() *BatchWrite

A BatchWrite can compose a number of put or delete, even across multiple tables, in a single operation.

func (*Client) CreateTable

func (c *Client) CreateTable(req *schema.CreateRequest) (*schema.CreateResult, error)

CreateTable makes a new table in your account.

This is not a synchronous operation; the table may take some time before it is actually usable.

func (*Client) DeleteItem

func (c *Client) DeleteItem(table string, key Document) *DeleteItem

DeleteItem lets you delete a single item in a table, optionally with conditions.

func (*Client) DeleteTable

func (c *Client) DeleteTable(table string) (*schema.DeleteResult, error)

DeleteTable deletes an existing table.

func (*Client) DescribeTable

func (c *Client) DescribeTable(table string) (*schema.DescribeResponse, error)

DescribeTable is used to get various attributes about the table.

func (*Client) GetItem

func (c *Client) GetItem(table string, key Document) *GetItem

GetItem gets a single document from a dynamo table.

key should be a Document containing enough attributes to describe the primary key.

You can use the HashKey or HashRangeKey helpers to help build a key:

client.GetItem("foo", dynago.HashKey("Id", 45))

client.GetItem("foo", dynago.HashRangeKey("UserId", 45, "Date", "20140512"))

func (*Client) ListTables

func (c *Client) ListTables() *ListTables

ListTables paginates through all the tables in an account.

func (*Client) PutItem

func (c *Client) PutItem(table string, item Document) *PutItem

PutItem creates or replaces a single document, optionally with conditions.

item should be a document representing the record and containing the attributes for the primary key.

Like all the other requests, you must call `Execute()` to run this.

func (*Client) Query

func (c *Client) Query(table string) *Query

Query returns one or more items with range keys inside a single hash key.

This returns a new Query struct which you can compose via chaining to build the query you want. Then finish the chain by calling Execute() to run the query.

func (*Client) Scan

func (c *Client) Scan(table string) *Scan

Scan can be used to enumerate an entire table or index.

func (*Client) UpdateItem

func (c *Client) UpdateItem(table string, key Document) *UpdateItem

UpdateItem creates or modifies a single document.

UpdateItem will perform its updates even if the document at that key doesn't exist; use a condition if you only want to update existing. documents.

The primary difference between PutItem and UpdateItem is the ability for UpdateItem to use expressions for partial updates of a value.

type ConsumedCapacity added in v1.4.1

type ConsumedCapacity struct {
	// Total capacity units for the entire operation
	CapacityUnits float64

	// Capacity units from local or global secondary indexes
	GlobalSecondaryIndexes map[string]*Capacity
	LocalSecondaryIndexes  map[string]*Capacity

	// Capacity units by table
	TableName string
	Table     *Capacity
}

ConsumedCapacity describes the write or read capacity units consumed by a given operation.

This is provided in a variety DynamoDB responses when consumed capacity detail is explicitly requested, and various elements may be unset or be nil based on the response.

Not all operations set all fields, so expect some of the fields to be empty or nil.

type DebugFlags

type DebugFlags uint

DebugFlags controls Dynago debugging

const (
	DebugRequests DebugFlags = 1 << iota
	DebugResponses
	DebugAuth
)
var Debug DebugFlags

Debug sets the debug mode.

This is a set of bit-flags you can use to set up how much debugging dynago uses:

dynago.Debug = dynago.DebugRequests | dynago.DebugResponses

Debug flags are copied into any executors, requesters, etc at creation time so the flags must be set before creating any Executor or client for them to take effect.

func (DebugFlags) HasFlag

func (v DebugFlags) HasFlag(flag DebugFlags) bool

DebugFlags is a convenience method to check if a value has a flag:

Debug.HasFlags(DebugRequests)

type DeleteItem

type DeleteItem struct {
	// contains filtered or unexported fields
}

func (DeleteItem) ConditionExpression

func (d DeleteItem) ConditionExpression(expression string, params ...Params) *DeleteItem

Set a ConditionExpression to do a conditional DeleteItem.

func (*DeleteItem) Execute

func (d *DeleteItem) Execute() (res *DeleteItemResult, err error)

Actually Execute this putitem.

DeleteItemResult will be nil unless ReturnValues is set.

func (DeleteItem) ReturnConsumedCapacity added in v1.4.1

func (d DeleteItem) ReturnConsumedCapacity(consumedCapacity CapacityDetail) *DeleteItem

func (DeleteItem) ReturnValues

func (d DeleteItem) ReturnValues(returnValues ReturnValues) *DeleteItem

Set ReturnValues. For DeleteItem, it can only be ReturnAllOld

type DeleteItemResult

type DeleteItemResult struct {
	Attributes Document
}

type Document

type Document map[string]interface{}

Document is the core type for many dynamo operations on documents. It is used to represent the root-level document, maps values, and can also be used to supply expression parameters to queries.

func HashKey

func HashKey(name string, value interface{}) Document

HashKey is a shortcut to building keys used for various item operations.

func HashRangeKey

func HashRangeKey(hashName string, hashVal interface{}, rangeName string, rangeVal interface{}) Document

HashRangeKey is a shortcut for building keys used for various item operations.

func (Document) AsParams

func (d Document) AsParams() (params []Param)

AsParams makes Document satisfy the Params interface.

func (Document) GetBool

func (d Document) GetBool(key string) bool

GetBool gets the value specified by key as a boolean.

If the value does not exist in this Document, returns false. If the value is the nil interface, also returns false. If the value is a bool, returns the value of the bool. If the value is a Number, returns true if value is non-zero. For any other values, panics.

func (Document) GetList

func (d Document) GetList(key string) List

GetList gets the value at key as a List.

If value at key is nil, returns a nil list. If value at key is not a List, will panic.

func (Document) GetNumber

func (d Document) GetNumber(key string) Number

GetNumber gets the value at key as a Number.

If the value at key is nil, returns a number containing the empty string. If the value is not a Number or nil, will panic.

func (Document) GetString

func (d Document) GetString(key string) string

GetString gets the value at key as a String.

If the value at key is nil, returns an empty string. If the value at key is not nil or a string, will panic.

func (Document) GetStringSet

func (d Document) GetStringSet(key string) StringSet

GetStringSet gets the value specified by key a StringSet.

If value at key is nil; returns an empty StringSet. If it exists but is not a StringSet, panics.

func (Document) GetTime

func (d Document) GetTime(key string) (t *time.Time)

Helper to get a Time from a document.

If the value is omitted from the DB, or an empty string, then the return is nil. If the value fails to parse as iso8601, then this method panics.

func (Document) MarshalJSON

func (d Document) MarshalJSON() ([]byte, error)

MarshalJSON is used for encoding Document into wire representation.

func (*Document) UnmarshalJSON

func (d *Document) UnmarshalJSON(buf []byte) error

UnmarshalJSON is used for unmarshaling Document from the wire representation.

type Error

type Error struct {
	Type          codes.ErrorCode // Parsed and mapped down type
	AmazonRawType string          // Raw error type from amazon
	Exception     string          // Exception from amazon
	Message       string          // Raw message from amazon
	Request       *http.Request   // If available, HTTP request
	RequestBody   []byte          // If available, raw request body bytes
	Response      *http.Response  // If available, HTTP response
	ResponseBody  []byte          // If available, raw response body bytes
}

Error encapsulates errors coming from amazon/dynamodb. It is returned whenever we get a non-2xx result from dynamodb.

func (*Error) Error

func (e *Error) Error() string

Error formats this error as a string.

type Executor

type Executor interface {
	BatchGetItem(*BatchGet) (*BatchGetResult, error)
	BatchWriteItem(*BatchWrite) (*BatchWriteResult, error)
	DeleteItem(*DeleteItem) (*DeleteItemResult, error)
	GetItem(*GetItem) (*GetItemResult, error)
	PutItem(*PutItem) (*PutItemResult, error)
	Query(*Query) (*QueryResult, error)
	Scan(*Scan) (*ScanResult, error)
	UpdateItem(*UpdateItem) (*UpdateItemResult, error)
	SchemaExecutor() SchemaExecutor
}

Executor defines how all the various queries manage their internal execution logic.

Executor is primarily provided so that testing and mocking can be done on the API level, not just the transport level.

Executor can also optionally return a SchemaExecutor to execute schema actions.

type GetItem

type GetItem struct {
	// contains filtered or unexported fields
}

GetItem is used to get a single item by key from the table.

func (GetItem) ConsistentRead

func (p GetItem) ConsistentRead(strong bool) *GetItem

ConsistentRead enables strongly consistent reads if the argument is true.

func (*GetItem) Execute

func (p *GetItem) Execute() (result *GetItemResult, err error)

Execute the get item.

func (GetItem) Param

func (p GetItem) Param(key string, value interface{}) *GetItem

Param is a shortcut to set a single bound parameter.

func (GetItem) Params

func (p GetItem) Params(params ...Params) *GetItem

Params sets multiple bound parameters on this query.

func (GetItem) ProjectionExpression

func (p GetItem) ProjectionExpression(expression string, params ...Params) *GetItem

ProjectionExpression allows the client to specify which attributes are returned.

func (GetItem) ReturnConsumedCapacity added in v1.4.1

func (p GetItem) ReturnConsumedCapacity(consumedCapacity CapacityDetail) *GetItem

ReturnConsumedCapacity enables capacity reporting on this GetItem. Defaults to CapacityNone if not set

type GetItemResult

type GetItemResult struct {
	Item             Document
	ConsumedCapacity *ConsumedCapacity
}

GetItemResult is the result from executing a GetItem.

type List

type List []interface{}

List represents DynamoDB lists, which are functionally very similar to JSON lists. Like JSON lists, these lists are heterogeneous, which means that the elements of the list can be any valid value type, which includes other lists, documents, numbers, strings, etc.

Example
l := dynago.List{
	1234,
	"Foo",
	dynago.Document{"Foo": "Bar"},
}
fmt.Printf("%s", l[1]) 
Output:

Foo

func (List) AsDocumentList

func (l List) AsDocumentList() ([]Document, error)

Return a copy of this list with all elements coerced as Documents.

It's very common to use lists in dynago where all elements in the list are a Document. For that reason, this method is provided as a convenience to get back your list as a list of documents.

If any element in the List is not a document, this will error. As a convenience, even when it errors, a slice containing any elements preceding the one which errored as documents will be given.

type ListTables

type ListTables struct {
	// contains filtered or unexported fields
}

ListTables lists tables in your account.

func (*ListTables) Execute

func (l *ListTables) Execute() (result *ListTablesResult, err error)

Execute this ListTables request

func (ListTables) Limit

func (l ListTables) Limit(limit uint) *ListTables

Limit the number of results returned.

type ListTablesResult

type ListTablesResult struct {
	TableNames []string
	// contains filtered or unexported fields
}

ListTablesResult is a helper for paginating.

func (ListTablesResult) Next

func (r ListTablesResult) Next() *ListTables

Next will get the ListTables for the next page of listings. If there is not a next page, returns nil.

type MockExecutor

type MockExecutor struct {
	Calls []MockExecutorCall // All calls made through this executor

	DeleteItemCalled bool
	DeleteItemCall   *MockExecutorCall
	DeleteItemResult *DeleteItemResult
	DeleteItemError  error

	PutItemCalled bool
	PutItemCall   *MockExecutorCall
	PutItemResult *PutItemResult
	PutItemError  error

	GetItemCalled bool
	GetItemCall   *MockExecutorCall
	GetItemResult *GetItemResult
	GetItemError  error

	BatchGetItemCalled bool
	BatchGetItemCall   *MockExecutorCall
	BatchGetItemResult *BatchGetResult

	BatchWriteItemCalled bool
	BatchWriteItemCall   *MockExecutorCall
	BatchWriteItemError  error

	QueryCalled bool              // True if query was called at least once
	QueryCall   *MockExecutorCall // Info for the last call to Query
	QueryError  error             // Specify the error from Query
	QueryResult *QueryResult      // Specify the result from Query

	ScanCalled bool
	ScanCall   *MockExecutorCall
	ScanResult *ScanResult
	ScanError  error

	UpdateItemCalled bool
	UpdateItemCall   *MockExecutorCall
	UpdateItemResult *UpdateItemResult
	UpdateItemError  error
}

MockExecutor is a fake executor to help with building tests.

This Executor doesn't actually run any network requests, so it can be used in unit testing for your own application which uses Dynago. It can be asserted on whether a specific underlying method got called, what it was called with, and the nature of how the query was built. You can also for most methods control which result is returned in order to control how results make it back to the application.

// example, normally you'd call into a real application not inside your
// test module and use dependency injection to specify the client.
func application(client *dynago.Client) int {
	result, err := client.PutItem("mytable", doc).Execute()
	// do something with result maybe.
}

func TestApplication() {
	executor := &dynago.MockExecutor{}
	client := dynago.NewClient(executor)
	executor.PutItemResult = &dynago.PutItemResult{}

	// call into application
	application(client)

	// assert things on the executor.
	assert.Equal(true, executor.PutItemCalled)
	assert.Equal("mytable", executor.PutItemCall.Table)
	... and so on
}

func (*MockExecutor) BatchGetItem added in v1.2.1

func (e *MockExecutor) BatchGetItem(batchGet *BatchGet) (*BatchGetResult, error)

func (*MockExecutor) BatchWriteItem

func (e *MockExecutor) BatchWriteItem(batchWrite *BatchWrite) (*BatchWriteResult, error)

func (*MockExecutor) DeleteItem

func (e *MockExecutor) DeleteItem(deleteItem *DeleteItem) (*DeleteItemResult, error)

func (*MockExecutor) GetItem

func (e *MockExecutor) GetItem(getItem *GetItem) (*GetItemResult, error)

func (*MockExecutor) PutItem

func (e *MockExecutor) PutItem(putItem *PutItem) (*PutItemResult, error)

func (*MockExecutor) Query

func (e *MockExecutor) Query(query *Query) (*QueryResult, error)

func (*MockExecutor) Scan

func (e *MockExecutor) Scan(scan *Scan) (*ScanResult, error)

func (*MockExecutor) SchemaExecutor

func (e *MockExecutor) SchemaExecutor() SchemaExecutor

Currently we don't implement mocking for SchemaExecutor. Returns nil.

func (*MockExecutor) UpdateItem

func (e *MockExecutor) UpdateItem(update *UpdateItem) (*UpdateItemResult, error)

type MockExecutorCall

type MockExecutorCall struct {
	// used for all calls
	Method string
	Table  string

	// used for calls with expressions (most of them)
	ExpressionAttributeNames  map[string]string
	ExpressionAttributeValues Document

	Key                 Document
	Item                Document
	UpdateExpression    string
	ConditionExpression string
	ReturnValues        ReturnValues
	ConsistentRead      bool

	// Query and Scan
	IndexName              string
	KeyConditionExpression string
	FilterExpression       string
	ProjectionExpression   string
	Ascending              bool
	Limit                  uint
	ExclusiveStartKey      Document
	Select                 Select
	Segment                *int
	TotalSegments          *int

	BatchWrites BatchWriteTableMap
	BatchGets   BatchGetTableMap

	ReturnConsumedCapacity CapacityDetail
}

MockExecutorCall is created for all calls into this executor.

This allows for inspecting in a safe manner the attributes which would have been sent to DynamoDB. Only attributes relevant to the call in question are set.

type Number

type Number string

A Number.

DynamoDB returns numbers as a string representation because they have a single high-precision number type that can take the place of integers, floats, and decimals for the majority of types.

This method has helpers to get the value of this number as one of various Golang numeric types.

func (Number) FloatVal

func (n Number) FloatVal() (float64, error)

FloatVal interprets this number as a floating point. error is returned if this number is not well-formed.

func (Number) Int64Val

func (n Number) Int64Val() (int64, error)

Int64Val interprets this number as an integer in base-10. error is returned if this string cannot be parsed as base 10 or is too large.

func (Number) IntVal

func (n Number) IntVal() (int, error)

IntVal interprets this number as an integer in base-10. error is returned if this is not a valid number or is too large.

func (Number) Uint64Val

func (n Number) Uint64Val() (uint64, error)

Uint64Val interprets this number as an unsigned integer. error is returned if this is not a valid positive integer or cannot fit.

type NumberSet

type NumberSet []string

NumberSet is an un-ordered set of numbers.

Sets in DynamoDB do not guarantee any ordering, so storing and retrieving a NumberSet may not give you back the same order you put it in. The main advantage of using sets in DynamoDB is using atomic updates with ADD and DELETE in your UpdateExpression.

type Param

type Param struct {
	Key   string
	Value interface{}
}

Param can be used as a single parameter.

func (Param) AsParams

func (p Param) AsParams() []Param

AsParsms allows a solo Param to also satisfy the Params interface

type Params

type Params interface {
	AsParams() []Param
}

Params encapsulates anything which can be used as expression parameters for dynamodb expressions.

DynamoDB item queries using expressions can be provided parameters in a number of handy ways:

.Param(":k1", v1).Param(":k2", v2)
-or-
.Params(P(":k1", v1), P(":k2", v2))
-or-
.FilterExpression("...", P(":k1", v1), P(":k2", v2))
-or-
.FilterExpression("...", Document{":k1": v1, ":k2": v2})

Or any combination of Param, Document, or potentially other custom types which provide the Params interface.

func P added in v1.4.2

func P(key string, value interface{}) Params

P is a shortcut to create a single dynago Param. This is mainly for brevity especially with cross-package imports.

type PutItem

type PutItem struct {
	// contains filtered or unexported fields
}

PutItem is used to create/replace single items in the table.

func (PutItem) ConditionExpression

func (p PutItem) ConditionExpression(expression string, params ...Params) *PutItem

ConditionExpression sets a condition which if not satisfied, the PutItem is not performed.

func (*PutItem) Execute

func (p *PutItem) Execute() (res *PutItemResult, err error)

Execute this PutItem.

PutItemResult will be nil unless ReturnValues or ReturnConsumedCapacity is set.

func (PutItem) Param

func (p PutItem) Param(key string, value interface{}) *PutItem

Param is a shortcut to set a single bound parameter.

func (PutItem) Params

func (p PutItem) Params(params ...Params) *PutItem

Params sets multiple bound parameters on this query.

func (PutItem) ReturnConsumedCapacity added in v1.4.1

func (p PutItem) ReturnConsumedCapacity(consumedCapacity CapacityDetail) *PutItem

ReturnConsumedCapacity enables capacity reporting on this PutItem.

func (PutItem) ReturnValues

func (p PutItem) ReturnValues(returnValues ReturnValues) *PutItem

ReturnValues can allow you to ask for either previous or new values on an update

type PutItemResult

type PutItemResult struct {
	Attributes       Document
	ConsumedCapacity *ConsumedCapacity
}

PutItemResult is returned when a PutItem is executed.

type Query

type Query struct {
	// contains filtered or unexported fields
}

Query is used to return items in the same hash key.

func (Query) ConsistentRead

func (q Query) ConsistentRead(strong bool) *Query

If strong is true, do a strongly consistent read. (defaults to false)

func (*Query) Desc

func (q *Query) Desc() *Query

Desc makes this query return results descending. Equivalent to q.ScanIndexForward(false)

func (Query) ExclusiveStartKey

func (q Query) ExclusiveStartKey(key Document) *Query

Set the start key (effectively the offset cursor)

func (*Query) Execute

func (q *Query) Execute() (result *QueryResult, err error)

Execute this query and return results.

func (Query) FilterExpression

func (q Query) FilterExpression(expression string, params ...Params) *Query

FilterExpression sets a post-filter expression for the results we scan.

func (Query) IndexName

func (q Query) IndexName(name string) *Query

IndexName specifies to query via a secondary index instead of the table's primary key.

func (Query) KeyConditionExpression

func (q Query) KeyConditionExpression(expression string, params ...Params) *Query

KeyConditionExpression sets a condition expression on the key to narrow down what we scan.

func (Query) Limit

func (q Query) Limit(limit uint) *Query

Set the limit on results count.

Note that getting less than `limit` records doesn't mean you're at the last page of results, that can only be safely asserted if there is no LastEvaluatedKey on the result.

func (Query) Param

func (q Query) Param(key string, value interface{}) *Query

Param is a shortcut to set a single bound parameter.

func (Query) Params

func (q Query) Params(params ...Params) *Query

Params sets multiple bound parameters on this query.

func (Query) ProjectionExpression

func (q Query) ProjectionExpression(expression string, params ...Params) *Query

ProjectionExpression allows the client to specify which attributes are returned.

func (Query) ReturnConsumedCapacity added in v1.4.1

func (q Query) ReturnConsumedCapacity(consumedCapacity CapacityDetail) *Query

ReturnConsumedCapacity enables capacity reporting on this Query. Defaults to CapacityNone if not set

func (Query) ScanIndexForward added in v1.3.1

func (q Query) ScanIndexForward(forward bool) *Query

Whether to scan the query index forward (true) or backwards (false).

Defaults to forward (true) if not called.

func (Query) Select added in v1.1.2

func (q Query) Select(value Select) *Query

Select specifies how attributes are chosen, or enables count mode.

Most of the time, specifying Select is not required, because the DynamoDB API does the "right thing" inferring values based on other attributes like the projection expression, index, etc.

type QueryResult

type QueryResult struct {
	Items            []Document // All the items in the result
	Count            int        // The total number of items in the result
	ScannedCount     int        // How many items were scanned past to get the result
	LastEvaluatedKey Document   // The offset key for the next page.

	// ConsumedCapacity is only set if ReturnConsumedCapacity is given.
	ConsumedCapacity *ConsumedCapacity
	// contains filtered or unexported fields
}

QueryResult is the result returned from a query.

func (*QueryResult) Next

func (qr *QueryResult) Next() (query *Query)

Next returns a query which get the next page of results when executed. Returns nil if there's no next page.

type ReturnValues

type ReturnValues string

ReturnValues enable returning some or all changed data from put operations.

const (
	ReturnNone       ReturnValues = "NONE"
	ReturnAllOld     ReturnValues = "ALL_OLD"
	ReturnUpdatedOld ReturnValues = "UPDATED_OLD"
	ReturnAllNew     ReturnValues = "ALL_NEW"
	ReturnUpdatedNew ReturnValues = "UPDATED_NEW"
)

type Scan

type Scan struct {
	// contains filtered or unexported fields
}

func (Scan) ExclusiveStartKey

func (s Scan) ExclusiveStartKey(key Document) *Scan

ExclusiveStartKey sets the start key (effectively the offset cursor).

func (*Scan) Execute

func (s *Scan) Execute() (*ScanResult, error)

Execute this Scan query.

func (Scan) FilterExpression

func (s Scan) FilterExpression(expression string, params ...Params) *Scan

FilterExpression post-filters results on this scan.

Scans with a FilterExpression may return 0 results due to scanning past records which don't match the filter, but still have more results to get.

func (Scan) IndexName

func (s Scan) IndexName(name string) *Scan

IndexName specifies a secondary index to scan instead of a table.

func (Scan) Limit

func (s Scan) Limit(limit uint) *Scan

Limit the maximum number of results to return per call.

func (Scan) ProjectionExpression

func (s Scan) ProjectionExpression(expression string, params ...Params) *Scan

ProjectionExpression allows the client to specify which attributes are returned.

func (Scan) ReturnConsumedCapacity added in v1.4.1

func (s Scan) ReturnConsumedCapacity(consumedCapacity CapacityDetail) *Scan

ReturnConsumedCapacity enables capacity reporting on this Query.

func (Scan) Segment

func (s Scan) Segment(segment, total int) *Scan

Segment chooses the parallel segment of the table to scan.

func (Scan) Select added in v1.1.2

func (s Scan) Select(value Select) *Scan

Select specifies how attributes are chosen, or enables count mode.

Most of the time, specifying Select is not required, because the DynamoDB API does the "right thing" inferring values based on other attributes like the projection expression, index, etc.

type ScanResult

type ScanResult struct {
	Items            []Document
	LastEvaluatedKey Document
	ConsumedCapacity *ConsumedCapacity
	// contains filtered or unexported fields
}

ScanResult is the result of Scan queries.

func (*ScanResult) Next

func (r *ScanResult) Next() *Scan

Next returns a scan which get the next page of results when executed.

If the scan has a LastEvaluatedKey, returns another Scan. Otherwise, returns nil.

type SchemaExecutor

type SchemaExecutor interface {
	CreateTable(*schema.CreateRequest) (*schema.CreateResult, error)
	DeleteTable(*schema.DeleteRequest) (*schema.DeleteResult, error)
	DescribeTable(*schema.DescribeRequest) (*schema.DescribeResponse, error)
	ListTables(*ListTables) (*schema.ListResponse, error)
}

SchemaExecutors implement schema management commands.

type Select

type Select string

Select describes which attributes to return in Scan and Query operations.

const (
	SelectAllAttributes      Select = "ALL_ATTRIBUTES"
	SelectAllProjected       Select = "ALL_PROJECTED_ATTRIBUTES"
	SelectCount              Select = "COUNT"
	SelectSpecificAttributes Select = "SPECIFIC_ATTRIBUTES"
)

type StringSet

type StringSet []string

StringSet is an un-ordered collection of distinct strings.

Sets in DynamoDB do not guarantee any ordering, so storing and retrieving a StringSet may not give you back the same order you put it in. The main advantage of using sets in DynamoDB is using atomic updates with ADD and DELETE in your UpdateExpression.

type UpdateItem

type UpdateItem struct {
	// contains filtered or unexported fields
}

UpdateItem is used to modify a single item in a table.

func (UpdateItem) ConditionExpression

func (u UpdateItem) ConditionExpression(expression string, params ...Params) *UpdateItem

ConditionExpression sets a condition which if not satisfied, the PutItem is not performed.

func (*UpdateItem) Execute

func (u *UpdateItem) Execute() (res *UpdateItemResult, err error)

Execute this UpdateItem and return the result.

func (UpdateItem) Param

func (u UpdateItem) Param(key string, value interface{}) *UpdateItem

Param is a shortcut to set a single bound parameter.

func (UpdateItem) Params

func (u UpdateItem) Params(params ...Params) *UpdateItem

Params sets multiple bound parameters on this query.

func (UpdateItem) ReturnValues

func (u UpdateItem) ReturnValues(returnValues ReturnValues) *UpdateItem

ReturnValues allows you to get return values of either updated or old fields (see ReturnValues const)

func (UpdateItem) UpdateExpression

func (u UpdateItem) UpdateExpression(expression string, params ...Params) *UpdateItem

UpdateExpression defines the operations which will be performed by this update.

UpdateExpression("SET Field1=:val1, Field2=:val2 DELETE Field3")

Expression values cannot be provided inside the expression strings, they must be referenced by the :param values.

See http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.Modifying.html for more information on how to use update expression strings

type UpdateItemResult

type UpdateItemResult struct {
	Attributes Document
}

UpdateItemResult is returned when ReturnValues is set on the UpdateItem.

Directories

Path Synopsis
internal
aws
Package aws handles AWS signature v4 and other AWS-specific auth functions.
Package aws handles AWS signature v4 and other AWS-specific auth functions.
codes
Package codes defines the error types dynago maps.
Package codes defines the error types dynago maps.
dynamodb
Package dynamodb maps information from dynamo itself, such as error tables and formats.
Package dynamodb maps information from dynamo itself, such as error tables and formats.
Package streams is a client for DynamoDB Streams within Dynago.
Package streams is a client for DynamoDB Streams within Dynago.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL