dynamoid 0.4.1 → 0.5.0

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.
@@ -2,4 +2,8 @@ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
2
 
3
3
  describe "Dynamoid" do
4
4
 
5
+ it "doesn't puke when asked for the assocations of a new record" do
6
+ User.new.books.should == []
7
+ end
8
+
5
9
  end
@@ -5,16 +5,19 @@ MODELS = File.join(File.dirname(__FILE__), "app/models")
5
5
 
6
6
  require 'rspec'
7
7
  require 'dynamoid'
8
+ require 'pry'
8
9
  require 'mocha'
9
10
 
11
+ ENV['ACCESS_KEY'] ||= 'abcd'
12
+ ENV['SECRET_KEY'] ||= '1234'
13
+
10
14
  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
15
+ config.adapter = 'aws_sdk'
16
+ config.access_key = ENV['ACCESS_KEY']
17
+ config.secret_key = ENV['SECRET_KEY']
18
+ config.endpoint = 'localhost'
19
+ config.port = '4567'
20
+ config.use_ssl = false
18
21
  config.namespace = 'dynamoid_tests'
19
22
  config.warn_on_scan = false
20
23
  end
@@ -29,26 +32,19 @@ Dir[ File.join(MODELS, "*.rb") ].sort.each { |file| require file }
29
32
 
30
33
  RSpec.configure do |config|
31
34
  config.mock_with(:mocha)
32
-
33
- if ENV['ACCESS_KEY'] && ENV['SECRET_KEY']
34
- config.before(:each) do
35
- Dynamoid::Adapter.list_tables.each do |table|
36
- if table =~ /^#{Dynamoid::Config.namespace}/
37
- table = Dynamoid::Adapter.get_table(table)
38
- table.items.each {|i| i.delete}
39
- end
40
- end
41
- end
42
-
43
- config.after(:suite) do
44
- Dynamoid::Adapter.list_tables.each do |table|
45
- Dynamoid::Adapter.delete_table(table) if table =~ /^#{Dynamoid::Config.namespace}/
35
+
36
+ config.before(:each) do
37
+ Dynamoid::Adapter.list_tables.each do |table|
38
+ if table =~ /^#{Dynamoid::Config.namespace}/
39
+ table = Dynamoid::Adapter.get_table(table)
40
+ table.items.each {|i| i.delete}
46
41
  end
47
42
  end
48
- else
49
- config.before(:each) do
50
- Dynamoid::Adapter.tables = []
51
- Dynamoid::Adapter.reset_data
43
+ end
44
+
45
+ config.after(:suite) do
46
+ Dynamoid::Adapter.list_tables.each do |table|
47
+ Dynamoid::Adapter.delete_table(table) if table =~ /^#{Dynamoid::Config.namespace}/
52
48
  end
53
49
  end
54
50
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dynamoid
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.1
4
+ version: 0.5.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-05-04 00:00:00.000000000 Z
12
+ date: 2012-08-22 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activemodel
@@ -60,7 +60,7 @@ dependencies:
60
60
  - !ruby/object:Gem::Version
61
61
  version: '0'
62
62
  - !ruby/object:Gem::Dependency
63
- name: mocha
63
+ name: rake
64
64
  requirement: !ruby/object:Gem::Requirement
65
65
  none: false
66
66
  requirements:
@@ -76,7 +76,7 @@ dependencies:
76
76
  - !ruby/object:Gem::Version
77
77
  version: '0'
78
78
  - !ruby/object:Gem::Dependency
79
- name: rake
79
+ name: rspec
80
80
  requirement: !ruby/object:Gem::Requirement
81
81
  none: false
82
82
  requirements:
@@ -92,7 +92,7 @@ dependencies:
92
92
  - !ruby/object:Gem::Version
93
93
  version: '0'
94
94
  - !ruby/object:Gem::Dependency
95
- name: rspec
95
+ name: bundler
96
96
  requirement: !ruby/object:Gem::Requirement
97
97
  none: false
98
98
  requirements:
@@ -108,7 +108,7 @@ dependencies:
108
108
  - !ruby/object:Gem::Version
109
109
  version: '0'
110
110
  - !ruby/object:Gem::Dependency
111
- name: bundler
111
+ name: jeweler
112
112
  requirement: !ruby/object:Gem::Requirement
113
113
  none: false
114
114
  requirements:
@@ -124,7 +124,7 @@ dependencies:
124
124
  - !ruby/object:Gem::Version
125
125
  version: '0'
126
126
  - !ruby/object:Gem::Dependency
127
- name: jeweler
127
+ name: yard
128
128
  requirement: !ruby/object:Gem::Requirement
129
129
  none: false
130
130
  requirements:
