dynamoid 0.7.1 → 1.0.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.
Files changed (123) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +2 -24
  3. data/README.markdown +89 -73
  4. data/Rakefile +10 -36
  5. data/dynamoid.gemspec +56 -191
  6. data/lib/dynamoid.rb +6 -4
  7. data/lib/dynamoid/adapter.rb +64 -150
  8. data/lib/dynamoid/adapter_plugin/aws_sdk_v2.rb +579 -0
  9. data/lib/dynamoid/components.rb +0 -1
  10. data/lib/dynamoid/config.rb +2 -5
  11. data/lib/dynamoid/criteria.rb +1 -1
  12. data/lib/dynamoid/criteria/chain.rb +27 -140
  13. data/lib/dynamoid/document.rb +2 -2
  14. data/lib/dynamoid/errors.rb +30 -9
  15. data/lib/dynamoid/fields.rb +15 -3
  16. data/lib/dynamoid/finders.rb +7 -6
  17. data/lib/dynamoid/identity_map.rb +1 -5
  18. data/lib/dynamoid/persistence.rb +108 -93
  19. metadata +56 -229
  20. data/.document +0 -5
  21. data/.rspec +0 -1
  22. data/.travis.yml +0 -7
  23. data/Gemfile.lock +0 -81
  24. data/Gemfile_activemodel4 +0 -24
  25. data/Gemfile_activemodel4.lock +0 -88
  26. data/VERSION +0 -1
  27. data/doc/.nojekyll +0 -0
  28. data/doc/Dynamoid.html +0 -328
  29. data/doc/Dynamoid/Adapter.html +0 -1872
  30. data/doc/Dynamoid/Adapter/AwsSdk.html +0 -2101
  31. data/doc/Dynamoid/Adapter/Local.html +0 -1574
  32. data/doc/Dynamoid/Associations.html +0 -138
  33. data/doc/Dynamoid/Associations/Association.html +0 -847
  34. data/doc/Dynamoid/Associations/BelongsTo.html +0 -161
  35. data/doc/Dynamoid/Associations/ClassMethods.html +0 -766
  36. data/doc/Dynamoid/Associations/HasAndBelongsToMany.html +0 -167
  37. data/doc/Dynamoid/Associations/HasMany.html +0 -167
  38. data/doc/Dynamoid/Associations/HasOne.html +0 -161
  39. data/doc/Dynamoid/Associations/ManyAssociation.html +0 -1684
  40. data/doc/Dynamoid/Associations/SingleAssociation.html +0 -627
  41. data/doc/Dynamoid/Components.html +0 -242
  42. data/doc/Dynamoid/Config.html +0 -412
  43. data/doc/Dynamoid/Config/Options.html +0 -638
  44. data/doc/Dynamoid/Criteria.html +0 -138
  45. data/doc/Dynamoid/Criteria/Chain.html +0 -1471
  46. data/doc/Dynamoid/Criteria/ClassMethods.html +0 -105
  47. data/doc/Dynamoid/Dirty.html +0 -424
  48. data/doc/Dynamoid/Dirty/ClassMethods.html +0 -174
  49. data/doc/Dynamoid/Document.html +0 -1033
  50. data/doc/Dynamoid/Document/ClassMethods.html +0 -1116
  51. data/doc/Dynamoid/Errors.html +0 -125
  52. data/doc/Dynamoid/Errors/ConditionalCheckFailedException.html +0 -141
  53. data/doc/Dynamoid/Errors/DocumentNotValid.html +0 -221
  54. data/doc/Dynamoid/Errors/Error.html +0 -137
  55. data/doc/Dynamoid/Errors/InvalidField.html +0 -141
  56. data/doc/Dynamoid/Errors/InvalidQuery.html +0 -131
  57. data/doc/Dynamoid/Errors/MissingRangeKey.html +0 -141
  58. data/doc/Dynamoid/Fields.html +0 -686
  59. data/doc/Dynamoid/Fields/ClassMethods.html +0 -438
  60. data/doc/Dynamoid/Finders.html +0 -135
  61. data/doc/Dynamoid/Finders/ClassMethods.html +0 -943
  62. data/doc/Dynamoid/IdentityMap.html +0 -492
  63. data/doc/Dynamoid/IdentityMap/ClassMethods.html +0 -534
  64. data/doc/Dynamoid/Indexes.html +0 -321
  65. data/doc/Dynamoid/Indexes/ClassMethods.html +0 -369
  66. data/doc/Dynamoid/Indexes/Index.html +0 -1142
  67. data/doc/Dynamoid/Middleware.html +0 -115
  68. data/doc/Dynamoid/Middleware/IdentityMap.html +0 -264
  69. data/doc/Dynamoid/Persistence.html +0 -892
  70. data/doc/Dynamoid/Persistence/ClassMethods.html +0 -836
  71. data/doc/Dynamoid/Validations.html +0 -415
  72. data/doc/_index.html +0 -506
  73. data/doc/class_list.html +0 -53
  74. data/doc/css/common.css +0 -1
  75. data/doc/css/full_list.css +0 -57
  76. data/doc/css/style.css +0 -338
  77. data/doc/file.LICENSE.html +0 -73
  78. data/doc/file.README.html +0 -416
  79. data/doc/file_list.html +0 -58
  80. data/doc/frames.html +0 -28
  81. data/doc/index.html +0 -416
  82. data/doc/js/app.js +0 -214
  83. data/doc/js/full_list.js +0 -178
  84. data/doc/js/jquery.js +0 -4
  85. data/doc/method_list.html +0 -1144
  86. data/doc/top-level-namespace.html +0 -112
  87. data/lib/dynamoid/adapter/aws_sdk.rb +0 -287
  88. data/lib/dynamoid/indexes.rb +0 -69
  89. data/lib/dynamoid/indexes/index.rb +0 -103
  90. data/spec/app/models/address.rb +0 -13
  91. data/spec/app/models/camel_case.rb +0 -34
  92. data/spec/app/models/car.rb +0 -6
  93. data/spec/app/models/magazine.rb +0 -11
  94. data/spec/app/models/message.rb +0 -9
  95. data/spec/app/models/nuclear_submarine.rb +0 -5
  96. data/spec/app/models/sponsor.rb +0 -8
  97. data/spec/app/models/subscription.rb +0 -12
  98. data/spec/app/models/tweet.rb +0 -12
  99. data/spec/app/models/user.rb +0 -26
  100. data/spec/app/models/vehicle.rb +0 -7
  101. data/spec/dynamoid/adapter/aws_sdk_spec.rb +0 -376
  102. data/spec/dynamoid/adapter_spec.rb +0 -155
  103. data/spec/dynamoid/associations/association_spec.rb +0 -194
  104. data/spec/dynamoid/associations/belongs_to_spec.rb +0 -71
  105. data/spec/dynamoid/associations/has_and_belongs_to_many_spec.rb +0 -47
  106. data/spec/dynamoid/associations/has_many_spec.rb +0 -42
  107. data/spec/dynamoid/associations/has_one_spec.rb +0 -45
  108. data/spec/dynamoid/associations_spec.rb +0 -16
  109. data/spec/dynamoid/config_spec.rb +0 -27
  110. data/spec/dynamoid/criteria/chain_spec.rb +0 -210
  111. data/spec/dynamoid/criteria_spec.rb +0 -75
  112. data/spec/dynamoid/dirty_spec.rb +0 -57
  113. data/spec/dynamoid/document_spec.rb +0 -180
  114. data/spec/dynamoid/fields_spec.rb +0 -156
  115. data/spec/dynamoid/finders_spec.rb +0 -147
  116. data/spec/dynamoid/identity_map_spec.rb +0 -45
  117. data/spec/dynamoid/indexes/index_spec.rb +0 -104
  118. data/spec/dynamoid/indexes_spec.rb +0 -25
  119. data/spec/dynamoid/persistence_spec.rb +0 -301
  120. data/spec/dynamoid/validations_spec.rb +0 -36
  121. data/spec/dynamoid_spec.rb +0 -9
  122. data/spec/spec_helper.rb +0 -55
  123. data/spec/support/with_partitioning.rb +0 -15
