toy-dynamo 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2c505b06ca1b99d16eb355a403fa7dcc40b9653a
4
- data.tar.gz: 010db3bf334c8759fc922cd5801b235b76cf3f05
3
+ metadata.gz: 342640e00f6ef382f4ad50e46015753ca5ac034f
4
+ data.tar.gz: 27ae95e381c9ca143507c0969edde91f9c9b51ee
5
5
  SHA512:
6
- metadata.gz: 7c76caefca0f5ecb58c5230afa9940b9e8efbc1c3c840d788f04296c4a40afdb064c3fd843a8dab837fedf3a4e7b0f4c89359ac4615a9139f791ef65afae947a
7
- data.tar.gz: 1a48d0ef0c3efd90e26bb154850500ca462bc229b2fb6328522d2a5a453970e1400ce67a7f8cd3b632b875e04560d1e65cb99c6bce072c29d813b8ca9a4ad015
6
+ metadata.gz: 5b7857e1165a65db0c8e0b61e12539eac7106cc9acdb34637b558abd652f1632161b8c1e676f6234e090d659b7d4ba3eeecede3d82ea286260ff868a32b86b70
7
+ data.tar.gz: 372cb2202e35588fad3aa8ed830dce5a12b654880f27e143d3cf782816b4e321a6cb77db960b571be54eb82640d23c4a42b2c0e3581c2807c0aa2b539faa4e2d
data/README.md CHANGED
@@ -1,3 +1,10 @@
1
+ ## Overview
2
+ toy-dynamo is an ORM for AWS DynamoDB. It is an extension to [toystore](https://github.com/jnunemaker/toystore) that provides an ActiveModel based ORM for schema-less type data stores.
3
+
4
+ > **Toy::Object** comes with all the goods you need for plain old ruby objects -- attributes, dirty attribute tracking, equality, inheritance, serialization, cloning, logging and pretty inspecting.
5
+
6
+ > **Toy::Store** includes Toy::Object and adds identity, persistence and querying through adapters, mass assignment, callbacks, validations and a few simple associations (lists and references).
7
+
1
8
  ## Install
2
9
  * toystore gem
3
10
  * originally [https://github.com/jnunemaker/toystore](https://github.com/jnunemaker/toystore)
@@ -8,12 +15,29 @@
8
15
  In ActiveModel model:
9
16
 
10
17
  ```
11
- dynamo_table do
12
- adapter :dynamo, AWS::DynamoDB::ClientV2.new, {:model => self}
13
- hash_key :thread_guid
18
+ class Comment
19
+
20
+ include Toy::Dynamo
21
+
22
+ adapter :dynamo, Toy::Dynamo::Adapter.default_client, {:model => self}
23
+
24
+ dynamo_table do
25
+ hash_key :thread_guid
26
+ range_key :comment_guid
27
+ local_secondary_index :posted_by
28
+ read_provision 50
29
+ write_provision 10
30
+ end
31
+
32
+ attribute :thread_guid, String
33
+ attribute :comment_guid, String, :default => lambda { SimpleUUID::UUID.new.to_guid }
34
+ attribute :body, String
35
+ attribute :posted_by, String
36
+
14
37
  end
15
38
  ```
16
- * **Other options:**
39
+ * **Other options for 'dynamo_table' config:**
40
+ * hash_key :comment_id
17
41
  * range_key :comment_id
18
42
  * table_name "user_dynamo_table"
19
43
  * read_provision 20
@@ -23,8 +47,11 @@ end
23
47
  * :projection => :all
24
48
  * Can also specify an Array of attributes to project besides the primary keys ex:
25
49
  * :projection => [:subject, :commenter_name]
50
+ * **aws-sdk config:**
51
+ * [http://docs.aws.amazon.com/AWSRubySDK/latest/AWS/Core/Configuration.html](http://docs.aws.amazon.com/AWSRubySDK/latest/AWS/Core/Configuration.html)
26
52
 
27
- ## Basic Usage
53
+
54
+ ## Basic Usage (toystore)
28
55
  * **Read Hash Key Only**
29
56
  * Example:
30
57
  * Model.read("xyz")
@@ -68,6 +95,15 @@ end
68
95
  :dynamo_db_endpoint => 'localhost',
69
96
  :dynamo_db_port => 4567
70
97
  }), {:model => self}
98
+ * **Create table**
99
+ * rake ddb:create CLASS=User
100
+ * rake ddb:create CLASS=User TABLE=user-2013-03-14
101
+ * **Delete table**
102
+ * rake ddb:delete CLASS=User
103
+ * rake ddb:delete CLASS=User TABLE=user-2013-03-14
104
+ * **Resize table read/write capacity**
105
+ * rake ddb:resize CLASS=User READ=50 WRITE=10
106
+ * rake ddb:resize CLASS=User # Use values from model dynamo_table read_provision/write_provision
71
107
 
72
108
  ## Compatibility
73
109
  * Tested with
@@ -76,6 +112,7 @@ end
76
112
 
77
113
  ## TODO
78
114
  * raise error if trying to use an attribute that wasn't 'select'ed (defaulting to selecting all attributes which loads everything with an extra read)
79
- * while loop for situation where batch_get_item returns batched results
80
- * error out on mismatch of table schema from dynamo_table schema (changed?)
81
- * allow changes to read write capacity
115
+ * lambdas for table_name (for dynamic table names)
116
+ * string and number sets (mostly for scans)
117
+ * use MAX_ITEM_SIZE (64kb)
118
+
@@ -3,6 +3,21 @@ require 'adapter'
3
3
  module Toy
4
4
  module Dynamo
5
5
  module Adapter
6
+
7
+ def self.default_client(config={})
8
+ options={}
9
+ options[:use_ssl] = Toy::Dynamo::Config.use_ssl
10
+ options[:use_ssl] = config[:use_ssl] if config.has_key?(:use_ssl)
11
+ options[:dynamo_db_endpoint] = config[:endpoint] || Toy::Dynamo::Config.endpoint
12
+ options[:dynamo_db_port] = config[:port] || Toy::Dynamo::Config.port
13
+
14
+ options[:dynamo_db_endpoint] = config[:endpoint] || Toy::Dynamo::Config.endpoint
15
+ options[:dynamo_db_port] = config[:port] || Toy::Dynamo::Config.port
16
+ #:dynamo_db_crc_32_check = false
17
+
18
+ @@default_client ||= AWS::DynamoDB::ClientV2.new(options)
19
+ end
20
+
6
21
  def read(key, options=nil)
7
22
  options ||= {}
8
23
  attrs = nil
@@ -0,0 +1,80 @@
1
+ # Shamelessly stolen from Mongoid (and Dynamoid)!
2
+ module Toy #:nodoc
3
+ module Dynamo #:nodoc
4
+ module Config
5
+
6
+ # Encapsulates logic for setting options.
7
+ module Options
8
+
9
+ # Get the defaults or initialize a new empty hash.
10
+ #
11
+ # @example Get the defaults.
12
+ # options.defaults
13
+ #
14
+ # @return [ Hash ] The default options.
15
+ #
16
+ # @since 0.2.0
17
+ def defaults
18
+ @defaults ||= {}
19
+ end
20
+
21
+ # Define a configuration option with a default.
22
+ #
23
+ # @example Define the option.
24
+ # Options.option(:persist_in_safe_mode, :default => false)
25
+ #
26
+ # @param [ Symbol ] name The name of the configuration option.
27
+ # @param [ Hash ] options Extras for the option.
28
+ #
29
+ # @option options [ Object ] :default The default value.
30
+ #
31
+ # @since 0.2.0
32
+ def option(name, options = {})
33
+ defaults[name] = settings[name] = options[:default]
34
+
35
+ class_eval <<-RUBY
36
+ def #{name}
37
+ settings[#{name.inspect}]
38
+ end
39
+
40
+ def #{name}=(value)
41
+ settings[#{name.inspect}] = value
42
+ end
43
+
44
+ def #{name}?
45
+ #{name}
46
+ end
47
+
48
+ def reset_#{name}
49
+ settings[#{name.inspect}] = defaults[#{name.inspect}]
50
+ end
51
+ RUBY
52
+ end
53
+
54
+ # Reset the configuration options to the defaults.
55
+ #
56
+ # @example Reset the configuration options.
57
+ # config.reset
58
+ #
59
+ # @return [ Hash ] The defaults.
60
+ #
61
+ # @since 0.2.0
62
+ def reset
63
+ settings.replace(defaults)
64
+ end
65
+
66
+ # Get the settings or initialize a new empty hash.
67
+ #
68
+ # @example Get the settings.
69
+ # options.settings
70
+ #
71
+ # @return [ Hash ] The setting options.
72
+ #
73
+ # @since 0.2.0
74
+ def settings
75
+ @settings ||= {}
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,56 @@
1
+ # encoding: utf-8
2
+ require "uri"
3
+ require "toy/dynamo/config/options"
4
+
5
+ # Shamelessly stolen from Dynamoid
6
+ module Toy
7
+ module Dynamo
8
+
9
+ # Contains all the basic configuration information required for Dynamoid: both sensible defaults and required fields.
10
+ module Config
11
+ extend self
12
+ extend Options
13
+
14
+ # All the default options.
15
+ option :logger, :default => defined?(Rails)
16
+ option :read_provision, :default => 50
17
+ option :write_provision, :default => 10
18
+ option :included_models, :default => []
19
+ # TODO - default adapter client based on config
20
+ #option :namespace, :default => defined?(Rails) ? "#{Rails.application.class.parent_name}_#{Rails.env}" : ""
21
+ option :endpoint, :default => 'dynamodb.us-west-2.amazonaws.com'
22
+ option :port, :default => 443
23
+ option :use_ssl, :default => true
24
+ # Use AWS config
25
+ #option :access_key
26
+ #option :secret_key
27
+
28
+ # The default logger for Dynamoid: either the Rails logger or just stdout.
29
+ #
30
+ # @since 0.2.0
31
+ def default_logger
32
+ defined?(Rails) && Rails.respond_to?(:logger) ? Rails.logger : ::Logger.new($stdout)
33
+ end
34
+
35
+ # Returns the assigned logger instance.
36
+ #
37
+ # @since 0.2.0
38
+ def logger
39
+ @logger ||= default_logger
40
+ end
41
+
42
+ # If you want to, set the logger manually to any output you'd like. Or pass false or nil to disable logging entirely.
43
+ #
44
+ # @since 0.2.0
45
+ def logger=(logger)
46
+ case logger
47
+ when false, nil then @logger = nil
48
+ when true then @logger = default_logger
49
+ else
50
+ @logger = logger if logger.respond_to?(:info)
51
+ end
52
+ end
53
+
54
+ end
55
+ end
56
+ end
@@ -4,24 +4,25 @@ module Toy
4
4
  extend ActiveSupport::Concern
5
5
 
6
6
  # Failsafe
7
- MAX_BATCH_ITERATIONS = 100
7
+ MAX_BATCH_ITERATIONS = 1000
8
+ DEFAULT_BATCH_SIZE = 100
8
9
 
9
10
  module ClassMethods
10
11
 
11
12
  # Read results up to the limit
12
- # read_range("1", :range_value => "2", :limit => 10)
13
+ # read_range("1", :range => { :varname.gte => "2"}, :limit => 10)
13
14
  # Loop results in given batch size until limit is hit or no more results
14
- # read_range("1", :range_value => "2", :batch => 10, :limit => 1000)
15
+ # read_range("1", :range => { :varname.eq => "2"}, :batch => 10, :limit => 1000)
15
16
  def read_range(hash_value, options={})
16
17
  raise ArgumentError, "no range_key specified for this table" if dynamo_table.range_keys.blank?
17
18
  aggregated_results = []
18
19
 
19
- if (batch_size = options.delete(:batch))
20
- max_results_limit = options[:limit]
21
- if options[:limit] && options[:limit] > batch_size
22
- options.merge!(:limit => batch_size)
23
- end
20
+ batch_size = options.delete(:batch) || DEFAULT_BATCH_SIZE
21
+ max_results_limit = options[:limit]
22
+ if options[:limit] && options[:limit] > batch_size
23
+ options.merge!(:limit => batch_size)
24
24
  end
25
+
25
26
  results = dynamo_table.query(hash_value, options)
26
27
  response = Response.new(results)
27
28
 
@@ -30,7 +31,7 @@ module Toy
30
31
  aggregated_results << load(attrs[dynamo_table.hash_key[:attribute_name]], attrs)
31
32
  end
32
33
 
33
- if batch_size
34
+ if response.more_results?
34
35
  results_returned = response.count
35
36
  batch_iteration = 0
36
37
  while response.more_results? && batch_iteration < MAX_BATCH_ITERATIONS
@@ -60,7 +60,7 @@ module Toy
60
60
  raise(ArgumentError, "Invalid read provision") unless val.to_i >= 1
61
61
  @dynamo_read_provision = val.to_i
62
62
  else
63
- @dynamo_read_provision || 10
63
+ @dynamo_read_provision || Toy::Dynamo::Config.read_provision
64
64
  end
65
65
  end
66
66
 
@@ -69,7 +69,7 @@ module Toy
69
69
  raise(ArgumentError, "Invalid write provision") unless val.to_i >= 1
70
70
  @dynamo_write_provision = val.to_i
71
71
  else
72
- @dynamo_write_provision || 10
72
+ @dynamo_write_provision || Toy::Dynamo::Config.write_provision
73
73
  end
74
74
  end
75
75
 
@@ -162,24 +162,24 @@ module Toy
162
162
  end
163
163
 
164
164
  def validate_key_schema
165
- if (@dynamo_table.schema_loaded_from_dynamo[:table][:key_schema] != table_schema[:key_schema])
165
+ if (@dynamo_table.schema_loaded_from_dynamo[:table][:key_schema].sort_by { |k| k[:key_type] } != table_schema[:key_schema].sort_by { |k| k[:key_type] })
166
166
  raise ArgumentError, "It appears your key schema (Hash Key/Range Key) have changed from the table definition. Rebuilding the table is necessary."
167
167
  end
168
168
 
169
- if (@dynamo_table.schema_loaded_from_dynamo[:table][:attribute_definitions] != table_schema[:attribute_definitions])
169
+ if (@dynamo_table.schema_loaded_from_dynamo[:table][:attribute_definitions].sort_by { |k| k[:attribute_name] } != table_schema[:attribute_definitions].sort_by { |k| k[:attribute_name] })
170
170
  raise ArgumentError, "It appears your attribute definition (types?) have changed from the table definition. Rebuilding the table is necessary."
171
171
  end
172
172
 
173
- if (@dynamo_table.schema_loaded_from_dynamo[:table][:local_secondary_indexes].dup.collect {|i| i.delete_if{|k, v| [:index_size_bytes, :item_count].include?(k) }; i } != table_schema[:local_secondary_indexes])
173
+ if (@dynamo_table.schema_loaded_from_dynamo[:table][:local_secondary_indexes].dup.collect {|i| i.delete_if{|k, v| [:index_size_bytes, :item_count].include?(k) }; i }.sort_by { |lsi| lsi[:index_name] } != table_schema[:local_secondary_indexes].sort_by { |lsi| lsi[:index_name] })
174
174
  raise ArgumentError, "It appears your local secondary indexes have changed from the table definition. Rebuilding the table is necessary."
175
175
  end
176
176
 
177
177
  if @dynamo_table.schema_loaded_from_dynamo[:table][:provisioned_throughput][:read_capacity_units] != read_provision
178
- puts "read_capacity_units mismatch. Need to update table?"
178
+ Toy::Dynamo::Config.logger.error "read_capacity_units mismatch. Need to update table?"
179
179
  end
180
180
 
181
181
  if @dynamo_table.schema_loaded_from_dynamo[:table][:provisioned_throughput][:write_capacity_units] != write_provision
182
- puts "write_capacity_units mismatch. Need to update table?"
182
+ Toy::Dynamo::Config.logger.error "write_capacity_units mismatch. Need to update table?"
183
183
  end
184
184
  end
185
185
 
@@ -40,7 +40,7 @@ module Toy
40
40
  begin
41
41
  self.load_schema
42
42
  rescue AWS::DynamoDB::Errors::ResourceNotFoundException => e
43
- puts "No table found!"
43
+ Toy::Dynamo::Config.logger.error "No table found!"
44
44
  #self.create
45
45
  #self.load_schema
46
46
  end
@@ -105,7 +105,7 @@ module Toy
105
105
  options[:select] ||= []
106
106
 
107
107
  get_item_request = {
108
- :table_name => options[:table_name] || @table_schema[:table_name],
108
+ :table_name => options[:table_name] || self.table_name,
109
109
  :key => hash_key_item_param(hash_key),
110
110
  :consistent_read => options[:consistent_read],
111
111
  :return_consumed_capacity => RETURNED_CONSUMED_CAPACITY[options[:return_consumed_capacity]]
@@ -133,7 +133,7 @@ module Toy
133
133
  key_conditions.merge!(hash_key_condition_param(hash_key_value))
134
134
 
135
135
  query_request = {
136
- :table_name => options[:table_name] || @table_schema[:table_name],
136
+ :table_name => options[:table_name] || self.table_name,
137
137
  :key_conditions => key_conditions,
138
138
  :consistent_read => options[:consistent_read],
139
139
  :return_consumed_capacity => RETURNED_CONSUMED_CAPACITY[options[:return_consumed_capacity]],
@@ -222,7 +222,7 @@ module Toy
222
222
  request_items_request.merge!( :attributes_to_get => [options[:select]].flatten ) unless options[:select].blank?
223
223
  request_items_request.merge!( :consistent_read => options[:consistent_read] ) if options[:consistent_read]
224
224
  batch_get_item_request = {
225
- :request_items => { (options[:table_name] || @table_schema[:table_name]) => request_items_request },
225
+ :request_items => { (options[:table_name] || self.table_name) => request_items_request },
226
226
  :return_consumed_capacity => RETURNED_CONSUMED_CAPACITY[options[:return_consumed_capacity]]
227
227
  }
228
228
  @client.batch_get_item(batch_get_item_request)
@@ -260,7 +260,7 @@ module Toy
260
260
  })
261
261
  end
262
262
  update_item_request = {
263
- :table_name => options[:table_name] || @table_schema[:table_name],
263
+ :table_name => options[:table_name] || self.table_name,
264
264
  :key => key_request,
265
265
  :attribute_updates => attrs_to_update,
266
266
  :return_consumed_capacity => RETURNED_CONSUMED_CAPACITY[options[:return_consumed_capacity]]
@@ -274,7 +274,7 @@ module Toy
274
274
  end
275
275
  items.merge!(hash_key_item_param(hash_key_value))
276
276
  put_item_request = {
277
- :table_name => options[:table_name] || @table_schema[:table_name],
277
+ :table_name => options[:table_name] || self.table_name,
278
278
  :item => items,
279
279
  :return_consumed_capacity => RETURNED_CONSUMED_CAPACITY[options[:return_consumed_capacity]]
280
280
  }
@@ -298,7 +298,7 @@ module Toy
298
298
  })
299
299
  end
300
300
  delete_item_request = {
301
- :table_name => options[:table_name] || @table_schema[:table_name],
301
+ :table_name => options[:table_name] || self.table_name,
302
302
  :key => key_request
303
303
  }
304
304
  @client.delete_item(delete_item_request)
@@ -324,13 +324,22 @@ module Toy
324
324
  end
325
325
  end
326
326
 
327
+ # Call proc or return string
328
+ def table_name
329
+ if @table_schema[:table_name].respond_to?(:call)
330
+ @table_schema[:table_name].call
331
+ else
332
+ @table_schema[:table_name]
333
+ end
334
+ end
335
+
327
336
  def create(options={})
328
- if @client.list_tables[:table_names].include?(options[:table_name] || @table_schema[:table_name])
329
- raise "Table #{options[:table_name] || @table_schema[:table_name]} already exists!"
337
+ if @client.list_tables[:table_names].include?(options[:table_name] || self.table_name)
338
+ raise "Table #{options[:table_name] || self.table_name} already exists"
330
339
  end
331
340
 
332
341
  @client.create_table(@table_schema.merge({
333
- :table_name => options[:table_name] || @table_schema[:table_name]
342
+ :table_name => options[:table_name] || self.table_name
334
343
  }))
335
344
 
336
345
  while (table_metadata = self.describe(options))[:table][:table_status] == "CREATING"
@@ -340,19 +349,35 @@ module Toy
340
349
  end
341
350
 
342
351
  def describe(options={})
343
- @client.describe_table(:table_name => options[:table_name] || @table_schema[:table_name])
352
+ @client.describe_table(:table_name => options[:table_name] || self.table_name)
344
353
  end
345
354
 
346
355
  def delete(options={})
347
- return false unless @client.list_tables[:table_names].include?(options[:table_name] || @table_schema[:table_name])
348
- @client.delete_table(:table_name => options[:table_name] || @table_schema[:table_name])
356
+ return false unless @client.list_tables[:table_names].include?(options[:table_name] || self.table_name)
357
+ @client.delete_table(:table_name => options[:table_name] || self.table_name)
349
358
  begin
350
359
  while (table_metadata = self.describe) && table_metadata[:table][:table_status] == "DELETING"
351
360
  sleep 1
352
361
  end
353
362
  rescue AWS::DynamoDB::Errors::ResourceNotFoundException => e
354
- puts "Table deleted!"
363
+ Toy::Dynamo::Config.logger.info "Table deleted"
364
+ end
365
+ true
366
+ end
367
+
368
+ def resize(options={})
369
+ return false unless @client.list_tables[:table_names].include?(options[:table_name] || self.table_name)
370
+ @client.update_table({
371
+ :provisioned_throughput => {
372
+ :read_capacity_units => (options[:read_capacity_units] || @table_schema[:provisioned_throughput][:read_capacity_units]).to_i,
373
+ :write_capacity_units => (options[:write_capacity_units] || @table_schema[:provisioned_throughput][:write_capacity_units]).to_i
374
+ },
375
+ :table_name => options[:table_name] || self.table_name
376
+ })
377
+ while (table_metadata = self.describe) && table_metadata[:table][:table_status] == "UPDATING"
378
+ sleep 1
355
379
  end
380
+ Toy::Dynamo::Config.logger.info "Table resized to #{table_metadata[:table][:provisioned_throughput]}"
356
381
  true
357
382
  end
358
383
 
@@ -9,6 +9,16 @@ namespace :ddb do
9
9
  ENV['CLASS'].constantize.dynamo_table.create(options)
10
10
  end
11
11
 
12
+ desc 'Resize a DynamoDB table read/write provision'
13
+ task :resize => :environment do
14
+ raise "expected usage: rake ddb:resize CLASS=User" unless ENV['CLASS']
15
+ options = {}
16
+ options.merge!(:table_name => ENV['TABLE']) if ENV['TABLE']
17
+ options.merge!(:read_capacity_units => ENV['READ'].to_i) if ENV['READ']
18
+ options.merge!(:write_capacity_units => ENV['WRITE'].to_i) if ENV['WRITE']
19
+ ENV['CLASS'].constantize.dynamo_table.resize(options)
20
+ end
21
+
12
22
  task :destroy => :environment do
13
23
  raise "expected usage: rake ddb:destroy CLASS=User" unless ENV['CLASS']
14
24
  options = {}
@@ -1,5 +1,5 @@
1
1
  module Toy
2
2
  module Dynamo
3
- VERSION = "0.0.3"
3
+ VERSION = "0.0.4"
4
4
  end
5
5
  end
data/lib/toy/dynamo.rb CHANGED
@@ -8,6 +8,7 @@ require "toy/dynamo/response"
8
8
  require "toy/dynamo/persistence"
9
9
  # Override 'write_attribute' for hash_key == id
10
10
  require "toy/dynamo/attributes"
11
+ require "toy/dynamo/config"
11
12
  require "toy/dynamo/extensions/array"
12
13
  require "toy/dynamo/extensions/boolean"
13
14
  require "toy/dynamo/extensions/date"
@@ -18,6 +19,9 @@ require "toy/dynamo/extensions/symbol"
18
19
 
19
20
  module Toy
20
21
  module Dynamo
22
+
23
+ MAX_ITEM_SIZE = 65_536
24
+
21
25
  extend ActiveSupport::Concern
22
26
  include Toy::Store
23
27
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: toy-dynamo
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Cary Dunn
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-05-17 00:00:00.000000000 Z
11
+ date: 2013-05-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -81,6 +81,8 @@ files:
81
81
  - lib/toy/dynamo.rb
82
82
  - lib/toy/dynamo/adapter.rb
83
83
  - lib/toy/dynamo/attributes.rb
84
+ - lib/toy/dynamo/config.rb
85
+ - lib/toy/dynamo/config/options.rb
84
86
  - lib/toy/dynamo/extensions/array.rb
85
87
  - lib/toy/dynamo/extensions/boolean.rb
86
88
  - lib/toy/dynamo/extensions/date.rb