@@ -140,7 +140,23 @@ dependencies:
140
140
  - !ruby/object:Gem::Version
141
141
  version: '0'
142
142
  - !ruby/object:Gem::Dependency
143
- name: yard
143
+ name: redcarpet
144
+ requirement: !ruby/object:Gem::Requirement
145
+ none: false
146
+ requirements:
147
+ - - '='
148
+ - !ruby/object:Gem::Version
149
+ version: 1.17.2
150
+ type: :development
151
+ prerelease: false
152
+ version_requirements: !ruby/object:Gem::Requirement
153
+ none: false
154
+ requirements:
155
+ - - '='
156
+ - !ruby/object:Gem::Version
157
+ version: 1.17.2
158
+ - !ruby/object:Gem::Dependency
159
+ name: github-markup
144
160
  requirement: !ruby/object:Gem::Requirement
145
161
  none: false
146
162
  requirements:
@@ -156,23 +172,23 @@ dependencies:
156
172
  - !ruby/object:Gem::Version
157
173
  version: '0'
158
174
  - !ruby/object:Gem::Dependency
159
- name: redcarpet
175
+ name: pry
160
176
  requirement: !ruby/object:Gem::Requirement
161
177
  none: false
162
178
  requirements:
163
- - - '='
179
+ - - ! '>='
164
180
  - !ruby/object:Gem::Version
165
- version: 1.17.2
181
+ version: '0'
166
182
  type: :development
167
183
  prerelease: false
168
184
  version_requirements: !ruby/object:Gem::Requirement
169
185
  none: false
170
186
  requirements:
171
- - - '='
187
+ - - ! '>='
172
188
  - !ruby/object:Gem::Version
173
- version: 1.17.2
189
+ version: '0'
174
190
  - !ruby/object:Gem::Dependency
175
- name: github-markup
191
+ name: fake_dynamo
176
192
  requirement: !ruby/object:Gem::Requirement
177
193
  none: false
178
194
  requirements:
@@ -187,6 +203,22 @@ dependencies:
187
203
  - - ! '>='
188
204
  - !ruby/object:Gem::Version
189
205
  version: '0'
206
+ - !ruby/object:Gem::Dependency
207
+ name: mocha
208
+ requirement: !ruby/object:Gem::Requirement
209
+ none: false
210
+ requirements:
211
+ - - '='
212
+ - !ruby/object:Gem::Version
213
+ version: 0.10.0
214
+ type: :development
215
+ prerelease: false
216
+ version_requirements: !ruby/object:Gem::Requirement
217
+ none: false
218
+ requirements:
219
+ - - '='
220
+ - !ruby/object:Gem::Version
221
+ version: 0.10.0
190
222
  description: Dynamoid is an ORM for Amazon's DynamoDB that supports offline development,
191
223
  associations, querying, and everything else you'd expect from an ActiveRecord-style
192
224
  replacement.
@@ -261,7 +293,6 @@ files:
261
293
  - lib/dynamoid.rb
262
294
  - lib/dynamoid/adapter.rb
263
295
  - lib/dynamoid/adapter/aws_sdk.rb
264
- - lib/dynamoid/adapter/local.rb
265
296
  - lib/dynamoid/associations.rb
266
297
  - lib/dynamoid/associations/association.rb
267
298
  - lib/dynamoid/associations/belongs_to.rb
@@ -275,23 +306,26 @@ files:
275
306
  - lib/dynamoid/config/options.rb
276
307
  - lib/dynamoid/criteria.rb
277
308
  - lib/dynamoid/criteria/chain.rb
309
+ - lib/dynamoid/dirty.rb
278
310
  - lib/dynamoid/document.rb
279
311
  - lib/dynamoid/errors.rb
280
312
  - lib/dynamoid/fields.rb
281
313
  - lib/dynamoid/finders.rb
314
+ - lib/dynamoid/identity_map.rb
282
315
  - lib/dynamoid/indexes.rb
283
316
  - lib/dynamoid/indexes/index.rb
317
+ - lib/dynamoid/middleware/identity_map.rb
284
318
  - lib/dynamoid/persistence.rb
285
319
  - lib/dynamoid/validations.rb
286
320
  - spec/app/models/address.rb
287
321
  - spec/app/models/camel_case.rb
288
322
  - spec/app/models/magazine.rb
323
+ - spec/app/models/message.rb
289
324
  - spec/app/models/sponsor.rb
290
325
  - spec/app/models/subscription.rb
291
326
  - spec/app/models/tweet.rb
292
327
  - spec/app/models/user.rb
293
328
  - spec/dynamoid/adapter/aws_sdk_spec.rb
294
- - spec/dynamoid/adapter/local_spec.rb
295
329
  - spec/dynamoid/adapter_spec.rb
