dyna_model 0.0.1

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ca4e3bd3b871756a2b5fad4bf362c334bbf804af
4
+ data.tar.gz: ac13badc8bca36d88787d6cbdb6134af19c69a93
5
+ SHA512:
6
+ metadata.gz: 23243b46398ab0517a2f6a7c57e1fdbbe3f4f63c8d55b8c1a8a73abe8de75a297395ad8554d06101c02cb472de16a696e738a509b46002427812b4efa6279e49
7
+ data.tar.gz: 32f20b9e28c107825230eb53dfd18b092f6626e91e66a4b1fd859b0523c4f5c38c1566d2e77e9417ec80b8612c4c91ba24269f47a74379eecc1611ee37b0b38a
data/.gitignore ADDED
@@ -0,0 +1,19 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ *.swp
19
+ *.swo
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in dyna_model.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Cary Dunn
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,81 @@
1
+ # DynaModel
2
+
3
+ AWS DynamoDB ORM for Rails based on AWS::Record in the aws-sdk gem. Still a work in progress but very functional.
4
+
5
+ ## Installation
6
+ ```
7
+ gem 'dyna_model'
8
+ ```
9
+
10
+ ## Sample Model
11
+ ```
12
+ class Dude
13
+
14
+ include DynaModel::Document
15
+
16
+ string_attr :hashy
17
+ integer_attr :ranger, default_value: 2
18
+ string_attr :name, default_value: lambda { "dude" }
19
+ boolean_attr :is_dude
20
+ datetime_attr :born
21
+ serialized_attr :cereal
22
+ timestamps
23
+
24
+ hash_key :hashy
25
+ range_key :ranger
26
+
27
+ set_shard_name "usery"
28
+
29
+ local_secondary_index :name
30
+ global_secondary_index(:name_index, { hash_key: :name, projection: [:name] })
31
+
32
+ read_provision 4
33
+ write_provision 4
34
+ guid_delimiter "!"
35
+
36
+ validates_presence_of :name
37
+
38
+ before_create :do_something
39
+ before_validation on: :create do
40
+ do_something
41
+ end
42
+
43
+ end
44
+ ```
45
+
46
+ ## Sample Methods
47
+ ```
48
+ # Read a single object by Hash and (optionally) Range keys
49
+ Dude.read
50
+
51
+ # Query by Hash and (optionally) Range keys (compatible with Local and Global Secondary Indexes)
52
+ Dude.read_range
53
+
54
+ # Batch read
55
+ Dude.read_multiple
56
+
57
+ # Read by guid (helper for hash + guid_delimiter + range)
58
+ Dude.read_guid
59
+
60
+ # Get count of query
61
+ Dude.count_range
62
+
63
+ # Table scan with more complex filters
64
+ Dude.scan
65
+
66
+ # Create Table
67
+ Dude.create_table
68
+
69
+ # Delete Table
70
+ Dude.delete_table
71
+
72
+ # Rake tasks
73
+ rake ddb:create CLASS=Dude
74
+ rake ddb:create CLASS=all
75
+ rake ddb:destroy CLASS=Dude
76
+ rake ddb:destroy CLASS=all
77
+ ```
78
+
79
+ # AWS::Record
80
+ * http://docs.aws.amazon.com/AWSRubySDK/latest/AWS/Record.html
81
+ * https://github.com/aws/aws-sdk-ruby/blob/master/lib/aws/record/abstract_base.rb
data/Rakefile ADDED
@@ -0,0 +1,11 @@
1
+ # encoding: utf-8
2
+
3
+ require "bundler/gem_tasks"
4
+
5
+ require 'rspec/core'
6
+ require 'rspec/core/rake_task'
7
+ RSpec::Core::RakeTask.new(:spec) do |spec|
8
+ spec.pattern = FileList['spec/**/*_spec.rb']
9
+ end
10
+
11
+ task :default => :spec
@@ -0,0 +1,31 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'dyna_model/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "dyna_model"
8
+ spec.version = DynaModel::VERSION
9
+ spec.authors = ["Cary Dunn"]
10
+ spec.email = ["cary.dunn@gmail.com"]
11
+ spec.summary = %q{DyanmoDB ORM on AWS::Record}
12
+ spec.description = %q{DyanmoDB ORM on AWS::Record}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.5"
22
+ spec.add_development_dependency "rake"
23
+ spec.add_development_dependency "rspec"
24
+ spec.add_development_dependency "mocha"
25
+
26
+ spec.add_dependency 'activesupport', '>= 4.0.0'
27
+ spec.add_dependency 'activemodel', '>= 4.0.0'
28
+ spec.add_dependency 'rails', '>= 4.0.0'
29
+ spec.add_dependency 'aws-sdk', '>= 1.38.0'
30
+ end
31
+
@@ -0,0 +1,187 @@
1
+ module DynaModel
2
+ module Attributes
3
+ extend ActiveSupport::Concern
4
+
5
+ module ClassMethods
6
+
7
+ # Adds a string attribute to this class.
8
+ #
9
+ # @example A standard string attribute
10
+ #
11
+ # class Recipe < AWS::Record::HashModel
12
+ # string_attr :name
13
+ # end
14
+ #
15
+ # recipe = Recipe.new(:name => "Buttermilk Pancakes")
16
+ # recipe.name #=> 'Buttermilk Pancakes'
17
+ #
18
+ # @example A string attribute with `:set` set to true
19
+ #
20
+ # class Recipe < AWS::Record::HashModel
21
+ # string_attr :tags, :set => true
22
+ # end
23
+ #
24
+ # recipe = Recipe.new(:tags => %w(popular dessert))
25
+ # recipe.tags #=> #<Set: {"popular", "desert"}>
26
+ #
27
+ # @param [Symbol] name The name of the attribute.
28
+ # @param [Hash] options
29
+ # @option options [Boolean] :set (false) When true this attribute
30
+ # can have multiple values.
31
+ def string_attr name, options = {}
32
+ add_attribute(AWS::Record::Attributes::StringAttr.new(name, options))
33
+ end
34
+
35
+ # Adds an integer attribute to this class.
36
+ #
37
+ # class Recipe < AWS::Record::HashModel
38
+ # integer_attr :servings
39
+ # end
40
+ #
41
+ # recipe = Recipe.new(:servings => '10')
42
+ # recipe.servings #=> 10
43
+ #
44
+ # @param [Symbol] name The name of the attribute.
45
+ # @param [Hash] options
46
+ # @option options [Boolean] :set (false) When true this attribute
47
+ # can have multiple values.
48
+ def integer_attr name, options = {}
49
+ add_attribute(AWS::Record::Attributes::IntegerAttr.new(name, options))
50
+ end
51
+
52
+ # Adds a float attribute to this class.
53
+ #
54
+ # class Listing < AWS::Record::HashModel
55
+ # float_attr :score
56
+ # end
57
+ #
58
+ # listing = Listing.new(:score => '123.456')
59
+ # listing.score # => 123.456
60
+ #
61
+ # @param [Symbol] name The name of the attribute.
62
+ # @param [Hash] options
63
+ # @option options [Boolean] :set (false) When true this attribute
64
+ # can have multiple values.
65
+ def float_attr name, options = {}
66
+ add_attribute(AWS::Record::Attributes::FloatAttr.new(name, options))
67
+ end
68
+
69
+ # Adds a boolean attribute to this class.
70
+ #
71
+ # @example
72
+ #
73
+ # class Book < AWS::Record::HashModel
74
+ # boolean_attr :read
75
+ # end
76
+ #
77
+ # b = Book.new
78
+ # b.read? # => false
79
+ # b.read = true
80
+ # b.read? # => true
81
+ #
82
+ # listing = Listing.new(:score => '123.456'
83
+ # listing.score # => 123.456
84
+ #
85
+ # @param [Symbol] name The name of the attribute.
86
+ def boolean_attr name, options = {}
87
+
88
+ attr = add_attribute(AWS::Record::Attributes::BooleanAttr.new(name, options))
89
+
90
+ # add the boolean question mark method
91
+ define_method("#{attr.name}?") do
92
+ !!__send__(attr.name)
93
+ end
94
+
95
+ end
96
+
97
+ # Adds a datetime attribute to this class.
98
+ #
99
+ # @example A standard datetime attribute
100
+ #
101
+ # class Recipe < AWS::Record::HashModel
102
+ # datetime_attr :invented
103
+ # end
104
+ #
105
+ # recipe = Recipe.new(:invented => Time.now)
106
+ # recipe.invented #=> <DateTime ...>
107
+ #
108
+ # If you add a datetime_attr for `:created_at` and/or `:updated_at` those
109
+ # will be automanaged.
110
+ #
111
+ # @param [Symbol] name The name of the attribute.
112
+ #
113
+ # @param [Hash] options
114
+ #
115
+ # @option options [Boolean] :set (false) When true this attribute
116
+ # can have multiple date times.
117
+ #
118
+ def datetime_attr name, options = {}
119
+ add_attribute(AWS::Record::Attributes::DateTimeAttr.new(name, options))
120
+ end
121
+
122
+ # Adds a date attribute to this class.
123
+ #
124
+ # @example A standard date attribute
125
+ #
126
+ # class Person < AWS::Record::HashModel
127
+ # date_attr :birthdate
128
+ # end
129
+ #
130
+ # baby = Person.new
131
+ # baby.birthdate = Time.now
132
+ # baby.birthdate #=> <Date: ....>
133
+ #
134
+ # @param [Symbol] name The name of the attribute.
135
+ #
136
+ # @param [Hash] options
137
+ #
138
+ # @option options [Boolean] :set (false) When true this attribute
139
+ # can have multiple dates.
140
+ #
141
+ def date_attr name, options = {}
142
+ add_attribute(AWS::Record::Attributes::DateAttr.new(name, options))
143
+ end
144
+
145
+ # Adds a DynamoDB binary attribute to this class. A binary
146
+ # attribute acts the same as a string attribute, except
147
+ #
148
+ # @param [Symbol] name The name of the attribute.
149
+ #
150
+ # @param [Hash] options
151
+ #
152
+ # @option options [Boolean] :set (false) When true this attribute
153
+ # can have multiple values.
154
+ #
155
+ # @note This should not be used for large objects.
156
+ #
157
+ def binary_attr name, options = {}
158
+ end
159
+
160
+ def serialized_attr name, options = {}
161
+ add_attribute(AWS::Record::Attributes::SerializedAttr.new(name, options))
162
+ end
163
+
164
+ # A convenience method for adding the standard two datetime attributes
165
+ # `:created_at` and `:updated_at`.
166
+ #
167
+ # @example
168
+ #
169
+ # class Recipe < AWS::Record::HashModel
170
+ # timestamps
171
+ # end
172
+ #
173
+ # recipe = Recipe.new
174
+ # recipe.save
175
+ # recipe.created_at #=> <DateTime ...>
176
+ # recipe.updated_at #=> <DateTime ...>
177
+ #
178
+ def timestamps
179
+ c = datetime_attr :created_at
180
+ u = datetime_attr :updated_at
181
+ [c, u]
182
+ end
183
+
184
+ end
185
+
186
+ end
187
+ end
@@ -0,0 +1,33 @@
1
+ module AWS
2
+ module Record
3
+ module Attributes
4
+ class SerializedAttr < BaseAttr
5
+
6
+ def self.type_cast raw_value, options = {}
7
+ case raw_value
8
+ when nil then nil
9
+ when '' then nil
10
+ when String # assume binary
11
+ begin
12
+ Marshal.load(raw_value)
13
+ rescue
14
+ raw_value
15
+ end
16
+ else # object to serialize
17
+ raw_value
18
+ end
19
+ end
20
+
21
+ def self.serialize obj, options = {}
22
+ AWS::DynamoDB::Binary.new(Marshal.dump(obj))
23
+ end
24
+
25
+ # @api private
26
+ def self.allow_set?
27
+ false
28
+ end
29
+
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,78 @@
1
+ # Shamelessly stolen from Mongoid (and Dynamoid)!
2
+ module DynaModel #:nodoc
3
+ module Config
4
+
5
+ # Encapsulates logic for setting options.
6
+ module Options
7
+
8
+ # Get the defaults or initialize a new empty hash.
9
+ #
10
+ # @example Get the defaults.
11
+ # options.defaults
12
+ #
13
+ # @return [ Hash ] The default options.
14
+ #
15
+ # @since 0.2.0
16
+ def defaults
17
+ @defaults ||= {}
18
+ end
19
+
20
+ # Define a configuration option with a default.
21
+ #
22
+ # @example Define the option.
23
+ # Options.option(:persist_in_safe_mode, :default => false)
24
+ #
25
+ # @param [ Symbol ] name The name of the configuration option.
26
+ # @param [ Hash ] options Extras for the option.
27
+ #
28
+ # @option options [ Object ] :default The default value.
29
+ #
30
+ # @since 0.2.0
31
+ def option(name, options = {})
32
+ defaults[name] = settings[name] = options[:default]
33
+
34
+ class_eval <<-RUBY
35
+ def #{name}
36
+ settings[#{name.inspect}]
37
+ end
38
+
39
+ def #{name}=(value)
40
+ settings[#{name.inspect}] = value
41
+ end
42
+
43
+ def #{name}?
44
+ #{name}
45
+ end
46
+
47
+ def reset_#{name}
48
+ settings[#{name.inspect}] = defaults[#{name.inspect}]
49
+ end
50
+ RUBY
51
+ end
52
+
53
+ # Reset the configuration options to the defaults.
54
+ #
55
+ # @example Reset the configuration options.
56
+ # config.reset
57
+ #
58
+ # @return [ Hash ] The defaults.
59
+ #
60
+ # @since 0.2.0
61
+ def reset
62
+ settings.replace(defaults)
63
+ end
64
+
65
+ # Get the settings or initialize a new empty hash.
66
+ #
67
+ # @example Get the settings.
68
+ # options.settings
69
+ #
70
+ # @return [ Hash ] The setting options.
71
+ #
72
+ # @since 0.2.0
73
+ def settings
74
+ @settings ||= {}
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,46 @@
1
+ # encoding: utf-8
2
+ require "uri"
3
+ require "dyna_model/config/options"
4
+
5
+ # Shamelessly stolen from Dynamoid
6
+ module DynaModel
7
+
8
+ # Contains all the basic configuration information required for Dynamoid: both sensible defaults and required fields.
9
+ module Config
10
+ extend self
11
+ extend Options
12
+
13
+ # All the default options.
14
+ option :logger, :default => defined?(Rails)
15
+ option :read_provision, :default => 50
16
+ option :write_provision, :default => 10
17
+ # TODO - default adapter client based on config
18
+ #option :namespace, :default => defined?(Rails) ? "#{Rails.application.class.parent_name}_#{Rails.env}" : ""
19
+ option :endpoint, :default => 'dynamodb.us-west-2.amazonaws.com'
20
+ option :port, :default => 443
21
+ option :use_ssl, :default => true
22
+ option :default_guid_delimiter, :default => ":"
23
+ option :namespace, :default => ""
24
+
25
+ # The default logger: either the Rails logger or just stdout.
26
+ def default_logger
27
+ defined?(Rails) && Rails.respond_to?(:logger) ? Rails.logger : ::Logger.new($stdout)
28
+ end
29
+
30
+ # Returns the assigned logger instance.
31
+ def logger
32
+ @logger ||= default_logger
33
+ end
34
+
35
+ # If you want to, set the logger manually to any output you'd like. Or pass false or nil to disable logging entirely.
36
+ def logger=(logger)
37
+ case logger
38
+ when false, nil then @logger = nil
39
+ when true then @logger = default_logger
40
+ else
41
+ @logger = logger if logger.respond_to?(:info)
42
+ end
43
+ end
44
+
45
+ end
46
+ end
@@ -0,0 +1,169 @@
1
+ module DynaModel
2
+ module Document
3
+
4
+ MAX_ITEM_SIZE = 65_536
5
+ # These delimiters are also reserved characters and should not be used in
6
+ # hash or range keys
7
+ GUID_DELIMITER_PRECEDENCE = ["_", ":", "|", ",", "!", "~", "@", "^"]
8
+
9
+ extend ActiveSupport::Concern
10
+
11
+ included do
12
+ class_attribute :read_only_attributes, :base_class
13
+ self.base_class = self
14
+
15
+ AWS::Record.table_prefix = "#{DynaModel::Config.namespace}#{Rails.application.class.parent_name.to_s.underscore.dasherize}-#{Rails.env}-"
16
+
17
+ extend ActiveModel::Translation
18
+ extend ActiveModel::Callbacks
19
+ extend AWS::Record::AbstractBase
20
+ include DynaModel::Persistence
21
+ include DynaModel::Validations
22
+
23
+ define_model_callbacks :create, :save, :destroy, :initialize, :update, :validation
24
+
25
+ # OVERRIDE
26
+ # https://github.com/aws/aws-sdk-ruby/blob/master/lib/aws/record/abstract_base.rb#L258
27
+ # AWS::Record::AbstractBase for :select attributes
28
+ protected
29
+ def [] attribute_name
30
+ # Warn if using attributes that were not part of the :select (common with GSI/LSI projections)
31
+ # we do not want to give the impression they are nil
32
+ if (selected_attrs = self.instance_variable_get("@_selected_attributes"))
33
+ raise "Attribute '#{attribute_name}' was not part of the select '#{self.instance_variable_get("@_select")}' (available attributes: #{selected_attrs})" unless selected_attrs.include?(attribute_name)
34
+ end
35
+ super
36
+ end
37
+ end
38
+
39
+ include ActiveModel::Conversion
40
+ include ActiveModel::MassAssignmentSecurity if defined?(ActiveModel::MassAssignmentSecurity)
41
+ include ActiveModel::Naming
42
+ include ActiveModel::Observing if defined?(ActiveModel::Observing)
43
+ include ActiveModel::Serializers::JSON
44
+ include ActiveModel::Serializers::Xml
45
+
46
+ include DynaModel::Attributes
47
+ include DynaModel::Schema
48
+ include DynaModel::Query
49
+
50
+ def to_param
51
+ self.dynamo_db_guid
52
+ end
53
+
54
+ def dynamo_db_guid
55
+ _guid = [self.dynamo_db_item_key_values[:hash_value]]
56
+ _guid << self.dynamo_db_item_key_values[:range_value] if self.dynamo_db_item_key_values[:range_value]
57
+ _guid.join(self.class.guid_delimiter)
58
+ end
59
+
60
+ def dynamo_db_item_key_values
61
+ key_values = { hash_value: self[self.class.hash_key[:attribute_name]] }
62
+ key_values.merge!(range_value: self[self.class.range_key[:attribute_name]]) if self.class.range_key
63
+ key_values
64
+ end
65
+
66
+ def all_attributes_loaded?
67
+ self.instance_variable_get("@_select") == :all
68
+ end
69
+
70
+ # When only partial attributes were selected (via GSI or projected attributes on an index)
71
+ def load_attributes!
72
+ raise "All attributes already loaded!" if self.instance_variable_get("@_select") == :all
73
+ options = { shard_name: self.shard }
74
+ if self.class.range_key
75
+ obj = self.class.read(dynamo_db_item_key_values[:hash_value], dynamo_db_item_key_values[:range_value], options)
76
+ else
77
+ obj = self.class.read(dynamo_db_item_key_values[:hash_value], options)
78
+ end
79
+ raise "Could not find object" unless obj
80
+ self.instance_variable_set("@_select", :all)
81
+ self.remove_instance_variable("@_selected_attributes")
82
+ self.instance_variable_set("@_data", obj.instance_variable_get("@_data"))
83
+ self
84
+ end
85
+
86
+ def touch
87
+ self.send(:touch_timestamps, "updated_at")
88
+ end
89
+
90
+ def touch!
91
+ self.touch
92
+ self.save
93
+ end
94
+
95
+ module ClassMethods
96
+
97
+ def create_table options = {}
98
+ table_name = self.dynamo_db_table_name(options[:shard_name])
99
+ if self.dynamo_db_client.list_tables[:table_names].include?(table_name)
100
+ puts "Table #{table_name} already exists"
101
+ return false
102
+ end
103
+ self.dynamo_db_client.create_table(self.table_schema.merge({
104
+ table_name: table_name
105
+ }))
106
+ while (table_metadata = self.describe_table(options))[:table][:table_status] == "CREATING"
107
+ sleep 1
108
+ end
109
+ table_metadata
110
+ end
111
+
112
+ def describe_table(options={})
113
+ self.dynamo_db_client.describe_table(table_name: self.dynamo_db_table_name(options[:shard_name]))
114
+ end
115
+
116
+ def delete_table(options={})
117
+ table_name = self.dynamo_db_table_name(options[:shard_name])
118
+ return false unless self.dynamo_db_client.list_tables[:table_names].include?(table_name)
119
+ self.dynamo_db_client.delete_table(table_name: table_name)
120
+ begin
121
+ while (table_metadata = self.describe_table) && table_metadata[:table][:table_status] == "DELETING"
122
+ sleep 1
123
+ end
124
+ rescue AWS::DynamoDB::Errors::ResourceNotFoundException => e
125
+ DynaModel::Config.logger.info "Table deleted"
126
+ end
127
+ true
128
+ end
129
+
130
+ def resize_table(options={})
131
+ table_name = self.dynamo_db_table_name(options[:shard_name])
132
+ return false unless self.dynamo_db_client.list_tables[:table_names].include?(table_name)
133
+ self.dynamo_db_client.update_table({
134
+ provisioned_throughput: {
135
+ read_capacity_units: (options[:read_capacity_units] || self.table_schema[:provisioned_throughput][:read_capacity_units]).to_i,
136
+ write_capacity_units: (options[:write_capacity_units] || self.table_schema[:provisioned_throughput][:write_capacity_units]).to_i
137
+ },
138
+ table_name: table_name
139
+ })
140
+ while (table_metadata = self.describe_table) && table_metadata[:table][:table_status] == "UPDATING"
141
+ sleep 1
142
+ end
143
+ DynaModel::Config.logger.info "Table resized to #{table_metadata[:table][:provisioned_throughput]}"
144
+ true
145
+ end
146
+
147
+ def dynamo_db_table(shard_name = nil)
148
+ @table_map ||= {}
149
+ @table_map[self.dynamo_db_table_name(shard_name)] ||= Table.new(self)
150
+ end
151
+
152
+ def dynamo_db_table_name(shard_name = nil)
153
+ "#{AWS::Record.table_prefix}#{self.shard_name(shard_name)}"
154
+ end
155
+
156
+ def dynamo_db_client(config={})
157
+ options = {}
158
+ options[:use_ssl] = DynaModel::Config.use_ssl
159
+ options[:use_ssl] = config[:use_ssl] if config.has_key?(:use_ssl)
160
+ options[:dynamo_db_endpoint] = config[:endpoint] || DynaModel::Config.endpoint
161
+ options[:dynamo_db_port] = config[:port] || DynaModel::Config.port
162
+ options[:api_version] ||= config[:api_version] || '2012-08-10'
163
+
164
+ @dynamo_db_client ||= AWS::DynamoDB::Client.new(options)
165
+ end
166
+
167
+ end
168
+ end
169
+ end