diff --git a/createtable.go b/createtable.go index 7e0e62f..4af30a5 100644 --- a/createtable.go +++ b/createtable.go @@ -49,6 +49,7 @@ type CreateTable struct { readUnits int64 writeUnits int64 streamView StreamView + ondemand bool err error } @@ -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 @@ -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 @@ -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, diff --git a/describetable.go b/describetable.go index 75a1927..32610d3 100644 --- a/describetable.go +++ b/describetable.go @@ -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 @@ -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) } diff --git a/updatetable.go b/updatetable.go index d404da3..34a33d0 100644 --- a/updatetable.go +++ b/updatetable.go @@ -13,6 +13,8 @@ type UpdateTable struct { table Table r, w int64 // throughput + billingMode *string + disableStream bool streamView StreamView @@ -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 @@ -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") @@ -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 != "" { @@ -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 { @@ -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) }