296
330
  - spec/dynamoid/associations/association_spec.rb
297
331
  - spec/dynamoid/associations/belongs_to_spec.rb
@@ -302,9 +336,11 @@ files:
302
336
  - spec/dynamoid/config_spec.rb
303
337
  - spec/dynamoid/criteria/chain_spec.rb
304
338
  - spec/dynamoid/criteria_spec.rb
339
+ - spec/dynamoid/dirty_spec.rb
305
340
  - spec/dynamoid/document_spec.rb
306
341
  - spec/dynamoid/fields_spec.rb
307
342
  - spec/dynamoid/finders_spec.rb
343
+ - spec/dynamoid/identity_map_spec.rb
308
344
  - spec/dynamoid/indexes/index_spec.rb
309
345
  - spec/dynamoid/indexes_spec.rb
310
346
  - spec/dynamoid/persistence_spec.rb
@@ -326,7 +362,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
326
362
  version: '0'
327
363
  segments:
328
364
  - 0
329
- hash: -1975783982419623416
365
+ hash: 396768872286184895
330
366
  required_rubygems_version: !ruby/object:Gem::Requirement
331
367
  none: false
332
368
  requirements:
@@ -335,7 +371,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
335
371
  version: '0'
336
372
  requirements: []
337
373
  rubyforge_project:
338
- rubygems_version: 1.8.24
374
+ rubygems_version: 1.8.23
339
375
  signing_key:
340
376
  specification_version: 3
341
377
  summary: Dynamoid is an ORM for Amazon's DynamoDB