@@ -1,112 +0,0 @@
1
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
2
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3
- <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
4
- <head>
5
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
6
- <title>
7
- Top Level Namespace
8
-
9
- &mdash; Documentation by YARD 0.8.6.1
10
-
11
- </title>
12
-
13
- <link rel="stylesheet" href="css/style.css" type="text/css" charset="utf-8" />
14
-
15
- <link rel="stylesheet" href="css/common.css" type="text/css" charset="utf-8" />
16
-
17
- <script type="text/javascript" charset="utf-8">
18
- hasFrames = window.top.frames.main ? true : false;
19
- relpath = '';
20
- framesUrl = "frames.html#!" + escape(window.location.href);
21
- </script>
22
-
23
-
24
- <script type="text/javascript" charset="utf-8" src="js/jquery.js"></script>
25
-
26
- <script type="text/javascript" charset="utf-8" src="js/app.js"></script>
27
-
28
-
29
- </head>
30
- <body>
31
- <div id="header">
32
- <div id="menu">
33
-
34
- <a href="_index.html">Index</a> &raquo;
35
-
36
-
37
- <span class="title">Top Level Namespace</span>
38
-
39
-
40
- <div class="noframes"><span class="title">(</span><a href="." target="_top">no frames</a><span class="title">)</span></div>
41
- </div>
42
-
43
- <div id="search">
44
-
45
- <a class="full_list_link" id="class_list_link"
46
- href="class_list.html">
47
- Class List
48
- </a>
49
-
50
- <a class="full_list_link" id="method_list_link"
51
- href="method_list.html">
52
- Method List
53
- </a>
54
-
55
- <a class="full_list_link" id="file_list_link"
56
- href="file_list.html">
57
- File List
58
- </a>
59
-
60
- </div>
61
- <div class="clear"></div>
62
- </div>
63
-
64
- <iframe id="search_frame"></iframe>
65
-
66
- <div id="content"><h1>Top Level Namespace
67
-
68
-
69
-
70
- </h1>
71
-
72
- <dl class="box">
73
-
74
-
75
-
76
-
77
-
78
-
79
-
80
-
81
- </dl>
82
- <div class="clear"></div>
83
-
84
- <h2>Defined Under Namespace</h2>
85
- <p class="children">
86
-
87
-
88
- <strong class="modules">Modules:</strong> <span class='object_link'><a href="Dynamoid.html" title="Dynamoid (module)">Dynamoid</a></span>
89
-
90
-
91
-
92
-
93
- </p>
94
-
95
-
96
-
97
-
98
-
99
-
100
-
101
-
102
-
103
- </div>
104
-
105
- <div id="footer">
106
- Generated on Thu Jun 27 21:59:09 2013 by
107
- <a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
108
- 0.8.6.1 (ruby-1.9.3).
109
- </div>
110
-
111
- </body>
112
- </html>
@@ -1,287 +0,0 @@
1
- # encoding: utf-8
2
- require 'aws'
3
-
4
- module Dynamoid
5
- module Adapter
6
-
7
- # The AwsSdk adapter provides support for the AWS-SDK for Ruby gem.
8
- # More information is available at that Gem's Github page:
9
- # https://github.com/amazonwebservices/aws-sdk-for-ruby
10
- #
11
- module AwsSdk
12
- extend self
13
- @@connection = nil
14
-
15
- # Establish the connection to DynamoDB.
16
- #
17
- # @return [AWS::DynamoDB::Connection] the raw DynamoDB connection
18
- # Call DynamoDB new, with no parameters.
19
- # Make sure the aws.yml file or aws.rb file, refer the link for more details.
20
- #https://github.com/amazonwebservices/aws-sdk-for-ruby
21
- # 1. Create config/aws.yml as follows:
22
- # Fill in your AWS Access Key ID and Secret Access Key
23
- # http://aws.amazon.com/security-credentials
24
- #access_key_id: REPLACE_WITH_ACCESS_KEY_ID
25
- #secret_access_key: REPLACE_WITH_SECRET_ACCESS_KEY
26
- #(or)
27
- #2, Create config/initializers/aws.rb as follows:
28
- # load the libraries
29
- #require 'aws'
30
- # log requests using the default rails logger
31
- #AWS.config(:logger => Rails.logger)
32
- # load credentials from a file
33
- #config_path = File.expand_path(File.dirname(__FILE__)+"/../aws.yml")
34
- #AWS.config(YAML.load(File.read(config_path)))
35
- #Additionally include any of the dynamodb paramters as needed
36
- #(eg: if you would like to change the dynamodb endpoint, then add the parameter in
37
- # the following paramter in the file aws.yml or aws.rb
38
- # dynamo_db_endpoint : dynamodb.ap-southeast-1.amazonaws.com)
39
- # @since 0.2.0
40
- def connect!
41
- @@connection = AWS::DynamoDB.new
42
- end
43
-
44
- # Return the established connection.
45
- #
46
- # @return [AWS::DynamoDB::Connection] the raw DynamoDB connection
47
- #
48
- # @since 0.2.0
49
- def connection
50
- @@connection
51
- end
52
-
53
- # Get many items at once from DynamoDB. More efficient than getting each item individually.
54
- #
55
- # @example Retrieve IDs 1 and 2 from the table testtable
56
- # Dynamoid::Adapter::AwsSdk.batch_get_item({'table1' => ['1', '2']}, :consistent_read => true)
57
- #
58
- # @param [Hash] table_ids the hash of tables and IDs to retrieve
59
- # @param [Hash] options to be passed to underlying BatchGet call
60
- #
61
- # @return [Hash] a hash where keys are the table names and the values are the retrieved items
62
- #
63
- # @since 0.2.0
64
- def batch_get_item(table_ids, options = {})
65
- hash = Hash.new{|h, k| h[k] = []}
66
- return hash if table_ids.all?{|k, v| v.empty?}
67
- table_ids.each do |t, ids|
68
- Array(ids).in_groups_of(100, false) do |group|
69
- batch = AWS::DynamoDB::BatchGet.new(:config => @@connection.config)
70
- batch.table(t, :all, Array(group), options) unless group.nil? || group.empty?
71
- batch.each do |table_name, attributes|
72
- hash[table_name] << attributes.symbolize_keys!
73
- end
74
- end
75
- end
76
- hash
77
- end
78
-
79
- # Delete many items at once from DynamoDB. More efficient than delete each item individually.
80
- #
81
- # @example Delete IDs 1 and 2 from the table testtable
82
- # Dynamoid::Adapter::AwsSdk.batch_delete_item('table1' => ['1', '2'])
83
- #or
84
- # Dynamoid::Adapter::AwsSdk.batch_delete_item('table1' => [['hk1', 'rk2'], ['hk1', 'rk2']]]))
85
- #
86
- # @param [Hash] options the hash of tables and IDs to delete
87
- #
88
- # @return nil
89
- #
90
- def batch_delete_item(options)
91
- return nil if options.all?{|k, v| v.empty?}
92
- options.each do |t, ids|
93
- Array(ids).in_groups_of(25, false) do |group|
94
- batch = AWS::DynamoDB::BatchWrite.new(:config => @@connection.config)
95
- batch.delete(t,group)
96
- batch.process!
97
- end
98
- end
99
- nil
100
- end
101
-
102
- # Create a table on DynamoDB. This usually takes a long time to complete.
103
- #
104
- # @param [String] table_name the name of the table to create
105
- # @param [Symbol] key the table's primary key (defaults to :id)
106
- # @param [Hash] options provide a range_key here if you want one for the table
107
- #
108
- # @since 0.2.0
109
- def create_table(table_name, key = :id, options = {})
110
- Dynamoid.logger.info "Creating #{table_name} table. This could take a while."
111
- options[:hash_key] ||= {key.to_sym => :string}
112
- read_capacity = options[:read_capacity] || Dynamoid::Config.read_capacity
113
- write_capacity = options[:write_capacity] || Dynamoid::Config.write_capacity
114
- table = @@connection.tables.create(table_name, read_capacity, write_capacity, options)
115
- sleep 0.5 while table.status == :creating
116
- return table
117
- end
118
-
119
- # Removes an item from DynamoDB.
120
- #
121
- # @param [String] table_name the name of the table
122
- # @param [String] key the hash key of the item to delete
123
- # @param [Number] range_key the range key of the item to delete, required if the table has a composite key
124
- #
125
- # @since 0.2.0
126
- def delete_item(table_name, key, options = {})
127
- range_key = options.delete(:range_key)
128
- table = get_table(table_name)
129
- result = table.items.at(key, range_key)
130
- result.delete unless result.attributes.to_h.empty?
131
- true
132
- end
133
-
134
- # Deletes an entire table from DynamoDB. Only 10 tables can be in the deleting state at once,
135
- # so if you have more this method may raise an exception.
136
- #
137
- # @param [String] table_name the name of the table to destroy
138
- #
139
- # @since 0.2.0
140
- def delete_table(table_name)
141
- Dynamoid.logger.info "Deleting #{table_name} table. This could take a while."
142
- table = @@connection.tables[table_name]
143
- table.delete
144
- sleep 0.5 while table.exists? == true
145
- end
146
-
147
- # @todo Add a DescribeTable method.
148
-
149
- # Fetches an item from DynamoDB.
150
- #
151
- # @param [String] table_name the name of the table
152
- # @param [String] key the hash key of the item to find
153
- # @param [Number] range_key the range key of the item to find, required if the table has a composite key
154
- #
155
- # @return [Hash] a hash representing the raw item in DynamoDB
156
- #
157
- # @since 0.2.0
158
- def get_item(table_name, key, options = {})
159
- range_key = options.delete(:range_key)
160
- table = get_table(table_name)
161
-
162
- result = table.items.at(key, range_key).attributes.to_h(options)
163
-
164
- if result.empty?
165
- nil
166
- else
167
- result.symbolize_keys!
168
- end
169
- end
170
-
171
- def update_item(table_name, key, options = {}, &block)
172
- range_key = options.delete(:range_key)
173
- conditions = options.delete(:conditions) || {}
174
- table = get_table(table_name)
175
- item = table.items.at(key, range_key)
176
- item.attributes.update(conditions.merge(:return => :all_new), &block)
177
- rescue AWS::DynamoDB::Errors::ConditionalCheckFailedException
178
- raise Dynamoid::Errors::ConditionalCheckFailedException
179
- end
180
-
181
- # List all tables on DynamoDB.
182
- #
183
- # @since 0.2.0
184
- def list_tables
185
- @@connection.tables.collect(&:name)
186
- end
187
-
188
- # Persists an item on DynamoDB.
189
- #
190
- # @param [String] table_name the name of the table
191
- # @param [Object] object a hash or Dynamoid object to persist
192
- #
193
- # @since 0.2.0
194
- def put_item(table_name, object, options = nil)
195
- table = get_table(table_name)
196
- table.items.create(
197
- object.delete_if{|k, v| v.nil? || (v.respond_to?(:empty?) && v.empty?)},
198
- options || {}
199
- )
200
- rescue AWS::DynamoDB::Errors::ConditionalCheckFailedException => e
201
- raise Dynamoid::Errors::ConditionalCheckFailedException
202
- end
203
-
204
- # Query the DynamoDB table. This employs DynamoDB's indexes so is generally faster than scanning, but is
205
- # only really useful for range queries, since it can only find by one hash key at once. Only provide
206
- # one range key to the hash.
207
- #
208
- # @param [String] table_name the name of the table
209
- # @param [Hash] opts the options to query the table with
210
- # @option opts [String] :hash_value the value of the hash key to find
211
- # @option opts [Range] :range_value find the range key within this range
212
- # @option opts [Number] :range_greater_than find range keys greater than this
213
- # @option opts [Number] :range_less_than find range keys less than this
214
- # @option opts [Number] :range_gte find range keys greater than or equal to this
215
- # @option opts [Number] :range_lte find range keys less than or equal to this
216
- #
217
- # @return [Enumerator] an iterator of all matching items
218
- #
219
- # @since 0.2.0
220
- def query(table_name, opts = {})
221
- table = get_table(table_name)
222
-
223
- Enumerator.new do |yielder|
224
- consistent_opts = { :consistent_read => opts[:consistent_read] || false }
225
- if table.composite_key?
226
- table.items.query(opts).each do |data|
227
- if opts.has_key? :select
228
- yielder.yield data.attributes.symbolize_keys!
229
- else
230
- yielder.yield data.attributes.to_h(consistent_opts).symbolize_keys!
231
- end
232
- end
233
- else
234
- yielder.yield get_item(table_name, opts[:hash_value])
235
- end
236
- end
237
- end
238
-
239
- # Scan the DynamoDB table. This is usually a very slow operation as it naively filters all data on
240
- # the DynamoDB servers.
241
- #
242
- # @param [String] table_name the name of the table
243
- # @param [Hash] scan_hash a hash of attributes: matching records will be returned by the scan
244
- #
245
- # @return [Enumerator] an iterator of all matching items
246
- #
247
- # @since 0.2.0
248
- def scan(table_name, scan_hash, select_opts)
249
- table = get_table(table_name)
250
- Enumerator.new do |yielder|
251
- table.items.where(scan_hash).select(select_opts).each do |data|
252
- yielder.yield data.attributes.symbolize_keys!
253
- end
254
- end
255
- end
256
-
257
- # @todo Add an UpdateItem method.
258
-
259
- # @todo Add an UpdateTable method.
260
-
261
- def get_table(table_name)
262
- unless table = table_cache[table_name]
263
- table = @@connection.tables[table_name]
264
- table.load_schema
265
- table_cache[table_name] = table
266
- end
267
- table
268
- end
269
-
270
- def table_cache
271
- @table_cache ||= {}
272
- end
273
-
274
- # Number of items from a table
275
- #
276
- # @param [String] table_name the name of the table
277
- #
278
- # @return [Integer] the number of items from a table
279
- #
280
- # @since 0.6.1
281
- def count(table_name)
282
- table = get_table(table_name)
283
- table.items.count
284
- end
285
- end
286
- end
287
- end
@@ -1,69 +0,0 @@
1
- # encoding: utf-8
2
- require 'dynamoid/indexes/index'
3
-
4
- module Dynamoid #:nodoc:
5
-
6
- # Indexes are quick ways of performing queries by anything other than id in DynamoDB. They are denormalized tables;
7
- # that is, data is duplicated in the initial table (where the object is saved) and the index table (where
8
- # we perform indexing).
9
- module Indexes
10
- extend ActiveSupport::Concern
11
-
12
- # Make some helpful attributes to persist indexes.
13
- included do
14
- class_attribute :indexes
15
-
16
- self.indexes = {}
17
- end
18
-
19
- module ClassMethods
20
-
21
- # The call to create an index. Generates a new index with the specified options -- for more information, see Dynamoid::Indexes::Index.
22
- # This function also attempts to immediately create the indexing table if it does not exist already.
23
- #
24
- # @since 0.2.0
25
- def index(name, options = {})
26
- index = Dynamoid::Indexes::Index.new(self, name, options)
27
- self.indexes[index.name] = index
28
- create_indexes
29
- end
30
-
31
- # Helper function to find indexes.
32
- #
33
- # @since 0.2.0
34
- def find_index(index)
35
- self.indexes[Array(index).collect(&:to_s).sort.collect(&:to_sym)]
36
- end
37
-
38
- # Helper function to create indexes (if they don't exist already).
39
- #
40
- # @since 0.2.0
41
- def create_indexes
42
- self.indexes.each do |name, index|
43
- opts = {:table_name => index.table_name, :id => :id}
44
- opts[:range_key] = { :range => :number } if index.range_key?
45
- self.create_table(opts)
46
- end
47
- end
48
- end
49
-
50
- # Callback for an object to save itself to each of a class' indexes.
51
- #
52
- # @since 0.2.0
53
- def save_indexes
54
- self.class.indexes.each do |name, index|
55
- index.save(self)
56
- end
57
- end
58
-
59
- # Callback for an object to delete itself from each of a class' indexes.
60
- #
61
- # @since 0.2.0
62
- def delete_indexes
63
- self.class.indexes.each do |name, index|
64
- index.delete(self)
65
- end
66
- end
67
- end
68
-
69
- end