dynomite 1.2.1 → 1.2.6

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 86f0dd2d67b74fad780ef023ce7d4dcf40b4ee1741ca57fa730d9c5d3a615a96
4
- data.tar.gz: d5f0f59d7761708f8ddb00efdd9bc82d9803234ba6fa4b1dda3486aae9210f60
3
+ metadata.gz: 6f80bf11d2121217d52d8ceac89defcd4e738b3ff220847f7421b1337fbc104f
4
+ data.tar.gz: cd1a4fb8c66678458c8e08b3222064ea3153129f31d1a81ff7ee6d25f1ac3928
5
5
  SHA512:
6
- metadata.gz: b32a45f367418c5d825bf294c1095949b963ea9abc86aafb3a3529c3097789cb723bc7f53940774c492b8512ddaf4e36746e3150520ca6cc796b7046db634a00
7
- data.tar.gz: ed3daf9d3667901038c4aa66884e2883d8d7cd6ef675212818b715ba539c834e57bb0832ab02b4fc376ced1a86b68735499638f177e765231b635d2383d371f3
6
+ metadata.gz: 890d2960cd53cec65a93b81b31fb61da535f123f4718d5e870eb2983813811352e2bbf93043007389ee85224590e2484ec0f2b0c5f377b384c5cf886923a87fd
7
+ data.tar.gz: 1e2ab49bfc684afe96927971d2a57544b9d4898bb1271b920b88969e267b79f5271c4bf71ed07f45b4b160c5f27ef7ff943250c62e42eb1ce1c1c81d720e78ab
data/.gitignore CHANGED
@@ -7,3 +7,4 @@
7
7
  /pkg/
8
8
  /spec/reports/
9
9
  /tmp/
