dynamoid 0.2.0 → 0.3.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 (97) hide show
  1. data/Dynamoid.gemspec +65 -3
  2. data/Gemfile +3 -0
  3. data/Gemfile.lock +6 -0
  4. data/README.markdown +117 -22
  5. data/Rakefile +22 -9
  6. data/VERSION +1 -1
  7. data/doc/.nojekyll +0 -0
  8. data/doc/Dynamoid.html +300 -0
  9. data/doc/Dynamoid/Adapter.html +1387 -0
  10. data/doc/Dynamoid/Adapter/AwsSdk.html +1561 -0
  11. data/doc/Dynamoid/Adapter/Local.html +1487 -0
  12. data/doc/Dynamoid/Associations.html +131 -0
  13. data/doc/Dynamoid/Associations/Association.html +1706 -0
  14. data/doc/Dynamoid/Associations/BelongsTo.html +339 -0
  15. data/doc/Dynamoid/Associations/ClassMethods.html +723 -0
  16. data/doc/Dynamoid/Associations/HasAndBelongsToMany.html +339 -0
  17. data/doc/Dynamoid/Associations/HasMany.html +339 -0
  18. data/doc/Dynamoid/Associations/HasOne.html +339 -0
  19. data/doc/Dynamoid/Components.html +202 -0
  20. data/doc/Dynamoid/Config.html +395 -0
  21. data/doc/Dynamoid/Config/Options.html +609 -0
  22. data/doc/Dynamoid/Criteria.html +131 -0
  23. data/doc/Dynamoid/Criteria/Chain.html +759 -0
  24. data/doc/Dynamoid/Criteria/ClassMethods.html +98 -0
  25. data/doc/Dynamoid/Document.html +512 -0
  26. data/doc/Dynamoid/Document/ClassMethods.html +581 -0
  27. data/doc/Dynamoid/Errors.html +118 -0
  28. data/doc/Dynamoid/Errors/DocumentNotValid.html +210 -0
  29. data/doc/Dynamoid/Errors/Error.html +130 -0
  30. data/doc/Dynamoid/Errors/InvalidField.html +133 -0
  31. data/doc/Dynamoid/Errors/MissingRangeKey.html +133 -0
  32. data/doc/Dynamoid/Fields.html +649 -0
  33. data/doc/Dynamoid/Fields/ClassMethods.html +264 -0
  34. data/doc/Dynamoid/Finders.html +128 -0
  35. data/doc/Dynamoid/Finders/ClassMethods.html +502 -0
  36. data/doc/Dynamoid/Indexes.html +308 -0
  37. data/doc/Dynamoid/Indexes/ClassMethods.html +351 -0
  38. data/doc/Dynamoid/Indexes/Index.html +1089 -0
  39. data/doc/Dynamoid/Persistence.html +653 -0
  40. data/doc/Dynamoid/Persistence/ClassMethods.html +568 -0
  41. data/doc/Dynamoid/Validations.html +399 -0
  42. data/doc/_index.html +439 -0
  43. data/doc/class_list.html +47 -0
  44. data/doc/css/common.css +1 -0
  45. data/doc/css/full_list.css +55 -0
  46. data/doc/css/style.css +322 -0
  47. data/doc/file.LICENSE.html +66 -0
  48. data/doc/file.README.html +279 -0
  49. data/doc/file_list.html +52 -0
  50. data/doc/frames.html +13 -0
  51. data/doc/index.html +279 -0
  52. data/doc/js/app.js +205 -0
  53. data/doc/js/full_list.js +173 -0
  54. data/doc/js/jquery.js +16 -0
  55. data/doc/method_list.html +1054 -0
  56. data/doc/top-level-namespace.html +105 -0
  57. data/lib/dynamoid.rb +2 -1
  58. data/lib/dynamoid/adapter.rb +77 -6
  59. data/lib/dynamoid/adapter/aws_sdk.rb +96 -16
  60. data/lib/dynamoid/adapter/local.rb +84 -15
  61. data/lib/dynamoid/associations.rb +53 -4
  62. data/lib/dynamoid/associations/association.rb +154 -26
  63. data/lib/dynamoid/associations/belongs_to.rb +32 -6
  64. data/lib/dynamoid/associations/has_and_belongs_to_many.rb +29 -3
  65. data/lib/dynamoid/associations/has_many.rb +30 -4
  66. data/lib/dynamoid/associations/has_one.rb +26 -3
  67. data/lib/dynamoid/components.rb +7 -5
  68. data/lib/dynamoid/config.rb +15 -2
  69. data/lib/dynamoid/config/options.rb +8 -0
  70. data/lib/dynamoid/criteria.rb +7 -2
  71. data/lib/dynamoid/criteria/chain.rb +55 -8
  72. data/lib/dynamoid/document.rb +68 -7
  73. data/lib/dynamoid/errors.rb +17 -2
  74. data/lib/dynamoid/fields.rb +44 -1
  75. data/lib/dynamoid/finders.rb +32 -6
  76. data/lib/dynamoid/indexes.rb +22 -2
  77. data/lib/dynamoid/indexes/index.rb +48 -7
  78. data/lib/dynamoid/persistence.rb +111 -51
  79. data/lib/dynamoid/validations.rb +36 -0
  80. data/spec/app/models/address.rb +2 -1
  81. data/spec/app/models/camel_case.rb +11 -0
  82. data/spec/app/models/magazine.rb +4 -1
  83. data/spec/app/models/sponsor.rb +3 -1
  84. data/spec/app/models/subscription.rb +5 -1
  85. data/spec/app/models/user.rb +10 -1
  86. data/spec/dynamoid/associations/association_spec.rb +67 -1
  87. data/spec/dynamoid/associations/belongs_to_spec.rb +16 -1
  88. data/spec/dynamoid/associations/has_and_belongs_to_many_spec.rb +7 -0
  89. data/spec/dynamoid/associations/has_many_spec.rb +14 -0
  90. data/spec/dynamoid/associations/has_one_spec.rb +10 -1
  91. data/spec/dynamoid/criteria_spec.rb +5 -1
  92. data/spec/dynamoid/document_spec.rb +23 -3
  93. data/spec/dynamoid/fields_spec.rb +10 -1
  94. data/spec/dynamoid/indexes/index_spec.rb +19 -0
  95. data/spec/dynamoid/persistence_spec.rb +24 -0
  96. data/spec/dynamoid/validations_spec.rb +36 -0
  97. metadata +105 -4
