diff --git a/README.md b/README.md index 31e2bb8..6ec4612 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,29 @@ Or install it yourself as: ## Usage +##Global Config + +### #namespace +The namespace is used to set the prefix applied to all table and index names. + + DynamoDbFramework.namespace = 'uat' + +> With a namespace of 'uat' and a table name of 'people', the resulting table name would be 'uat.people' + +### #namespace_delimiter +This is the delimiter used to join the namespace prefix to table/index names. + +> DEFAULT = '.' + + DynamoDbFramework.namespace_delimiter = '-' + +### #default_store +This is used to set the default store that should be used for all connection actions that don't specify a store override. + + DynamoDbFramework.default_store = store + +> If no [DynamoDbFramework::Store] is manually specified then the default store will attempt to use the aws credentials from the host machines aws configuration profile. + # Table Before you can work with any data in dynamodb you require a table definition. To define a table create a class and use the `DynamoDbFramework::Table` module. @@ -51,27 +74,29 @@ This method is called create the table definition within a dynamodb account. - **write_capacity** [Integer] [Optional] [Default=25] This is used to specify the write capacity to provision for this table. - ExampleTable.create(store: store, read_capacity: 50, write_capacity: 35) + ExampleTable.create(read_capacity: 50, write_capacity: 35) ## #update This method is called to update the provisioned capacity for the table. **Params** - - **store** [DynamoDbFramework::Store] [Required] This is used to specify the Dynamodb instance/account to connect to. + - **store** [DynamoDbFramework::Store] [Optional] This is used to specify the Dynamodb instance/account to connect to. If not specified the `DyanmoDbFramework.default_store` will be used. - **read_capacity** [Integer] [Required] This is used to specify the read capacity to provision for this table. - **write_capacity** [Integer] [Required] This is used to specify the write capacity to provision for this table. - ExampleTable.update(store: store, read_capacity: 100, write_capacity: 50) + + ExampleTable.update(read_capacity: 100, write_capacity: 50) ## #drop This method is called to drop the table from a dynamodb account. **Params** - - **store** [DynamoDbFramework::Store] [Required] This is used to specify the Dynamodb instance/account to connect to. + - **store** [DynamoDbFramework::Store] [Optional] This is used to specify the Dynamodb instance/account to connect to. If not specified the `DyanmoDbFramework.default_store` will be used. + - ExampleTable.drop(store: store) + ExampleTable.drop ## #exists? @@ -79,21 +104,22 @@ This method is called to determine if this table exists in a dynamodb account. **Params** - - **store** [DynamoDbFramework::Store] [Required] This is used to specify the Dynamodb instance/account to connect to. + - **store** [DynamoDbFramework::Store] [Optional] This is used to specify the Dynamodb instance/account to connect to. If not specified the `DyanmoDbFramework.default_store` will be used. + - ExampleTable.exists?(store: store) + ExampleTable.exists? ## #get_item This method is called to get a single item from the table by its unique key. **Params** - - **store** [DynamoDbFramework::Store] [Required] This is used to specify the Dynamodb instance/account to connect to. + - **store** [DynamoDbFramework::Store] [Optional] This is used to specify the Dynamodb instance/account to connect to. If not specified the `DyanmoDbFramework.default_store` will be used. - **partition** [object] [Required] This is used to specify the partition_key value of the item to get. - **range** [object] [Optional] This is used to specify the range_key value of the item to get. - ExampleTable.get_item(store: store, partition: uuid, range: timestamp) + ExampleTable.get_item(partition: uuid, range: timestamp) ## #put_item @@ -101,11 +127,11 @@ This method is called to put a single item into the table. **Params** - - **store** [DynamoDbFramework::Store] [Required] This is used to specify the Dynamodb instance/account to connect to. + - **store** [DynamoDbFramework::Store] [Optional] This is used to specify the Dynamodb instance/account to connect to. If not specified the `DyanmoDbFramework.default_store` will be used. - **item** [object] [Required] This is the item to store in the table. - ExampleTable.put_item(store: store, item: item) + ExampleTable.put_item(item: item) ## #delete_item @@ -113,12 +139,12 @@ This method is called to delete an item from the table. **Params** - - **store** [DynamoDbFramework::Store] [Required] This is used to specify the Dynamodb instance/account to connect to. + - **store** [DynamoDbFramework::Store] [Optional] This is used to specify the Dynamodb instance/account to connect to. If not specified the `DyanmoDbFramework.default_store` will be used. - **partition** [object] [Required] This is used to specify the partition_key value of the item. - **range** [object] [Optional] This is used to specify the range_key value of the item. - ExampleTable.delete_item(store: store, partition: uuid, range: timestamp) + ExampleTable.delete_item(partition: uuid, range: timestamp) ## #all @@ -126,9 +152,9 @@ This method is called to return all items from the table. **Params** - - **store** [DynamoDbFramework::Store] [Required] This is used to specify the Dynamodb instance/account to connect to. + - **store** [DynamoDbFramework::Store] [Optional] This is used to specify the Dynamodb instance/account to connect to. If not specified the `DyanmoDbFramework.default_store` will be used. - ExampleTable.all(store: store) + ExampleTable.all ## #query @@ -148,14 +174,14 @@ The above query chain translates into: To execute the query you can then call `#execute` on the query: - query.execute(store: store) + query.execute ### #execute This method is called to execute a query. **Params** - - **store** [DynamoDbFramework::Store] [Required] This is used to specify the Dynamodb instance/account to connect to. + - **store** [DynamoDbFramework::Store] [Optional] This is used to specify the Dynamodb instance/account to connect to. If not specified the `DyanmoDbFramework.default_store` will be used. - **limit** [Integer] [Optional] This is used to specify a limit to the number of items returned by the query. - **count** [Boolean] [Optional] This is used to specify if the query should just return a count of results. @@ -217,41 +243,44 @@ This method is called create the index definition within a dynamodb account. **Params** - - **store** [DynamoDbFramework::Store] [Required] This is used to specify the Dynamodb instance/account to connect to. + - **store** [DynamoDbFramework::Store] [Optional] This is used to specify the Dynamodb instance/account to connect to. If not specified the `DyanmoDbFramework.default_store` will be used. - **read_capacity** [Integer] [Optional] [Default=25] This is used to specify the read capacity to provision for this index. - **write_capacity** [Integer] [Optional] [Default=25] This is used to specify the write capacity to provision for this index. - ExampleIndex.create(store: store, read_capacity: 50, write_capacity: 35) + ExampleIndex.create(read_capacity: 50, write_capacity: 35) ## #update This method is called to update the provisioned capacity for the index. **Params** - - **store** [DynamoDbFramework::Store] [Required] This is used to specify the Dynamodb instance/account to connect to. + - **store** [DynamoDbFramework::Store] [Optional] This is used to specify the Dynamodb instance/account to connect to. If not specified the `DyanmoDbFramework.default_store` will be used. - **read_capacity** [Integer] [Required] This is used to specify the read capacity to provision for this index. - **write_capacity** [Integer] [Required] This is used to specify the write capacity to provision for this index. - ExampleIndex.update(store: store, read_capacity: 100, write_capacity: 50) + + ExampleIndex.update(read_capacity: 100, write_capacity: 50) ## #drop This method is called to drop the current index. **Params** - - **store** [DynamoDbFramework::Store] [Required] This is used to specify the Dynamodb instance/account to connect to. + - **store** [DynamoDbFramework::Store] [Optional] This is used to specify the Dynamodb instance/account to connect to. If not specified the `DyanmoDbFramework.default_store` will be used. + - ExampleIndex.drop(store: store) + ExampleIndex.drop ## #exists? This method is called to determine if this index exists in a dynamodb account. **Params** - - **store** [DynamoDbFramework::Store] [Required] This is used to specify the Dynamodb instance/account to connect to. + - **store** [DynamoDbFramework::Store] [Optional] This is used to specify the Dynamodb instance/account to connect to. If not specified the `DyanmoDbFramework.default_store` will be used. + - ExampleIndex.exists?(store: store) + ExampleIndex.exists? ## #query @@ -271,14 +300,14 @@ The above query chain translates into: To execute the query you can then call `#execute` on the query: - query.execute(store: store) + query.execute ### #execute This method is called to execute a query. **Params** - - **store** [DynamoDbFramework::Store] [Required] This is used to specify the Dynamodb instance/account to connect to. + - **store** [DynamoDbFramework::Store] [Optional] This is used to specify the Dynamodb instance/account to connect to. If not specified the `DyanmoDbFramework.default_store` will be used. - **limit** [Integer] [Optional] This is used to specify a limit to the number of items returned by the query. - **count** [Boolean] [Optional] This is used to specify if the query should just return a count of results. @@ -328,10 +357,10 @@ To create or modify a DynamoDb instance you first need to create a migration scr end def apply - EventTrackingTable.create(store: store, read_capacity: 50, write_capacity: 35) + EventTrackingTable.create(read_capacity: 50, write_capacity: 35) end def undo - EventTrackingTable.drop(store: store) + EventTrackingTable.drop end end diff --git a/lib/dynamodb_framework.rb b/lib/dynamodb_framework.rb index fb538da..496e344 100644 --- a/lib/dynamodb_framework.rb +++ b/lib/dynamodb_framework.rb @@ -29,4 +29,13 @@ def self.namespace_delimiter=(value) def self.namespace_delimiter @namespace_delimiter ||= '.' end + def self.default_store=(value) + unless value.is_a?(DynamoDbFramework::Store) + raise 'Invalid default store specified. Store must be of type: [DynamoDbFramework::Store]' + end + @default_store = value + end + def self.default_store + @default_store ||= DynamoDbFramework::Store.new + end end diff --git a/lib/dynamodb_framework/dynamodb_index.rb b/lib/dynamodb_framework/dynamodb_index.rb index 57aea31..ae86caa 100644 --- a/lib/dynamodb_framework/dynamodb_index.rb +++ b/lib/dynamodb_framework/dynamodb_index.rb @@ -46,7 +46,7 @@ def range_key(field, type) self.instance_variable_set(:@range_key, { field: field, type: type }) end - def create(store:, read_capacity: 25, write_capacity: 25) + def create(store: DynamoDbFramework.default_store, read_capacity: 25, write_capacity: 25) unless self.instance_variable_defined?(:@table) raise DynamoDbFramework::Index::InvalidConfigException.new('Table must be specified.') end @@ -83,7 +83,7 @@ def create(store:, read_capacity: 25, write_capacity: 25) table_manager.add_index(table_name, builder.attributes, index) end - def update(store:, read_capacity:, write_capacity:) + def update(store: DynamoDbFramework.default_store, read_capacity:, write_capacity:) unless self.instance_variable_defined?(:@table) raise DynamoDbFramework::Index::InvalidConfigException.new('Table must be specified.') end @@ -92,7 +92,7 @@ def update(store:, read_capacity:, write_capacity:) DynamoDbFramework::TableManager.new(store).update_index_throughput(table.config[:table_name], full_index_name, read_capacity, write_capacity) end - def drop(store:) + def drop(store: DynamoDbFramework.default_store) unless self.instance_variable_defined?(:@table) raise DynamoDbFramework::Index::InvalidConfigException.new('Table must be specified.') end @@ -102,7 +102,7 @@ def drop(store:) DynamoDbFramework::TableManager.new(store).drop_index(table_name, full_index_name) end - def exists?(store:) + def exists?(store: DynamoDbFramework.default_store) unless self.instance_variable_defined?(:@table) raise DynamoDbFramework::Index::InvalidConfigException.new('Table must be specified.') end diff --git a/lib/dynamodb_framework/dynamodb_query.rb b/lib/dynamodb_framework/dynamodb_query.rb index 10427b8..4aa8bc3 100644 --- a/lib/dynamodb_framework/dynamodb_query.rb +++ b/lib/dynamodb_framework/dynamodb_query.rb @@ -80,7 +80,7 @@ def or self end - def execute(store:, limit: nil, count: false) + def execute(store: DynamoDbFramework.default_store, limit: nil, count: false) build repository = DynamoDbFramework::Repository.new(store) repository.table_name = @table_name diff --git a/lib/dynamodb_framework/dynamodb_table.rb b/lib/dynamodb_framework/dynamodb_table.rb index 1cfff97..eb04e8d 100644 --- a/lib/dynamodb_framework/dynamodb_table.rb +++ b/lib/dynamodb_framework/dynamodb_table.rb @@ -41,7 +41,7 @@ def range_key(field, type) self.instance_variable_set(:@range_key, { field: field, type: type }) end - def create(store:, read_capacity: 25, write_capacity: 25) + def create(store: DynamoDbFramework.default_store, read_capacity: 25, write_capacity: 25) unless self.instance_variable_defined?(:@partition_key) raise DynamoDbFramework::Table::InvalidConfigException.new('Partition key must be specified.') end @@ -60,15 +60,15 @@ def create(store:, read_capacity: 25, write_capacity: 25) DynamoDbFramework::TableManager.new(store).create_table({ name: full_table_name, attributes: builder.attributes, read_capacity: read_capacity, write_capacity: write_capacity }) end - def update(store:, read_capacity:, write_capacity:) + def update(store: DynamoDbFramework.default_store, read_capacity:, write_capacity:) DynamoDbFramework::TableManager.new(store).update_throughput(full_table_name, read_capacity, write_capacity) end - def drop(store:) + def drop(store: DynamoDbFramework.default_store) DynamoDbFramework::TableManager.new(store).drop(full_table_name) end - def exists?(store:) + def exists?(store: DynamoDbFramework.default_store) DynamoDbFramework::TableManager.new(store).exists?(full_table_name) end @@ -76,19 +76,19 @@ def query(partition:) DynamoDbFramework::Query.new(table_name: config[:table_name], partition_key: config[:partition_key][:field], partition_value: partition) end - def all(store:) + def all(store: DynamoDbFramework.default_store) repository = DynamoDbFramework::Repository.new(store) repository.table_name = config[:table_name] repository.all end - def put_item(store:, item:) + def put_item(store: DynamoDbFramework.default_store, item:) repository = DynamoDbFramework::Repository.new(store) repository.table_name = config[:table_name] repository.put(item) end - def get_item(store:, partition:, range: nil) + def get_item(store: DynamoDbFramework.default_store, partition:, range: nil) repository = DynamoDbFramework::Repository.new(store) repository.table_name = config[:table_name] @@ -99,7 +99,7 @@ def get_item(store:, partition:, range: nil) end end - def delete_item(store:, partition:, range: nil) + def delete_item(store: DynamoDbFramework.default_store, partition:, range: nil) repository = DynamoDbFramework::Repository.new(store) repository.table_name = config[:table_name] diff --git a/spec/dynamodb_index_spec.rb b/spec/dynamodb_index_spec.rb index 708da29..af59347 100644 --- a/spec/dynamodb_index_spec.rb +++ b/spec/dynamodb_index_spec.rb @@ -43,6 +43,21 @@ expect(table_manager.has_index?(table_name, index_name)).to be true end end + + context 'when no store is specified' do + let(:index_name) { ExampleIndex.config[:index_name] } + before do + DynamoDbFramework.default_store = store + if table_manager.has_index?(table_name, index_name) + table_manager.drop_index(table_name, index_name) + end + end + it 'should create the index using the default store' do + expect(table_manager.has_index?(table_name, index_name)).to be false + ExampleIndex.create + expect(table_manager.has_index?(table_name, index_name)).to be true + end + end end context 'when an invalid index class calls the create method' do context 'without a index_name specified' do @@ -75,6 +90,15 @@ it 'should update the index' do ExampleIndex.update(store: store, read_capacity: 50, write_capacity: 50) end + context 'when no store is specified' do + let(:index_name) { ExampleIndex.config[:index_name] } + before do + DynamoDbFramework.default_store = store + end + it 'should update the index using the default store' do + ExampleIndex.update(read_capacity: 50, write_capacity: 50) + end + end end context 'when an invalid index class calls the update method' do context 'without an index_name specified' do @@ -103,6 +127,15 @@ ExampleIndex.drop(store: store) expect(table_manager.has_index?(table_name, index_name)).to be false end + context 'when no store is specified' do + before do + DynamoDbFramework.default_store = store + end + it 'should drop the index using the default store' do + ExampleIndex.drop + expect(table_manager.has_index?(table_name, index_name)).to be false + end + end end context 'when an invalid index class calls the drop method' do context 'without an index_name specified' do @@ -130,6 +163,14 @@ it 'should return true' do expect(ExampleIndex.exists?(store: store)).to be true end + context 'when no store is specified' do + before do + DynamoDbFramework.default_store = store + end + it 'should return true using the default store' do + expect(ExampleIndex.exists?).to be true + end + end end context 'when the index does NOT exist' do let(:index_name) { ExampleIndex.config[:index_name] } @@ -141,6 +182,14 @@ it 'should return false' do expect(ExampleIndex.exists?(store: store)).to be false end + context 'when no store is specified' do + before do + DynamoDbFramework.default_store = store + end + it 'should return false using the default store' do + expect(ExampleIndex.exists?).to be false + end + end end end @@ -164,9 +213,10 @@ def create_query_item(name, number) end before do + DynamoDbFramework::default_store = store table_manager.drop(table_name) - ExampleTable.create(store: store) - ExampleIndex.create(store: store) + ExampleTable.create + ExampleIndex.create create_query_item('name 1', 1) create_query_item('name 1', 2) @@ -187,6 +237,16 @@ def create_query_item(name, number) .execute(store: store) expect(results.length).to eq 4 end + context 'when no store is specified' do + it 'should return the expected items' do + results = ExampleIndex.query(partition: 'name 1') + .number.gt_eq(1) + .and + .number.lt_eq(5) + .execute + expect(results.length).to eq 4 + end + end context 'when limit is specified' do it 'should return the expected items' do results = ExampleIndex.query(partition: 'name 1')