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.
- data/.document +5 -0
- data/.rspec +1 -0
- data/Dynamoid.gemspec +193 -0
- data/Gemfile +23 -0
- data/Gemfile.lock +86 -0
- data/LICENSE.txt +20 -0
- data/README.markdown +265 -0
- data/Rakefile +62 -0
- data/VERSION +1 -0
- data/doc/.nojekyll +0 -0
- data/doc/Dynamoid.html +312 -0
- data/doc/Dynamoid/Adapter.html +1385 -0
- data/doc/Dynamoid/Adapter/AwsSdk.html +1585 -0
- data/doc/Dynamoid/Adapter/Local.html +1574 -0
- data/doc/Dynamoid/Associations.html +131 -0
- data/doc/Dynamoid/Associations/Association.html +794 -0
- data/doc/Dynamoid/Associations/BelongsTo.html +158 -0
- data/doc/Dynamoid/Associations/ClassMethods.html +723 -0
- data/doc/Dynamoid/Associations/HasAndBelongsToMany.html +164 -0
- data/doc/Dynamoid/Associations/HasMany.html +164 -0
- data/doc/Dynamoid/Associations/HasOne.html +158 -0
- data/doc/Dynamoid/Associations/ManyAssociation.html +1640 -0
- data/doc/Dynamoid/Associations/SingleAssociation.html +598 -0
- data/doc/Dynamoid/Components.html +204 -0
- data/doc/Dynamoid/Config.html +395 -0
- data/doc/Dynamoid/Config/Options.html +609 -0
- data/doc/Dynamoid/Criteria.html +131 -0
- data/doc/Dynamoid/Criteria/Chain.html +1063 -0
- data/doc/Dynamoid/Criteria/ClassMethods.html +98 -0
- data/doc/Dynamoid/Document.html +666 -0
- data/doc/Dynamoid/Document/ClassMethods.html +937 -0
- data/doc/Dynamoid/Errors.html +118 -0
- data/doc/Dynamoid/Errors/DocumentNotValid.html +210 -0
- data/doc/Dynamoid/Errors/Error.html +130 -0
- data/doc/Dynamoid/Errors/InvalidField.html +133 -0
- data/doc/Dynamoid/Errors/MissingRangeKey.html +133 -0
- data/doc/Dynamoid/Fields.html +669 -0
- data/doc/Dynamoid/Fields/ClassMethods.html +309 -0
- data/doc/Dynamoid/Finders.html +128 -0
- data/doc/Dynamoid/Finders/ClassMethods.html +516 -0
- data/doc/Dynamoid/Indexes.html +308 -0
- data/doc/Dynamoid/Indexes/ClassMethods.html +353 -0
- data/doc/Dynamoid/Indexes/Index.html +1104 -0
- data/doc/Dynamoid/Persistence.html +651 -0
- data/doc/Dynamoid/Persistence/ClassMethods.html +670 -0
- data/doc/Dynamoid/Validations.html +399 -0
- data/doc/_index.html +461 -0
- data/doc/class_list.html +47 -0
- data/doc/css/common.css +1 -0
- data/doc/css/full_list.css +55 -0
- data/doc/css/style.css +322 -0
- data/doc/file.LICENSE.html +66 -0
- data/doc/file.README.html +312 -0
- data/doc/file_list.html +52 -0
- data/doc/frames.html +13 -0
- data/doc/index.html +312 -0
- data/doc/js/app.js +205 -0
- data/doc/js/full_list.js +173 -0
- data/doc/js/jquery.js +16 -0
- data/doc/method_list.html +1238 -0
- data/doc/top-level-namespace.html +105 -0
- data/lib/dynamoid.rb +47 -0
- data/lib/dynamoid/adapter.rb +177 -0
- data/lib/dynamoid/adapter/aws_sdk.rb +223 -0
- data/lib/dynamoid/associations.rb +106 -0
- data/lib/dynamoid/associations/association.rb +105 -0
- data/lib/dynamoid/associations/belongs_to.rb +44 -0
- data/lib/dynamoid/associations/has_and_belongs_to_many.rb +40 -0
- data/lib/dynamoid/associations/has_many.rb +39 -0
- data/lib/dynamoid/associations/has_one.rb +39 -0
- data/lib/dynamoid/associations/many_association.rb +191 -0
- data/lib/dynamoid/associations/single_association.rb +69 -0
- data/lib/dynamoid/components.rb +36 -0
- data/lib/dynamoid/config.rb +57 -0
- data/lib/dynamoid/config/options.rb +78 -0
- data/lib/dynamoid/criteria.rb +29 -0
- data/lib/dynamoid/criteria/chain.rb +243 -0
- data/lib/dynamoid/dirty.rb +41 -0
- data/lib/dynamoid/document.rb +184 -0
- data/lib/dynamoid/errors.rb +28 -0
- data/lib/dynamoid/fields.rb +130 -0
- data/lib/dynamoid/finders.rb +131 -0
- data/lib/dynamoid/identity_map.rb +96 -0
- data/lib/dynamoid/indexes.rb +69 -0
- data/lib/dynamoid/indexes/index.rb +103 -0
- data/lib/dynamoid/middleware/identity_map.rb +16 -0
- data/lib/dynamoid/persistence.rb +247 -0
- data/lib/dynamoid/validations.rb +36 -0
- data/spec/app/models/address.rb +10 -0
- data/spec/app/models/camel_case.rb +24 -0
- data/spec/app/models/magazine.rb +11 -0
- data/spec/app/models/message.rb +9 -0
- data/spec/app/models/sponsor.rb +8 -0
- data/spec/app/models/subscription.rb +12 -0
- data/spec/app/models/tweet.rb +12 -0
- data/spec/app/models/user.rb +26 -0
- data/spec/dynamoid/adapter/aws_sdk_spec.rb +186 -0
- data/spec/dynamoid/adapter_spec.rb +117 -0
- data/spec/dynamoid/associations/association_spec.rb +194 -0
- data/spec/dynamoid/associations/belongs_to_spec.rb +71 -0
- data/spec/dynamoid/associations/has_and_belongs_to_many_spec.rb +47 -0
- data/spec/dynamoid/associations/has_many_spec.rb +42 -0
- data/spec/dynamoid/associations/has_one_spec.rb +45 -0
- data/spec/dynamoid/associations_spec.rb +16 -0
- data/spec/dynamoid/config_spec.rb +27 -0
- data/spec/dynamoid/criteria/chain_spec.rb +140 -0
- data/spec/dynamoid/criteria_spec.rb +72 -0
- data/spec/dynamoid/dirty_spec.rb +49 -0
- data/spec/dynamoid/document_spec.rb +118 -0
- data/spec/dynamoid/fields_spec.rb +127 -0
- data/spec/dynamoid/finders_spec.rb +135 -0
- data/spec/dynamoid/identity_map_spec.rb +45 -0
- data/spec/dynamoid/indexes/index_spec.rb +104 -0
- data/spec/dynamoid/indexes_spec.rb +25 -0
- data/spec/dynamoid/persistence_spec.rb +176 -0
- data/spec/dynamoid/validations_spec.rb +36 -0
- data/spec/dynamoid_spec.rb +9 -0
- data/spec/spec_helper.rb +50 -0
- metadata +376 -0
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
module Dynamoid
|
|
3
|
+
|
|
4
|
+
# Provide ActiveModel validations to Dynamoid documents.
|
|
5
|
+
module Validations
|
|
6
|
+
extend ActiveSupport::Concern
|
|
7
|
+
|
|
8
|
+
include ActiveModel::Validations
|
|
9
|
+
include ActiveModel::Validations::Callbacks
|
|
10
|
+
|
|
11
|
+
# Override save to provide validation support.
|
|
12
|
+
#
|
|
13
|
+
# @since 0.2.0
|
|
14
|
+
def save(options = {})
|
|
15
|
+
options.reverse_merge!(:validate => true)
|
|
16
|
+
return false if options[:validate] and (not valid?)
|
|
17
|
+
super
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Is this object valid?
|
|
21
|
+
#
|
|
22
|
+
# @since 0.2.0
|
|
23
|
+
def valid?(context = nil)
|
|
24
|
+
context ||= (new_record? ? :create : :update)
|
|
25
|
+
super(context)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Raise an error unless this object is valid.
|
|
29
|
+
#
|
|
30
|
+
# @since 0.2.0
|
|
31
|
+
def save!
|
|
32
|
+
raise Dynamoid::Errors::DocumentNotValid.new(self) unless valid?
|
|
33
|
+
save(:validate => false)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
class CamelCase
|
|
2
|
+
include Dynamoid::Document
|
|
3
|
+
|
|
4
|
+
field :color
|
|
5
|
+
|
|
6
|
+
belongs_to :magazine
|
|
7
|
+
has_many :users
|
|
8
|
+
has_one :sponsor
|
|
9
|
+
has_and_belongs_to_many :subscriptions
|
|
10
|
+
|
|
11
|
+
before_create :doing_before_create
|
|
12
|
+
after_create :doing_after_create
|
|
13
|
+
|
|
14
|
+
private
|
|
15
|
+
|
|
16
|
+
def doing_before_create
|
|
17
|
+
true
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def doing_after_create
|
|
21
|
+
true
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
class User
|
|
2
|
+
include Dynamoid::Document
|
|
3
|
+
|
|
4
|
+
field :name
|
|
5
|
+
field :email
|
|
6
|
+
field :password
|
|
7
|
+
field :last_logged_in_at, :datetime
|
|
8
|
+
|
|
9
|
+
index :name
|
|
10
|
+
index :email
|
|
11
|
+
index [:name, :email]
|
|
12
|
+
index :name, :range_key => :created_at
|
|
13
|
+
index :name, :range_key => :last_logged_in_at
|
|
14
|
+
index :created_at, :range => true
|
|
15
|
+
|
|
16
|
+
has_and_belongs_to_many :subscriptions
|
|
17
|
+
|
|
18
|
+
has_many :books, :class_name => 'Magazine', :inverse_of => :owner
|
|
19
|
+
has_one :monthly, :class_name => 'Subscription', :inverse_of => :customer
|
|
20
|
+
|
|
21
|
+
has_and_belongs_to_many :followers, :class_name => 'User', :inverse_of => :following
|
|
22
|
+
has_and_belongs_to_many :following, :class_name => 'User', :inverse_of => :followers
|
|
23
|
+
|
|
24
|
+
belongs_to :camel_case
|
|
25
|
+
|
|
26
|
+
end
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
require 'dynamoid/adapter/aws_sdk'
|
|
2
|
+
require File.expand_path(File.dirname(__FILE__) + '../../../spec_helper')
|
|
3
|
+
|
|
4
|
+
describe Dynamoid::Adapter::AwsSdk do
|
|
5
|
+
|
|
6
|
+
if ENV['ACCESS_KEY'] && ENV['SECRET_KEY']
|
|
7
|
+
|
|
8
|
+
context 'without a preexisting table' do
|
|
9
|
+
# CreateTable and DeleteTable
|
|
10
|
+
it 'performs CreateTable and DeleteTable' do
|
|
11
|
+
table = Dynamoid::Adapter.create_table('CreateTable', :id, :range_key => { :created_at => :number })
|
|
12
|
+
|
|
13
|
+
Dynamoid::Adapter.connection.tables.collect{|t| t.name}.should include 'CreateTable'
|
|
14
|
+
|
|
15
|
+
Dynamoid::Adapter.delete_table('CreateTable')
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
context 'with a preexisting table' do
|
|
20
|
+
before(:all) do
|
|
21
|
+
Dynamoid::Adapter.create_table('dynamoid_tests_TestTable1', :id) unless Dynamoid::Adapter.list_tables.include?('dynamoid_tests_TestTable1')
|
|
22
|
+
Dynamoid::Adapter.create_table('dynamoid_tests_TestTable2', :id) unless Dynamoid::Adapter.list_tables.include?('dynamoid_tests_TestTable2')
|
|
23
|
+
Dynamoid::Adapter.create_table('dynamoid_tests_TestTable3', :id, :range_key => { :range => :number }) unless Dynamoid::Adapter.list_tables.include?('dynamoid_tests_TestTable3')
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# GetItem, PutItem and DeleteItem
|
|
27
|
+
it "performs GetItem for an item that does not exist" do
|
|
28
|
+
Dynamoid::Adapter.get_item('dynamoid_tests_TestTable1', '1').should be_nil
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it "performs GetItem for an item that does exist" do
|
|
32
|
+
Dynamoid::Adapter.put_item('dynamoid_tests_TestTable1', {:id => '1', :name => 'Josh'})
|
|
33
|
+
|
|
34
|
+
Dynamoid::Adapter.get_item('dynamoid_tests_TestTable1', '1').should == {:name => 'Josh', :id => '1'}
|
|
35
|
+
|
|
36
|
+
Dynamoid::Adapter.delete_item('dynamoid_tests_TestTable1', '1')
|
|
37
|
+
|
|
38
|
+
Dynamoid::Adapter.get_item('dynamoid_tests_TestTable1', '1').should be_nil
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
it 'performs GetItem for an item that does exist with a range key' do
|
|
42
|
+
Dynamoid::Adapter.put_item('dynamoid_tests_TestTable3', {:id => '1', :name => 'Josh', :range => 2.0})
|
|
43
|
+
|
|
44
|
+
Dynamoid::Adapter.get_item('dynamoid_tests_TestTable3', '1', :range_key => 2.0).should == {:name => 'Josh', :id => '1', :range => 2.0}
|
|
45
|
+
|
|
46
|
+
Dynamoid::Adapter.delete_item('dynamoid_tests_TestTable3', '1', :range_key => 2.0)
|
|
47
|
+
|
|
48
|
+
Dynamoid::Adapter.get_item('dynamoid_tests_TestTable3', '1', :range_key => 2.0).should be_nil
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
it 'performs DeleteItem for an item that does not exist' do
|
|
52
|
+
Dynamoid::Adapter.delete_item('dynamoid_tests_TestTable1', '1')
|
|
53
|
+
|
|
54
|
+
Dynamoid::Adapter.get_item('dynamoid_tests_TestTable1', '1').should be_nil
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
it 'performs PutItem for an item that does not exist' do
|
|
58
|
+
Dynamoid::Adapter.put_item('dynamoid_tests_TestTable1', {:id => '1', :name => 'Josh'})
|
|
59
|
+
|
|
60
|
+
Dynamoid::Adapter.get_item('dynamoid_tests_TestTable1', '1').should == {:id => '1', :name => 'Josh'}
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# BatchGetItem
|
|
64
|
+
it "performs BatchGetItem with singular keys" do
|
|
65
|
+
Dynamoid::Adapter.put_item('dynamoid_tests_TestTable1', {:id => '1', :name => 'Josh'})
|
|
66
|
+
Dynamoid::Adapter.put_item('dynamoid_tests_TestTable2', {:id => '1', :name => 'Justin'})
|
|
67
|
+
|
|
68
|
+
results = Dynamoid::Adapter.batch_get_item('dynamoid_tests_TestTable1' => '1', 'dynamoid_tests_TestTable2' => '1')
|
|
69
|
+
results.size.should == 2
|
|
70
|
+
results['dynamoid_tests_TestTable1'].should include({:name => 'Josh', :id => '1'})
|
|
71
|
+
results['dynamoid_tests_TestTable2'].should include({:name => 'Justin', :id => '1'})
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
it "performs BatchGetItem with multiple keys" do
|
|
75
|
+
Dynamoid::Adapter.put_item('dynamoid_tests_TestTable1', {:id => '1', :name => 'Josh'})
|
|
76
|
+
Dynamoid::Adapter.put_item('dynamoid_tests_TestTable1', {:id => '2', :name => 'Justin'})
|
|
77
|
+
|
|
78
|
+
results = Dynamoid::Adapter.batch_get_item('dynamoid_tests_TestTable1' => ['1', '2'])
|
|
79
|
+
results.size.should == 1
|
|
80
|
+
results['dynamoid_tests_TestTable1'].should include({:name => 'Josh', :id => '1'})
|
|
81
|
+
results['dynamoid_tests_TestTable1'].should include({:name => 'Justin', :id => '2'})
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
it 'performs BatchGetItem with one ranged key' do
|
|
85
|
+
Dynamoid::Adapter.put_item('dynamoid_tests_TestTable3', {:id => '1', :name => 'Josh', :range => 1.0})
|
|
86
|
+
Dynamoid::Adapter.put_item('dynamoid_tests_TestTable3', {:id => '2', :name => 'Justin', :range => 2.0})
|
|
87
|
+
|
|
88
|
+
results = Dynamoid::Adapter.batch_get_item('dynamoid_tests_TestTable3' => [['1', 1.0]])
|
|
89
|
+
results.size.should == 1
|
|
90
|
+
results['dynamoid_tests_TestTable3'].should include({:name => 'Josh', :id => '1', :range => 1.0})
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
it 'performs BatchGetItem with multiple ranged keys' do
|
|
94
|
+
Dynamoid::Adapter.put_item('dynamoid_tests_TestTable3', {:id => '1', :name => 'Josh', :range => 1.0})
|
|
95
|
+
Dynamoid::Adapter.put_item('dynamoid_tests_TestTable3', {:id => '2', :name => 'Justin', :range => 2.0})
|
|
96
|
+
|
|
97
|
+
results = Dynamoid::Adapter.batch_get_item('dynamoid_tests_TestTable3' => [['1', 1.0],['2', 2.0]])
|
|
98
|
+
results.size.should == 1
|
|
99
|
+
results['dynamoid_tests_TestTable3'].should include({:name => 'Josh', :id => '1', :range => 1.0})
|
|
100
|
+
results['dynamoid_tests_TestTable3'].should include({:name => 'Justin', :id => '2', :range => 2.0})
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# ListTables
|
|
104
|
+
it 'performs ListTables' do
|
|
105
|
+
Dynamoid::Adapter.list_tables.should include 'dynamoid_tests_TestTable1'
|
|
106
|
+
Dynamoid::Adapter.list_tables.should include 'dynamoid_tests_TestTable2'
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
# Query
|
|
110
|
+
it 'performs query on a table and returns items' do
|
|
111
|
+
Dynamoid::Adapter.put_item('dynamoid_tests_TestTable1', {:id => '1', :name => 'Josh'})
|
|
112
|
+
|
|
113
|
+
Dynamoid::Adapter.query('dynamoid_tests_TestTable1', :hash_value => '1').should == { :id=> '1', :name=>"Josh" }
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
it 'performs query on a table and returns items if there are multiple items' do
|
|
117
|
+
Dynamoid::Adapter.put_item('dynamoid_tests_TestTable1', {:id => '1', :name => 'Josh'})
|
|
118
|
+
Dynamoid::Adapter.put_item('dynamoid_tests_TestTable1', {:id => '2', :name => 'Justin'})
|
|
119
|
+
|
|
120
|
+
Dynamoid::Adapter.query('dynamoid_tests_TestTable1', :hash_value => '1').should == { :id=> '1', :name=>"Josh" }
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
context 'range queries' do
|
|
124
|
+
before do
|
|
125
|
+
Dynamoid::Adapter.put_item('dynamoid_tests_TestTable3', {:id => '1', :range => 1.0})
|
|
126
|
+
Dynamoid::Adapter.put_item('dynamoid_tests_TestTable3', {:id => '1', :range => 3.0})
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
it 'performs query on a table with a range and selects items in a range' do
|
|
130
|
+
Dynamoid::Adapter.query('dynamoid_tests_TestTable3', :hash_value => '1', :range_value => 0.0..3.0).should =~ [{:id => '1', :range => BigDecimal.new(1)}, {:id => '1', :range => BigDecimal.new(3)}]
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
it 'performs query on a table with a range and selects items greater than' do
|
|
134
|
+
Dynamoid::Adapter.query('dynamoid_tests_TestTable3', :hash_value => '1', :range_greater_than => 1.0).should =~ [{:id => '1', :range => BigDecimal.new(3)}]
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
it 'performs query on a table with a range and selects items less than' do
|
|
138
|
+
Dynamoid::Adapter.query('dynamoid_tests_TestTable3', :hash_value => '1', :range_less_than => 2.0).should =~ [{:id => '1', :range => BigDecimal.new(1)}]
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
it 'performs query on a table with a range and selects items gte' do
|
|
142
|
+
Dynamoid::Adapter.query('dynamoid_tests_TestTable3', :hash_value => '1', :range_gte => 1.0).should =~ [{:id => '1', :range => BigDecimal.new(1)}, {:id => '1', :range => BigDecimal.new(3)}]
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
it 'performs query on a table with a range and selects items lte' do
|
|
146
|
+
Dynamoid::Adapter.query('dynamoid_tests_TestTable3', :hash_value => '1', :range_lte => 3.0).should =~ [{:id => '1', :range => BigDecimal.new(1)}, {:id => '1', :range => BigDecimal.new(3)}]
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
# Scan
|
|
151
|
+
it 'performs scan on a table and returns items' do
|
|
152
|
+
Dynamoid::Adapter.put_item('dynamoid_tests_TestTable1', {:id => '1', :name => 'Josh'})
|
|
153
|
+
|
|
154
|
+
Dynamoid::Adapter.scan('dynamoid_tests_TestTable1', :name => 'Josh').should == [{ :id=> '1', :name=>"Josh" }]
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
it 'performs scan on a table and returns items if there are multiple items but only one match' do
|
|
158
|
+
Dynamoid::Adapter.put_item('dynamoid_tests_TestTable1', {:id => '1', :name => 'Josh'})
|
|
159
|
+
Dynamoid::Adapter.put_item('dynamoid_tests_TestTable1', {:id => '2', :name => 'Justin'})
|
|
160
|
+
|
|
161
|
+
Dynamoid::Adapter.scan('dynamoid_tests_TestTable1', :name => 'Josh').should == [{ :id=> '1', :name=>"Josh" }]
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
it 'performs scan on a table and returns multiple items if there are multiple matches' do
|
|
165
|
+
Dynamoid::Adapter.put_item('dynamoid_tests_TestTable1', {:id => '1', :name => 'Josh'})
|
|
166
|
+
Dynamoid::Adapter.put_item('dynamoid_tests_TestTable1', {:id => '2', :name => 'Josh'})
|
|
167
|
+
|
|
168
|
+
Dynamoid::Adapter.scan('dynamoid_tests_TestTable1', :name => 'Josh').should include({:name=>"Josh", :id=>"2"}, {:name=>"Josh", :id=>"1"})
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
it 'performs scan on a table and returns all items if no criteria are specified' do
|
|
172
|
+
Dynamoid::Adapter.put_item('dynamoid_tests_TestTable1', {:id => '1', :name => 'Josh'})
|
|
173
|
+
Dynamoid::Adapter.put_item('dynamoid_tests_TestTable1', {:id => '2', :name => 'Josh'})
|
|
174
|
+
|
|
175
|
+
Dynamoid::Adapter.scan('dynamoid_tests_TestTable1', {}).should include({:name=>"Josh", :id=>"2"}, {:name=>"Josh", :id=>"1"})
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
# DescribeTable
|
|
180
|
+
|
|
181
|
+
# UpdateItem
|
|
182
|
+
|
|
183
|
+
# UpdateTable
|
|
184
|
+
|
|
185
|
+
end
|
|
186
|
+
end
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
|
2
|
+
|
|
3
|
+
describe "Dynamoid::Adapter" do
|
|
4
|
+
|
|
5
|
+
before(:all) do
|
|
6
|
+
Dynamoid::Adapter.create_table('dynamoid_tests_TestTable', :id) unless Dynamoid::Adapter.list_tables.include?('dynamoid_tests_TestTable')
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
it 'extends itself automatically' do
|
|
10
|
+
lambda {Dynamoid::Adapter.list_tables}.should_not raise_error
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
it 'raises nomethod if we try a method that is not on the child' do
|
|
14
|
+
lambda {Dynamoid::Adapter.foobar}.should raise_error
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
context 'without partioning' do
|
|
18
|
+
before(:all) do
|
|
19
|
+
@previous_value = Dynamoid::Config.partitioning
|
|
20
|
+
Dynamoid::Config.partitioning = false
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
after(:all) do
|
|
24
|
+
Dynamoid::Config.partitioning = @previous_value
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it 'writes through the adapter' do
|
|
28
|
+
Dynamoid::Adapter.expects(:put_item).with('dynamoid_tests_TestTable', {:id => '123'}).returns(true)
|
|
29
|
+
|
|
30
|
+
Dynamoid::Adapter.write('dynamoid_tests_TestTable', {:id => '123'})
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
it 'reads through the adapter for one ID' do
|
|
34
|
+
Dynamoid::Adapter.expects(:get_item).with('dynamoid_tests_TestTable', '123', {}).returns(true)
|
|
35
|
+
|
|
36
|
+
Dynamoid::Adapter.read('dynamoid_tests_TestTable', '123')
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it 'reads through the adapter for many IDs' do
|
|
40
|
+
Dynamoid::Adapter.expects(:batch_get_item).with({'dynamoid_tests_TestTable' => ['1', '2']}).returns(true)
|
|
41
|
+
|
|
42
|
+
Dynamoid::Adapter.read('dynamoid_tests_TestTable', ['1', '2'])
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
it 'reads through the adapter for one ID and a range key' do
|
|
46
|
+
Dynamoid::Adapter.expects(:get_item).with('dynamoid_tests_TestTable', '123', :range_key => 2.0).returns(true)
|
|
47
|
+
|
|
48
|
+
Dynamoid::Adapter.read('dynamoid_tests_TestTable', '123', :range_key => 2.0)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
it 'reads through the adapter for many IDs and a range key' do
|
|
52
|
+
Dynamoid::Adapter.expects(:batch_get_item).with({'dynamoid_tests_TestTable' => [['1', 2.0], ['2', 2.0]]}).returns(true)
|
|
53
|
+
|
|
54
|
+
Dynamoid::Adapter.read('dynamoid_tests_TestTable', ['1', '2'], :range_key => 2.0)
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
context 'with partitioning' do
|
|
59
|
+
before(:all) do
|
|
60
|
+
@previous_value = Dynamoid::Config.partitioning
|
|
61
|
+
Dynamoid::Config.partitioning = true
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
after(:all) do
|
|
65
|
+
Dynamoid::Config.partitioning = @previous_value
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
it 'writes through the adapter' do
|
|
69
|
+
Random.expects(:rand).with(Dynamoid::Config.partition_size).once.returns(0)
|
|
70
|
+
Dynamoid::Adapter.write('dynamoid_tests_TestTable', {:id => 'testid'})
|
|
71
|
+
|
|
72
|
+
Dynamoid::Adapter.get_item('dynamoid_tests_TestTable', 'testid.0')[:id].should == 'testid.0'
|
|
73
|
+
Dynamoid::Adapter.get_item('dynamoid_tests_TestTable', 'testid.0')[:updated_at].should_not be_nil
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
it 'reads through the adapter for one ID' do
|
|
77
|
+
Dynamoid::Adapter.expects(:batch_get_item).with('dynamoid_tests_TestTable' => (0...Dynamoid::Config.partition_size).collect{|n| "123.#{n}"}).returns({})
|
|
78
|
+
|
|
79
|
+
Dynamoid::Adapter.read('dynamoid_tests_TestTable', '123')
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
it 'reads through the adapter for many IDs' do
|
|
83
|
+
Dynamoid::Adapter.expects(:batch_get_item).with('dynamoid_tests_TestTable' => (0...Dynamoid::Config.partition_size).collect{|n| "1.#{n}"} + (0...Dynamoid::Config.partition_size).collect{|n| "2.#{n}"}).returns({})
|
|
84
|
+
|
|
85
|
+
Dynamoid::Adapter.read('dynamoid_tests_TestTable', ['1', '2'])
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
it 'reads through the adapter for one ID and a range key' do
|
|
89
|
+
Dynamoid::Adapter.expects(:batch_get_item).with('dynamoid_tests_TestTable' => (0...Dynamoid::Config.partition_size).collect{|n| ["123.#{n}", 2.0]}).returns({})
|
|
90
|
+
|
|
91
|
+
Dynamoid::Adapter.read('dynamoid_tests_TestTable', '123', :range_key => 2.0)
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
it 'reads through the adapter for many IDs and a range key' do
|
|
95
|
+
Dynamoid::Adapter.expects(:batch_get_item).with('dynamoid_tests_TestTable' => (0...Dynamoid::Config.partition_size).collect{|n| ["1.#{n}", 2.0]} + (0...Dynamoid::Config.partition_size).collect{|n| ["2.#{n}", 2.0]}).returns({})
|
|
96
|
+
|
|
97
|
+
Dynamoid::Adapter.read('dynamoid_tests_TestTable', ['1', '2'], :range_key => 2.0)
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
it 'returns an ID with all partitions' do
|
|
101
|
+
Dynamoid::Adapter.id_with_partitions('1').should =~ (0...Dynamoid::Config.partition_size).collect{|n| "1.#{n}"}
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
it 'returns an ID and range key with all partitions' do
|
|
105
|
+
Dynamoid::Adapter.id_with_partitions([['1', 1.0]]).should =~ (0...Dynamoid::Config.partition_size).collect{|n| ["1.#{n}", 1.0]}
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
it 'returns a result for one partitioned element' do
|
|
109
|
+
@time = DateTime.now
|
|
110
|
+
@array =[{:id => '1.0', :updated_at => @time - 6.hours}, {:id => '1.1', :updated_at => @time - 3.hours}, {:id => '1.2', :updated_at => @time - 1.hour}, {:id => '1.3', :updated_at => @time - 6.hours}, {:id => '2.0', :updated_at => @time}]
|
|
111
|
+
|
|
112
|
+
Dynamoid::Adapter.result_for_partition(@array).should =~ [{:id => '1', :updated_at => @time - 1.hour}, {:id => '2', :updated_at => @time}]
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
end
|