10
+ vendor/bundle
@@ -3,6 +3,23 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  This project *tries* to adhere to [Semantic Versioning](http://semver.org/), even before v1.0.
5
5
 
6
+ ## [1.2.6]
7
+ - Implement the `PAY_PER_USE` billing mode for table creations and updates. See [DynamoDB On Demand](https://aws.amazon.com/blogs/aws/amazon-dynamodb-on-demand-no-capacity-planning-and-pay-per-request-pricing/).
8
+
9
+ ## [1.2.5]
10
+ - use correct color method
11
+
12
+ ## [1.2.4]
13
+ - #16 add rainbow gem dependency for color method
14
+ - #17 fix table names for models with namespaces
15
+
16
+ ## [1.2.3]
17
+ - #11 fix comments in dsl.rb
18
+ - #13 update find method to support composite key
19
+
20
+ ## [1.2.2]
21
+ - update Jets.root usage
22
+
6
23
  ## [1.2.1]
7
24
  - #10 from gotchane/fix-readme-about-validation
8
25
  - #8 from patchkit-net/feature/replace-return-self
data/README.md CHANGED
@@ -1,9 +1,15 @@
1
1
  # Dynomite
2
2
 
3
+ [![BoltOps Badge](https://img.boltops.com/boltops/badges/boltops-badge.png)](https://www.boltops.com)
4
+
3
5
  NOTE: Am looking for maintainers to help with this gem. Send me an email! Also [dynamoid](https://github.com/Dynamoid/dynamoid) seems like a good option that should be considered delegating to or straight using. Learning on delegation so we can have better default behavior for a DynamoDB model layer for Jets.
4
6
 
5
7
  A simple wrapper library to make DynamoDB usage a little more friendly. The modeling is ActiveRecord-ish but not exactly because DynamoDB is a different type of database. Examples below explain it best:
6
8
 
9
+ ## Jets Docs
10
+
11
+ * [Database DynamoDB](https://rubyonjets.com/docs/database/dynamodb/)
12
+
7
13
  ## Examples
8
14
 
9
15
  First define a class:
@@ -11,7 +17,7 @@ First define a class:
11
17
  ```ruby
12
18
  class Post < Dynomite::Item
13
19
  # partition_key "id" # optional, defaults to id
14
-
20
+
15
21
  column :id, :title, :desc
16
22
  end
17
23
  ```
@@ -21,7 +27,7 @@ end
21
27
  ```ruby
22
28
  post = Post.new
23
29
  post = post.replace(title: "test title")
24
- post.attrs # {"id" => "generated-id", title" => "my title"}
30
+ post.attrs # {"id" => "generated-id", title" => "test title"}
25
31
  ```
26
32
 
27
33
  `post.attrs[:id]` now contain a generated unique partition_key id. Usually the partition_key is 'id'. You can set your own unique id also by specifying id.
@@ -112,7 +118,7 @@ post.replace
112
118
 
113
119
  puts post.id # 1962DE7D852298C5CDC809C0FEF50D8262CEDF09
114
120
  puts post.name # "My First Post"
115
- ```
121
+ ```
116
122
 
117
123
  Note that any column not defined using the `column` method can still be accessed using the `attrs`
118
124
  method.
@@ -125,15 +131,15 @@ Just add `include ActiveModel::Validations` at the top of your item class.
125
131
  ```ruby
126
132
  class Post < Dynomite::Item
127
133
  include ActiveModel::Validations
128
-
134
+
129
135
  column :id, :name # needed
130
-
136
+
131
137
  validates :id, presence: true
132
138
  validates :name, presence: true
133
139
  end
134
- ```
140
+ ```
135
141
 
136
- **Be sure to define all validated columns using `column` method**.
142
+ **Be sure to define all validated columns using `column` method**.
137
143
 
138
144
  Validations are executed by default as soon as you call the `replace` method, returning `false` on
139
145
  failure. It also can be ran manually using the `valid?` method just like with ActiveRecord models.
@@ -55,6 +55,9 @@ class CreateCommentsMigration < Dynomite::Migration
55
55
  # read_capacity_units: 5,
56
56
  # write_capacity_units: 5
57
57
  # )
58
+
59
+ # set the billing mode to on-demand (NOTE: this overrides provisioned_throughput)
60
+ # t.billing_mode(:pay_per_use)
58
61
  end
59
62
  end
60
63
  end
@@ -62,6 +65,8 @@ end
62
65
  class UpdateCommentsMigration < Dynomite::Migration
63
66
  def up
64
67
  update_table :comments do |t|
68
+ # You can update from provisioned_throughput to on-demand pricing
69
+ # t.billing_mode(:pay_per_use)
65
70
 
66
71
  # t.global_secondary_index do
67
72
  # t.gsi(METHOD, INDEX_NAME) do
@@ -120,4 +125,3 @@ class UpdateCommentsMigration < Dynomite::Migration
120
125
  end
121
126
  end
122
127
  end
123
-
@@ -22,6 +22,7 @@ Gem::Specification.new do |spec|
22
22
 
23
23
  spec.add_dependency "activesupport"
24
24
  spec.add_dependency "aws-sdk-dynamodb"
25
+ spec.add_dependency "rainbow"
25
26
 
26
27
  spec.add_development_dependency "bundler"
27
28
  spec.add_development_dependency "rake"
@@ -1,5 +1,6 @@
1
1
  $:.unshift(File.expand_path("../", __FILE__))
2
2
  require "dynomite/version"
3
+ require "rainbow/ext/string"
3
4
 
4
5
  module Dynomite
5
6
  ATTRIBUTE_TYPES = {
@@ -73,7 +73,7 @@ module Dynomite::DbConfig
73
73
  return @db_config if @db_config
74
74
 
75
75
  if defined?(Jets)
76
- config_path = "#{Jets.root}config/dynamodb.yml"
76
+ config_path = "#{Jets.root}/config/dynamodb.yml"
77
77
  env = Jets.env
78
78
  else
79
79
  config_path = ENV['DYNOMITE_CONFIG'] || "./config/dynamodb.yml"
@@ -26,7 +26,7 @@ class Dynomite::Erb
26
26
  error_info ||= e.backtrace.grep(/\(erb\)/)[0]
27
27
  raise unless error_info # unable to find the (erb):xxx: error line
28
28
  line = error_info.split(':')[1].to_i
29
- log "Error evaluating ERB template on line #{line.to_s.colorize(:red)} of: #{path.sub(/^\.\//, '').colorize(:green)}"
29
+ log "Error evaluating ERB template on line #{line.to_s.color(:red)} of: #{path.sub(/^\.\//, '').color(:green)}"
30
30
 
31
31
  template_lines = template.split("\n")
32
32
  context = 5 # lines of context
@@ -35,7 +35,7 @@ class Dynomite::Erb
35
35
  template_lines[top..bottom].each_with_index do |line_content, index|
36
36
  line_number = top+index+1
37
37
  if line_number == line
38
- printf("%#{spacing}d %s\n".colorize(:red), line_number, line_content)
38
+ printf("%#{spacing}d %s\n".color(:red), line_number, line_content)
39
39
  else
40
40
  printf("%#{spacing}d %s\n", line_number, line_content)
41
41
  end
@@ -236,9 +236,17 @@ module Dynomite
236
236
  end
237
237
 
238
238
  def self.find(id)
239
+ params =
240
+ case id
241
+ when String
242
+ { partition_key => id }
243
+ when Hash
244
+ id
245
+ end
246
+
239
247
  resp = db.get_item(
240
248
  table_name: table_name,
241
- key: {partition_key => id}
249
+ key: params
242
250
  )
243
251
  attributes = resp.item # unwraps the item's attributes
244
252
  self.new(attributes) if attributes
@@ -298,7 +306,7 @@ module Dynomite
298
306
  end
299
307
 
300
308
  def self.get_table_name
301
- @table_name ||= self.name.pluralize.underscore
309
+ @table_name ||= self.name.pluralize.gsub('::','-').underscore.dasherize
302
310
  [table_namespace, @table_name].reject {|s| s.nil? || s.empty?}.join('-')
303
311
  end
304
312
 
@@ -1,5 +1,12 @@
1
1
  class Dynomite::Migration
2
2
  class Dsl
3
+ ATTRIBUTES = %i[
4
+ key_schema
5
+ attribute_definitions
6
+ table_name
7
+ billing_mode
8
+ ].freeze
9
+
3
10
  autoload :Common, "dynomite/migration/common"
4
11
  autoload :BaseSecondaryIndex, "dynomite/migration/dsl/base_secondary_index"
5
12
  autoload :LocalSecondaryIndex, "dynomite/migration/dsl/local_secondary_index"
@@ -8,15 +15,16 @@ class Dynomite::Migration
8
15
  include Dynomite::DbConfig
9
16
  include Common
10
17
 
11
- attr_accessor :key_schema, :attribute_definitions
12
- attr_accessor :table_name
18
+ attr_accessor(*ATTRIBUTES)
19
+
13
20
  def initialize(method_name, table_name, &block)
14
21
  @method_name = method_name
15
22
  @table_name = table_name
16
23
  @block = block
17
24
 
18
- # Dsl fills in atttributes in as methods are called within the block.
25
+ # Dsl fills in attributes in as methods are called within the block.
19
26
  # Attributes for both create_table and updated_table:
27
+ @billing_mode = 'PROVISIONED'
20
28
  @attribute_definitions = []
21
29
  @provisioned_throughput = {
22
30
  read_capacity_units: 5,
@@ -31,9 +39,17 @@ class Dynomite::Migration
31
39
  @lsi_indexes = []
32
40
  end
33
41
 
42
+ # t.billing_mode(:pay_per_request)
43
+ # t.billing_mode(:provisioned) # default value
44
+ def billing_mode(mode = nil)
45
+ return @billing_mode if mode.nil?
46
+
47
+ @billing_mode = mode.to_s.upcase
48
+ end
49
+
34
50
  # t.gsi(:create) do |i|
35
- # i.partition_key = "category:string"
36
- # i.sort_key = "created_at:string" # optional
51
+ # i.partition_key "category:string"
52
+ # i.sort_key "created_at:string" # optional
37
53
  # end
38
54
  def gsi(action=:create, index_name=nil, &block)
39
55
  gsi_index = GlobalSecondaryIndex.new(action, index_name, &block)
@@ -42,8 +58,8 @@ class Dynomite::Migration
42
58
  alias_method :global_secondary_index, :gsi
43
59
 
44
60
  # t.lsi(:create) do |i|
45
- # i.partition_key = "category:string"
46
- # i.sort_key = "created_at:string" # optional
61
+ # i.partition_key "category:string"
62
+ # i.sort_key "created_at:string" # optional
47
63
  # end
48
64
  def lsi(action=:create, index_name=nil, &block)
49
65
  # dont need action create but have it to keep the lsi and gsi method consistent
@@ -81,9 +97,10 @@ class Dynomite::Migration
81
97
  table_name: namespaced_table_name,
82
98
  key_schema: @key_schema,
83
99
  attribute_definitions: @attribute_definitions,
84
- provisioned_throughput: @provisioned_throughput
100
+ billing_mode: @billing_mode
85
101
  }
86
102
 
103
+ params[:provisioned_throughput] = @provisioned_throughput if @billing_mode == 'PROVISIONED'
87
104
  params[:local_secondary_indexes] = lsi_secondary_index_creates unless @lsi_indexes.empty?
88
105
  params[:global_secondary_indexes] = gsi_secondary_index_creates unless @gsi_indexes.empty?
89
106
  params
@@ -95,12 +112,15 @@ class Dynomite::Migration
95
112
  params = {
96
113
  table_name: namespaced_table_name,
97
114
  attribute_definitions: @attribute_definitions,
115
+ billing_mode: @billing_mode
98
116
  # update table take values only some values for the "parent" table
99
117
  # no key_schema, update_table does not handle key_schema for the "parent" table
100
118
  }
101
119
  # only set "parent" table provisioned_throughput if user actually invoked
102
120
  # it in the dsl
103
- params[:provisioned_throughput] = @provisioned_throughput if @provisioned_throughput_set_called
121
+ if @provisioned_throughput_set_called && @billing_mode == 'PROVISIONED'
122
+ params[:provisioned_throughput] = @provisioned_throughput
123
+ end
104
124
  params[:global_secondary_index_updates] = global_secondary_index_updates
105
125
  params
106
126
  end
@@ -31,7 +31,7 @@ class Dynomite::Migration
31
31
 
32
32
  puts "DynamoDB Table: #{@table_name} Status: #{result.table_description.table_status}"
33
33
  rescue Aws::DynamoDB::Errors::ServiceError => error
34
- puts "Unable to #{@method_name.to_s.gsub('_',' ')}: #{error.message}".colorize(:red)
34
+ puts "Unable to #{@method_name.to_s.gsub('_',' ')}: #{error.message}".color(:red)
35
35
  end
36
36
  end
37
37
  end
@@ -31,7 +31,7 @@ class Dynomite::Migration
31
31
  table_name: table_name,
32
32
  partition_key: @options[:partition_key],
33
33
  sort_key: @options[:sort_key],
34
- provisioned_throughput: @options[:provisioned_throughput] || 5,
34
+ provisioned_throughput: @options[:provisioned_throughput] || 5
35
35
  )
36
36
  end
37
37
 
@@ -5,6 +5,7 @@ class <%= @migration_class_name %> < Dynomite::Migration
5
5
  <% if @sort_key # so extra spaces are not added when generated -%>
6
6
  t.sort_key "<%= @sort_key %>" # optional
7
7
  <% end -%>
8
+ t.billing_mode(:PROVISIONED)
8
9
  t.provisioned_throughput(<%= @provisioned_throughput %>) # sets both read and write, defaults to 5 when not set
9
10
 
10
11
  # Instead of using partition_key and sort_key you can set the
@@ -1,3 +1,3 @@
1
1
  module Dynomite
2
- VERSION = "1.2.1"
2
+ VERSION = "1.2.6"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dynomite
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.1
4
+ version: 1.2.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tung Nguyen
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-01-20 00:00:00.000000000 Z
11
+ date: 2020-05-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rainbow
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: bundler
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -135,8 +149,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
135
149
  - !ruby/object:Gem::Version
136
150
  version: '0'
137
151
  requirements: []
138
- rubyforge_project:
139
- rubygems_version: 2.7.6
152
+ rubygems_version: 3.1.2
140
153
  signing_key:
141
154
  specification_version: 4
142
155
  summary: ActiveRecord-ish Dynamodb Model