dynamoid 0.4.1 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "dynamoid"
8
- s.version = "0.4.1"
8
+ s.version = "0.5.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Josh Symonds"]
12
- s.date = "2012-05-04"
12
+ s.date = "2012-08-22"
13
13
  s.description = "Dynamoid is an ORM for Amazon's DynamoDB that supports offline development, associations, querying, and everything else you'd expect from an ActiveRecord-style replacement."
14
14
  s.email = "josh@joshsymonds.com"
15
15
  s.extra_rdoc_files = [
@@ -81,7 +81,6 @@ Gem::Specification.new do |s|
81
81
  "lib/dynamoid.rb",
82
82
  "lib/dynamoid/adapter.rb",
83
83
  "lib/dynamoid/adapter/aws_sdk.rb",
84
- "lib/dynamoid/adapter/local.rb",
85
84
  "lib/dynamoid/associations.rb",
86
85
  "lib/dynamoid/associations/association.rb",
87
86
  "lib/dynamoid/associations/belongs_to.rb",
@@ -95,23 +94,26 @@ Gem::Specification.new do |s|
95
94
  "lib/dynamoid/config/options.rb",
96
95
  "lib/dynamoid/criteria.rb",
97
96
  "lib/dynamoid/criteria/chain.rb",
97
+ "lib/dynamoid/dirty.rb",
98
98
  "lib/dynamoid/document.rb",
99
99
  "lib/dynamoid/errors.rb",
100
100
  "lib/dynamoid/fields.rb",
101
101
  "lib/dynamoid/finders.rb",
102
+ "lib/dynamoid/identity_map.rb",
102
103
  "lib/dynamoid/indexes.rb",
103
104
  "lib/dynamoid/indexes/index.rb",
105
+ "lib/dynamoid/middleware/identity_map.rb",
104
106
  "lib/dynamoid/persistence.rb",
105
107
  "lib/dynamoid/validations.rb",
106
108
  "spec/app/models/address.rb",
107
109
  "spec/app/models/camel_case.rb",
108
110
  "spec/app/models/magazine.rb",
111
+ "spec/app/models/message.rb",
109
112
  "spec/app/models/sponsor.rb",
110
113
  "spec/app/models/subscription.rb",
111
114
  "spec/app/models/tweet.rb",
112
115
  "spec/app/models/user.rb",
113
116
  "spec/dynamoid/adapter/aws_sdk_spec.rb",
114
- "spec/dynamoid/adapter/local_spec.rb",
115
117
  "spec/dynamoid/adapter_spec.rb",
116
118
  "spec/dynamoid/associations/association_spec.rb",
117
119
  "spec/dynamoid/associations/belongs_to_spec.rb",
@@ -122,9 +124,11 @@ Gem::Specification.new do |s|
122
124
  "spec/dynamoid/config_spec.rb",
123
125
  "spec/dynamoid/criteria/chain_spec.rb",
124
126
  "spec/dynamoid/criteria_spec.rb",
127
+ "spec/dynamoid/dirty_spec.rb",
125
128
  "spec/dynamoid/document_spec.rb",
126
129
  "spec/dynamoid/fields_spec.rb",
127
130
  "spec/dynamoid/finders_spec.rb",
131
+ "spec/dynamoid/identity_map_spec.rb",
128
132
  "spec/dynamoid/indexes/index_spec.rb",
129
133
  "spec/dynamoid/indexes_spec.rb",
130
134
  "spec/dynamoid/persistence_spec.rb",
@@ -135,7 +139,7 @@ Gem::Specification.new do |s|
135
139
  s.homepage = "http://github.com/Veraticus/Dynamoid"
136
140
  s.licenses = ["MIT"]
137
141
  s.require_paths = ["lib"]
138
- s.rubygems_version = "1.8.24"
142
+ s.rubygems_version = "1.8.23"
139
143
  s.summary = "Dynamoid is an ORM for Amazon's DynamoDB"
140
144
 
141
145
  if s.respond_to? :specification_version then
@@ -145,7 +149,6 @@ Gem::Specification.new do |s|
145
149
  s.add_runtime_dependency(%q<activemodel>, [">= 0"])
146
150
  s.add_runtime_dependency(%q<tzinfo>, [">= 0"])
147
151
  s.add_runtime_dependency(%q<aws-sdk>, [">= 0"])
148
- s.add_development_dependency(%q<mocha>, [">= 0"])
149
152
  s.add_development_dependency(%q<rake>, [">= 0"])
150
153
  s.add_development_dependency(%q<rspec>, [">= 0"])
151
154
  s.add_development_dependency(%q<bundler>, [">= 0"])
@@ -153,11 +156,13 @@ Gem::Specification.new do |s|
153
156
  s.add_development_dependency(%q<yard>, [">= 0"])
154
157
  s.add_development_dependency(%q<redcarpet>, ["= 1.17.2"])
155
158
  s.add_development_dependency(%q<github-markup>, [">= 0"])
159
+ s.add_development_dependency(%q<pry>, [">= 0"])
160
+ s.add_development_dependency(%q<fake_dynamo>, [">= 0"])
161
+ s.add_development_dependency(%q<mocha>, ["= 0.10.0"])
156
162
  else
157
163
  s.add_dependency(%q<activemodel>, [">= 0"])
158
164
  s.add_dependency(%q<tzinfo>, [">= 0"])
159
165
  s.add_dependency(%q<aws-sdk>, [">= 0"])
160
- s.add_dependency(%q<mocha>, [">= 0"])
161
166
  s.add_dependency(%q<rake>, [">= 0"])
162
167
  s.add_dependency(%q<rspec>, [">= 0"])
163
168
  s.add_dependency(%q<bundler>, [">= 0"])
@@ -165,12 +170,14 @@ Gem::Specification.new do |s|
165
170
  s.add_dependency(%q<yard>, [">= 0"])
166
171
  s.add_dependency(%q<redcarpet>, ["= 1.17.2"])
167
172
  s.add_dependency(%q<github-markup>, [">= 0"])
173
+ s.add_dependency(%q<pry>, [">= 0"])
174
+ s.add_dependency(%q<fake_dynamo>, [">= 0"])
175
+ s.add_dependency(%q<mocha>, ["= 0.10.0"])
168
176
  end
169
177
  else
170
178
  s.add_dependency(%q<activemodel>, [">= 0"])
171
179
  s.add_dependency(%q<tzinfo>, [">= 0"])
172
180
  s.add_dependency(%q<aws-sdk>, [">= 0"])
173
- s.add_dependency(%q<mocha>, [">= 0"])
174
181
  s.add_dependency(%q<rake>, [">= 0"])
175
182
  s.add_dependency(%q<rspec>, [">= 0"])
176
183
  s.add_dependency(%q<bundler>, [">= 0"])
@@ -178,6 +185,9 @@ Gem::Specification.new do |s|
178
185
  s.add_dependency(%q<yard>, [">= 0"])
179
186
  s.add_dependency(%q<redcarpet>, ["= 1.17.2"])
180
187
  s.add_dependency(%q<github-markup>, [">= 0"])
188
+ s.add_dependency(%q<pry>, [">= 0"])
189
+ s.add_dependency(%q<fake_dynamo>, [">= 0"])
190
+ s.add_dependency(%q<mocha>, ["= 0.10.0"])
181
191
  end
182
192
  end
183
193
 
data/Gemfile CHANGED
@@ -10,7 +10,6 @@ gem 'aws-sdk'
10
10
  # Add dependencies to develop your gem here.
11
11
  # Include everything needed to run rake, tests, features, etc.
12
12
  group :development do
13
- gem "mocha"
14
13
  gem "rake"
15
14
  gem "rspec"
16
15
  gem "bundler"
@@ -18,4 +17,7 @@ group :development do
18
17
  gem "yard"
19
18
  gem "redcarpet", '1.17.2'
20
19
  gem 'github-markup'
20
+ gem 'pry'
21
+ gem 'fake_dynamo'
22
+ gem "mocha", '0.10.0'
21
23
  end
@@ -1,49 +1,71 @@
1
1
  GEM
2
2
  remote: http://rubygems.org/
3
3
  specs:
4
- activemodel (3.1.3)
5
- activesupport (= 3.1.3)
4
+ activemodel (3.2.8)
5
+ activesupport (= 3.2.8)
6
6
  builder (~> 3.0.0)
7
+ activesupport (3.2.8)
7
8
  i18n (~> 0.6)
8
- activesupport (3.1.3)
9
9
  multi_json (~> 1.0)
10
- aws-sdk (1.3.5)
10
+ aws-sdk (1.6.4)
11
11
  httparty (~> 0.7)
12
12
  json (~> 1.4)
13
13
  nokogiri (>= 1.4.4)
14
14
  uuidtools (~> 2.1)
15
15
  builder (3.0.0)
16
+ coderay (1.0.7)
16
17
  diff-lcs (1.1.3)
18
+ fake_dynamo (0.0.9)
19
+ activesupport
20
+ json
21
+ sinatra
17
22
  git (1.2.5)
18
- github-markup (0.7.1)
19
- httparty (0.8.1)
20
- multi_json
23
+ github-markup (0.7.4)
24
+ httparty (0.8.3)
25
+ multi_json (~> 1.0)
21
26
  multi_xml
22
27
  i18n (0.6.0)
23
- jeweler (1.6.4)
28
+ jeweler (1.8.4)
24
29
  bundler (~> 1.0)
25
30
  git (>= 1.2.5)
26
31
  rake
27
- json (1.6.5)
32
+ rdoc
33
+ json (1.7.5)
28
34
  metaclass (0.0.1)
35
+ method_source (0.8)
29
36
  mocha (0.10.0)
30
37
  metaclass (~> 0.0.1)
31
- multi_json (1.0.4)
32
- multi_xml (0.4.1)
33
- nokogiri (1.5.0)
38
+ multi_json (1.3.6)
39
+ multi_xml (0.5.1)
40
+ nokogiri (1.5.5)
41
+ pry (0.9.10)
42
+ coderay (~> 1.0.5)
43
+ method_source (~> 0.8)
44
+ slop (~> 3.3.1)
45
+ rack (1.4.1)
46
+ rack-protection (1.2.0)
47
+ rack
34
48
  rake (0.9.2.2)
49
+ rdoc (3.12)
50
+ json (~> 1.4)
35
51
  redcarpet (1.17.2)
36
- rspec (2.8.0)
37
- rspec-core (~> 2.8.0)
38
- rspec-expectations (~> 2.8.0)
39
- rspec-mocks (~> 2.8.0)
40
- rspec-core (2.8.0)
41
- rspec-expectations (2.8.0)
42
- diff-lcs (~> 1.1.2)
43
- rspec-mocks (2.8.0)
44
- tzinfo (0.3.31)
45
- uuidtools (2.1.2)
46
- yard (0.7.5)
52
+ rspec (2.11.0)
53
+ rspec-core (~> 2.11.0)
54
+ rspec-expectations (~> 2.11.0)
55
+ rspec-mocks (~> 2.11.0)
56
+ rspec-core (2.11.1)
57
+ rspec-expectations (2.11.2)
58
+ diff-lcs (~> 1.1.3)
59
+ rspec-mocks (2.11.2)
60
+ sinatra (1.3.3)
61
+ rack (~> 1.3, >= 1.3.6)
62
+ rack-protection (~> 1.2)
63
+ tilt (~> 1.3, >= 1.3.3)
64
+ slop (3.3.2)
65
+ tilt (1.3.3)
66
+ tzinfo (0.3.33)
67
+ uuidtools (2.1.3)
68
+ yard (0.8.2.1)
47
69
 
48
70
  PLATFORMS
49
71
  ruby
@@ -52,9 +74,11 @@ DEPENDENCIES
52
74
  activemodel
53
75
  aws-sdk
54
76
  bundler
77
+ fake_dynamo
55
78
  github-markup
56
79
  jeweler
57
- mocha
80
+ mocha (= 0.10.0)
81
+ pry
58
82
  rake
59
83
  redcarpet (= 1.17.2)
60
84
  rspec
@@ -1,6 +1,10 @@
1
1
  # Dynamoid
2
2
 
3
- Dynamoid is an ORM for Amazon's DynamoDB for Ruby applications. It provides similar functionality to ActiveRecord and improves on Amazon's existing [HashModel](http://docs.amazonwebservices.com/AWSRubySDK/latest/AWS/Record/HashModel.html) by providing better searching tools, native association support, and a local adapter for offline development.
3
+ Dynamoid is an ORM for Amazon's DynamoDB for Ruby applications. It
4
+ provides similar functionality to ActiveRecord and improves on
5
+ Amazon's existing
6
+ [HashModel](http://docs.amazonwebservices.com/AWSRubySDK/latest/AWS/Record/HashModel.html)
7
+ by providing better searching tools and native association support.
4
8
 
5
9
  DynamoDB is not like other document-based databases you might know, and is very different indeed from relational databases. It sacrifices anything beyond the simplest relational queries and transactional support to provide a fast, cost-efficient, and highly durable storage solution. If your database requires complicated relational queries and transaction support, then this modest Gem cannot provide them for you, and neither can DynamoDB. In those cases you would do better to look elsewhere for your database needs.
6
10
 
@@ -18,7 +22,6 @@ Then you need to initialize it to get it going. Put code similar to this somewhe
18
22
 
19
23
  ```ruby
20
24
  Dynamoid.configure do |config|
21
- config.adapter = 'local' # This adapter allows offline development without connecting to the DynamoDB servers. Data is *NOT* persisted.
22
25
  # config.adapter = 'aws_sdk' # This adapter establishes a connection to the DynamoDB servers using Amazon's own AWS gem.
23
26
  # config.access_key = 'access_key' # If connecting to DynamoDB, your access key is required.
24
27
  # config.secret_key = 'secret_key' # So is your secret key.
@@ -254,7 +257,7 @@ Also, without contributors the project wouldn't be nearly as awesome. So many th
254
257
 
255
258
  ## Running the tests
256
259
 
257
- The tests can be run in the simple predictable way with ```rake```. However, if you provide environment variables for ACCESS_KEY and SECRET_KEY, the tests will use the aws_sdk adapter rather than the local adapter: ```ACCESS_KEY=<accesskey> SECRET_KEY=<secretkey> rake```. Keep in mind this takes much, much longer than the local tests.
260
+ Running the tests is fairly simple. In one window, run `fake_dynamo`, and in the other, use `rake`.
258
261
 
259
262
  ## Copyright
260
263
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.4.1
1
+ 0.5.0
@@ -13,14 +13,18 @@ require 'dynamoid/fields'
13
13
  require 'dynamoid/indexes'
14
14
  require 'dynamoid/associations'
15
15
  require 'dynamoid/persistence'
16
+ require 'dynamoid/dirty'
16
17
  require 'dynamoid/validations'
17
18
  require 'dynamoid/criteria'
18
19
  require 'dynamoid/finders'
20
+ require 'dynamoid/identity_map'
19
21
  require 'dynamoid/config'
20
22
  require 'dynamoid/components'
21
23
  require 'dynamoid/document'
22
24
  require 'dynamoid/adapter'
23
25
 
26
+ require 'dynamoid/middleware/identity_map'
27
+
24
28
  module Dynamoid
25
29
  extend self
26
30
 
@@ -7,7 +7,7 @@ module Dynamoid
7
7
  extend self
8
8
  attr_accessor :tables
9
9
 
10
- # The actual adapter currently in use: presently, either AwsSdk or Local.
10
+ # The actual adapter currently in use: presently AwsSdk.
11
11
  #
12
12
  # @since 0.2.0
13
13
  def adapter
@@ -164,8 +164,8 @@ module Dynamoid
164
164
  # Delegate all methods that aren't defind here to the underlying adapter.
165
165
  #
166
166
  # @since 0.2.0
167
- def method_missing(method, *args)
168
- return benchmark(method, *args) {adapter.send(method, *args)} if @adapter.respond_to?(method)
167
+ def method_missing(method, *args, &block)
168
+ return benchmark(method, *args) {adapter.send(method, *args, &block)} if @adapter.respond_to?(method)
169
169
  super
170
170
  end
171
171
 
@@ -18,7 +18,7 @@ module Dynamoid
18
18
  #
19
19
  # @since 0.2.0
20
20
  def connect!
21
- @@connection = AWS::DynamoDB.new(:access_key_id => Dynamoid::Config.access_key, :secret_access_key => Dynamoid::Config.secret_key, :dynamo_db_endpoint => Dynamoid::Config.endpoint)
21
+ @@connection = AWS::DynamoDB.new(:access_key_id => Dynamoid::Config.access_key, :secret_access_key => Dynamoid::Config.secret_key, :dynamo_db_endpoint => Dynamoid::Config.endpoint, :use_ssl => Dynamoid::Config.use_ssl, :dynamo_db_port => Dynamoid::Config.port)
22
22
  end
23
23
 
24
24
  # Return the established connection.
@@ -63,7 +63,7 @@ module Dynamoid
63
63
  #
64
64
  # @since 0.2.0
65
65
  def create_table(table_name, key = :id, options = {})
66
- Dynamite.logger.info "Creating #{table_name} table. This could take a while."
66
+ Dynamoid.logger.info "Creating #{table_name} table. This could take a while."
67
67
  options[:hash_key] ||= {key.to_sym => :string}
68
68
  read_capacity = options[:read_capacity] || Dynamoid::Config.read_capacity
69
69
  write_capacity = options[:write_capacity] || Dynamoid::Config.write_capacity
@@ -82,11 +82,7 @@ module Dynamoid
82
82
  def delete_item(table_name, key, options = {})
83
83
  range_key = options.delete(:range_key)
84
84
  table = get_table(table_name)
85
- result = if table.composite_key?
86
- table.items.at(key, range_key)
87
- else
88
- table.items[key]
89
- end
85
+ result = table.items.at(key, range_key)
90
86
  result.delete unless result.attributes.to_h.empty?
91
87
  true
92
88
  end
@@ -98,7 +94,10 @@ module Dynamoid
98
94
  #
99
95
  # @since 0.2.0
100
96
  def delete_table(table_name)
101
- @@connection.tables[table_name].delete
97
+ Dynamoid.logger.info "Deleting #{table_name} table. This could take a while."
98
+ table = @@connection.tables[table_name]
99
+ table.delete
100
+ sleep 0.5 while table.exists? == true
102
101
  end
103
102
 
104
103
  # @todo Add a DescribeTable method.
@@ -119,11 +118,8 @@ module Dynamoid
119
118
  range_key = options.delete(:range_key)
120
119
  table = get_table(table_name)
121
120
 
122
- result = if table.composite_key?
123
- table.items.at(key, range_key)
124
- else
125
- table.items[key]
126
- end.attributes.to_h(options)
121
+ result = table.items.at(key, range_key).attributes.to_h(options)
122
+
127
123
  if result.empty?
128
124
  nil
129
125
  else
@@ -131,6 +127,16 @@ module Dynamoid
131
127
  end
132
128
  end
133
129
 
130
+ def update_item(table_name, key, options = {}, &block)
131
+ range_key = options.delete(:range_key)
132
+ conditions = options.delete(:conditions) || {}
133
+ table = get_table(table_name)
134
+ item = table.items.at(key, range_key)
135
+ item.attributes.update(conditions.merge(:return => :all_new), &block)
136
+ rescue AWS::DynamoDB::Errors::ConditionalCheckFailedException
137
+ raise Dynamoid::Errors::ConditionalCheckFailedException
138
+ end
139
+
134
140
  # List all tables on DynamoDB.
135
141
  #
136
142
  # @since 0.2.0
@@ -1,6 +1,6 @@
1
1
  # encoding: utf-8
2
2
  module Dynamoid
3
-
3
+
4
4
  # All modules that a Document is composed of are defined in this
5
5
  # module, to keep the document class from getting too cluttered.
6
6
  module Components
@@ -10,15 +10,14 @@ module Dynamoid
10
10
  extend ActiveModel::Translation
11
11
  extend ActiveModel::Callbacks
12
12
 
13
- define_model_callbacks :create, :save, :destroy
14
-
13
+ define_model_callbacks :create, :save, :destroy, :initialize
14
+
15
15
  before_create :set_created_at
16
16
  before_save :set_updated_at
17
17
  end
18
18
 
19
19
  include ActiveModel::AttributeMethods
20
20
  include ActiveModel::Conversion
21
- include ActiveModel::Dirty
22
21
  include ActiveModel::MassAssignmentSecurity
23
22
  include ActiveModel::Naming
24
23
  include ActiveModel::Observing
@@ -31,5 +30,7 @@ module Dynamoid
31
30
  include Dynamoid::Associations
32
31
  include Dynamoid::Criteria
33
32
  include Dynamoid::Validations
33
+ include Dynamoid::IdentityMap
34
+ include Dynamoid::Dirty
34
35
  end
35
36
  end
@@ -3,7 +3,7 @@ require "uri"
3
3
  require "dynamoid/config/options"
4
4
 
5
5
  module Dynamoid
6
-
6
+
7
7
  # Contains all the basic configuration information required for Dynamoid: both sensible defaults and required fields.
8
8
  module Config
9
9
  extend self
@@ -11,7 +11,7 @@ module Dynamoid
11
11
  include ActiveModel::Observing
12
12
 
13
13
  # All the default options.
14
- option :adapter, :default => 'local'
14
+ option :adapter, :default => 'aws-sdk'
15
15
  option :namespace, :default => defined?(Rails) ? "dynamoid_#{Rails.application.class.parent_name}_#{Rails.env}" : "dynamoid"
16
16
  option :logger, :default => defined?(Rails)
17
17
  option :access_key
@@ -22,8 +22,11 @@ module Dynamoid
22
22
  option :partitioning, :default => false
23
23
  option :partition_size, :default => 200
24
24
  option :endpoint, :default => 'dynamodb.us-east-1.amazonaws.com'
25
+ option :use_ssl, :default => true
26
+ option :port, :default => '80'
25
27
  option :included_models, :default => []
26
-
28
+ option :identity_map, :default => false
29
+
27
30
  # The default logger for Dynamoid: either the Rails logger or just stdout.
28
31
  #
29
32
  # @since 0.2.0
@@ -37,7 +40,7 @@ module Dynamoid
37
40
  def logger
38
41
  @logger ||= default_logger
39
42
  end
40
-
43
+
41
44
  # If you want to, set the logger manually to any output you'd like. Or pass false or nil to disable logging entirely.
42
45
  #
43
46
  # @since 0.2.0