Skip to content

Commit

Permalink
Merge pull request #4 from Sage/auto_convert_dates
Browse files Browse the repository at this point in the history
Convert DateTime and Time for dynamodb
  • Loading branch information
vaughanbrittonsage authored Feb 9, 2017
2 parents d15efd2 + 3160d35 commit 5a087b8
Show file tree
Hide file tree
Showing 7 changed files with 67 additions and 6 deletions.
2 changes: 1 addition & 1 deletion .idea/.rakeTasks

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,10 @@ source 'https://rubygems.org'
# Specify your gem's dependencies in dynamodb_framework.gemspec
gemspec

group :test, :development do
gem 'yard'
end

group :test do
gem 'simplecov', :require => false
end
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,15 @@ Before calling any methods from the repository the **.table_name** attribute mus
### #put
This method is called to insert an item into a DynamoDb table.

*Note*:

[DateTime] attributes will be stored as an ISO8601 string
[Time] attributes will be stored as an Epoch Int

The intent is that if you need to sort in dynamo by dates, then make sure you use a [Time] type. The Epoch int allows
you to compare properly as comparing date strings are not reliable.

**Params**

- **item** [Object] [Required] The document to store within the table.
Expand Down
19 changes: 18 additions & 1 deletion lib/dynamodb_framework/dynamodb_repository.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,12 @@ def initialize(store)
@dynamodb = store
end

# Store the hash of an object to the dynamodb table
# *Note* : [DateTime] attributes will be stored as an ISO8601 string
# [Time] attributes will be stored as an Epoch Int
# The intent is that if you need to sort in dynamo by dates, then make sure you use a [Time] type. The Epoch int allows
# you to compare properly as comparing date strings are not reliable.
def put(item)

hash = to_hash(item)

clean_hash(hash)
Expand Down Expand Up @@ -196,14 +200,27 @@ def hash_helper
@hash_helper ||= HashHelper.new
end

# Convert empty string values to nil, as well as convert DateTime and Time to appropriate storage formats.
def clean_hash(hash)
hash.each do |key, value|
if value == ''
hash[key] = nil
elsif value.is_a?(Array)
value.each do |item|
clean_hash(item) if item.is_a?(Hash)
end
elsif [DateTime, Time].include?(value.class)
hash[key] = convert_date(value)
elsif value.is_a?(Hash)
clean_hash(value)
end
end
end

def convert_date(value)
klass = value.class
return value.iso8601 if klass == DateTime
return value.to_i if klass == Time
end
end
end
29 changes: 25 additions & 4 deletions spec/dynamodb_repository_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def create_query_item(name, number, table_name)
item = TestItem.new
item.id = SecureRandom.uuid
item.name = name
item.timestamp = Time.now.to_i
item.timestamp = Time.now
item.number = number
subject.table_name = table_name
subject.put(item)
Expand All @@ -27,7 +27,7 @@ def create_query_item(name, number, table_name)
let(:current_time) { Time.now }
let(:id ) { 'Item1' }
let(:name ) { 'Name' }
let(:timestamp ) { current_time.to_i }
let(:timestamp ) { current_time }
let(:number ) { 5 }

let(:item) do
Expand Down Expand Up @@ -61,7 +61,6 @@ def create_query_item(name, number, table_name)

expect(stored_item['id']).to eq(id)
expect(stored_item['name']).to eq(name)
expect(stored_item['timestamp']).to eq(timestamp)
expect(stored_item['number']).to eq(number)
end
end
Expand All @@ -76,11 +75,33 @@ def create_query_item(name, number, table_name)

expect(stored_item['id']).to eq(id)
expect(stored_item['name']).to eq(nil)
expect(stored_item['timestamp']).to eq(timestamp)
expect(stored_item['number']).to eq(number)
end
end

context 'when a date attribute is a DateTime class' do
let(:timestamp) {DateTime.now}

it 'stores the attribute in an iso8601 string format' do

subject.put(item)
stored_item = subject.get_by_key('id', id)

expect(stored_item['timestamp']).to eq(timestamp.iso8601)
end
end

context 'when a date attribute is a Time class' do
let(:timestamp) {Time.now}

it 'stores the attribute as an Epoch int' do
subject.put(item)
stored_item = subject.get_by_key('id', id)

expect(stored_item['timestamp']).to eq(timestamp.to_i)
end
end

after do
schema_manager.drop('put')
end
Expand Down
5 changes: 5 additions & 0 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@
require_relative '../spec/test_item.rb'
require 'pry'

require 'simplecov'
SimpleCov.start do
add_filter '/spec/'
end

DYNAMODB_STORE_ENDPOINT = 'http://192.168.99.100:8000'

Aws.config[:credentials] = Aws::Credentials.new('test_key', 'test_secret')
Expand Down
3 changes: 3 additions & 0 deletions yard.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/usr/bin/bash

yard stats --list-undoc

0 comments on commit 5a087b8

Please sign in to comment.