dynamoid 0.7.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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