Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support inheritance #124

Merged
merged 83 commits into from
Nov 16, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
83 commits
Select commit Hold shift + click to select a range
4d0d15f
Add method to register superclass attributes
jterapin Oct 19, 2022
96895b2
Update to include to support parent class attributes and keys to be i…
jterapin Oct 19, 2022
00d5acf
Clean up code that was used to experiment
jterapin Oct 19, 2022
8c50a13
Add set up for unit testing
jterapin Oct 19, 2022
8d0677f
Draft unit tests with different cases
jterapin Oct 19, 2022
8339d2d
Update unit test set up to include a second child class
jterapin Oct 20, 2022
d3d2066
Add unit test to check child classes having parent attributes
jterapin Oct 21, 2022
9139b1d
Update unit test to confirm parent class with its own attributes
jterapin Oct 21, 2022
e36f9c6
Add unit test to test child class to override keys
jterapin Oct 21, 2022
def2c60
Add unit test to check dv inheritance
jterapin Oct 21, 2022
9887915
Add unit test to check parent class attributes after changes
jterapin Oct 21, 2022
e19b364
Update unit tests for consistency
jterapin Oct 21, 2022
98f86c4
Create new integration test file for inheritance
jterapin Oct 21, 2022
839d1d9
Add set up for integration testing
jterapin Oct 21, 2022
736a1a5
Set up Background for integration test
jterapin Oct 21, 2022
94c8410
Update integration background and scenarios for the feature
jterapin Oct 24, 2022
cfa9a95
Add inheritance for @table_name
jterapin Oct 24, 2022
afcb526
Clean up whitespaces
jterapin Oct 24, 2022
ecb515f
Add inheritance for @track_mutations
jterapin Oct 24, 2022
a59e0d4
Add inheritance for @dynamodb_client
jterapin Oct 25, 2022
f7b04ce
Set up unit tests for @table_name and @track_mutations inheritance
jterapin Oct 26, 2022
7978021
Update behavior on table_name inheritance
jterapin Oct 26, 2022
656fee2
Update behavior on dynamodb_client inheritance
jterapin Oct 26, 2022
b768639
Clean up it block to stay within character limit
jterapin Oct 26, 2022
ba339b2
Update configure_client to fix failing unit tests
jterapin Oct 27, 2022
7ac933f
Fix spacing style
jterapin Oct 27, 2022
1cc475f
Update unit test setup
jterapin Oct 28, 2022
654eabb
Update unit tests for table name and track mutations inheritance
jterapin Oct 28, 2022
0d899d2
Update wording in it block to clarify
jterapin Oct 28, 2022
b505038
Add new test file and testing for dynamodb inheritance
jterapin Oct 28, 2022
be1c20f
Fix unit tests for client configuration
jterapin Oct 28, 2022
e7bca32
Fix unit tests for client config
jterapin Oct 28, 2022
6e11ce0
Fix unit tests for client config part 2
jterapin Oct 28, 2022
4a44fac
Update unit tests for dyanmodb_client
jterapin Oct 28, 2022
631a2b2
Refactor table_name to handle nil as class names
jterapin Oct 28, 2022
5e4de4e
Add inheritance support for local and global secondary indexes
jterapin Nov 1, 2022
379202b
Set up unit tests for @global_secdonary_indexes and @local_secondary_…
jterapin Nov 2, 2022
8706085
Add more attributes to test models for testing
jterapin Nov 2, 2022
8229b03
Add unit test to confirm child class inheriting secondary indexes
jterapin Nov 2, 2022
e54c5c6
Update implementation of secondary indexes
jterapin Nov 4, 2022
28f4d5f
Update unit tests for secondary indexes inheritance
jterapin Nov 4, 2022
f066114
Add unit test to confirm child class define and override parent indexes
jterapin Nov 4, 2022
c589d80
Set up integration test files
jterapin Nov 4, 2022
9711de6
Update implementation of secondary indexes
jterapin Nov 4, 2022
39578d5
Update feature file with tag
jterapin Nov 7, 2022
aacf3e2
Add step def to define parent or child models
jterapin Nov 7, 2022
51ba5a2
Rename feature file
jterapin Nov 7, 2022
00c5f44
Update instance variable for parent model
jterapin Nov 7, 2022
83662aa
Add scenario to test inheritance on same table
jterapin Nov 7, 2022
fae7aa4
Add scenario to test inheritance on different table
jterapin Nov 7, 2022
a7dfdeb
Fix unit tests for secondary indexes
jterapin Nov 7, 2022
313d294
Fix whitespaces
jterapin Nov 7, 2022
b454d74
Update names for consistency
jterapin Nov 8, 2022
9673688
Add docs for generalized inheritance info, mutation tracking and tabl…
jterapin Nov 9, 2022
ee85af7
Add docs for dynamodb client inheritance
jterapin Nov 9, 2022
3f408ed
Add docs for secondary indexes inheritance
jterapin Nov 9, 2022
06a3e35
Add docs for attributes and keys inheritance
jterapin Nov 9, 2022
ba1d1dd
Update initial inheritance docs
jterapin Nov 11, 2022
1cf1548
Update docs regarding table names and mutation tracking
jterapin Nov 11, 2022
9b2383b
Update docs on table name to be more specific
jterapin Nov 11, 2022
58fbc8c
Update docs on mutation tracking to be more specific
jterapin Nov 11, 2022
43c9fe4
Update docs on dynamodb client to be more specific
jterapin Nov 11, 2022
e4ede57
Update docs on secondary indexes to be more specific
jterapin Nov 11, 2022
93a2f7f
Add linking for inherited objects
jterapin Nov 11, 2022
edd1d63
Update configure_client to simplify logic
jterapin Nov 11, 2022
cba2018
Remove unit test that is redundant
jterapin Nov 11, 2022
a6e1120
Remove redundant attributes from models
jterapin Nov 11, 2022
8120b56
Update unit test matcher to ensure that they are looking at the same …
jterapin Nov 11, 2022
2dad536
Add test case to check default class names are table_names when inher…
jterapin Nov 11, 2022
0c4773d
Update Readme to hold inheritance information
jterapin Nov 14, 2022
76c76d5
Update step definitions to use case statements
jterapin Nov 15, 2022
3728f69
Update to add clarification to the support
jterapin Nov 15, 2022
db3bb8e
Update to include to inherit check function and docs
jterapin Nov 15, 2022
0735737
Update to utilize new inheritance check and add inheritance track mut…
jterapin Nov 15, 2022
115e782
Update to add inheritance helper for attributes
jterapin Nov 15, 2022
5bf0b92
Update to add inheritance helper for dynamodb client
jterapin Nov 15, 2022
f0b060e
Update to add inheritance helper for indexes
jterapin Nov 15, 2022
48a5904
Update wording for Inheritance Support doc and readme
jterapin Nov 16, 2022
404bafe
Update function to not be included in docs
jterapin Nov 16, 2022
6d06820
Update wording to be more clear
jterapin Nov 16, 2022
aabded2
Update Changelog
jterapin Nov 16, 2022
94e34ac
Update Changelog to expand on the feature
jterapin Nov 16, 2022
7a0a80a
Update raising
jterapin Nov 16, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
Unreleased Changes
------------------

