dynamoid 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. data/.document +5 -0
  2. data/.rspec +1 -0
  3. data/Dynamoid.gemspec +116 -0
  4. data/Gemfile +19 -0
  5. data/Gemfile.lock +58 -0
  6. data/LICENSE.txt +20 -0
  7. data/README.markdown +86 -0
  8. data/Rakefile +49 -0
  9. data/VERSION +1 -0
  10. data/lib/dynamoid.rb +32 -0
  11. data/lib/dynamoid/adapter.rb +24 -0
  12. data/lib/dynamoid/adapter/aws_sdk.rb +100 -0
  13. data/lib/dynamoid/adapter/local.rb +77 -0
  14. data/lib/dynamoid/associations.rb +54 -0
  15. data/lib/dynamoid/associations/association.rb +80 -0
  16. data/lib/dynamoid/associations/belongs_to.rb +39 -0
  17. data/lib/dynamoid/associations/has_and_belongs_to_many.rb +34 -0
  18. data/lib/dynamoid/associations/has_many.rb +33 -0
  19. data/lib/dynamoid/associations/has_one.rb +36 -0
  20. data/lib/dynamoid/attributes.rb +37 -0
  21. data/lib/dynamoid/components.rb +25 -0
  22. data/lib/dynamoid/config.rb +19 -0
  23. data/lib/dynamoid/config/options.rb +74 -0
  24. data/lib/dynamoid/document.rb +35 -0
  25. data/lib/dynamoid/errors.rb +8 -0
  26. data/lib/dynamoid/fields.rb +32 -0
  27. data/lib/dynamoid/finders.rb +62 -0
  28. data/lib/dynamoid/indexes.rb +59 -0
  29. data/lib/dynamoid/persistence.rb +35 -0
  30. data/lib/dynamoid/relations.rb +21 -0
  31. data/spec/app/models/address.rb +5 -0
  32. data/spec/app/models/magazine.rb +6 -0
  33. data/spec/app/models/sponsor.rb +6 -0
  34. data/spec/app/models/subscription.rb +6 -0
  35. data/spec/app/models/user.rb +13 -0
  36. data/spec/dynamoid/adapter/aws_sdk_spec.rb +123 -0
  37. data/spec/dynamoid/adapter/local_spec.rb +150 -0
  38. data/spec/dynamoid/adapter_spec.rb +13 -0
  39. data/spec/dynamoid/associations/association_spec.rb +71 -0
  40. data/spec/dynamoid/associations/belongs_to_spec.rb +50 -0
  41. data/spec/dynamoid/associations/has_and_belongs_to_many_spec.rb +30 -0
  42. data/spec/dynamoid/associations/has_many_spec.rb +28 -0
  43. data/spec/dynamoid/associations/has_one_spec.rb +37 -0
  44. data/spec/dynamoid/associations_spec.rb +16 -0
  45. data/spec/dynamoid/attributes_spec.rb +43 -0
  46. data/spec/dynamoid/document_spec.rb +38 -0
  47. data/spec/dynamoid/fields_spec.rb +26 -0
  48. data/spec/dynamoid/finders_spec.rb +114 -0
  49. data/spec/dynamoid/indexes_spec.rb +54 -0
  50. data/spec/dynamoid/persistence_spec.rb +55 -0
  51. data/spec/dynamoid/relations_spec.rb +6 -0
  52. data/spec/dynamoid_spec.rb +5 -0
  53. data/spec/spec_helper.rb +52 -0
  54. metadata +204 -0
@@ -0,0 +1,38 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe "Dynamoid::Document" do
4
+
5
+ it 'initializes a new document' do
6
+ @address = Address.new
7
+
8
+ @address.new_record.should be_true
9
+ @address.attributes.should == {:id => nil, :city => nil}
10
+ end
11
+
12
+ it 'initializes a new document with attributes' do
13
+ @address = Address.new(:city => 'Chicago')
14
+
15
+ @address.new_record.should be_true
16
+
17
+ @address.attributes.should == {:id => nil, :city => 'Chicago'}
18
+ end
19
+
20
+ it 'creates a new document' do
21
+ @address = Address.create(:city => 'Chicago')
22
+
23
+ @address.new_record.should be_false
24
+ @address.id.should_not be_nil
25
+ end
26
+
27
+ it 'tests equivalency with itself' do
28
+ @addres.should == @address
29
+ end
30
+
31
+ it 'is not equivalent to another document' do
32
+ @address.should_not == Address.create
33
+ end
34
+
35
+ it 'is not equivalent to another object' do
36
+ @address.should_not == "test"
37
+ end
38
+ end
@@ -0,0 +1,26 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe "Dynamoid::Fields" do
4
+
5
+ before do
6
+ @address = Address.new
7
+ end
8
+
9
+ it 'declares read attributes' do
10
+ @address.city.should be_nil
11
+ end
12
+
13
+ it 'declares write attributes' do
14
+ @address.city = 'Chicago'
15
+ @address.city.should == 'Chicago'
16
+ end
17
+
18
+ it 'declares a query attribute' do
19
+ @address.city?.should be_false
20
+
21
+ @address.city = 'Chicago'
22
+
23
+ @address.city?.should be_true
24
+ end
25
+
26
+ end
@@ -0,0 +1,114 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe "Dynamoid::Finders" do
4
+
5
+ before do
6
+ @address = Address.create(:city => 'Chicago')
7
+ end
8
+
9
+ it 'finds an existing address' do
10
+ found = Address.find(@address.id)
11
+
12
+ found.should == @address
13
+ found.city.should == 'Chicago'
14
+ end
15
+
16
+ it 'is not a new object' do
17
+ found = Address.find(@address.id)
18
+
19
+ found.new_record.should_not be_true
20
+ end
21
+
22
+ it 'returns nil when nothing is found' do
23
+ Address.find('1234').should be_nil
24
+ end
25
+
26
+ it 'finds multiple ids' do
27
+ @address2 = Address.create(:city => 'Illinois')
28
+
29
+ Address.find(@address.id, @address2.id).should include @address, @address2
30
+ end
31
+
32
+ context 'with users' do
33
+ before do
34
+ User.create_indexes
35
+ end
36
+
37
+ it 'finds using method_missing for attributes' do
38
+ array = Address.find_by_city('Chicago')
39
+
40
+ array.should == @address
41
+ end
42
+
43
+ it 'finds using method_missing for multiple attributes' do
44
+ @user = User.create(:name => 'Josh', :email => 'josh@joshsymonds.com')
45
+
46
+ array = User.find_all_by_name_and_email('Josh', 'josh@joshsymonds.com')
47
+
48
+ array.should == [@user]
49
+ end
50
+
51
+ it 'finds using method_missing for single attributes and multiple results' do
52
+ @user1 = User.create(:name => 'Josh', :email => 'josh@joshsymonds.com')
53
+ @user2 = User.create(:name => 'Josh', :email => 'josh@joshsymonds.com')
54
+
55
+ array = User.find_all_by_name('Josh')
56
+
57
+ array.size.should == 2
58
+ array.should include @user1
59
+ array.should include @user2
60
+ end
61
+
62
+ it 'finds using method_missing for multiple attributes and multiple results' do
63
+ @user1 = User.create(:name => 'Josh', :email => 'josh@joshsymonds.com')
64
+ @user2 = User.create(:name => 'Josh', :email => 'josh@joshsymonds.com')
65
+
66
+ array = User.find_all_by_name_and_email('Josh', 'josh@joshsymonds.com')
67
+
68
+ array.size.should == 2
69
+ array.should include @user1
70
+ array.should include @user2
71
+ end
72
+
73
+ it 'finds using method_missing for multiple attributes and no results' do
74
+ @user1 = User.create(:name => 'Josh', :email => 'josh@joshsymonds.com')
75
+ @user2 = User.create(:name => 'Justin', :email => 'justin@joshsymonds.com')
76
+
77
+ array = User.find_all_by_name_and_email('Gaga','josh@joshsymonds.com')
78
+
79
+ array.should be_empty
80
+ end
81
+
82
+ it 'finds using method_missing for a single attribute and no results' do
83
+ @user1 = User.create(:name => 'Josh', :email => 'josh@joshsymonds.com')
84
+ @user2 = User.create(:name => 'Justin', :email => 'justin@joshsymonds.com')
85
+
86
+ array = User.find_all_by_name('Gaga')
87
+
88
+ array.should be_empty
89
+ end
90
+
91
+ it 'should find on a query that is not indexed' do
92
+ @user = User.create(:password => 'Test')
93
+
94
+ array = User.find_all_by_password('Test')
95
+
96
+ array.should == [@user]
97
+ end
98
+
99
+ it 'should find on a query on multiple attributes that are not indexed' do
100
+ @user = User.create(:password => 'Test', :name => 'Josh')
101
+
102
+ array = User.find_all_by_password_and_name('Test', 'Josh')
103
+
104
+ array.should == [@user]
105
+ end
106
+
107
+ it 'should return an empty array when fields exist but nothing is found' do
108
+ array = User.find_all_by_password('Test')
109
+
110
+ array.should be_empty
111
+ end
112
+
113
+ end
114
+ end
@@ -0,0 +1,54 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe "Dynamoid::Indexes" do
4
+
5
+ before do
6
+ User.create_indexes
7
+ end
8
+
9
+ it 'raises an error if a field does not exist' do
10
+ lambda {User.send(:index, :test)}.should raise_error(Dynamoid::Errors::InvalidField)
11
+ end
12
+
13
+ it 'adds indexes to the index array' do
14
+ User.indexes.should == [[:name], [:email], [:email, :name]]
15
+ end
16
+
17
+ it 'reorders index names alphabetically' do
18
+ User.indexes.last.should == [:email, :name]
19
+ end
20
+
21
+ it 'creates a name for a table index' do
22
+ User.index_table_name([:email, :name]).should == 'dynamoid_tests_index_user_emails_and_names'
23
+ end
24
+
25
+ it 'creates a key name for a table index' do
26
+ User.index_key_name([:email, :name]).should == 'user_emails_and_names'
27
+ end
28
+
29
+ it 'creates a table after an index is created' do
30
+ User.send(:index, :password)
31
+
32
+ User.table_exists?(User.index_table_name([:password])).should be_true
33
+ end
34
+
35
+ it 'assembles a hashed value for the key of an index' do
36
+ @user = User.create(:name => 'Josh', :email => 'josh@joshsymonds.com')
37
+
38
+ @user.key_for_index([:email, :name]).should == (Digest::SHA2.new << 'Josh' << 'josh@joshsymonds.com').to_s
39
+ end
40
+
41
+ it 'saves indexes to their tables' do
42
+ @user = User.create(:name => 'Josh')
43
+
44
+ Dynamoid::Adapter.get_item("dynamoid_tests_index_user_names", @user.key_for_index([:name])).should == {@user.class.index_key_name([:name]).to_sym => @user.key_for_index([:name]), :ids => Set[@user.id]}
45
+ end
46
+
47
+ it 'saves multiple indexes with the same value as an array' do
48
+ @user1 = User.create(:name => 'Josh')
49
+ @user2 = User.create(:name => 'Josh')
50
+
51
+ Dynamoid::Adapter.get_item("dynamoid_tests_index_user_names", @user1.key_for_index([:name])).should == {@user1.class.index_key_name([:name]).to_sym => @user1.key_for_index([:name]), :ids => Set[@user2.id, @user1.id]}
52
+ end
53
+
54
+ end
@@ -0,0 +1,55 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe "Dynamoid::Persistence" do
4
+
5
+ before do
6
+ @address = Address.new
7
+ end
8
+
9
+ context 'without AWS keys' do
10
+ unless ENV['ACCESS_KEY'] && ENV['SECRET_KEY']
11
+ before do
12
+ Dynamoid::Adapter.delete_table(Address.table_name) if Dynamoid::Adapter.list_tables.include?(Address.table_name)
13
+ end
14
+
15
+ it 'creates a table' do
16
+ Address.create_table(Address.table_name)
17
+
18
+ Dynamoid::Adapter.list_tables.should include 'dynamoid_tests_addresses'
19
+ end
20
+
21
+ it 'checks if a table already exists' do
22
+ Address.create_table(Address.table_name)
23
+
24
+ Address.table_exists?(Address.table_name).should be_true
25
+ Address.table_exists?('crazytable').should be_false
26
+ end
27
+ end
28
+ end
29
+
30
+
31
+ it 'assigns itself an id on save' do
32
+ @address.save
33
+
34
+ Dynamoid::Adapter.get_item("dynamoid_tests_addresses", @address.id)[:id].should == @address.id
35
+ end
36
+
37
+ it 'assigns itself an id on save only if it does not have one' do
38
+ @address.id = 'test123'
39
+ @address.save
40
+
41
+ Dynamoid::Adapter.get_item("dynamoid_tests_addresses", 'test123').should_not be_empty
42
+ end
43
+
44
+ it 'has a table name' do
45
+ Address.table_name.should == 'dynamoid_tests_addresses'
46
+ end
47
+
48
+ it 'saves indexes along with itself' do
49
+ @user = User.new(:name => 'Josh')
50
+
51
+ @user.expects(:save_indexes).once.returns(true)
52
+ @user.save
53
+ end
54
+
55
+ end
@@ -0,0 +1,6 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe "Dynamoid::Relations" do
4
+
5
+
6
+ end
@@ -0,0 +1,5 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "Dynamoid" do
4
+
5
+ end
@@ -0,0 +1,52 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
3
+
4
+ MODELS = File.join(File.dirname(__FILE__), "app/models")
5
+
6
+ require 'rspec'
7
+ require 'dynamoid'
8
+ require 'mocha'
9
+
10
+ Dynamoid.configure do |config|
11
+ if ENV['ACCESS_KEY'] && ENV['SECRET_KEY']
12
+ config.adapter = 'aws_sdk'
13
+ config.access_key = ENV['ACCESS_KEY']
14
+ config.secret_key = ENV['SECRET_KEY']
15
+ else
16
+ config.adapter = 'local'
17
+ end
18
+ config.namespace = 'dynamoid_tests'
19
+ config.warn_on_scan = false
20
+ end
21
+
22
+ # Requires supporting files with custom matchers and macros, etc,
23
+ # in ./support/ and its subdirectories.
24
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
25
+
26
+ Dir[ File.join(MODELS, "*.rb") ].sort.each { |file| require file }
27
+
28
+ RSpec.configure do |config|
29
+ config.mock_with(:mocha)
30
+
31
+ if ENV['ACCESS_KEY'] && ENV['SECRET_KEY']
32
+ config.before(:each) do
33
+ Dynamoid::Adapter.list_tables.each do |table|
34
+ if table =~ /^#{Dynamoid::Config.namespace}/
35
+ table = Dynamoid::Adapter.connection.tables[table]
36
+ table.load_schema
37
+ table.items.each {|i| i.delete}
38
+ end
39
+ end
40
+ end
41
+
42
+ #config.after(:suite) do
43
+ # Dynamoid::Adapter.list_tables.each do |table|
44
+ # Dynamoid::Adapter.delete_table(table) if table =~ /^#{Dynamoid::Config.namespace}/
45
+ # end
46
+ #end
47
+ else
48
+ config.before(:each) do
49
+ Dynamoid::Adapter.reset_data
50
+ end
51
+ end
52
+ end
metadata ADDED
@@ -0,0 +1,204 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dynamoid
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Josh Symonds
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-02-26 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: activemodel
16
+ requirement: &70308512101780 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70308512101780
25
+ - !ruby/object:Gem::Dependency
26
+ name: tzinfo
27
+ requirement: &70308512117280 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *70308512117280
36
+ - !ruby/object:Gem::Dependency
37
+ name: aws-sdk
38
+ requirement: &70308512115100 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :runtime
45
+ prerelease: false
46
+ version_requirements: *70308512115100
47
+ - !ruby/object:Gem::Dependency
48
+ name: mocha
49
+ requirement: &70308512112760 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *70308512112760
58
+ - !ruby/object:Gem::Dependency
59
+ name: rake
60
+ requirement: &70308511927640 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *70308511927640
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ requirement: &70308511926580 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: *70308511926580
80
+ - !ruby/object:Gem::Dependency
81
+ name: bundler
82
+ requirement: &70308511926080 !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ! '>='
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ type: :development
89
+ prerelease: false
90
+ version_requirements: *70308511926080
91
+ - !ruby/object:Gem::Dependency
92
+ name: jeweler
93
+ requirement: &70308511925480 !ruby/object:Gem::Requirement
94
+ none: false
95
+ requirements:
96
+ - - ! '>='
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ type: :development
100
+ prerelease: false
101
+ version_requirements: *70308511925480
102
+ - !ruby/object:Gem::Dependency
103
+ name: rcov
104
+ requirement: &70308511924800 !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ type: :development
111
+ prerelease: false
112
+ version_requirements: *70308511924800
113
+ description: Dynamoid is an ORM for Amazon's DynamoDB that supports offline development,
114
+ associations, querying, and everything else you'd expect from an ActiveRecord-style
115
+ replacement.
116
+ email: josh@joshsymonds.com
117
+ executables: []
118
+ extensions: []
119
+ extra_rdoc_files:
120
+ - LICENSE.txt
121
+ - README.markdown
122
+ files:
123
+ - .document
124
+ - .rspec
125
+ - Dynamoid.gemspec
126
+ - Gemfile
127
+ - Gemfile.lock
128
+ - LICENSE.txt
129
+ - README.markdown
130
+ - Rakefile
131
+ - VERSION
132
+ - lib/dynamoid.rb
133
+ - lib/dynamoid/adapter.rb
134
+ - lib/dynamoid/adapter/aws_sdk.rb
135
+ - lib/dynamoid/adapter/local.rb
136
+ - lib/dynamoid/associations.rb
137
+ - lib/dynamoid/associations/association.rb
138
+ - lib/dynamoid/associations/belongs_to.rb
139
+ - lib/dynamoid/associations/has_and_belongs_to_many.rb
140
+ - lib/dynamoid/associations/has_many.rb
141
+ - lib/dynamoid/associations/has_one.rb
142
+ - lib/dynamoid/attributes.rb
143
+ - lib/dynamoid/components.rb
144
+ - lib/dynamoid/config.rb
145
+ - lib/dynamoid/config/options.rb
146
+ - lib/dynamoid/document.rb
147
+ - lib/dynamoid/errors.rb
148
+ - lib/dynamoid/fields.rb
149
+ - lib/dynamoid/finders.rb
150
+ - lib/dynamoid/indexes.rb
151
+ - lib/dynamoid/persistence.rb
152
+ - lib/dynamoid/relations.rb
153
+ - spec/app/models/address.rb
154
+ - spec/app/models/magazine.rb
155
+ - spec/app/models/sponsor.rb
156
+ - spec/app/models/subscription.rb
157
+ - spec/app/models/user.rb
158
+ - spec/dynamoid/adapter/aws_sdk_spec.rb
159
+ - spec/dynamoid/adapter/local_spec.rb
160
+ - spec/dynamoid/adapter_spec.rb
161
+ - spec/dynamoid/associations/association_spec.rb
162
+ - spec/dynamoid/associations/belongs_to_spec.rb
163
+ - spec/dynamoid/associations/has_and_belongs_to_many_spec.rb
164
+ - spec/dynamoid/associations/has_many_spec.rb
165
+ - spec/dynamoid/associations/has_one_spec.rb
166
+ - spec/dynamoid/associations_spec.rb
167
+ - spec/dynamoid/attributes_spec.rb
168
+ - spec/dynamoid/document_spec.rb
169
+ - spec/dynamoid/fields_spec.rb
170
+ - spec/dynamoid/finders_spec.rb
171
+ - spec/dynamoid/indexes_spec.rb
172
+ - spec/dynamoid/persistence_spec.rb
173
+ - spec/dynamoid/relations_spec.rb
174
+ - spec/dynamoid_spec.rb
175
+ - spec/spec_helper.rb
176
+ homepage: http://github.com/Veraticus/Dynamoid
177
+ licenses:
178
+ - MIT
179
+ post_install_message:
180
+ rdoc_options: []
181
+ require_paths:
182
+ - lib
183
+ required_ruby_version: !ruby/object:Gem::Requirement
184
+ none: false
185
+ requirements:
186
+ - - ! '>='
187
+ - !ruby/object:Gem::Version
188
+ version: '0'
189
+ segments:
190
+ - 0
191
+ hash: 2111085687923262415
192
+ required_rubygems_version: !ruby/object:Gem::Requirement
193
+ none: false
194
+ requirements:
195
+ - - ! '>='
196
+ - !ruby/object:Gem::Version
197
+ version: '0'
198
+ requirements: []
199
+ rubyforge_project:
200
+ rubygems_version: 1.8.10
201
+ signing_key:
202
+ specification_version: 3
203
+ summary: Dynamoid is an ORM for Amazon's DynamoDB
204
+ test_files: []