@@ -0,0 +1,105 @@
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.7.5
10
+
11
+ </title>
12
+
13
+ <link rel="stylesheet" href="css/style.css" type="text/css" media="screen" charset="utf-8" />
14
+
15
+ <link rel="stylesheet" href="css/common.css" type="text/css" media="screen" charset="utf-8" />
16
+
17
+ <script type="text/javascript" charset="utf-8">
18
+ relpath = '';
19
+ if (relpath != '') relpath += '/';
20
+ </script>
21
+
22
+ <script type="text/javascript" charset="utf-8" src="js/jquery.js"></script>
23
+
24
+ <script type="text/javascript" charset="utf-8" src="js/app.js"></script>
25
+
26
+
27
+ </head>
28
+ <body>
29
+ <script type="text/javascript" charset="utf-8">
30
+ if (window.top.frames.main) document.body.className = 'frames';
31
+ </script>
32
+
33
+ <div id="header">
34
+ <div id="menu">
35
+
36
+ <a href="_index.html">Index</a> &raquo;
37
+
38
+
39
+ <span class="title">Top Level Namespace</span>
40
+
41
+
42
+ <div class="noframes"><span class="title">(</span><a href="." target="_top">no frames</a><span class="title">)</span></div>
43
+ </div>
44
+
45
+ <div id="search">
46
+
47
+ <a id="class_list_link" href="#">Class List</a>
48
+
49
+ <a id="method_list_link" href="#">Method List</a>
50
+
51
+ <a id="file_list_link" href="#">File List</a>
52
+
53
+ </div>
54
+ <div class="clear"></div>
55
+ </div>
56
+
57
+ <iframe id="search_frame"></iframe>
58
+
59
+ <div id="content"><h1>Top Level Namespace
60
+
61
+
62
+
63
+ </h1>
64
+
65
+ <dl class="box">
66
+
67
+
68
+
69
+
70
+
71
+
72
+
73
+
74
+ </dl>
75
+ <div class="clear"></div>
76
+
77
+ <h2>Defined Under Namespace</h2>
78
+ <p class="children">
79
+
80
+
81
+ <strong class="modules">Modules:</strong> <span class='object_link'><a href="Dynamoid.html" title="Dynamoid (module)">Dynamoid</a></span>
82
+
83
+
84
+
85
+
86
+ </p>
87
+
88
+
89
+
90
+
91
+
92
+
93
+
94
+
95
+
96
+ </div>
97
+
98
+ <div id="footer">
99
+ Generated on Tue Mar 27 17:53:07 2012 by
100
+ <a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
101
+ 0.7.5 (ruby-1.9.3).
102
+ </div>
103
+
104
+ </body>
105
+ </html>
data/lib/dynamoid.rb CHANGED
@@ -13,6 +13,7 @@ require 'dynamoid/fields'
13
13
  require 'dynamoid/indexes'
