adept_dynamoid 0.5.0.6

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 (119) hide show
  1. data/.document +5 -0
  2. data/.rspec +1 -0
  3. data/Dynamoid.gemspec +193 -0
  4. data/Gemfile +23 -0
  5. data/Gemfile.lock +86 -0
  6. data/LICENSE.txt +20 -0
  7. data/README.markdown +265 -0
  8. data/Rakefile +62 -0
  9. data/VERSION +1 -0
  10. data/doc/.nojekyll +0 -0
  11. data/doc/Dynamoid.html +312 -0
  12. data/doc/Dynamoid/Adapter.html +1385 -0
  13. data/doc/Dynamoid/Adapter/AwsSdk.html +1585 -0
  14. data/doc/Dynamoid/Adapter/Local.html +1574 -0
  15. data/doc/Dynamoid/Associations.html +131 -0
  16. data/doc/Dynamoid/Associations/Association.html +794 -0
  17. data/doc/Dynamoid/Associations/BelongsTo.html +158 -0
  18. data/doc/Dynamoid/Associations/ClassMethods.html +723 -0
  19. data/doc/Dynamoid/Associations/HasAndBelongsToMany.html +164 -0
  20. data/doc/Dynamoid/Associations/HasMany.html +164 -0
  21. data/doc/Dynamoid/Associations/HasOne.html +158 -0
  22. data/doc/Dynamoid/Associations/ManyAssociation.html +1640 -0
  23. data/doc/Dynamoid/Associations/SingleAssociation.html +598 -0
  24. data/doc/Dynamoid/Components.html +204 -0
  25. data/doc/Dynamoid/Config.html +395 -0
  26. data/doc/Dynamoid/Config/Options.html +609 -0
  27. data/doc/Dynamoid/Criteria.html +131 -0
  28. data/doc/Dynamoid/Criteria/Chain.html +1063 -0
  29. data/doc/Dynamoid/Criteria/ClassMethods.html +98 -0
  30. data/doc/Dynamoid/Document.html +666 -0
  31. data/doc/Dynamoid/Document/ClassMethods.html +937 -0
  32. data/doc/Dynamoid/Errors.html +118 -0
  33. data/doc/Dynamoid/Errors/DocumentNotValid.html +210 -0
  34. data/doc/Dynamoid/Errors/Error.html +130 -0
  35. data/doc/Dynamoid/Errors/InvalidField.html +133 -0
  36. data/doc/Dynamoid/Errors/MissingRangeKey.html +133 -0
  37. data/doc/Dynamoid/Fields.html +669 -0
  38. data/doc/Dynamoid/Fields/ClassMethods.html +309 -0
  39. data/doc/Dynamoid/Finders.html +128 -0
  40. data/doc/Dynamoid/Finders/ClassMethods.html +516 -0
  41. data/doc/Dynamoid/Indexes.html +308 -0
  42. data/doc/Dynamoid/Indexes/ClassMethods.html +353 -0
  43. data/doc/Dynamoid/Indexes/Index.html +1104 -0
  44. data/doc/Dynamoid/Persistence.html +651 -0
  45. data/doc/Dynamoid/Persistence/ClassMethods.html +670 -0
  46. data/doc/Dynamoid/Validations.html +399 -0
  47. data/doc/_index.html +461 -0
  48. data/doc/class_list.html +47 -0
  49. data/doc/css/common.css +1 -0
  50. data/doc/css/full_list.css +55 -0
  51. data/doc/css/style.css +322 -0
  52. data/doc/file.LICENSE.html +66 -0
  53. data/doc/file.README.html +312 -0
  54. data/doc/file_list.html +52 -0
  55. data/doc/frames.html +13 -0
  56. data/doc/index.html +312 -0
  57. data/doc/js/app.js +205 -0
  58. data/doc/js/full_list.js +173 -0
  59. data/doc/js/jquery.js +16 -0
  60. data/doc/method_list.html +1238 -0
  61. data/doc/top-level-namespace.html +105 -0
  62. data/lib/dynamoid.rb +47 -0
  63. data/lib/dynamoid/adapter.rb +177 -0
  64. data/lib/dynamoid/adapter/aws_sdk.rb +223 -0
  65. data/lib/dynamoid/associations.rb +106 -0
  66. data/lib/dynamoid/associations/association.rb +105 -0
  67. data/lib/dynamoid/associations/belongs_to.rb +44 -0
  68. data/lib/dynamoid/associations/has_and_belongs_to_many.rb +40 -0
  69. data/lib/dynamoid/associations/has_many.rb +39 -0
  70. data/lib/dynamoid/associations/has_one.rb +39 -0
  71. data/lib/dynamoid/associations/many_association.rb +191 -0
  72. data/lib/dynamoid/associations/single_association.rb +69 -0
  73. data/lib/dynamoid/components.rb +36 -0
  74. data/lib/dynamoid/config.rb +57 -0
  75. data/lib/dynamoid/config/options.rb +78 -0
  76. data/lib/dynamoid/criteria.rb +29 -0
  77. data/lib/dynamoid/criteria/chain.rb +243 -0
  78. data/lib/dynamoid/dirty.rb +41 -0
  79. data/lib/dynamoid/document.rb +184 -0
  80. data/lib/dynamoid/errors.rb +28 -0
  81. data/lib/dynamoid/fields.rb +130 -0
  82. data/lib/dynamoid/finders.rb +131 -0
  83. data/lib/dynamoid/identity_map.rb +96 -0
  84. data/lib/dynamoid/indexes.rb +69 -0
  85. data/lib/dynamoid/indexes/index.rb +103 -0
  86. data/lib/dynamoid/middleware/identity_map.rb +16 -0
  87. data/lib/dynamoid/persistence.rb +247 -0
  88. data/lib/dynamoid/validations.rb +36 -0
  89. data/spec/app/models/address.rb +10 -0
  90. data/spec/app/models/camel_case.rb +24 -0
  91. data/spec/app/models/magazine.rb +11 -0
  92. data/spec/app/models/message.rb +9 -0
  93. data/spec/app/models/sponsor.rb +8 -0
  94. data/spec/app/models/subscription.rb +12 -0
  95. data/spec/app/models/tweet.rb +12 -0
  96. data/spec/app/models/user.rb +26 -0
  97. data/spec/dynamoid/adapter/aws_sdk_spec.rb +186 -0
  98. data/spec/dynamoid/adapter_spec.rb +117 -0
  99. data/spec/dynamoid/associations/association_spec.rb +194 -0
  100. data/spec/dynamoid/associations/belongs_to_spec.rb +71 -0
  101. data/spec/dynamoid/associations/has_and_belongs_to_many_spec.rb +47 -0
  102. data/spec/dynamoid/associations/has_many_spec.rb +42 -0
  103. data/spec/dynamoid/associations/has_one_spec.rb +45 -0
  104. data/spec/dynamoid/associations_spec.rb +16 -0
  105. data/spec/dynamoid/config_spec.rb +27 -0
  106. data/spec/dynamoid/criteria/chain_spec.rb +140 -0
  107. data/spec/dynamoid/criteria_spec.rb +72 -0
  108. data/spec/dynamoid/dirty_spec.rb +49 -0
  109. data/spec/dynamoid/document_spec.rb +118 -0
  110. data/spec/dynamoid/fields_spec.rb +127 -0
  111. data/spec/dynamoid/finders_spec.rb +135 -0
  112. data/spec/dynamoid/identity_map_spec.rb +45 -0
  113. data/spec/dynamoid/indexes/index_spec.rb +104 -0
  114. data/spec/dynamoid/indexes_spec.rb +25 -0
  115. data/spec/dynamoid/persistence_spec.rb +176 -0
  116. data/spec/dynamoid/validations_spec.rb +36 -0
  117. data/spec/dynamoid_spec.rb +9 -0
  118. data/spec/spec_helper.rb +50 -0
  119. metadata +376 -0
