mince_dynamo_db 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,6 @@
1
+ *.gem
2
+ .yardoc
3
+ doc
4
+ .bundle
5
+ Gemfile.lock
6
+ pkg/*
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --colour
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm use 1.9.3@mince_dynamo_db --create
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in mince_dynamo_db.gemspec
4
+ gemspec
data/Guardfile ADDED
@@ -0,0 +1,11 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+ #
4
+
5
+ guard 'rspec', :version => 2 do
6
+ watch(%r{^spec/lib/.+_spec\.rb$})
7
+ watch(%r{^lib/(.+)\.rb}) { |m| "spec/lib/#{m[1]}_spec.rb" }
8
+ watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
9
+ watch(%r{^spec/support/shared_examples/(.+)\.rb$}) { "spec" }
10
+ end
11
+
data/README.md ADDED
@@ -0,0 +1,59 @@
1
+ # What is mince dynamo db?
2
+
3
+ Light weight ORM to persist data to an Amazon DynamoDB database.
4
+
5
+ Provides a very light weight interface for storing and retreiving information to DynamoDB.
6
+
7
+ The motivation behind this is so your application is not tightly tied to a specific database. As your application grows you may need to upgrade to a different database or pull specific models to a different persistence strategy.
8
+
9
+ [@github](https://github.com/coffeencoke/mince_dynamo_db)
10
+ [@rubygems (not yet published)](#)
11
+
12
+ # How to use
13
+
14
+ view the [example mince rails app](https://github.com/coffeencoke/mince_rails_example) to see how to use this.
15
+
16
+ <pre>
17
+ # Add a book to the books collection
18
+ MinceDynamoDb::DataStore.add 'books', title: 'The World In Photographs', publisher: 'National Geographic'
19
+
20
+ # Retrieve all records from the books collection
21
+ MinceDynamoDb::DataStore.find_all 'books'
22
+
23
+ # Replace a specific book
24
+ MinceDynamoDb::DataStore.replace 'books', id: 1, title: 'A World In Photographs', publisher: 'National Geographic'
25
+ </pre>
26
+
27
+ View the docs for MinceDynamoDb::DataStore for all methods available.
28
+
29
+ Use with [mince data model](https://github.com/asynchrony/mince_data_model) to make it easy to change from one data storage to another, like [Hashy Db](https://github.com/asynchrony/hashy_db), a Hash data persistence implementation, or [Mince](https://github.com/asynchrony/mince), a MongoDB implementation.
30
+
31
+ # Why would you want this?
32
+
33
+ - To defer choosing your database until you know most about your application.
34
+ - Provides assitance in designing a database agnostic architecture.
35
+ - When used along with [Hashy Db](https://github.com/asynchrony/hashy_db) it offers very little technical dependencies. Use Hashy Db in development mode so that you can clone the repo and develop, and run tests, cucumbers without databases, migrations, etc. Then in production mode, switch to Mince Dynamo DB.
36
+
37
+ If you are able to switch between Hashy Db and Mince Dynamo Db, your application will be more open to new and improved database in the future, or as your application evolves you aren't tied to a database.
38
+
39
+
40
+ # Todo
41
+
42
+ - Write integration specs
43
+ - Do not use singleton for data store
44
+ - Refactor data store
45
+ - Remove dependency on Active Support
46
+
47
+ # Contribute
48
+
49
+ - fork into a topic branch, write specs, make a pull request.
50
+
51
+ # Owners
52
+
53
+ Matt Simpson - [@railsgrammer](https://twitter.com/railsgrammer)
54
+
55
+ # Contributors
56
+
57
+ - Your name here!
58
+
59
+ ![Mince Some App](https://github.com/coffeencoke/gist-files/raw/master/images/mince%20garlic.png)
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ begin
4
+ require 'rspec/core/rake_task'
5
+
6
+ desc 'Default: run specs.'
7
+ task :default => :spec
8
+
9
+ desc "Run specs"
10
+ RSpec::Core::RakeTask.new
11
+ rescue LoadError
12
+ end
@@ -0,0 +1,24 @@
1
+ require 'aws'
2
+ require 'singleton'
3
+
4
+ module MinceDynamoDb
5
+ class Connection
6
+ include Singleton
7
+
8
+ attr_reader :connection
9
+
10
+ def initialize
11
+ @connection = AWS::DynamoDB.new access_key_id: access_key_id, secret_access_key: secret_access_key
12
+ end
13
+
14
+ private
15
+
16
+ def access_key_id
17
+ AWS.config.access_key_id
18
+ end
19
+
20
+ def secret_access_key
21
+ AWS.config.secret_access_key
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,233 @@
1
+ require 'singleton'
2
+ require 'digest'
3
+ require 'active_support/hash_with_indifferent_access'
4
+
5
+ require_relative 'connection'
6
+
7
+ module MinceDynamoDb # :nodoc:
8
+ # = Mince DynamoDb Data Store
9
+ #
10
+ # Mince DynamoDb Data Store stores and retrieves data from a DynamoDB table. It supports the same methods
11
+ # as the following libraries:
12
+ #
13
+ # Mince::
14
+ # A lightweight ruby library to store and retrieve data from MongoDB (https://github.com/asynchrony/mince)
15
+ # HashyDb::
16
+ # A lightweight ruby library to store and retrieve data from a hash in-memory. (https://github.com/asynchrony/hashy_db)
17
+ #
18
+ # Using this library offers more extensibility and growth for your application. If at any point in time
19
+ # you want to support a different database for all, or even one, of your classes, you only need to implement
20
+ # the few methods defined in this class.
21
+ #
22
+ # You can use the {https://github.com/asynchrony/mince_data_model Mince Data Model} as a helper library to
23
+ # provide support in writing an application using these data persistance libraries.
24
+ #
25
+ # To use the Data Store, define your DynamoDB access_key_id and secret_access_key. If you are using rails
26
+ # you can do this by creating a file at config/aws.yml with the following contents:
27
+ #
28
+ # development:
29
+ # access_key_id: REPLACE_WITH_ACCESS_KEY_ID
30
+ # secret_access_key: REPLACE_WITH_SECRET_ACCESS_KEY
31
+ #
32
+ # Otherwise, you can set the configurations like so:
33
+ #
34
+ # require 'aws'
35
+ #
36
+ # AWS.config.access_key_id = REPLACE_WITH_ACCESS_KEY_ID
37
+ # AWS.config.secret_access_key = REPLACE_WITH_SECRET_ACCESS_KEY
38
+ #
39
+ # View the aws documentation for more details at http://docs.amazonwebservices.com/AWSRubySDK/latest/frames.html
40
+ #
41
+ # Once you have the settings configured, you can start storing and retrieving data:
42
+ #
43
+ # data_store = MinceDynamoDb::DataStore.instance
44
+ # data_store.add 'fruits', id: '1', name: 'Shnawzberry', color: 'redish', quantity: '20'
45
+ # data_store.get_for_key_with_value 'fruits', :color, 'redish'
46
+ #
47
+ # @author Matt Simpson
48
+ class DataStore
49
+ include Singleton
50
+
51
+ # Returns the primary key identifier for records. This is necessary because not all databases use the same
52
+ # primary key.
53
+ #
54
+ # @return [String] the name of the primary key field.
55
+ def self.primary_key_identifier
56
+ 'id'
57
+ end
58
+
59
+ # Generates a unique ID for a database record
60
+ #
61
+ # @note This is necessary because different databases use different types of primary key values. Thus, each mince
62
+ # implementation must define how to generate a unique id.
63
+ #
64
+ # @param [#to_s] salt any object that responds to #to_s
65
+ # @return [String] A unique id based on the salt and the current time
66
+ def self.generate_unique_id(salt)
67
+ Digest::SHA256.hexdigest("#{Time.current.utc}#{salt}")[0..6]
68
+ end
69
+
70
+ # Inserts one record into a collection.
71
+ #
72
+ # @param [String] collection_name the name of the collection
73
+ # @param [Hash] hash a hash of data to be added to the collection
74
+ def add(collection_name, hash)
75
+ hash.delete_if{|k,v| v.nil? }
76
+ items(collection_name).create(hash)
77
+ end
78
+
79
+ # Replaces a record in the collection based on the primary key's value. The hash must contain a key, defined
80
+ # by the +primary_key_identifier+ method, with a value. If a record in the data store is found with that key and
81
+ # value, the entire record will be replaced with the given hash.
82
+ #
83
+ # @param [String] collection_name the name of the collection
84
+ # @param [Hash] hash a hash to replace the record in the collection with
85
+ def replace(collection_name, hash)
86
+ items(collection_name).put(hash)
87
+ end
88
+
89
+ # Gets all records that have the value for a given key.
90
+ #
91
+ # @param [String] collection_name the name of the collection
92
+ # @param [String] key the key, or field, to get a record for
93
+ # @param [*] value the value to get a record for
94
+ # @return [Array] an array of records that match the key and value
95
+ def get_all_for_key_with_value(collection_name, key, value)
96
+ get_by_params(collection_name, key => value)
97
+ end
98
+
99
+ # Gets the first record that has the value for a given key.
100
+ #
101
+ # @param [String] collection_name the name of the collection
102
+ # @param [String] key the key to find a record by
103
+ # @param [String] value the value to find a record by
104
+ # @return [Hash] a hash for the record found by the key and value in the collection
105
+ def get_for_key_with_value(collection_name, key, value)
106
+ get_all_for_key_with_value(collection_name, key.to_s, value).first
107
+ end
108
+
109
+ # Gets all records that have all of the keys and values in the given hash.
110
+ #
111
+ # @param [String] collection_name the name of the collection
112
+ # @param [Hash] hash a hash to get a record for
113
+ # @return [Array] an array of all records matching the given hash for the collection
114
+ def get_by_params(collection_name, hash)
115
+ hash = HashWithIndifferentAccess.new(hash)
116
+ array_to_hash(items(collection_name).where(hash))
117
+ end
118
+
119
+ # Gets all records for a collection
120
+ #
121
+ # @param [String] collection_name the name of the collection
122
+ # @return [Array] all records for the given collection name
123
+ def find_all(collection_name)
124
+ array_to_hash(items(collection_name))
125
+ end
126
+
127
+ # Gets a record matching a key and value
128
+ #
129
+ # @param [String] collection_name the name of the collection
130
+ # @param [String] key the key to find a record by
131
+ # @param [*] value a value the find a record by
132
+ # @return [Hash] a record that matches the given key and value
133
+ def find(collection_name, key, value)
134
+ get_for_key_with_value(collection_name, key, value)
135
+ end
136
+
137
+ # Pushes a value to a record's key that is an array
138
+ #
139
+ # @param [String] collection_name the name of the collection
140
+ # @param [String] identifying_key the field used to find the record
141
+ # @param [*] identifying_value the value used to find the record
142
+ # @param [String] array_key the field to push an array to
143
+ # @param [*] value_to_push the value to push to the array
144
+ def push_to_array(collection_name, identifying_key, identifying_value, array_key, value_to_push)
145
+ item = items(collection_name).where(identifying_key.to_s => identifying_value).first
146
+ item.attributes.add(array_key => [value_to_push])
147
+ end
148
+
149
+ # Removes a value from a record's key that is an array
150
+ #
151
+ # @param [String] collection_name the name of the collection
152
+ # @param [String] identifying_key the field used to find the record
153
+ # @param [*] identifying_value the value used to find the record
154
+ # @param [String] array_key the field to push an array from
155
+ # @param [*] value_to_remove the value to remove from the array
156
+ def remove_from_array(collection_name, identifying_key, identifying_value, array_key, value_to_remove)
157
+ item = items(collection_name).where(identifying_key.to_s => identifying_value).first
158
+ item.attributes.delete(array_key => [value_to_remove])
159
+ end
160
+
161
+ # Returns all records where the given key contains any of the values provided
162
+ #
163
+ # @param [String] collection_name the name of the collection
164
+ # @param [String] key the key to find the record by
165
+ # @param [Array] values an array of values that the record could contain
166
+ # @return [Array] all records that contain any of the values given
167
+ def containing_any(collection_name, key, values)
168
+ array_to_hash items(collection_name).where(key.to_sym).in(values)
169
+ end
170
+
171
+ # Returns all records where the given key contains the given value
172
+ #
173
+ # @param [String] collection_name the name of the collection
174
+ # @param [String] key the key to find records by
175
+ # @param [*] value the value to find a record by
176
+ # @return [Array] all records where the key contains the given value
177
+ def array_contains(collection_name, key, value)
178
+ array_to_hash items(collection_name).where(key.to_sym).contains(value)
179
+ end
180
+
181
+ # Clears the data store.
182
+ # Mainly used for rolling back the data store in tests.
183
+ def clear
184
+ db.tables.each do |t|
185
+ t.hash_key unless t.schema_loaded? # to load the schema
186
+ t.items.each do |i|
187
+ i.delete
188
+ end
189
+ end
190
+ end
191
+
192
+ # Returns the collection, or table, for a given collection name
193
+ #
194
+ # The schema must be loaded before any queries are made against a collection
195
+ # There are a couple ways to do this, from digging in their documentation about
196
+ # this topic. One is to have the schema loaded in memory, which is not recommended
197
+ # for production code, the other way is to call hash_key :) not sure why this works.
198
+ #
199
+ # @param [String] collection_name the name of the collection
200
+ # @return [AWS::DynamoDB::Table] the AWS::DynamoDB::Table for the given collection_name
201
+ def collection(collection_name)
202
+ db.tables[collection_name.to_s].tap do |c|
203
+ c.hash_key unless c.schema_loaded?
204
+ end
205
+ end
206
+
207
+ private
208
+
209
+ # Takes a DynamoDB item and returns the attributes of that item as a hash
210
+ def to_hash(item)
211
+ item.attributes.to_h if item
212
+ end
213
+
214
+ # Takes an array of DynamoDB items and returns the attributes of each item as a hash.
215
+ # calls
216
+ def array_to_hash(array)
217
+ array.map{|a| to_hash(a) }
218
+ end
219
+
220
+ # Returns the database object which comes from MinceDynamoDb::Connection
221
+ def db
222
+ MinceDynamoDb::Connection.instance.connection
223
+ end
224
+
225
+ def collections
226
+ db.tables
227
+ end
228
+
229
+ def items(collection_name)
230
+ collection(collection_name).items
231
+ end
232
+ end
233
+ end
@@ -0,0 +1,3 @@
1
+ module MinceDynamoDb
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,3 @@
1
+ require 'mince_dynamo_db/connection'
2
+ require 'mince_dynamo_db/data_store'
3
+ require "mince_dynamo_db/version"
@@ -0,0 +1,28 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "mince_dynamo_db/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "mince_dynamo_db"
7
+ s.version = MinceDynamoDb::VERSION
8
+ s.authors = ["Matt Simpson"]
9
+ s.email = ["matt@railsgrammer.com"]
10
+ s.homepage = "https://github.com/coffeencoke/mince_dynamo_db"
11
+ s.summary = %q{Lightweight ORM for Amazon's DynamoDB with Ruby Apps}
12
+ s.description = %q{Lightweight ORM for Amazon's DynamoDB with Ruby Apps}
13
+
14
+ s.rubyforge_project = "mince_dynamo_db"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ s.add_dependency 'aws-sdk', "~> 1.3.7"
22
+ s.add_dependency 'activesupport', "~> 3.0"
23
+
24
+ s.add_development_dependency "rspec", "~> 2.8.0"
25
+ s.add_development_dependency "guard-rspec", "~> 0.6.0"
26
+ s.add_development_dependency "yard", "~> 0.7.5"
27
+ s.add_development_dependency "redcarpet", "~> 2.1.1"
28
+ end
@@ -0,0 +1,18 @@
1
+ require_relative '../../lib/mince_dynamo_db'
2
+ require 'aws'
3
+
4
+ describe 'Testing mince_dynamo_db/data_store while actually hitting dynamo db:' do
5
+ AWS.config.access_key_id = 'enter_access_key_id_here'
6
+ AWS.config.secret_access_key = 'enter_secret_access_key_here'
7
+
8
+ # Ensure clear db before tests
9
+ before(:all) do
10
+ MinceDynamoeDb::DataStore.instance.clear
11
+ end
12
+
13
+ # Ensure clear db after tests
14
+ after(:all) do
15
+ MinceDynamoeDb::DataStore.instance.clear
16
+ end
17
+ end
18
+
@@ -0,0 +1,20 @@
1
+ require_relative '../../lib/mince_dynamo_db/connection'
2
+
3
+ describe MinceDynamoDb::Connection do
4
+ subject { described_class.instance }
5
+
6
+ let(:connection) { mock 'an amazon dynamo db object' }
7
+ let(:access_key_id) { mock 'access key id provided by amazon'}
8
+ let(:secret_access_key) { mock 'secret access key provided by amazon'}
9
+ let(:aws_config) { mock 'aws config object', secret_access_key: secret_access_key, access_key_id: access_key_id }
10
+
11
+ before do
12
+ AWS.stub(config: aws_config)
13
+ end
14
+
15
+ it 'has a dynamo db connection' do
16
+ AWS::DynamoDB.should_receive(:new).with(access_key_id: access_key_id, secret_access_key: secret_access_key).and_return(connection)
17
+
18
+ subject.connection.should == connection
19
+ end
20
+ end
@@ -0,0 +1,133 @@
1
+ require_relative '../../lib/mince_dynamo_db/data_store'
2
+
3
+ describe MinceDynamoDb::DataStore do
4
+ subject { described_class.instance }
5
+
6
+ let(:db) { mock 'dynamo db connection', tables: { collection_name => collection } }
7
+ let(:mince_dynamo_db_connection) { mock 'mince dynamo db connection', connection: db }
8
+ let(:collection) { mock 'some collection', items: items, schema_loaded?: true }
9
+ let(:collection_name) { 'some_collection_name'}
10
+ let(:primary_key) { mock 'primary key'}
11
+ let(:mock_id) { mock 'id' }
12
+ let(:data) { { :_id => mock_id}}
13
+ let(:return_data) { mock 'return data', attributes: attributes }
14
+ let(:attributes) { mock 'attributes', to_h: hash }
15
+ let(:hash) { mock 'hash' }
16
+ let(:items) { mock 'items' }
17
+
18
+ before do
19
+ MinceDynamoDb::Connection.stub(:instance => mince_dynamo_db_connection)
20
+ end
21
+
22
+ it 'uses the correct collection' do
23
+ subject.collection(collection_name).should == collection
24
+ end
25
+
26
+ it 'has a primary key identifier' do
27
+ described_class.primary_key_identifier.should == 'id'
28
+ end
29
+
30
+ describe "Generating a primary key" do
31
+ let(:unique_id) { '123456789012345' }
32
+ let(:time) { mock 'time' }
33
+ let(:salt) { mock 'salt' }
34
+
35
+ before do
36
+ Time.stub_chain('current.utc' => time)
37
+ end
38
+
39
+ it 'should create a reasonably unique id' do
40
+ Digest::SHA256.should_receive(:hexdigest).with("#{time}#{salt}").and_return(unique_id)
41
+ shorter_id = unique_id.to_s[0..6]
42
+
43
+ described_class.generate_unique_id(salt).should == shorter_id
44
+ end
45
+ end
46
+
47
+ it 'can write to the collection' do
48
+ items.should_receive(:create).with(data).and_return(return_data)
49
+
50
+ subject.add(collection_name, data).should == return_data
51
+ end
52
+
53
+ it 'can read from the collection' do
54
+ item_hash = mock 'hash of attributes for an item'
55
+ item_attributes = mock 'attributes for an item', to_h: item_hash
56
+ item = mock 'item', attributes: item_attributes
57
+ collection.stub(items: [item])
58
+
59
+ subject.find_all(collection_name).should == [item_hash]
60
+ end
61
+
62
+ it 'can replace a record' do
63
+ items.should_receive(:put).with(data)
64
+
65
+ subject.replace(collection_name, data)
66
+ end
67
+
68
+ it 'can get one document' do
69
+ field = "stuff"
70
+ value = "more stuff"
71
+
72
+ items.should_receive(:where).with(field => value).and_return([return_data])
73
+
74
+ subject.find(collection_name, field, value).should == hash
75
+ end
76
+
77
+ it 'can clear the data store' do
78
+ item = mock 'item', delete: nil
79
+ item2 = mock 'item 2', delete: nil
80
+ collection_1 = mock 'collection 1', name: 'collection 1', schema_loaded?: true, items: [item]
81
+ collection_2 = mock 'collection 2', name: 'collection 2', schema_loaded?: true, items: [item2]
82
+ collections = [collection_1, collection_2]
83
+
84
+ db.stub(:tables => collections)
85
+
86
+ item.should_receive(:delete)
87
+ item2.should_receive(:delete)
88
+
89
+ subject.clear
90
+ end
91
+
92
+ it 'can get all records of a specific key value' do
93
+ items.should_receive(:where).with("key" => "value").and_return([return_data])
94
+
95
+ subject.get_all_for_key_with_value(collection_name, "key", "value").should == [hash]
96
+ end
97
+
98
+ it 'can get a record of a specific key value' do
99
+ items.should_receive(:where).with({"key" => "value"}).and_return([return_data])
100
+
101
+ subject.get_for_key_with_value(collection_name, "key", "value").should == hash
102
+ end
103
+
104
+ it 'can get all records where a value includes any of a set of values' do
105
+ filter = mock 'filter', in: return_data
106
+ items.should_receive(:where).with(:key1).and_return(filter)
107
+ filter.should_receive(:in).with([1,2,4]).and_return([return_data])
108
+
109
+ subject.containing_any(collection_name, "key1", [1,2,4]).should == [hash]
110
+ end
111
+
112
+ it 'can get all records where the array includes a value' do
113
+ filter = mock 'filter', contains: return_data
114
+ items.should_receive(:where).with(:key).and_return(filter)
115
+ filter.should_receive(:contains).with('value').and_return([return_data])
116
+
117
+ subject.array_contains(collection_name, "key", "value").should == [hash]
118
+ end
119
+
120
+ it 'can push a value to an array for a specific record' do
121
+ items.should_receive(:where).with("key" => "value").and_return([return_data])
122
+ attributes.should_receive(:add).with(:array_key => ["value_to_push"])
123
+
124
+ subject.push_to_array(collection_name, :key, "value", :array_key, "value_to_push")
125
+ end
126
+
127
+ it 'can remove a value from an array for a specific record' do
128
+ items.should_receive(:where).with("key" => "value").and_return([return_data])
129
+ attributes.should_receive(:delete).with(:array_key => ["value_to_remove"])
130
+
131
+ subject.remove_from_array(collection_name, :key, "value", :array_key, "value_to_remove")
132
+ end
133
+ end
File without changes
metadata ADDED
@@ -0,0 +1,132 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mince_dynamo_db
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Matt Simpson
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-03-23 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: aws-sdk
16
+ requirement: &70289094931040 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 1.3.7
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70289094931040
25
+ - !ruby/object:Gem::Dependency
26
+ name: activesupport
27
+ requirement: &70289094958080 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ~>
31
+ - !ruby/object:Gem::Version
32
+ version: '3.0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *70289094958080
36
+ - !ruby/object:Gem::Dependency
37
+ name: rspec
38
+ requirement: &70289094957560 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ version: 2.8.0
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *70289094957560
47
+ - !ruby/object:Gem::Dependency
48
+ name: guard-rspec
49
+ requirement: &70289094956900 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: 0.6.0
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *70289094956900
58
+ - !ruby/object:Gem::Dependency
59
+ name: yard
60
+ requirement: &70289094956260 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ~>
64
+ - !ruby/object:Gem::Version
65
+ version: 0.7.5
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *70289094956260
69
+ - !ruby/object:Gem::Dependency
70
+ name: redcarpet
71
+ requirement: &70289094955340 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ~>
75
+ - !ruby/object:Gem::Version
76
+ version: 2.1.1
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: *70289094955340
80
+ description: Lightweight ORM for Amazon's DynamoDB with Ruby Apps
81
+ email:
82
+ - matt@railsgrammer.com
83
+ executables: []
84
+ extensions: []
85
+ extra_rdoc_files: []
86
+ files:
87
+ - .gitignore
88
+ - .rspec
89
+ - .rvmrc
90
+ - Gemfile
91
+ - Guardfile
92
+ - README.md
93
+ - Rakefile
94
+ - lib/mince_dynamo_db.rb
95
+ - lib/mince_dynamo_db/connection.rb
96
+ - lib/mince_dynamo_db/data_store.rb
97
+ - lib/mince_dynamo_db/version.rb
98
+ - mince_dynamo_db.gemspec
99
+ - spec/integration/persisting_to_dynamodb_test.rb
100
+ - spec/lib/connection_spec.rb
101
+ - spec/lib/data_store_spec.rb
102
+ - spec/support/aws_example.yml
103
+ homepage: https://github.com/coffeencoke/mince_dynamo_db
104
+ licenses: []
105
+ post_install_message:
106
+ rdoc_options: []
107
+ require_paths:
108
+ - lib
109
+ required_ruby_version: !ruby/object:Gem::Requirement
110
+ none: false
111
+ requirements:
112
+ - - ! '>='
113
+ - !ruby/object:Gem::Version
114
+ version: '0'
115
+ required_rubygems_version: !ruby/object:Gem::Requirement
116
+ none: false
117
+ requirements:
118
+ - - ! '>='
119
+ - !ruby/object:Gem::Version
120
+ version: '0'
121
+ requirements: []
122
+ rubyforge_project: mince_dynamo_db
123
+ rubygems_version: 1.8.10
124
+ signing_key:
125
+ specification_version: 3
126
+ summary: Lightweight ORM for Amazon's DynamoDB with Ruby Apps
127
+ test_files:
128
+ - spec/integration/persisting_to_dynamodb_test.rb
129
+ - spec/lib/connection_spec.rb
130
+ - spec/lib/data_store_spec.rb
131
+ - spec/support/aws_example.yml
132
+ has_rdoc: