rdy 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -1,5 +1,5 @@
1
1
  source "http://rubygems.org"
2
- gem "aws-sdk", ">= 1.3.2"
2
+ gem "aws-sdk", ">= 1.3.5"
3
3
  group :development do
4
4
  gem "shoulda", ">= 0"
5
5
  gem "bundler", "~> 1.0.0"
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  GEM
2
2
  remote: http://rubygems.org/
3
3
  specs:
4
- aws-sdk (1.3.4)
4
+ aws-sdk (1.3.5)
5
5
  httparty (~> 0.7)
6
6
  json (~> 1.4)
7
7
  nokogiri (>= 1.4.4)
@@ -15,19 +15,23 @@ GEM
15
15
  git (>= 1.2.5)
16
16
  rake
17
17
  json (1.6.5)
18
- multi_json (1.0.4)
18
+ multi_json (1.1.0)
19
19
  multi_xml (0.4.1)
20
20
  nokogiri (1.5.0)
21
21
  rake (0.9.2.2)
22
22
  rcov (1.0.0)
23
- shoulda (2.11.3)
23
+ shoulda (3.0.1)
24
+ shoulda-context (~> 1.0.0)
25
+ shoulda-matchers (~> 1.0.0)
26
+ shoulda-context (1.0.0)
27
+ shoulda-matchers (1.0.0)
24
28
  uuidtools (2.1.2)
25
29
 
26
30
  PLATFORMS
27
31
  ruby
28
32
 
29
33
  DEPENDENCIES
30
- aws-sdk (>= 1.3.2)
34
+ aws-sdk (>= 1.3.5)
31
35
  bundler (~> 1.0.0)
32
36
  jeweler (~> 1.6.4)
33
37
  rcov
data/README.md CHANGED
@@ -2,10 +2,12 @@
2
2
 
3
3
  Fun little ruby client for Amazon DynamoDB.
4
4
 
5
+ # hash-key based tables
5
6
  rdy = Rdy.new("your_table", [:your_hash_key, :string])
6
7
  rdy.any_attribute = "nice!"
7
8
  rdy.foo = "bar"
8
- rdy.save("1") # hash key value
9
+ rdy.save("1") # set your hash key value
10
+ # rdy.save # if ommitted the hash key value is generated
9
11
 
10
12
  rdy.foo = "bar2"
11
13
  rdy.save # update
@@ -13,7 +15,9 @@ Fun little ruby client for Amazon DynamoDB.
13
15
  rdy.any_attribute = nil
14
16
  rdy.save # delete an attribute
15
17
 
16
- rdy.find("1") # find by hash key value
18
+ rdy.find("1") # find by hash key value / sets values to current instance
19
+ rdy_instance = Rdy.find([:id, :string, 'mykey1']) # returns new Rdy instance
20
+
17
21
  rdy.destroy # delete item
18
22
 
19
23
  rdy.all
@@ -21,20 +25,41 @@ Fun little ruby client for Amazon DynamoDB.
21
25
 
22
26
  rdy.scan(:any_attribute => 'nice!')
23
27
  limit = 10
24
- rdy.scan(:any_attribute => 'nice!', 10)
28
+ rdy.scan(:any_attribute => 'nice!', limit)
29
+
30
+ # hash & range-key based tables
31
+ rdy2 = Rdy.new("your_table", [:your_hash_key, :string], [:your_range_key, :number])
32
+ rdy2.your_range_key = 1
33
+ rdy2.save('mykey1') # or just rdy2.save
34
+
35
+ rdy2.find('mykey1', 1) # sets item values to current instance
36
+ rdy_instance = Rdy.find([:your_hash_key, :string, 'mykey1'], [:your_range_key, :number, 1]) # returns new Rdy instance
37
+
38
+ rdy2.query(:hash_value => 'mykey1', :range_value => 1)
39
+ rdy2.query_by_range_value(1)
25
40
 
26
41
  read_capacity_units = 10
27
42
  write_capacity_units = 5
28
43
  Rdy.create_table("rdy", read_capacity_units, write_capacity_units, :id => :string) # hash key only