@@ -1,196 +0,0 @@
1
- module Dynamoid
2
- module Adapter
3
-
4
- # This gimpy hash construct should be equivalent to Amazon's actual DynamoDB, for offline development.
5
- # All tests pass with either this or connecting to the real DynamoDB, and that's good enough for me.
6
- module Local
7
- extend self
8
-
9
- # The hash holding all of our data.
10
- #
11
- # @return [Hash] a hash of raw values
12
- #
13
- # @since 0.2.0
14
- def data
15
- @data ||= {}
16
- end
17
-
18
- # A convenience method for testing that destroys all table data without destroying their structure.
19
- #
20
- # @since 0.2.0
21
- def reset_data
22
- self.data.each {|k, v| v[:data] = {}}
23
- end
24
-
25
- # Get many items at once from the hash.
26
- #
27
- # @example Retrieve IDs 1 and 2 from the table testtable
28
- # Dynamoid::Adapter::Local.batch_get_item('table1' => ['1', '2'])
29
- #
30
- # @param [Hash] options the hash of tables and IDs to retrieve
31
- #
32
- # @return [Hash] a hash where keys are the table names and the values are the retrieved items
33
- #
34
- # @since 0.2.0
35
- def batch_get_item(options)
36
- Hash.new { |h, k| h[k] = Array.new }.tap do |hash|
37
- options.each do |table_name, keys|
38
- table = data[table_name]
39
- if table[:range_key]
40
- Array(keys).each do |hash_key, range_key|
41
- hash[table_name] << get_item(table_name, hash_key, :range_key => range_key)
42
- end
43
- else
44
- Array(keys).each do |key|
45
- hash[table_name] << get_item(table_name, key)
46
- end
47
- end
48
- end
49
- end
50
- end
51
-
52
- # Create a table.
53
- #
54
- # @param [String] table_name the name of the table to create
55
- # @param [Symbol] key the table's primary key (defaults to :id)
56
- # @param [Hash] options provide a range_key here if you want one for the table
57
- #
58
- # @since 0.2.0
59
- def create_table(table_name, key, options = {})
60
- range_key = options[:range_key] && options[:range_key].keys.first
61
- data[table_name] = {:hash_key => key, :range_key => range_key, :data => {}}
62
- end
63
-
64
- # Removes an item from the hash.
65
- #
66
- # @param [String] table_name the name of the table
67
- # @param [String] key the hash key of the item to delete
68
- # @param [Number] range_key the range key of the item to delete, required if the table has a composite key
69
- #
70
- # @since 0.2.0
71
- def delete_item(table_name, key, options = {})
72
- range_key = options.delete(:range_key)
73
- data[table_name][:data].delete("#{key}.#{range_key}")
74
- end
75
-
76
- # Deletes an entire table from the hash.
77
- #
78
- # @param [String] table_name the name of the table to destroy
79
- #
80
- # @since 0.2.0
81
- def delete_table(table_name)
82
- data.delete(table_name)
83
- end
84
-
85
- # @todo Add a DescribeTable method.
86
-
87
- # Fetches an item from the hash.
88
- #
89
- # @param [String] table_name the name of the table
90
- # @param [String] key the hash key of the item to find
91
- # @param [Number] range_key the range key of the item to find, required if the table has a composite key
92
- #
93
- # @return [Hash] a hash representing the raw item
94
- #
95
- # @since 0.2.0
96
- def get_item(table_name, key, options = {})
97
- range_key = options[:range_key]
98
- if data[table_name][:data]
99
- data[table_name][:data]["#{key}.#{range_key}"]
100
- else
101
- nil
102
- end
103
- end
104
-
105
- # List all tables on DynamoDB.
106
- #
107
- # @since 0.2.0
108
- def list_tables
109
- data.keys
110
- end
111
-
112
- # Persists an item in the hash.
113
- #
114
- # @param [String] table_name the name of the table
115
- # @param [Object] object a hash or Dynamoid object to persist
116
- #
117
- # @since 0.2.0
118
- def put_item(table_name, object)
119
- table = data[table_name]
120
- table[:data][object[table[:hash_key]]]
121
- table[:data]["#{object[table[:hash_key]]}.#{object[table[:range_key]]}"] = object.delete_if{|k, v| v.nil? || (v.respond_to?(:empty?) && v.empty?)}
122
- rescue
123
- raise data.inspect
124
- end
125
-
126
- # Query the hash.
127
- #
128
- # @param [String] table_name the name of the table
129
- # @param [Hash] opts the options to query the table with
130
- # @option opts [String] :hash_value the value of the hash key to find
131
- # @option opts [Range] :range_value find the range key within this range
132
- # @option opts [Number] :range_greater_than find range keys greater than this
133
- # @option opts [Number] :range_less_than find range keys less than this
134
- # @option opts [Number] :range_gte find range keys greater than or equal to this
135
- # @option opts [Number] :range_lte find range keys less than or equal to this
136
- #
137
- # @return [Array] an array of all matching items
138
- #
139
- # @since 0.2.0
140
- def query(table_name, opts = {})
141
- id = opts[:hash_value]
142
- hash_key = data[table_name][:hash_key]
143
- range_key = data[table_name][:range_key]
144
-
145
- results = if opts[:range_value]
146
- data[table_name][:data].values.find_all{|v| v[hash_key] == id && !v[range_key].nil? && opts[:range_value].include?(v[range_key])}
147
- elsif opts[:range_greater_than]
148
- data[table_name][:data].values.find_all{|v| v[hash_key] == id && !v[range_key].nil? && v[range_key] > opts[:range_greater_than]}
149
- elsif opts[:range_less_than]
150
- data[table_name][:data].values.find_all{|v| v[hash_key] == id && !v[range_key].nil? && v[range_key] < opts[:range_less_than]}
151
- elsif opts[:range_gte]
152
- data[table_name][:data].values.find_all{|v| v[hash_key] == id && !v[range_key].nil? && v[range_key] >= opts[:range_gte]}
153
- elsif opts[:range_lte]
154
- data[table_name][:data].values.find_all{|v| v[hash_key] == id && !v[range_key].nil? && v[range_key] <= opts[:range_lte]}
155
- else
156
- data[table_name][:data].values.find_all{|v| v[hash_key] == id}
157
- end
158
-
159
- results = drop_till_start(results, opts[:next_token], range_key, hash_key)
160
- results = results.take(opts[:limit]) if opts[:limit]
161
- results
162
- end
163
-
164
- # Scan the hash.
165
- #
166
- # @param [String] table_name the name of the table
167
- # @param [Hash] scan_hash a hash of attributes: matching records will be returned by the scan
168
- #
169
- # @return [Array] an array of all matching items
170
- #
171
- # @since 0.2.0
172
- def scan(table_name, scan_hash, opts = {})
173
- return [] if data[table_name].nil?
174
- results = data[table_name][:data].values.flatten.select{|d| scan_hash.all?{|k, v| !d[k].nil? && d[k] == v}}
175
- results = drop_till_start(results, opts[:next_token], data[table_name][:range_key], data[table_name][:hash_key])
176
- results = results.take(opts[:limit]) if opts[:limit]
177
- results
178
- end
179
-
180
- def drop_till_start(results, next_token, range_key, hash_key)
181
- return results unless next_token
182
-
183
- hash_value = next_token[:hash_key_element].values.first
184
- range_value = next_token[:range_key_element].values.first if next_token[:range_key_element]
185
-
186
- results = results.drop_while do |r|
187
- (r[hash_key] != hash_value or r[range_key] != range_value)
188
- end.drop(1)
189
- end
190
-
191
- # @todo Add an UpdateItem method.
192
-
193
- # @todo Add an UpdateTable method.
194
- end
195
- end
196
- end