14
14
  require 'dynamoid/associations'
15
15
  require 'dynamoid/persistence'
16
+ require 'dynamoid/validations'
16
17
  require 'dynamoid/criteria'
17
18
  require 'dynamoid/finders'
18
19
  require 'dynamoid/config'
@@ -37,4 +38,4 @@ module Dynamoid
37
38
  @included_models ||= []
38
39
  end
39
40
 
40
- end
41
+ end
@@ -1,15 +1,23 @@
1
1
  # encoding: utf-8
2
- module Dynamoid #:nodoc:
2
+ module Dynamoid
3
3
 
4
+ # Adapter provides a generic, write-through class that abstracts variations in the underlying connections to provide a uniform response
5
+ # to Dynamoid.
4
6
  module Adapter
5
7
  extend self
6
8
  attr_accessor :tables
7
9
 
10
+ # The actual adapter currently in use: presently, either AwsSdk or Local.
11
+ #
12
+ # @since 0.2.0
8
13
  def adapter
9
14
  reconnect! unless @adapter
10
15
  @adapter
11
16
  end
12
17
 
18
+ # Establishes a connection to the underyling adapter and caches all its tables for speedier future lookups. Issued when the adapter is first called.
19
+ #
20
+ # @since 0.2.0
13
21
  def reconnect!
14
22
  require "dynamoid/adapter/#{Dynamoid::Config.adapter}" unless Dynamoid::Adapter.const_defined?(Dynamoid::Config.adapter.camelcase)
15
23
  @adapter = Dynamoid::Adapter.const_get(Dynamoid::Config.adapter.camelcase)
@@ -17,6 +25,15 @@ module Dynamoid #:nodoc:
17
25
  self.tables = benchmark('Cache Tables') {list_tables}
18
26
  end
19
27
 
28
+ # Shows how long it takes a method to run on the adapter. Useful for generating logged output.
29
+ #
30
+ # @param [Symbol] method the name of the method to appear in the log
31
+ # @param [Array] args the arguments to the method to appear in the log
32
+ # @yield the actual code to benchmark
33
+ #
34
+ # @return the result of the yield
35
+ #
36
+ # @since 0.2.0
20
37
  def benchmark(method, *args)
21
38
  start = Time.now
22
39
  result = yield
@@ -24,6 +41,14 @@ module Dynamoid #:nodoc:
24
41
  return result
25
42
  end
26
43
 
44
+ # Write an object to the adapter. Partition it to a randomly selected key first if necessary.
45
+ #
46
+ # @param [String] table the name of the table to write the object to
47
+ # @param [Object] object the object itself
48
+ #
49
+ # @return [Object] the persisted object
50
+ #
51
+ # @since 0.2.0
27
52
  def write(table, object)
28
53
  if Dynamoid::Config.partitioning? && object[:id]
29
54
  object[:id] = "#{object[:id]}.#{Random.rand(Dynamoid::Config.partition_size)}"
@@ -32,6 +57,16 @@ module Dynamoid #:nodoc:
32
57
  benchmark('Put Item', object) {put_item(table, object)}
33
58
  end
34
59
 
60
+ # Read one or many keys from the selected table. This method intelligently calls batch_get or get on the underlying adapter depending on
61
+ # whether ids is a range or a single key: additionally, if partitioning is enabled, it batch_gets all keys in the partition space
62
+ # automatically. Finally, if a range key is present, it will also interpolate that into the ids so that the batch get will acquire the
63
+ # correct record.
64
+ #
65
+ # @param [String] table the name of the table to write the object to
66
+ # @param [Array] ids to fetch, can also be a string of just one id
67
+ # @param [Number] range_key the range key of the record
68
+ #
69
+ # @since 0.2.0
35
70
  def read(table, ids, range_key = nil)
36
71
  if ids.respond_to?(:each)
37
72
  ids = ids.collect{|id| range_key ? [id, range_key] : id}
@@ -52,16 +87,29 @@ module Dynamoid #:nodoc:
52
87
  end
53
88
  end
54
89
 
55
- def delete(table, id)
90
+ # Delete an item from a table. If partitioning is turned on, deletes all partitioned keys as well.
91
+ #
92
+ # @param [String] table the name of the table to write the object to
93
+ # @param [String] id the id of the record
94
+ # @param [Number] range_key the range key of the record
95
+ #
96
+ # @since 0.2.0
97
+ def delete(table, id, range_key = nil)
56
98
  if Dynamoid::Config.partitioning?
57
99
  benchmark('Delete Item', id) do
58
- id_with_partitions(id).each {|i| delete_item(table, i)}
100
+ id_with_partitions(id).each {|i| delete_item(table, i, range_key)}
59
101
  end
60
102
  else
61
- benchmark('Delete Item', id) {delete_item(table, id)}
103
+ benchmark('Delete Item', id) {delete_item(table, id, range_key)}
62
104
  end
63
105
  end
64
106
 
107
+ # Scans a table. Generally quite slow; try to avoid using scan if at all possible.
108
+ #
109
+ # @param [String] table the name of the table to write the object to
110
+ # @param [Hash] scan_hash a hash of attributes: matching records will be returned by the scan
111
+ #
112
+ # @since 0.2.0
65
113
  def scan(table, query)
66
114
  if Dynamoid::Config.partitioning?
67
115
  results = benchmark('Scan', table, query) {adapter.scan(table, query)}
@@ -72,17 +120,37 @@ module Dynamoid #:nodoc:
72
120
  end
73
121
 
74
122
  [:batch_get_item, :create_table, :delete_item, :delete_table, :get_item, :list_tables, :put_item].each do |m|
123
+ # Method delegation with benchmark to the underlying adapter. Faster than relying on method_missing.
124
+ #
125
+ # @since 0.2.0
75
126
  define_method(m) do |*args|
76
127
  benchmark("#{m.to_s}", args) {adapter.send(m, *args)}
77
128
  end
78
129
  end
79
130
 
131
+ # Takes a list of ids and returns them with partitioning added. If an array of arrays is passed, we assume the second key is the range key
132
+ # and pass it in unchanged.
133
+ #
134
+ # @example Partition id 1
135
+ # Dynamoid::Adapter.id_with_partitions(['1']) # ['1.0', '1.1', '1.2', ..., '1.199']
136
+ # @example Partition id 1 and range_key 1.0
137
+ # Dynamoid::Adapter.id_with_partitions([['1', 1.0]]) # [['1.0', 1.0], ['1.1', 1.0], ['1.2', 1.0], ..., ['1.199', 1.0]]
138
+ #
139
+ # @param [Array] ids array of ids to partition
140
+ #
141
+ # @since 0.2.0
80
142
  def id_with_partitions(ids)
81
143
  Array(ids).collect {|id| (0...Dynamoid::Config.partition_size).collect{|n| id.is_a?(Array) ? ["#{id.first}.#{n}", id.last] : "#{id}.#{n}"}}.flatten(1)
82
144
  end
83
145
 
146
+ # Takes an array of results that are partitioned, find the most recently updated one, and return only it. Compares each result by
147
+ # their id and updated_at attributes; if the updated_at is the greatest, then it must be the correct result.
148
+ #
149
+ # @param [Array] returned partitioned results from a query
150
+ #
151
+ # @since 0.2.0
84
152
  def result_for_partition(results)