29
44
  Rdy.create_table("rdy2", read_capacity_units, write_capacity_units, {:id => :string}, {:comment_id => :number}) # hash and range key
30
-
31
- Advanced features like queries, scans etc. are not supported yet.
45
+
46
+ # You can also create your own class
47
+ class User < RdyItem
48
+ def initialize([:id, :string], [:your_range_key, :number]) # this will save data to the 'users' table
49
+ end
50
+ end
32
51
 
33
52
  ## Installation
34
53
 
35
54
  gem install rdy
36
55
 
37
- Then create a .rdy.yml file with your AWS credentials in your home directory. Checkout the sample file for help. Also make sure you activate DynamoDB in your AWS account.
56
+ Create a .rdy.yml file with your AWS credentials in your home directory. Checkout the sample file for help. Also make sure you activate DynamoDB in your AWS account.
57
+
58
+ ## Tests
59
+
60
+ rake test
61
+
62
+ On the initial run the tables are created. This may take a while, so it's possible the first run of the tests is going to fail. You can also create the tables manually if you want to avoid this. Check out the helper.rb class.
38
63
 
39
64
  ## Contributing to rdy
40
65
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.0
1
+ 0.2.1
data/lib/rdy.rb CHANGED
@@ -1,13 +1,14 @@
1
1
  require "rubygems"
2
2
  gem "aws-sdk"
3
3
  require "aws-sdk"
4
+ require 'digest'
4
5
 
5
6
  class Rdy
6
7
  attr_accessor :hash_key_conditional_check, :check_table_status
7
8
  @@_tables = {}
8
9
 
9
10
  def initialize(table, hash_key, range_key = nil)
10
- @attributes = {}; @table = table; @hash_key = hash_key[0].to_s
11
+ @attributes = {}; @table = table.to_s; @hash_key = hash_key[0].to_s
11
12
  @range_key = range_key[0].to_s if range_key
12
13
  @is_new = true
13
14
  self.hash_key_conditional_check = false
@@ -28,13 +29,16 @@ class Rdy
28
29
  end
29
30
  end
30
31
  end
31
- def table=(value); @table = value; end
32
+ def table=(value); @table = value.to_s; end
32
33
  def table; @table; end
34
+ def table_exists?; @_table.exists?; end
33
35
  def attributes; @attributes; end
34
36
  def hash_value; @hash_value; end
35
37
  def hash_key; @hash_key; end
36
38
  def range_key; @range_key; end
37
-
39
+ def range_value; @range_value; end
40
+ def self.generate_key; Digest::SHA1.hexdigest((0...50).map{ ('a'..'z').to_a[rand(26)] }.join); end
41
+
38
42
  def self.dynamo_db
39
43
  config = YAML.load(File.read("#{ENV['HOME']}/.rdy.yml"))
40
44
  raise "Config file expected in ~/.rdy.yml" unless config
@@ -46,18 +50,32 @@ class Rdy
46
50
  :hash_key => hash_key, :range_key => range_key)
47
51
  end
48
52
 
53
+ def build(attrs)
54
+ if attrs
55
+ @attributes.clear
56
+ attrs.each {|k, v| self.send("#{k.to_s}=".to_sym, v) unless k == @hash_key }
57
+ return self
58
+ end
59
+ end
60
+
49
61
  def all; @_table.items.collect {|i| i.attributes.to_h }; end
62
+ def self.find(table, hash_key_value, range_key_value = nil)
63
+ rdy = Rdy.new(table, hash_key_value[0..1], range_key_value ? range_key_value[0..1] : nil)
64
+ rdy.find(hash_key_value[2], range_key_value ? range_key_value[2] : nil)
65
+ rdy
66
+ end
50
67
  def find(hash_value, range_value = nil)
51
68
  raise "missing hash value" if hash_value.nil?
52
69
  if @range_key and range_value
53
- @_item = @_table.items.at(@hash_value, range_value)
70
+ @_item = @_table.items.at(hash_value, range_value)
54
71
  else
55
72
  @_item = @_table.items[hash_value]
56
73
  end
57
74
  @attributes.clear
58
75
  if @_item and @_item.attributes and @_item.attributes.any?
59
- @_item.attributes.to_h.each {|k, v| self.send("#{k}=".to_sym, v) unless k == @hash_key }
76
+ self.build(@_item.attributes.to_h)
60
77
  @hash_value = hash_value; @is_new = false
78
+ @range_value = range_value if range_value
61
79
  else
62
80
  @hash_value = nil
63
81
  end
@@ -67,7 +85,7 @@ class Rdy
67
85
 
68
86
  def is_new?; @is_new; end
69
87
  def save(hash_value = nil)
70
- raise "missing hash value" if hash_value.nil? and is_new?
88
+ hash_value = Rdy.generate_key if hash_value.nil? and is_new?
71
89
  if is_new?
72
90
  if @range_key
73
91
  values = { @hash_key.to_sym => hash_value, @range_key.to_sym => @attributes[@range_key] }
@@ -75,7 +93,7 @@ class Rdy
75
93
  values = { @hash_key.to_sym => hash_value }
76
94
  end
77
95
  options = {}
78
- options[:unless_exists] = @hash_key if hash_key_conditional_check
96
+ options[:unless_exists] = @hash_key if hash_key_conditional_check
79
97
  @_item = @_table.items.create(values, options)
80
98
  end
81
99
  if @_item
@@ -100,6 +118,17 @@ class Rdy
100
118
  values
101
119
  end
102
120
 
121
+ def query(options = {})
122
+ if options and options.any?
123
+ values = []
124
+ @_table.items.query(options).each do |item|
125
+ values << item.attributes.to_h
126
+ end
127
+ values
128
+ end
129
+ end
130
+ def query_by_range_value(value); query(:hash_value => self.hash_value.to_s, :range_value => value); end
131
+
103
132
  def destroy
104
133
  unless is_new?
105
134
  @_item.delete
@@ -116,3 +145,14 @@ class Rdy
116
145
  end
117
146
  end
118
147
  end
148
+
149
+ class RdyItem < Rdy
150
+ def initialize(hash_key, range_key = nil, table = nil)
151
+ super(table ? table.to_s : "#{self.class.name.downcase}s", hash_key, range_key)
152
+ end
153
+
154
+ def self.create_table(read_capacity_units, write_capacity_units, hash_key, range_key = nil)
155
+ dynamo_db.tables.create(self.table, read_capacity_units, write_capacity_units,
156
+ :hash_key => hash_key, :range_key => range_key)
157
+ end
158
+ end
data/test/helper.rb CHANGED
@@ -16,10 +16,24 @@ require 'rdy'
16
16
 
17
17
  RDY_SIMPLE_TABLE = 'rdy_test_simple'
18
18
  RDY_RANGE_TABLE = 'rdy_test_range'
19
+ creating = false
19
20
 
20
- puts "Setting up test tables for Rdy..."
21
- Rdy.create_table(RDY_SIMPLE_TABLE, 10, 5, :id => :string) rescue nil
22
- Rdy.create_table(RDY_RANGE_TABLE, 10, 5, {:id => :string}, {:foo => :string}) rescue nil
21
+ unless Rdy.new(RDY_SIMPLE_TABLE, [:id, :string]).table_exists?
22
+ puts "Setting up test tables for Rdy: #{RDY_SIMPLE_TABLE}"
23
+ Rdy.create_table(RDY_SIMPLE_TABLE, 10, 5, :id => :string)
24
+ creating = true
25
+ end
26
+
27
+ unless Rdy.new(RDY_RANGE_TABLE, [:id, :string], [:foo, :string]).table_exists?
28
+ puts "Setting up test tables for Rdy: #{RDY_RANGE_TABLE}"
29
+ Rdy.create_table(RDY_RANGE_TABLE, 10, 5, {:id => :string}, {:foo => :string})
30
+ creating = true
31
+ end
32
+
33
+ if creating
34
+ puts "Waiting for tables to become active..."
35
+ sleep 60
36
+ end
23
37
 