* Feature - Add support for inheritance. Aws Record models can now be extended using standard ruby inheritance (#80).

2.8.0 (2022-10-12)
------------------

Expand Down
31 changes: 31 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,3 +88,34 @@ item.name = "Item"
item.active = false
item.save
```

### Inheritance Support
Aws Record models can be extended using standard ruby inheritance. The child model must
include `Aws::Record` in their model and the following will be inherited:
* [set_table_name](https://docs.aws.amazon.com/sdk-for-ruby/aws-record/api/Aws/Record/RecordClassMethods.html#set_table_name-instance_method)
* [Attributes and Keys](https://docs.aws.amazon.com/sdk-for-ruby/aws-record/api/Aws/Record/Attributes.html#initialize-instance_method)
* Mutation Tracking:
* [enable_mutation_tracking](https://docs.aws.amazon.com/sdk-for-ruby/aws-record/api/Aws/Record/RecordClassMethods.html#enable_mutation_tracking-instance_method)
* [disable_mutation_tracking](https://docs.aws.amazon.com/sdk-for-ruby/aws-record/api/Aws/Record/RecordClassMethods.html#disable_mutation_tracking-instance_method)
* [local_secondary_indexes](https://docs.aws.amazon.com/sdk-for-ruby/aws-record/api/Aws/Record/SecondaryIndexes/SecondaryIndexesClassMethods.html#local_secondary_indexes-instance_method)
* [global_secondary_indexes](https://docs.aws.amazon.com/sdk-for-ruby/aws-record/api/Aws/Record/SecondaryIndexes/SecondaryIndexesClassMethods.html#global_secondary_indexes-instance_method)
* [configure_client](https://docs.aws.amazon.com/sdk-for-ruby/aws-record/api/Aws/Record/ClientConfiguration.html#configure_client-instance_method)

See example below to see the feature in action.

```ruby
class Animal
include Aws::Record
string_attr :name, hash_key: true
integer_attr :age
end

class Dog < Animal
include Aws::Record
boolean_attr :family_friendly
end

dog = Dog.find(name: 'Sunflower')
dog.age = 3
dog.family_friendly = true
```
168 changes: 168 additions & 0 deletions features/inheritance/inheritance.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
# Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"). You may not
# use this file except in compliance with the License. A copy of the License is
# located at
#
# http://aws.amazon.com/apache2.0/
#
# or in the "license" file accompanying this file. This file is distributed on
# an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
# or implied. See the License for the specific language governing permissions
# and limitations under the License.

# language: en

@dynamodb @inheritance
Feature: Amazon DynamoDB Inheritance
This feature tests inheritance between parent class and child classes. To run
these tests, you will need to have valid AWS credentials that are accessible
with the AWS SDK for Ruby's standard credential provider chain. In practice,
this means a shared credential file or environment variables with your credentials.
These tests may have some AWS costs associated with running them since AWS resources
are created and destroyed within these tests.


Background:
Given a Parent model with definition:
"""
set_table_name('Animal')
integer_attr :id, hash_key: true
string_attr :name, range_key: true
string_attr :size
list_attr :characteristics
global_secondary_index(
:gsi,
hash_key: :id,
range_key: :size,
projection: {
projection_type: "ALL"
}
)
"""

Scenario: Create a Table and be able to create Items from both Child model and Parent model
Given a Child model with definition:
"""
boolean_attr :family_friendly
"""
And a TableConfig of:
"""
Aws::Record::TableConfig.define do |t|
t.model_class(TableConfigTestModel)
t.read_capacity_units(2)
t.write_capacity_units(2)
t.global_secondary_index(:gsi) do |i|
i.read_capacity_units(1)
i.write_capacity_units(1)
end
t.client_options(region: "us-east-1")
end
"""
When we migrate the TableConfig
Then eventually the table should exist in DynamoDB
And the table should have a global secondary index named "gsi"
And we create a new instance of the Child model with attribute value pairs:
"""
[
["id", 1],
["name", "Cheeseburger"],
["size", "Large"],
["characteristics", ["Friendly", "Curious", "Loves kisses"]],
["family_friendly", true]
]
"""
And we save the model instance
And we call the 'find' class method with parameter data:
"""
{
"id": 1,
"name": "Cheeseburger"
}
"""
Then we should receive an aws-record item with attribute data:
"""
{
"id": 1,
"name": "Cheeseburger",
"size": "Large",
"characteristics": ["Friendly", "Curious", "Loves kisses"],
"family_friendly": true
}
"""
And we create a new instance of the Parent model with attribute value pairs:
"""
[
["id", 2],
["name", "Applejack"],
["size", "Medium"],
["characteristics", ["Aloof", "Dignified"]]
]
"""
And we save the model instance
And we call the 'find' class method with parameter data:
"""
{
"id": 2,
"name": "Applejack"
}
"""
Then we should receive an aws-record item with attribute data:
"""
{
"id": 2,
"name": "Applejack",
"size": "Medium",
"characteristics": ["Aloof", "Dignified"]
}
"""

Scenario: Create a Table based on the Child Model and be able to create an item
Given a Child model with definition:
"""
set_table_name('Cat')
integer_attr :toe_beans
"""
And a TableConfig of:
"""
Aws::Record::TableConfig.define do |t|
t.model_class(TableConfigTestModel)
t.read_capacity_units(2)
t.write_capacity_units(2)
t.global_secondary_index(:gsi) do |i|
i.read_capacity_units(1)
i.write_capacity_units(1)
end
t.client_options(region: "us-east-1")
end
"""
When we migrate the TableConfig
Then eventually the table should exist in DynamoDB
And we create a new instance of the Child model with attribute value pairs:
"""
[
["id", 1],
["name", "Donut"],
["size", "Chonk"],
["characteristics", ["Makes good bread", "Likes snacks"]],
["toe_beans", 9]
]
"""
And we save the model instance
And we call the 'find' class method with parameter data:
"""
{
"id": 1,
"name": "Donut"
}
"""
Then we should receive an aws-record item with attribute data:
"""
{
"id": 1,
"name": "Donut",
"size": "Chonk",
"characteristics": ["Makes good bread", "Likes snacks"],
"toe_beans": 9
}
"""
49 changes: 49 additions & 0 deletions features/inheritance/step_definitions.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"). You may not
# use this file except in compliance with the License. A copy of the License is
# located at
#
# http://aws.amazon.com/apache2.0/
#
# or in the "license" file accompanying this file. This file is distributed on
# an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
# or implied. See the License for the specific language governing permissions
# and limitations under the License.



Given(/^a (Parent|Child) model with definition:$/) do |model, string|
case model
when 'Parent'
@parent = Class.new do
include(Aws::Record)
end
@parent.class_eval(string)
@table_name = @parent.table_name
when 'Child'
@model = Class.new(@parent) do
include(Aws::Record)
end
@model.class_eval(string)
@table_name = @model.table_name
else
raise 'Model must be either a Parent or Child'
end
end

And(/^we create a new instance of the (Parent|Child) model with attribute value pairs:$/) do |model, string|
data = JSON.parse(string)
case model
when 'Parent'
@instance = @parent.new
when 'Child'
@instance = @model.new
else
raise 'Model must be either a Parent or Child'
end
data.each do |row|
attribute, value = row
@instance.send(:"#{attribute}=", value)
end
end
Loading