dyna_model 0.0.1

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