24
38
  class Test::Unit::TestCase
25
39
  end
data/test/test_rdy.rb CHANGED
@@ -44,8 +44,18 @@ class TestRdy < Test::Unit::TestCase
44
44
  assert_equal @rdy.attributes.size, 1
45
45
  assert_equal @rdy.attributes['foo'], 'bar'
46
46
  end
47
+
48
+ should "build an Rdy instance from an attributes hash" do
49
+ rdy
50
+ attributes = { 'test' => 'testval', 'foo' => 'bar', :number => 1}
51
+ rdy_instance = Rdy.new(RDY_SIMPLE_TABLE, [:id, :string]).build(attributes)
52
+ assert_not_nil rdy_instance
53
+ assert_equal rdy_instance.test, 'testval'
54
+ assert_equal rdy_instance.foo, 'bar'
55
+ assert_equal rdy_instance.number, 1
56
+ end
47
57
  end
48
-
58
+
49
59
  context "Creating" do
50
60
  setup do
51
61
  rdy
@@ -59,8 +69,28 @@ class TestRdy < Test::Unit::TestCase
59
69
  assert_equal @rdy.foo, "bar"
60
70
  assert_equal @rdy.table, RDY_SIMPLE_TABLE
61
71
  assert_nil @rdy.hash_value
62
- attributes = @rdy.save('1')
63
- assert_equal @rdy.hash_value, '1'
72
+ hash_value = Rdy.generate_key
73
+ attributes = @rdy.save(hash_value)
74
+ assert_equal @rdy.hash_value, hash_value
75
+ assert_equal attributes.size, 4
76
+ assert attributes.keys.include?('id')
77
+ assert attributes.keys.include?('foo')
78
+ assert attributes.keys.include?('count')
79
+ assert attributes.keys.include?('tags')
80
+ assert !@rdy.is_new?
81
+ @rdy.destroy
82
+ end
83
+
84
+ should "save an item with a generated hash key value" do
85
+ assert @rdy.is_new?
86
+ @rdy.foo = "bar"
87
+ @rdy.count = 1
88
+ @rdy.tags = ['a', 'b', 'c']
89
+ assert_equal @rdy.foo, "bar"
90
+ assert_equal @rdy.table, RDY_SIMPLE_TABLE
91
+ assert_nil @rdy.hash_value
92
+ attributes = @rdy.save
93
+ assert_not_nil @rdy.hash_value
64
94
  assert_equal attributes.size, 4
65
95
  assert attributes.keys.include?('id')
66
96
  assert attributes.keys.include?('foo')
@@ -70,7 +100,7 @@ class TestRdy < Test::Unit::TestCase
70
100
  @rdy.destroy
71
101
  end
72
102
  end
73
-
103
+
74
104
  context "Updating" do
75
105
  setup do
76
106
  rdy
@@ -78,15 +108,16 @@ class TestRdy < Test::Unit::TestCase
78
108
 
79
109
  should "update an item" do
80
110
  @rdy.foo = "bar"
81
- attributes = @rdy.save("2")
111
+ hash_value = Rdy.generate_key
112
+ attributes = @rdy.save(hash_value)
82
113
  assert !@rdy.is_new?
83
- assert_equal @rdy.hash_value, "2"
114
+ assert_equal @rdy.hash_value, hash_value
84
115
  assert_equal @rdy.foo, "bar"
85
116
  assert_equal attributes['foo'], "bar"
86
117
  @rdy.foo = "bar2"
87
118
  attributes = @rdy.save
88
119
  assert !@rdy.is_new?
89
- assert_equal @rdy.hash_value, "2"
120
+ assert_equal @rdy.hash_value, hash_value
90
121
  assert_equal @rdy.foo, "bar2"
91
122
  assert_equal attributes['foo'], "bar2"
92
123
  @rdy.destroy
@@ -100,12 +131,13 @@ class TestRdy < Test::Unit::TestCase
100
131
 
101
132
  should "destroy an item" do
102
133
  @rdy.foo = "bar"
103
- attributes = @rdy.save("3")
104
- @rdy.find("3")
134
+ hash_value = Rdy.generate_key
135
+ attributes = @rdy.save(hash_value)
136
+ @rdy.find(hash_value)
105
137
  assert_not_nil @rdy.foo
106
138
  assert_equal @rdy.foo, "bar"
107
139
  @rdy.destroy
108
- @rdy.find("3")
140
+ @rdy.find(hash_value)
109
141
  assert_nil @rdy.hash_value
110
142
  end
111
143
  end
@@ -116,15 +148,17 @@ class TestRdy < Test::Unit::TestCase
116
148
  end
117
149
 
118
150
  should "scan table by attribute values" do
151
+ hash_value1 = Rdy.generate_key
119
152
  @rdy2 = Rdy.new(RDY_RANGE_TABLE, [:id, :string], [:foo, :string])
120
153
  @rdy2.foo = "bar1"
121
154
  @rdy2.data = "test"
122
- @rdy2.save("4")
155
+ @rdy2.save(hash_value1)
123
156
 
157
+ hash_value2 = Rdy.generate_key
124
158
  @rdy3 = Rdy.new(RDY_RANGE_TABLE, [:id, :string], [:foo, :string])
125
159
  @rdy3.foo = "bar2"
126
160
  @rdy3.data = "test"
127
- @rdy3.save("5")
161
+ @rdy3.save(hash_value2)
128
162
 
129
163
  attrs = @rdy2.scan(:data => 'test')
130
164
  assert_not_nil attrs
@@ -145,10 +179,10 @@ class TestRdy < Test::Unit::TestCase
145
179
  assert_not_nil attrs
146
180
  assert_equal attrs.size, 1
147
181
 
148
- @rdy2.find("4", "bar1")
182
+ @rdy2.find(hash_value1, "bar1")
149
183
  @rdy2.destroy
150
184
 
151
- @rdy3.find("5", "bar2")
185
+ @rdy3.find(hash_value2, "bar2")
152
186
  @rdy3.destroy
153
187
  end
154
188
  end
@@ -159,27 +193,112 @@ class TestRdy < Test::Unit::TestCase
159
193
  end
160
194
 
161
195
  should "find an item by hash-key" do
196
+ hash_value = Rdy.generate_key
162
197
  @rdy.foo = "bar"
163
- attributes = @rdy.save("6")
164
- @rdy.find("6")
198
+ attributes = @rdy.save(hash_value)
199
+ @rdy.find(hash_value)
165
200
  assert_not_nil @rdy.foo
166
201
  assert_equal @rdy.foo, "bar"
167
202
  @rdy.destroy
168
203
  end
204
+
205
+ should "use the find class method" do
206
+ hash_value = Rdy.generate_key
207
+ @rdy.foo = "bar"
208
+ attributes = @rdy.save(hash_value)
209
+ rdy_result = Rdy.find(RDY_SIMPLE_TABLE, [:id, :string, hash_value])
210
+ assert_not_nil rdy_result
211
+ assert rdy_result.is_a?(Rdy)
212
+ assert_not_nil rdy_result.attributes
213
+ assert_equal rdy_result.foo, 'bar'
214
+ assert_equal rdy_result.hash_value, hash_value
215
+ @rdy.destroy
216
+ end
169
217
  end
170
-
218
+
171
219
  context "Finding hash-key/range based items" do
172
220
  setup do
173
221
  rdy_range
174
222
  end
175
223
 
176
224
  should "find an item by hash-key & range combination" do
225
+ hash_value = Rdy.generate_key
177
226
  @rdy2.foo = "bar"
178
- attributes = @rdy2.save("7")
179
- @rdy2.find("7", "bar")
227
+ attributes = @rdy2.save(hash_value)
228
+ @rdy2.find(hash_value, "bar")
180
229
  assert_not_nil @rdy2.foo
181
230
  assert_equal @rdy2.foo, "bar"
182
231
  @rdy2.destroy
183
232
  end
233
+
234
+ should "use the find class method" do
235
+ hash_value = Rdy.generate_key
236
+ @rdy2.foo = "bar"
237
+ attributes = @rdy2.save(hash_value)
238
+ rdy_result = Rdy.find(RDY_RANGE_TABLE, [:id, :string, hash_value], [:foo, :string, 'bar'])
239
+ assert_not_nil rdy_result
240
+ assert rdy_result.is_a?(Rdy)
241
+ assert_not_nil rdy_result.attributes
242
+ assert_equal rdy_result.foo, 'bar'
243
+ assert_equal rdy_result.hash_value, hash_value
244
+ assert_equal rdy_result.range_value, 'bar'
245
+ @rdy2.destroy
246
+ end
247
+ end
248
+
249
+ context "Query Table" do
250
+ setup do
251
+ rdy_range
252
+ end
253
+
254
+ should "query table by hash value and range value" do
255
+ hash_value1 = Rdy.generate_key
256
+ @rdy2 = Rdy.new(RDY_RANGE_TABLE, [:id, :string], [:foo, :string])
257
+ @rdy2.foo = "a"
258
+ @rdy2.save(hash_value1)
259
+
260
+ hash_value2 = Rdy.generate_key
261
+ @rdy3 = Rdy.new(RDY_RANGE_TABLE, [:id, :string], [:foo, :string])
262
+ @rdy3.foo = "b"
263
+ @rdy3.save(hash_value2)
264
+
265
+ attrs = @rdy2.query(:hash_value => hash_value1, :range_value => "a")
266
+ assert_not_nil attrs
267
+ assert_equal attrs.size, 1
268
+ assert_equal attrs[0]['id'], hash_value1
269
+ assert_equal attrs[0]['foo'], 'a'
270
+
271
+ attrs = @rdy2.query_by_range_value("a")
272
+ assert_not_nil attrs
273
+ assert_equal attrs.size, 1
274
+ assert_equal attrs[0]['id'], hash_value1
275
+ assert_equal attrs[0]['foo'], 'a'
276
+
277
+ attrs = @rdy2.query_by_range_value("b")
278
+ assert_not_nil attrs
279
+ assert_equal attrs.size, 0
280
+
281
+ attrs = @rdy3.query(:hash_value => hash_value2, :range_value => "b")
282
+ assert_not_nil attrs
283
+ assert_equal attrs.size, 1
284
+ assert_equal attrs[0]['id'], hash_value2
285
+ assert_equal attrs[0]['foo'], 'b'
286
+
287
+ attrs = @rdy3.query_by_range_value("b")
288
+ assert_not_nil attrs
289
+ assert_equal attrs.size, 1
290
+ assert_equal attrs[0]['id'], hash_value2
291
+ assert_equal attrs[0]['foo'], 'b'
292
+
293
+ attrs = @rdy3.query_by_range_value("a")
294
+ assert_not_nil attrs
295
+ assert_equal attrs.size, 0
296
+
297
+ @rdy2.find(hash_value1, "a")
298
+ @rdy2.destroy
299
+
300
+ @rdy3.find(hash_value2, "b")
301
+ @rdy3.destroy
302
+ end
184
303
  end
185
304
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rdy
3
3
  version: !ruby/object:Gem::Version
4
- hash: 23
4
+ hash: 21
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 2
9
- - 0
10
- version: 0.2.0
9
+ - 1
10
+ version: 0.2.1
11
11
  platform: ruby
12
12
  authors:
13
13
  - Oliver Kiessler
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2012-02-15 00:00:00 Z
18
+ date: 2012-03-03 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  version_requirements: &id001 !ruby/object:Gem::Requirement
@@ -23,12 +23,12 @@ dependencies:
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- hash: 31
26
+ hash: 17
27
27
  segments:
28
28
  - 1
29
29
  - 3
30
- - 2
31
- version: 1.3.2
30
+ - 5
31
+ version: 1.3.5
32
32
  name: aws-sdk
33
33
  prerelease: false
34
34
  type: :runtime