Class: Aws::Record::TableConfig
- Inherits:
-
Object
- Object
- Aws::Record::TableConfig
- Defined in:
- lib/aws-record/record/table_config.rb
Overview
Aws::Record::TableConfig
provides a DSL for describing and modifying the remote configuration of your DynamoDB tables. A table configuration object can perform intelligent comparisons and incremental migrations versus the current remote configuration, if the table exists, or do a full create if it does not. In this manner, table configuration becomes fully declarative.
Defined Under Namespace
Classes: GlobalSecondaryIndex
Instance Attribute Summary collapse
-
#client ⇒ Object
Returns the value of attribute client.
Class Method Summary collapse
-
.define(&block) ⇒ Object
Creates a new table configuration, using a DSL in the provided block.
Instance Method Summary collapse
- #billing_mode(mode) ⇒ Object private
- #client_options(opts) ⇒ Object private
-
#compatible? ⇒ Boolean
Checks the remote table for compatibility.
- #configure_client ⇒ Object private
-
#exact_match? ⇒ Boolean
Checks against the remote table’s configuration.
- #global_secondary_index(name, &block) ⇒ Object private
-
#initialize ⇒ TableConfig
constructor
private
A new instance of TableConfig.
-
#migrate! ⇒ Object
Performs a migration, if needed, against the remote table.
- #model_class(model) ⇒ Object private
- #read_capacity_units(units) ⇒ Object private
- #ttl_attribute(attribute_symbol) ⇒ Object private
- #write_capacity_units(units) ⇒ Object private
Constructor Details
#initialize ⇒ TableConfig
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Returns a new instance of TableConfig.
155 156 157 158 159 |
# File 'lib/aws-record/record/table_config.rb', line 155 def initialize @client_options = {} @global_secondary_indexes = {} @billing_mode = 'PROVISIONED' # default end |
Instance Attribute Details
#client ⇒ Object
Returns the value of attribute client.
92 93 94 |
# File 'lib/aws-record/record/table_config.rb', line 92 def client @client end |
Class Method Details
.define(&block) ⇒ Object
Creates a new table configuration, using a DSL in the provided block. The DSL has the following methods:
-
#model_class
A class name reference to theAws::Record
model class. -
#read_capacity_units
Sets the read capacity units for the table. -
#write_capacity_units
Sets the write capacity units for the table. -
#global_secondary_index(index_symbol, &block) Defines a global secondary index with capacity attributes in a block:
-
#read_capacity_units
Sets the read capacity units for the index. -
#write_capacity_units
Sets the write capacity units for the index.
-
-
#ttl_attribute
Sets the attribute ID to be used as the TTL attribute, and if present, TTL will be enabled for the table. -
#billing_mode
Sets the billing mode, with the current supported options being “PROVISIONED” and “PAY_PER_REQUEST”. If using “PAY_PER_REQUEST” you must not set provisioned throughput values, and if using “PROVISIONED” you must set provisioned throughput values. Default assumption is “PROVISIONED”.
146 147 148 149 150 151 |
# File 'lib/aws-record/record/table_config.rb', line 146 def define(&block) cfg = TableConfig.new cfg.instance_eval(&block) cfg.configure_client cfg end |
Instance Method Details
#billing_mode(mode) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
203 204 205 |
# File 'lib/aws-record/record/table_config.rb', line 203 def billing_mode(mode) @billing_mode = mode end |
#client_options(opts) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
184 185 186 |
# File 'lib/aws-record/record/table_config.rb', line 184 def (opts) @client_options = opts end |
#compatible? ⇒ Boolean
Checks the remote table for compatibility. Similar to #exact_match?
, this will return false
if the remote table does not exist. It also checks the keys, declared global secondary indexes, declared attribute definitions, and throughput for exact matches. However, if the remote end has additional attribute definitions and global secondary indexes not defined in your config, will still return true
. This allows for a check that is friendly to single table inheritance use cases.
269 270 271 272 273 274 |
# File 'lib/aws-record/record/table_config.rb', line 269 def compatible? resp = @client.describe_table(table_name: @model_class.table_name) _compatible_check(resp) && _ttl_compatibility_check rescue DynamoDB::Errors::ResourceNotFoundException false end |
#configure_client ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
189 190 191 192 |
# File 'lib/aws-record/record/table_config.rb', line 189 def configure_client @client = Aws::DynamoDB::Client.new(@client_options) @client.config.user_agent_frameworks << 'aws-record' end |
#exact_match? ⇒ Boolean
Checks against the remote table’s configuration. If the remote table does not exist, guaranteed false
. Otherwise, will check if the remote throughput, keys, attribute definitions, and global secondary indexes are exactly equal to your declared configuration.
282 283 284 285 286 287 288 289 290 291 |
# File 'lib/aws-record/record/table_config.rb', line 282 def exact_match? resp = @client.describe_table(table_name: @model_class.table_name) _throughput_equal(resp) && _keys_equal(resp) && _ad_equal(resp) && _gsi_equal(resp) && _ttl_match_check rescue DynamoDB::Errors::ResourceNotFoundException false end |
#global_secondary_index(name, &block) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
177 178 179 180 181 |
# File 'lib/aws-record/record/table_config.rb', line 177 def global_secondary_index(name, &block) gsi = GlobalSecondaryIndex.new gsi.instance_eval(&block) if block_given? @global_secondary_indexes[name] = gsi end |
#migrate! ⇒ Object
Performs a migration, if needed, against the remote table. If #compatible?
would return true, the remote table already has the same throughput, key schema, attribute definitions, and global secondary indexes, so no further API calls are made. Otherwise, a DynamoDB table will be created or updated to match your declared configuration.
212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 |
# File 'lib/aws-record/record/table_config.rb', line 212 def migrate! _validate_required_configuration begin resp = @client.describe_table(table_name: @model_class.table_name) if _compatible_check(resp) nil else # Gotcha: You need separate migrations for indexes and throughput unless _throughput_equal(resp) @client.update_table(_update_throughput_opts(resp)) @client.wait_until( :table_exists, table_name: @model_class.table_name ) end unless _gsi_superset(resp) @client.update_table(_update_index_opts(resp)) @client.wait_until( :table_exists, table_name: @model_class.table_name ) end end rescue DynamoDB::Errors::ResourceNotFoundException # Code Smell: Exception as control flow. # Can I use SDK ability to skip raising an exception for this? @client.create_table(_create_table_opts) @client.wait_until(:table_exists, table_name: @model_class.table_name) end # At this stage, we have a table and need to check for after-effects to # apply. # First up is TTL attribute. Since this migration is not exact match, # we will only alter TTL status if we have a TTL attribute defined. We # may someday support explicit TTL deletion, but we do not yet do this. return unless @ttl_attribute return if _ttl_compatibility_check client.update_time_to_live( table_name: @model_class.table_name, time_to_live_specification: { enabled: true, attribute_name: @ttl_attribute } ) # Else TTL is compatible and we are done. # Else our work is done. end |
#model_class(model) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
162 163 164 |
# File 'lib/aws-record/record/table_config.rb', line 162 def model_class(model) @model_class = model end |
#read_capacity_units(units) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
167 168 169 |
# File 'lib/aws-record/record/table_config.rb', line 167 def read_capacity_units(units) @read_capacity_units = units end |
#ttl_attribute(attribute_symbol) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
195 196 197 198 199 200 |
# File 'lib/aws-record/record/table_config.rb', line 195 def ttl_attribute(attribute_symbol) attribute = @model_class.attributes.attribute_for(attribute_symbol) raise ArgumentError, "Invalid attribute #{attribute_symbol} for #{@model_class}" unless attribute @ttl_attribute = attribute.database_name end |
#write_capacity_units(units) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
172 173 174 |
# File 'lib/aws-record/record/table_config.rb', line 172 def write_capacity_units(units) @write_capacity_units = units end |