85
- Hash.new.tap do |hash|
153
+ {}.tap do |hash|
86
154
  Array(results).each do |result|
87
155
  next if result.nil?
88
156
  id = result[:id].split('.').first
@@ -94,6 +162,9 @@ module Dynamoid #:nodoc:
94
162
  end.values
95
163
  end
96
164
 
165
+ # Delegate all methods that aren't defind here to the underlying adapter.
166
+ #
167
+ # @since 0.2.0
97
168
  def method_missing(method, *args)
98
169
  return benchmark(method, *args) {adapter.send(method, *args)} if @adapter.respond_to?(method)
99
170
  super
@@ -101,4 +172,4 @@ module Dynamoid #:nodoc:
101
172
 
102
173
  end
103
174
 
104
- end
175
+ end
@@ -1,20 +1,45 @@
1
+ # encoding: utf-8
1
2
  require 'aws'
2
3
 
3
4
  module Dynamoid
4
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
+ #
5
11
  module AwsSdk
6
12
  extend self
7
13
  @@connection = nil
8
14
 
15
+ # Establish the connection to DynamoDB.
16
+ #
17
+ # @return [AWS::DynamoDB::Connection] the raw DynamoDB connection
18
+ #
19
+ # @since 0.2.0
9
20
  def connect!
10
21
  @@connection = AWS::DynamoDB.new(:access_key_id => Dynamoid::Config.access_key, :secret_access_key => Dynamoid::Config.secret_key)
11
22
  end
12
23
 
24
+ # Return the established connection.
25
+ #
26
+ # @return [AWS::DynamoDB::Connection] the raw DynamoDB connection
27
+ #
28
+ # @since 0.2.0
13
29
  def connection
14
30
  @@connection
15
31
  end
16
32
 
17
- # BatchGetItem
33
+ # Get many items at once from DynamoDB. More efficient than getting each item individually.
34
+ #
35
+ # @example Retrieve IDs 1 and 2 from the table testtable
36
+ # Dynamoid::Adapter::AwsSdk.batch_get_item('table1' => ['1', '2'])
37
+ #
38
+ # @param [Hash] options the hash of tables and IDs to retrieve
39
+ #
40
+ # @return [Hash] a hash where keys are the table names and the values are the retrieved items
41
+ #
42
+ # @since 0.2.0
18
43
  def batch_get_item(options)
19
44
  hash = Hash.new{|h, k| h[k] = []}
20
45
  return hash if options.all?{|k, v| v.empty?}
@@ -30,16 +55,30 @@ module Dynamoid
30
55
  hash
31
56
  end
32
57
 
33
- # CreateTable
58
+ # Create a table on DynamoDB. This usually takes a long time to complete.
59
+ #
60
+ # @param [String] table_name the name of the table to create
61
+ # @param [Symbol] key the table's primary key (defaults to :id)
62
+ # @param [Hash] options provide a range_key here if you want one for the table
63
+ #
64
+ # @since 0.2.0
34
65
  def create_table(table_name, key = :id, options = {})
35
66
  options[:hash_key] ||= {key.to_sym => :string}
36
67
  options[:range_key] = {options[:range_key].to_sym => :number} if options[:range_key]
37
- table = @@connection.tables.create(table_name, 100, 20, options)
68
+ read_capacity = options[:read_capacity] || Dynamoid::Config.read_capacity
69
+ write_capacity = options[:write_capacity] || Dynamoid::Config.write_capacity
70
+ table = @@connection.tables.create(table_name, read_capacity, write_capacity, options)
38
71
  sleep 0.5 while table.status == :creating
39
72
  return table
40
73
  end
41
74
 
42
- # DeleteItem
75
+ # Removes an item from DynamoDB.
76
+ #
77
+ # @param [String] table_name the name of the table
78
+ # @param [String] key the hash key of the item to delete
79
+ # @param [Number] range_key the range key of the item to delete, required if the table has a composite key
80
+ #
81
+ # @since 0.2.0
43
82
  def delete_item(table_name, key, range_key = nil)
44
83
  table = @@connection.tables[table_name]
45
84
  table.load_schema
@@ -52,14 +91,27 @@ module Dynamoid
52
91
  true
