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 +4 -4
- data/README.md +45 -8
- data/lib/toy/dynamo/adapter.rb +15 -0
- data/lib/toy/dynamo/config/options.rb +80 -0
- data/lib/toy/dynamo/config.rb +56 -0
- data/lib/toy/dynamo/querying.rb +10 -9
- data/lib/toy/dynamo/schema.rb +7 -7
- data/lib/toy/dynamo/table.rb +39 -14
- data/lib/toy/dynamo/tasks.rb +10 -0
- data/lib/toy/dynamo/version.rb +1 -1
- data/lib/toy/dynamo.rb +4 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 342640e00f6ef382f4ad50e46015753ca5ac034f
|
4
|
+
data.tar.gz: 27ae95e381c9ca143507c0969edde91f9c9b51ee
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
|
12
|
-
|
13
|
-
|
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
|
-
|
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
|
-
*
|
80
|
-
*
|
81
|
-
*
|
115
|
+
* lambdas for table_name (for dynamic table names)
|
116
|
+
* string and number sets (mostly for scans)
|
117
|
+
* use MAX_ITEM_SIZE (64kb)
|
118
|
+
|
data/lib/toy/dynamo/adapter.rb
CHANGED
@@ -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
|
data/lib/toy/dynamo/querying.rb
CHANGED
@@ -4,24 +4,25 @@ module Toy
|
|
4
4
|
extend ActiveSupport::Concern
|
5
5
|
|
6
6
|
# Failsafe
|
7
|
-
MAX_BATCH_ITERATIONS =
|
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", :
|
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", :
|
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
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
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
|
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
|
data/lib/toy/dynamo/schema.rb
CHANGED
@@ -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 ||
|
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 ||
|
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
|
-
|
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
|
-
|
182
|
+
Toy::Dynamo::Config.logger.error "write_capacity_units mismatch. Need to update table?"
|
183
183
|
end
|
184
184
|
end
|
185
185
|
|
data/lib/toy/dynamo/table.rb
CHANGED
@@ -40,7 +40,7 @@ module Toy
|
|
40
40
|
begin
|
41
41
|
self.load_schema
|
42
42
|
rescue AWS::DynamoDB::Errors::ResourceNotFoundException => e
|
43
|
-
|
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] ||
|
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] ||
|
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] ||
|
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] ||
|
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] ||
|
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] ||
|
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] ||
|
329
|
-
raise "Table #{options[:table_name] ||
|
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] ||
|
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] ||
|
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] ||
|
348
|
-
@client.delete_table(:table_name => options[: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
|
-
|
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
|
|
data/lib/toy/dynamo/tasks.rb
CHANGED
@@ -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 = {}
|
data/lib/toy/dynamo/version.rb
CHANGED
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.
|
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-
|
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
|