@@ -0,0 +1,194 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
+
3
+ describe "Dynamoid::Associations::Association" do
4
+
5
+ before do
6
+ Subscription.create_table
7
+ @magazine = Magazine.create
8
+ end
9
+
10
+ it 'returns an empty array if there are no associations' do
11
+ @magazine.subscriptions.should be_empty
12
+ end
13
+
14
+ it 'adds an item to an association' do
15
+ @subscription = Subscription.create
16
+
17
+ @magazine.subscriptions << @subscription
18
+ @magazine.subscriptions.size.should == 1
19
+ @magazine.subscriptions.should include @subscription
20
+ end
21
+
22
+ it 'deletes an item from an association' do
23
+ @subscription = Subscription.create
24
+ @magazine.subscriptions << @subscription
25
+
26
+ @magazine.subscriptions.delete(@subscription)
27
+ @magazine.subscriptions.size.should == 0
28
+ end
29
+
30
+ it 'creates an item from an association' do
31
+ @subscription = @magazine.subscriptions.create
32
+
33
+ @subscription.class.should == Subscription
34
+ @magazine.subscriptions.size.should == 1
35
+ @magazine.subscriptions.should include @subscription
36
+ end
37
+
38
+ it 'returns the number of items in the association' do
39
+ @magazine.subscriptions.create
40
+ @magazine.subscriptions.size.should == 1
41
+
42
+ @second = @magazine.subscriptions.create
43
+ @magazine.subscriptions.size.should == 2
44
+
45
+ @magazine.subscriptions.delete(@second)
46
+ @magazine.subscriptions.size.should == 1
47
+
48
+ @magazine.subscriptions = []
49
+ @magazine.subscriptions.size.should == 0
50
+ end
51
+
52
+ it 'assigns directly via the equals operator' do
53
+ @subscription = Subscription.create
54
+ @magazine.subscriptions = [@subscription]
55
+
56
+ @magazine.subscriptions.should == [@subscription]
57
+ end
58
+
59
+ it 'assigns directly via the equals operator and reflects to the target association' do
60
+ @subscription = Subscription.create
61
+ @magazine.subscriptions = [@subscription]
62
+
63
+ @subscription.magazine.should == @magazine
64
+ end
65
+
66
+ it 'does not assign reflection association if the reflection association does not exist' do
67
+ @sponsor = Sponsor.create
68
+
69
+ @subscription = @sponsor.subscriptions.create
70
+ @subscription.should_not respond_to :sponsor
71
+ @subscription.should_not respond_to :sponsors
72
+ @subscription.should_not respond_to :sponsors_ids
73
+ @subscription.should_not respond_to :sponsor_ids
74
+ end
75
+
76
+ it 'deletes all items from the association' do
77
+ @magazine.subscriptions << Subscription.create
78
+ @magazine.subscriptions << Subscription.create
79
+ @magazine.subscriptions << Subscription.create
80
+
81
+ @magazine.subscriptions.size.should == 3
82
+
83
+ @magazine.subscriptions = nil
84
+ @magazine.subscriptions.size.should == 0
85
+ end
86
+
87
+ it 'uses where inside an association and returns a result' do
88
+ @included_subscription = @magazine.subscriptions.create(:length => 10)
89
+ @unincldued_subscription = @magazine.subscriptions.create(:length => 8)
90
+
91
+ @magazine.subscriptions.where(:length => 10).all.should == [@included_subscription]
92
+ end
93
+
94
+ it 'uses where inside an association and returns an empty set' do
95
+ @included_subscription = @magazine.subscriptions.create(:length => 10)
96
+ @unincldued_subscription = @magazine.subscriptions.create(:length => 8)
97
+
98
+ @magazine.subscriptions.where(:length => 6).all.should be_empty
99
+ end
100
+
101
+ it 'includes enumerable' do
102
+ @subscription1 = @magazine.subscriptions.create
103
+ @subscription2 = @magazine.subscriptions.create
104
+ @subscription3 = @magazine.subscriptions.create
105
+
106
+ @magazine.subscriptions.collect(&:id).should =~ [@subscription1.id, @subscription2.id, @subscription3.id]
107
+ end
108
+
109
+ it 'works for camel-cased associations' do
110
+ @magazine.camel_cases.create.class.should == CamelCase
111
+ end
112
+
113
+ it 'destroys associations' do
114
+ @subscription = Subscription.new
115
+ @magazine.subscriptions.expects(:target).returns([@subscription])
116
+ @subscription.expects(:destroy)
117
+
118
+ @magazine.subscriptions.destroy_all
119
+ end
120
+
121
+ it 'deletes associations' do
122
+ @subscription = Subscription.new
123
+ @magazine.subscriptions.expects(:target).returns([@subscription])
124
+ @subscription.expects(:delete)
125
+
126
+ @magazine.subscriptions.delete_all
127
+ end
128
+
129
+ # TODO This test is broken using the AWS SDK adapter.
130
+ #it 'returns the first and last record when they exist' do
131
+ # @subscription1 = @magazine.subscriptions.create
132
+ # @subscription2 = @magazine.subscriptions.create
133
+ # @subscription3 = @magazine.subscriptions.create
134
+ #
135
+ # @magazine.subscriptions.instance_eval { [first, last] }.should == [@subscription1, @subscription3]
136
+ #end
137
+
138
+ it 'replaces existing associations when using the setter' do
139
+ @subscription1 = @magazine.subscriptions.create
140
+ @subscription2 = @magazine.subscriptions.create
141
+ @subscription3 = Subscription.create
142
+
143
+ @subscription1.reload.magazine_ids.should_not be_nil
144
+ @subscription2.reload.magazine_ids.should_not be_nil
145
+
146
+ @magazine.subscriptions = @subscription3
147
+ @magazine.subscriptions_ids.should == Set[@subscription3.id]
148
+
149
+ @subscription1.reload.magazine_ids.should be_nil
150
+ @subscription2.reload.magazine_ids.should be_nil
151
+ @subscription3.reload.magazine_ids.should == Set[@magazine.id]
152
+ end
153
+
154
+ it 'destroys all objects and removes them from the association' do
155
+ @subscription1 = @magazine.subscriptions.create
156
+ @subscription2 = @magazine.subscriptions.create
157
+ @subscription3 = @magazine.subscriptions.create
158
+
159
+ @magazine.subscriptions.destroy_all
160
+
161
+ @magazine.subscriptions.should be_empty
162
+ Subscription.all.should be_empty
163
+ end
164
+
165
+ it 'deletes all objects and removes them from the association' do
166
+ @subscription1 = @magazine.subscriptions.create
167
+ @subscription2 = @magazine.subscriptions.create
168
+ @subscription3 = @magazine.subscriptions.create
169
+
170
+ @magazine.subscriptions.delete_all
171
+
172
+ @magazine.subscriptions.should be_empty
173
+ Subscription.all.should be_empty
174
+ end
175
+
176
+ it 'delegates class to the association object' do
177
+ @magazine.sponsor.class.should == nil.class
178
+ @magazine.sponsor.create
179
+ @magazine.sponsor.class.should == Sponsor
180
+
181
+ @magazine.subscriptions.class.should == Array
182
+ @magazine.subscriptions.create
183
+ @magazine.subscriptions.class.should == Array
184
+ end
185
+
186
+ it 'loads association one time only' do
187
+ @sponsor = @magazine.sponsor.create
188
+ @magazine.sponsor.expects(:find_target).once.returns(@sponsor)
189
+
190
+ @magazine.sponsor.id
191
+ @magazine.sponsor.id
192
+ end
193
+
194
+ end
@@ -0,0 +1,71 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
+
3
+ describe "Dynamoid::Associations::BelongsTo" do
4
+
5
+ context 'has many' do
6
+ before do
7
+ @subscription = Subscription.create
8
+ @camel_case = CamelCase.create
9
+ end
10
+
11
+ it 'determines nil if it has no associated record' do
12
+ @subscription.magazine.should be_nil
13
+ end
14
+
15
+ it 'determines target association correctly' do
16
+ @camel_case.magazine.send(:target_association).should == :camel_cases
17
+ end
18
+
19
+
20
+ it 'delegates equality to its source record' do
21
+ @magazine = @subscription.magazine.create
22
+
23
+ @subscription.magazine.should == @magazine
24
+ end
25
+
26
+ it 'associates has_many automatically' do
27
+ @magazine = @subscription.magazine.create
28
+
29
+ @magazine.subscriptions.should include @subscription
30
+
31
+ @magazine = Magazine.create
32
+ @user = @magazine.owner.create
33
+ @user.books.size.should == 1
34
+ @user.books.should include @magazine
35
+ end
36
+
37
+ it 'behaves like the object it is trying to be' do
38
+ @magazine = @subscription.magazine.create
39
+
40
+ @subscription.magazine.update_attribute(:title, 'Test Title')
41
+
42
+ Magazine.first.title.should == 'Test Title'
43
+ end
44
+ end
45
+
46
+ context 'has one' do
47
+ before do
48
+ @sponsor = Sponsor.create
49
+ @subscription = Subscription.create
50
+ end
51
+
52
+ it 'determins nil if it has no associated record' do
53
+ @sponsor.magazine.should be_nil
54
+ end
55
+
56
+ it 'delegates equality to its source record' do
57
+ @magazine = @sponsor.magazine.create
58
+
59
+ @sponsor.magazine.should == @magazine
60
+ end
61
+
62
+ it 'associates has_one automatically' do
63
+ @magazine = @sponsor.magazine.create
64
+
65
+ @magazine.sponsor.should == @sponsor
66
+
67
+ @user = @subscription.customer.create
68
+ @user.monthly.should == @subscription
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,47 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
+
3
+ describe "Dynamoid::Associations::HasAndBelongsToMany" do
4
+
5
+ before do
6
+ @subscription = Subscription.create
7
+ @camel_case = CamelCase.create
8
+ end
9
+
10
+ it 'determines equality from its records' do
11
+ @user = @subscription.users.create
12
+
13
+ @subscription.users.size.should == 1
14
+ @subscription.users.should include @user
15
+ end
16
+
17
+ it 'determines target association correctly' do
18
+ @subscription.users.send(:target_association).should == :subscriptions
19
+ @camel_case.subscriptions.send(:target_association).should == :camel_cases
20
+ end
21
+
22
+ it 'determines target attribute' do
23
+ @subscription.users.send(:target_attribute).should == :subscriptions_ids
24
+ end
25
+
26
+ it 'associates has_and_belongs_to_many automatically' do
27
+ @user = @subscription.users.create
28
+
29
+ @user.subscriptions.size.should == 1
30
+ @user.subscriptions.should include @subscription
31
+ @subscription.users.size.should == 1
32
+ @subscription.users.should include @user
33
+
34
+ @user = User.create
35
+ @follower = @user.followers.create
36
+ @follower.following.should include @user
37
+ @user.followers.should include @follower
38
+ end
39
+
40
+ it 'disassociates has_and_belongs_to_many automatically' do
41
+ @user = @subscription.users.create
42
+
43
+ @subscription.users.delete(@user)
44
+ @subscription.users.size.should == 0
45
+ @user.subscriptions.size.should == 0
46
+ end
47
+ end
@@ -0,0 +1,42 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
+
3
+ describe "Dynamoid::Associations::HasMany" do
4
+
5
+ before do
6
+ @magazine = Magazine.create
7
+ @user = User.create
8
+ @camel_case = CamelCase.create
9
+ end
10
+
11
+ it 'determines equality from its records' do
12
+ @subscription = @magazine.subscriptions.create
13
+
14
+ @magazine.subscriptions.should == @subscription
15
+ end
16
+
17
+ it 'determines target association correctly' do
18
+ @magazine.subscriptions.send(:target_association).should == :magazine
19
+ @user.books.send(:target_association).should == :owner
20
+ @camel_case.users.send(:target_association).should == :camel_case
21
+ end
22
+
23
+ it 'determins target class correctly' do
24
+ @magazine.subscriptions.send(:target_class).should == Subscription
25
+ @user.books.send(:target_class).should == Magazine
26
+ end
27
+
28
+ it 'determines target attribute' do
29
+ @magazine.subscriptions.send(:target_attribute).should == :magazine_ids
30
+ @user.books.send(:target_attribute).should == :owner_ids
31
+ end
32
+
33
+ it 'associates belongs_to automatically' do
34
+ @subscription = @magazine.subscriptions.create
35
+
36
+ @subscription.magazine.should == @magazine
37
+
38
+ @magazine = @user.books.create
39
+ @magazine.owner.should == @user
40
+ end
41
+
42
+ end
@@ -0,0 +1,45 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
+
3
+ describe "Dynamoid::Associations::HasOne" do
4
+
5
+ before do
6
+ @magazine = Magazine.create
7
+ @user = User.create
8
+ @camel_case = CamelCase.create
9
+ end
10
+
11
+ it 'determines nil if it has no associated record' do
12
+ @magazine.sponsor.should be_nil
13
+ end
14
+
15
+ it 'determines target association correctly' do
16
+ @camel_case.sponsor.send(:target_association).should == :camel_case
17
+ end
18
+
19
+ it 'returns only one object when associated' do
20
+ @magazine.sponsor.create
21
+
22
+ @magazine.sponsor.should_not be_a_kind_of Array
23
+ end
24
+
25
+ it 'delegates equality to its source record' do
26
+ @sponsor = @magazine.sponsor.create
27
+
28
+ @magazine.sponsor.should == @sponsor
29
+ end
30
+
31
+ it 'is equal from its target record' do
32
+ @sponsor = @magazine.sponsor.create
33
+
34
+ @magazine.sponsor.should == @sponsor
35
+ end
36
+
37
+ it 'associates belongs_to automatically' do
38
+ @sponsor = @magazine.sponsor.create
39
+ @sponsor.magazine.should == @magazine
40
+ @magazine.sponsor.should == @sponsor
41
+
42
+ @subscription = @user.monthly.create
43
+ @subscription.customer.should == @user
44
+ end
45
+ end
@@ -0,0 +1,16 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe "Dynamoid::Associations" do
4
+
5
+ before do
6
+ @magazine = Magazine.create
7
+ end
8
+
9
+ it 'defines a getter' do
10
+ @magazine.should respond_to :subscriptions
11
+ end
12
+
13
+ it 'defines a setter' do
14
+ @magazine.should respond_to :subscriptions=
15
+ end
16
+ end
@@ -0,0 +1,27 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe "Dynamoid::Config" do
4
+
5
+ before(:each) do
6
+ Dynamoid::Config.reset_namespace
7
+ end
8
+
9
+ after(:each) do
10
+ Dynamoid.config {|config| config.namespace = 'dynamoid_tests'}
11
+ end
12
+
13
+ it 'returns a namespace for non-Rails apps' do
14
+ Dynamoid::Config.namespace.should == 'dynamoid'
15
+ end
16
+
17
+ it 'returns a namespace for Rails apps' do
18
+ class Rails; end
19
+ Rails.stubs(:application => stubs(:class => stubs(:parent_name => 'TestApp')))
20
+ Rails.stubs(:env => 'development')
21
+ Dynamoid::Config.send(:option, :namespace, :default => defined?(Rails) ? "dynamoid_#{Rails.application.class.parent_name}_#{Rails.env}" : "dynamoid")
22
+
23
+ # TODO Make this return what we actually expect
24
+ Dynamoid::Config.namespace.should == "dynamoid_Mocha_development"
25
+ end
26
+
27
+ end