53
92
  end
54
93
 
55
- # DeleteTable
94
+ # Deletes an entire table from DynamoDB. Only 10 tables can be in the deleting state at once,
95
+ # so if you have more this method may raise an exception.
96
+ #
97
+ # @param [String] table_name the name of the table to destroy
98
+ #
99
+ # @since 0.2.0
56
100
  def delete_table(table_name)
57
101
  @@connection.tables[table_name].delete
58
102
  end
59
103
 
60
- # DescribeTable
104
+ # @todo Add a DescribeTable method.
61
105
 
62
- # GetItem
106
+ # Fetches an item from DynamoDB.
107
+ #
108
+ # @param [String] table_name the name of the table
109
+ # @param [String] key the hash key of the item to find
110
+ # @param [Number] range_key the range key of the item to find, required if the table has a composite key
111
+ #
112
+ # @return [Hash] a hash representing the raw item in DynamoDB
113
+ #
114
+ # @since 0.2.0
63
115
  def get_item(table_name, key, range_key = nil)
64
116
  table = @@connection.tables[table_name]
65
117
  table.load_schema
@@ -73,23 +125,43 @@ module Dynamoid
73
125
  else
74
126
  result.symbolize_keys!
75
127
  end
76
- rescue
77
- raise [table_name, key, range_key].inspect
78
128
  end
79
129
 
80
- # ListTables
130
+ # List all tables on DynamoDB.
131
+ #
132
+ # @since 0.2.0
81
133
  def list_tables
82
134
  @@connection.tables.collect(&:name)
83
135
  end
84
136
 
85
- # PutItem
137
+ # Persists an item on DynamoDB.
138
+ #
139
+ # @param [String] table_name the name of the table
140
+ # @param [Object] object a hash or Dynamoid object to persist
141
+ #
142
+ # @since 0.2.0
86
143
  def put_item(table_name, object)
87
144
  table = @@connection.tables[table_name]
88
145
  table.load_schema
89
146
  table.items.create(object.delete_if{|k, v| v.nil? || (v.respond_to?(:empty?) && v.empty?)})
90
147
  end
91
148
 
92
- # Query
149
+ # Query the DynamoDB table. This employs DynamoDB's indexes so is generally faster than scanning, but is
150
+ # only really useful for range queries, since it can only find by one hash key at once. Only provide
151
+ # one range key to the hash.
152
+ #
153
+ # @param [String] table_name the name of the table
154
+ # @param [Hash] opts the options to query the table with
155
+ # @option opts [String] :hash_value the value of the hash key to find
156
+ # @option opts [Range] :range_value find the range key within this range
157
+ # @option opts [Number] :range_greater_than find range keys greater than this
158
+ # @option opts [Number] :range_less_than find range keys less than this
159
+ # @option opts [Number] :range_gte find range keys greater than or equal to this
160
+ # @option opts [Number] :range_lte find range keys less than or equal to this
161
+ #
162
+ # @return [Array] an array of all matching items
163
+ #
164
+ # @since 0.2.0
93
165
  def query(table_name, opts = {})
94
166
  table = @@connection.tables[table_name]
95
167
  table.load_schema
@@ -103,7 +175,15 @@ module Dynamoid
103
175
  end
104
176
  end
105
177
 
106
- # Scan
178
+ # Scan the DynamoDB table. This is usually a very slow operation as it naively filters all data on
179
+ # the DynamoDB servers.
180
+ #
181
+ # @param [String] table_name the name of the table
182
+ # @param [Hash] scan_hash a hash of attributes: matching records will be returned by the scan
183
+ #
184
+ # @return [Array] an array of all matching items
185
+ #
186
+ # @since 0.2.0
107
187
  def scan(table_name, scan_hash)
108
188
  table = @@connection.tables[table_name]
109
189
  table.load_schema
@@ -114,9 +194,9 @@ module Dynamoid
114
194
  results
115
195
  end
116
196
 
117
- # UpdateItem
197
+ # @todo Add an UpdateItem method.
118
198
 
119
- # UpdateTable
199
+ # @todo Add an UpdateTable method.
120
200
  end
121
201
  end
122
- end
202
+ end