Skip to content

Commit

Permalink
support on-demand billing mode in CreateTable and UpdateTable
Browse files Browse the repository at this point in the history
also table Description
(resolves #87)
  • Loading branch information
guregu committed Feb 26, 2019
1 parent c966a18 commit 1a59fd6
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 12 deletions.
22 changes: 18 additions & 4 deletions createtable.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ type CreateTable struct {
readUnits int64
writeUnits int64
streamView StreamView
ondemand bool
err error
}

Expand Down Expand Up @@ -81,8 +82,15 @@ func (db *DB) CreateTable(name string, from interface{}) *CreateTable {
return ct
}

// OnDemand specifies to create the table with on-demand (pay per request) billing mode,
// if enabled. On-demand mode is disabled by default.
func (ct *CreateTable) OnDemand(enabled bool) *CreateTable {
ct.ondemand = enabled
return ct
}

// Provision specifies the provisioned read and write capacity for this table.
// If Provision isn't called, the table will be created with 1 unit each.
// If Provision isn't called and on-demand mode is disabled, the table will be created with 1 unit each.
func (ct *CreateTable) Provision(readUnits, writeUnits int64) *CreateTable {
ct.readUnits, ct.writeUnits = readUnits, writeUnits
return ct
Expand Down Expand Up @@ -283,10 +291,14 @@ func (ct *CreateTable) input() *dynamodb.CreateTableInput {
TableName: &ct.tableName,
AttributeDefinitions: ct.attribs,
KeySchema: ct.schema,
ProvisionedThroughput: &dynamodb.ProvisionedThroughput{
}
if ct.ondemand {
input.BillingMode = aws.String(dynamodb.BillingModePayPerRequest)
} else {
input.ProvisionedThroughput = &dynamodb.ProvisionedThroughput{
ReadCapacityUnits: &ct.readUnits,
WriteCapacityUnits: &ct.writeUnits,
},
}
}
if ct.streamView != "" {
enabled := true
Expand Down Expand Up @@ -324,7 +336,9 @@ func (ct *CreateTable) input() *dynamodb.CreateTableInput {
ProjectionType: &all,
}
}
if idx.ProvisionedThroughput == nil {
if ct.ondemand {
idx.ProvisionedThroughput = nil
} else if idx.ProvisionedThroughput == nil {
units := int64(1)
idx.ProvisionedThroughput = &dynamodb.ProvisionedThroughput{
ReadCapacityUnits: &units,
Expand Down
6 changes: 6 additions & 0 deletions describetable.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ type Description struct {

// Provisioned throughput for this table.
Throughput Throughput
// OnDemand is true if on-demand (pay per request) billing mode is enabled.
OnDemand bool

// The number of items of the table, updated every 6 hours.
Items int64
Expand Down Expand Up @@ -104,6 +106,10 @@ func newDescription(table *dynamodb.TableDescription) Description {
desc.HashKeyType = lookupADType(table.AttributeDefinitions, desc.HashKey)
desc.RangeKeyType = lookupADType(table.AttributeDefinitions, desc.RangeKey)

if table.BillingModeSummary != nil && table.BillingModeSummary.BillingMode != nil {
desc.OnDemand = *table.BillingModeSummary.BillingMode == dynamodb.BillingModePayPerRequest
}

if table.ProvisionedThroughput != nil {
desc.Throughput = newThroughput(table.ProvisionedThroughput)
}
Expand Down
30 changes: 22 additions & 8 deletions updatetable.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ type UpdateTable struct {
table Table
r, w int64 // throughput

billingMode *string

disableStream bool
streamView StreamView

Expand All @@ -32,6 +34,17 @@ func (table Table) UpdateTable() *UpdateTable {
}
}

// OnDemand sets this table to use on-demand (pay per request) billing mode if enabled is true.
// If enabled is false, this table will be changed to provisioned billing mode.
func (ut *UpdateTable) OnDemand(enabled bool) *UpdateTable {
if enabled {
ut.billingMode = aws.String(dynamodb.BillingModePayPerRequest)
} else {
ut.billingMode = aws.String(dynamodb.BillingModeProvisioned)
}
return ut
}

// Provision sets this table's read and write throughput capacity.
func (ut *UpdateTable) Provision(read, write int64) *UpdateTable {
ut.r, ut.w = read, write
Expand All @@ -45,7 +58,8 @@ func (ut *UpdateTable) ProvisionIndex(name string, read, write int64) *UpdateTab
}

// CreateIndex adds a new secondary global index.
// You must specify the index name, keys, key types, projection, and throughput.
// You must specify the index name, keys, key types, projection.
// If this table is not on-demand you must also specify throughput.
func (ut *UpdateTable) CreateIndex(index Index) *UpdateTable {
if index.Name == "" {
ut.err = errors.New("dynamo: update table: missing index name")
Expand All @@ -62,9 +76,6 @@ func (ut *UpdateTable) CreateIndex(index Index) *UpdateTable {
if index.ProjectionType == "" {
ut.err = errors.New("dynamo: update table: missing projection type")
}
if index.Throughput.Read < 1 || index.Throughput.Write < 1 {
ut.err = errors.New("dynamo: update table: throughput read and write must be 1 or more")
}

ut.addAD(index.HashKey, index.HashKeyType)
if index.RangeKey != "" {
Expand Down Expand Up @@ -124,6 +135,7 @@ func (ut *UpdateTable) input() *dynamodb.UpdateTableInput {
input := &dynamodb.UpdateTableInput{
TableName: aws.String(ut.table.Name()),
AttributeDefinitions: ut.ads,
BillingMode: ut.billingMode,
}

if ut.r != 0 || ut.w != 0 {
Expand Down Expand Up @@ -196,14 +208,16 @@ func createIndexAction(index Index) *dynamodb.CreateGlobalSecondaryIndexAction {
add := &dynamodb.CreateGlobalSecondaryIndexAction{
IndexName: &index.Name,
KeySchema: ks,
ProvisionedThroughput: &dynamodb.ProvisionedThroughput{
ReadCapacityUnits: aws.Int64(index.Throughput.Read),
WriteCapacityUnits: aws.Int64(index.Throughput.Write),
},
Projection: &dynamodb.Projection{
ProjectionType: aws.String((string)(index.ProjectionType)),
},
}
if index.Throughput.Read > 0 && index.Throughput.Write > 0 {
add.ProvisionedThroughput = &dynamodb.ProvisionedThroughput{
ReadCapacityUnits: aws.Int64(index.Throughput.Read),
WriteCapacityUnits: aws.Int64(index.Throughput.Write),
}
}
if index.ProjectionType == IncludeProjection {
add.Projection.NonKeyAttributes = aws.StringSlice(index.ProjectionAttribs)
}
Expand Down

0 comments on commit 1a59fd6

Please sign in to comment.