aws-sdk-rails 3.7.1 → 3.9.0

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.
@@ -1,217 +1,217 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rails/generators'
2
4
  require_relative 'generated_attribute'
3
5
  require_relative 'secondary_index'
4
6
 
5
7
  module AwsRecord
6
- module Generators
7
- class Base < Rails::Generators::NamedBase
8
- argument :attributes, type: :array, default: [], banner: "field[:type][:opts]...", desc: "Describes the fields in the model"
9
- check_class_collision
10
-
11
- class_option :disable_mutation_tracking, type: :boolean, desc: "Disables dirty tracking"
12
- class_option :timestamps, type: :boolean, desc: "Adds created, updated timestamps to the model"
13
- class_option :table_config, type: :hash, default: {}, banner: "primary:R-W [SecondaryIndex1:R-W]...", desc: "Declares the r/w units for the model as well as any secondary indexes", :required => true
14
- class_option :gsi, type: :array, default: [], banner: "name:hkey{field_name}[,rkey{field_name},proj_type{ALL|KEYS_ONLY|INCLUDE}]...", desc: "Allows for the declaration of secondary indexes"
15
- class_option :table_name, type: :string, banner: "model_table_name"
16
- class_option :password_digest, type: :boolean, desc: "Whether to add a password_digest field to the model"
17
-
18
- class_option :required, type: :string, banner: "field1...", desc: "A list of attributes that are required for an instance of the model"
19
- class_option :length_validations, type: :hash, default: {}, banner: "field1:MIN-MAX...", desc: "Validations on the length of attributes in a model"
20
-
21
- attr_accessor :primary_read_units, :primary_write_units, :gsi_rw_units, :gsis, :required_attrs, :length_validations
22
-
23
- private
24
-
25
- def initialize(args, *options)
26
- options[0] << "--skip-table-config" if options[1][:behavior] == :revoke
27
- @parse_errors = []
28
-
29
- super
30
- ensure_unique_fields
31
- ensure_hkey
32
- parse_gsis!
33
- parse_table_config!
34
- parse_validations!
35
-
36
- if !@parse_errors.empty?
37
- STDERR.puts "The following errors were encountered while trying to parse the given attributes"
38
- STDERR.puts
39
- STDERR.puts @parse_errors
40
- STDERR.puts
41
-
42
- abort("Please fix the errors before proceeding.")
43
- end
44
- end
45
-
46
- def parse_attributes!
47
-
48
- self.attributes = (attributes || []).map do |attr|
49
- begin
50
- GeneratedAttribute.parse(attr)
51
- rescue ArgumentError => e
52
- @parse_errors << e
53
- next
54
- end
55
- end
56
- self.attributes = self.attributes.compact
8
+ module Generators
9
+ class Base < Rails::Generators::NamedBase
10
+ argument :attributes, type: :array, default: [], banner: 'field[:type][:opts]...',
11
+ desc: 'Describes the fields in the model'
12
+ check_class_collision
13
+
14
+ class_option :disable_mutation_tracking, type: :boolean, desc: 'Disables dirty tracking'
15
+ class_option :timestamps, type: :boolean, desc: 'Adds created, updated timestamps to the model'
16
+ class_option :table_config, type: :hash, default: {}, banner: 'primary:R-W [SecondaryIndex1:R-W]...',
17
+ desc: 'Declares the r/w units for the model as well as any secondary indexes', required: true
18
+ class_option :gsi, type: :array, default: [],
19
+ banner: 'name:hkey{field_name}[,rkey{field_name},proj_type{ALL|KEYS_ONLY|INCLUDE}]...', desc: 'Allows for the declaration of secondary indexes'
20
+ class_option :table_name, type: :string, banner: 'model_table_name'
21
+ class_option :password_digest, type: :boolean, desc: 'Whether to add a password_digest field to the model'
22
+
23
+ class_option :required, type: :string, banner: 'field1...',
24
+ desc: 'A list of attributes that are required for an instance of the model'
25
+ class_option :length_validations, type: :hash, default: {}, banner: 'field1:MIN-MAX...',
26
+ desc: 'Validations on the length of attributes in a model'
27
+
28
+ attr_accessor :primary_read_units, :primary_write_units, :gsi_rw_units, :gsis, :required_attrs,
29
+ :length_validations
30
+
31
+ private
32
+
33
+ def initialize(args, *options)
34
+ options[0] << '--skip-table-config' if options[1][:behavior] == :revoke
35
+ @parse_errors = []
36
+
37
+ super
38
+ ensure_unique_fields
39
+ ensure_hkey
40
+ parse_gsis!
41
+ parse_table_config!
42
+ parse_validations!
43
+
44
+ return if @parse_errors.empty?
45
+
46
+ warn 'The following errors were encountered while trying to parse the given attributes'
47
+ $stderr.puts
48
+ warn @parse_errors
49
+ $stderr.puts
50
+
51
+ abort('Please fix the errors before proceeding.')
52
+ end
57
53
 
58
- if options['password_digest']
59
- self.attributes << GeneratedAttribute.new("password_digest", :string_attr, :digest => true)
54
+ def parse_attributes!
55
+ self.attributes = (attributes || []).map do |attr|
56
+ begin
57
+ GeneratedAttribute.parse(attr)
58
+ rescue ArgumentError => e
59
+ @parse_errors << e
60
+ next
60
61
  end
62
+ end
63
+ self.attributes = attributes.compact
61
64
 
62
- if options['timestamps']
63
- self.attributes << GeneratedAttribute.parse("created:datetime:default_value{Time.now}")
64
- self.attributes << GeneratedAttribute.parse("updated:datetime:default_value{Time.now}")
65
- end
65
+ if options['password_digest']
66
+ attributes << GeneratedAttribute.new('password_digest', :string_attr, digest: true)
66
67
  end
67
68
 
68
- def ensure_unique_fields
69
- used_names = Set.new
70
- duplicate_fields = []
69
+ return unless options['timestamps']
71
70
 
72
- self.attributes.each do |attr|
71
+ attributes << GeneratedAttribute.parse('created:datetime:default_value{Time.now}')
72
+ attributes << GeneratedAttribute.parse('updated:datetime:default_value{Time.now}')
73
+ end
73
74
 
74
- if used_names.include? attr.name
75
- duplicate_fields << [:attribute, attr.name]
76
- end
77
- used_names.add attr.name
75
+ def ensure_unique_fields
76
+ used_names = Set.new
77
+ duplicate_fields = []
78
78
 
79
- if attr.options.key? :database_attribute_name
80
- raw_db_attr_name = attr.options[:database_attribute_name].delete('"') # db attribute names are wrapped with " to make template generation easier
79
+ attributes.each do |attr|
80
+ duplicate_fields << [:attribute, attr.name] if used_names.include? attr.name
81
+ used_names.add attr.name
81
82
 
82
- if used_names.include? raw_db_attr_name
83
- duplicate_fields << [:database_attribute_name, raw_db_attr_name]
84
- end
83
+ next unless attr.options.key? :database_attribute_name
85
84
 
86
- used_names.add raw_db_attr_name
87
- end
88
- end
85
+ raw_db_attr_name = attr.options[:database_attribute_name].delete('"') # db attribute names are wrapped with " to make template generation easier
89
86
 
90
- if !duplicate_fields.empty?
91
- duplicate_fields.each do |invalid_attr|
92
- @parse_errors << ArgumentError.new("Found duplicated field name: #{invalid_attr[1]}, in attribute#{invalid_attr[0]}")
93
- end
94
- end
87
+ duplicate_fields << [:database_attribute_name, raw_db_attr_name] if used_names.include? raw_db_attr_name
88
+
89
+ used_names.add raw_db_attr_name
95
90
  end
96
91
 
97
- def ensure_hkey
98
- uuid_member = nil
99
- hkey_member = nil
100
- rkey_member = nil
92
+ return if duplicate_fields.empty?
101
93
 
102
- self.attributes.each do |attr|
103
- if attr.options.key? :hash_key
104
- if hkey_member
105
- @parse_errors << ArgumentError.new("Redefinition of hash_key attr: #{attr.name}, original declaration of hash_key on: #{hkey_member.name}")
106
- next
107
- end
94
+ duplicate_fields.each do |invalid_attr|
95
+ @parse_errors << ArgumentError.new("Found duplicated field name: #{invalid_attr[1]}, in attribute#{invalid_attr[0]}")
96
+ end
97
+ end
108
98
 
109
- hkey_member = attr
110
- elsif attr.options.key? :range_key
111
- if rkey_member
112
- @parse_errors << ArgumentError.new("Redefinition of range_key attr: #{attr.name}, original declaration of range_key on: #{hkey_member.name}")
113
- next
114
- end
99
+ def ensure_hkey
100
+ uuid_member = nil
101
+ hkey_member = nil
102
+ rkey_member = nil
115
103
 
116
- rkey_member = attr
104
+ attributes.each do |attr|
105
+ if attr.options.key? :hash_key
106
+ if hkey_member
107
+ @parse_errors << ArgumentError.new("Redefinition of hash_key attr: #{attr.name}, original declaration of hash_key on: #{hkey_member.name}")
108
+ next
117
109
  end
118
110
 
119
- if attr.name.include? "uuid"
120
- uuid_member = attr
111
+ hkey_member = attr
112
+ elsif attr.options.key? :range_key
113
+ if rkey_member
114
+ @parse_errors << ArgumentError.new("Redefinition of range_key attr: #{attr.name}, original declaration of range_key on: #{hkey_member.name}")
115
+ next
121
116
  end
122
- end
123
117
 
124
- if !hkey_member
125
- if uuid_member
126
- uuid_member.options[:hash_key] = true
127
- else
128
- self.attributes.unshift GeneratedAttribute.parse("uuid:hkey")
129
- end
118
+ rkey_member = attr
130
119
  end
131
- end
132
120
 
133
- def mutation_tracking_disabled?
134
- options['disable_mutation_tracking']
121
+ uuid_member = attr if attr.name.include? 'uuid'
135
122
  end
136
123
 
137
- def has_validations?
138
- !@required_attrs.empty? || !@length_validations.empty?
124
+ return if hkey_member
125
+
126
+ if uuid_member
127
+ uuid_member.options[:hash_key] = true
128
+ else
129
+ attributes.unshift GeneratedAttribute.parse('uuid:hkey')
139
130
  end
131
+ end
140
132
 
141
- def parse_table_config!
142
- return unless options['table_config']
133
+ def mutation_tracking_disabled?
134
+ options['disable_mutation_tracking']
135
+ end
143
136
 
144
- @primary_read_units, @primary_write_units = parse_rw_units("primary")
137
+ def has_validations?
138
+ !@required_attrs.empty? || !@length_validations.empty?
139
+ end
145
140
 
146
- @gsi_rw_units = @gsis.map { |idx|
147
- [idx.name, parse_rw_units(idx.name)]
148
- }.to_h
141
+ def parse_table_config!
142
+ return unless options['table_config']
149
143
 
150
- options['table_config'].each do |config, rw_units|
151
- if config == "primary"
152
- next
153
- else
154
- gsi = @gsis.select { |idx| idx.name == config}
144
+ @primary_read_units, @primary_write_units = parse_rw_units('primary')
155
145
 
156
- if gsi.empty?
157
- @parse_errors << ArgumentError.new("Could not find a gsi declaration for #{config}")
158
- end
159
- end
160
- end
146
+ @gsi_rw_units = @gsis.map do |idx|
147
+ [idx.name, parse_rw_units(idx.name)]
148
+ end.to_h
149
+
150
+ options['table_config'].each do |config, _rw_units|
151
+ next if config == 'primary'
152
+
153
+ gsi = @gsis.select { |idx| idx.name == config }
154
+
155
+ @parse_errors << ArgumentError.new("Could not find a gsi declaration for #{config}") if gsi.empty?
161
156
  end
157
+ end
162
158
 
163
- def parse_rw_units(name)
164
- if !options['table_config'].key? name
165
- @parse_errors << ArgumentError.new("Please provide a table_config definition for #{name}")
166
- else
167
- rw_units = options['table_config'][name]
168
- return rw_units.gsub(/[,.-]/, ':').split(':').reject { |s| s.empty? }
169
- end
159
+ def parse_rw_units(name)
160
+ if options['table_config'].key? name
161
+ rw_units = options['table_config'][name]
162
+ rw_units.gsub(/[,.-]/, ':').split(':').reject(&:empty?)
163
+ else
164
+ @parse_errors << ArgumentError.new("Please provide a table_config definition for #{name}")
170
165
  end
166
+ end
171
167
 
172
- def parse_gsis!
173
- @gsis = (options['gsi'] || []).map do |raw_idx|
174
- begin
175
- idx = SecondaryIndex.parse(raw_idx)
168
+ def parse_gsis!
169
+ @gsis = (options['gsi'] || []).map do |raw_idx|
170
+ begin
171
+ idx = SecondaryIndex.parse(raw_idx)
176
172
 
177
- attributes = self.attributes.select { |attr| attr.name == idx.hash_key}
173
+ attributes = self.attributes.select { |attr| attr.name == idx.hash_key }
174
+ if attributes.empty?
175
+ @parse_errors << ArgumentError.new("Could not find attribute #{idx.hash_key} for gsi #{idx.name} hkey")
176
+ next
177
+ end
178
+
179
+ if idx.range_key
180
+ attributes = self.attributes.select { |attr| attr.name == idx.range_key }
178
181
  if attributes.empty?
179
- @parse_errors << ArgumentError.new("Could not find attribute #{idx.hash_key} for gsi #{idx.name} hkey")
182
+ @parse_errors << ArgumentError.new("Could not find attribute #{idx.range_key} for gsi #{idx.name} rkey")
180
183
  next
181
184
  end
182
-
183
- if idx.range_key
184
- attributes = self.attributes.select { |attr| attr.name == idx.range_key}
185
- if attributes.empty?
186
- @parse_errors << ArgumentError.new("Could not find attribute #{idx.range_key} for gsi #{idx.name} rkey")
187
- next
188
- end
189
- end
190
-
191
- idx
192
- rescue ArgumentError => e
193
- @parse_errors << e
194
- next
195
185
  end
196
- end
197
186
 
198
- @gsis = @gsis.compact
187
+ idx
188
+ rescue ArgumentError => e
189
+ @parse_errors << e
190
+ next
191
+ end
199
192
  end
200
193
 
201
- def parse_validations!
202
- @required_attrs = options['required'] ? options['required'].split(',') : []
203
- @required_attrs.each do |val_attr|
204
- @parse_errors << ArgumentError.new("No such field #{val_attr} in required validations") if !self.attributes.any? { |attr| attr.name == val_attr }
205
- end
194
+ @gsis = @gsis.compact
195
+ end
206
196
 
207
- @length_validations = options['length_validations'].map do |val_attr, bounds|
208
- @parse_errors << ArgumentError.new("No such field #{val_attr} in required validations") if !self.attributes.any? { |attr| attr.name == val_attr }
197
+ def parse_validations!
198
+ @required_attrs = options['required'] ? options['required'].split(',') : []
199
+ @required_attrs.each do |val_attr|
200
+ @parse_errors << ArgumentError.new("No such field #{val_attr} in required validations") if attributes.none? do |attr|
201
+ attr.name == val_attr
202
+ end
203
+ end
209
204
 
210
- bounds = bounds.gsub(/[,.-]/, ':').split(':').reject { |s| s.empty? }
211
- [val_attr, "#{bounds[0]}..#{bounds[1]}"]
212
- end
213
- @length_validations = @length_validations.to_h
205
+ @length_validations = options['length_validations'].map do |val_attr, bounds|
206
+ @parse_errors << ArgumentError.new("No such field #{val_attr} in required validations") if attributes.none? do |attr|
207
+ attr.name == val_attr
208
+ end
209
+
210
+ bounds = bounds.gsub(/[,.-]/, ':').split(':').reject(&:empty?)
211
+ [val_attr, "#{bounds[0]}..#{bounds[1]}"]
214
212
  end
213
+ @length_validations = @length_validations.to_h
215
214
  end
216
215
  end
217
216
  end
217
+ end
@@ -1,28 +1,31 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module AwsRecord
2
4
  module Generators
3
5
  class GeneratedAttribute
4
-
5
- OPTS = %w(hkey rkey persist_nil db_attr_name ddb_type default_value)
6
- INVALID_HKEY_TYPES = %i(map_attr list_attr numeric_set_attr string_set_attr)
6
+ OPTS = %w[hkey rkey persist_nil db_attr_name ddb_type default_value].freeze
7
+ INVALID_HKEY_TYPES = %i[map_attr list_attr numeric_set_attr string_set_attr].freeze
7
8
  attr_reader :name, :type
8
9
  attr_accessor :options
9
10
 
10
11
  def field_type
11
12
  case @type
12
- when :integer_attr then :number_field
13
- when :date_attr then :date_select
14
- when :datetime_attr then :datetime_select
15
- when :boolean_attr then :check_box
16
- else :text_field
13
+ when :integer_attr then :number_field
14
+ when :date_attr then :date_select
15
+ when :datetime_attr then :datetime_select
16
+ when :boolean_attr then :check_box
17
+ else :text_field
17
18
  end
18
19
  end
19
20
 
20
21
  class << self
21
-
22
22
  def parse(field_definition)
23
23
  name, type, opts = field_definition.split(':')
24
- type = "string" if not type
25
- type, opts = "string", type if OPTS.any? { |opt| type.include? opt }
24
+ type ||= 'string'
25
+ if OPTS.any? { |opt| type.include? opt }
26
+ opts = type
27
+ type = 'string'
28
+ end
26
29
 
27
30
  opts = opts.split(',') if opts
28
31
  type, opts = parse_type_and_options(name, type, opts)
@@ -34,65 +37,71 @@ module AwsRecord
34
37
  private
35
38
 
36
39
  def validate_opt_combs(name, type, opts)
37
- if opts
38
- is_hkey = opts.key?(:hash_key)
39
- is_rkey = opts.key?(:range_key)
40
+ return unless opts
41
+
42
+ is_hkey = opts.key?(:hash_key)
43
+ is_rkey = opts.key?(:range_key)
40
44
 
41
- raise ArgumentError.new("Field #{name} cannot be a range key and hash key simultaneously") if is_hkey && is_rkey
42
- raise ArgumentError.new("Field #{name} cannot be a hash key and be of type #{type}") if is_hkey and INVALID_HKEY_TYPES.include? type
45
+ if is_hkey && is_rkey
46
+ raise ArgumentError,
47
+ "Field #{name} cannot be a range key and hash key simultaneously"
43
48
  end
49
+ return unless is_hkey && INVALID_HKEY_TYPES.include?(type)
50
+
51
+ raise ArgumentError,
52
+ "Field #{name} cannot be a hash key and be of type #{type}"
44
53
  end
45
54
 
46
55
  def parse_type_and_options(name, type, opts)
47
- opts = [] if not opts
48
- return parse_type(name, type), opts.map { |opt| parse_option(name, opt) }.to_h
56
+ opts ||= []
57
+ [parse_type(name, type), opts.map { |opt| parse_option(name, opt) }.to_h]
49
58
  end
50
59
 
51
60
  def parse_option(name, opt)
52
61
  case opt
53
62
 
54
- when "hkey"
55
- return :hash_key, true
56
- when "rkey"
57
- return :range_key, true
58
- when "persist_nil"
59
- return :persist_nil, true
63
+ when 'hkey'
64
+ [:hash_key, true]
65
+ when 'rkey'
66
+ [:range_key, true]
67
+ when 'persist_nil'
68
+ [:persist_nil, true]
60
69
  when /db_attr_name\{(\w+)\}/
61
- return :database_attribute_name, '"' + $1 + '"'
70
+ [:database_attribute_name, "\"#{::Regexp.last_match(1)}\""]
62
71
  when /ddb_type\{(S|N|B|BOOL|SS|NS|BS|M|L)\}/i
63
- return :dynamodb_type, '"' + $1.upcase + '"'
72
+ [:dynamodb_type, "\"#{::Regexp.last_match(1).upcase}\""]
64
73
  when /default_value\{(.+)\}/
65
- return :default_value, $1
74
+ [:default_value, ::Regexp.last_match(1)]
66
75
  else
67
- raise ArgumentError.new("You provided an invalid option for #{name}: #{opt}")
76
+ raise ArgumentError, "You provided an invalid option for #{name}: #{opt}"
68
77
  end
69
78
  end
70
79
 
71
80
  def parse_type(name, type)
72
81
  case type.downcase
73
82
 
74
- when "bool", "boolean"
83
+ when 'bool', 'boolean'
75
84
  :boolean_attr
76
- when "date"
85
+ when 'date'
77
86
  :date_attr
78
- when "datetime"
87
+ when 'datetime'
79
88
  :datetime_attr
80
- when "float"
89
+ when 'float'
81
90
  :float_attr
82
- when "int", "integer"
91
+ when 'int', 'integer'
83
92
  :integer_attr
84
- when "list"
93
+ when 'list'
85
94
  :list_attr
86
- when "map"
95
+ when 'map'
87
96
  :map_attr
88
- when "num_set", "numeric_set", "nset"
97
+ when 'num_set', 'numeric_set', 'nset'
89
98
  :numeric_set_attr
90
- when "string_set", "s_set", "sset"
99
+ when 'string_set', 's_set', 'sset'
91
100
  :string_set_attr
92
- when "string"
101
+ when 'string'
93
102
  :string_attr
94
103
  else
95
- raise ArgumentError.new("Invalid type for #{name}: #{type}")
104
+ raise ArgumentError, "Invalid type for #{name}: #{type}"
96
105
  end
97
106
  end
98
107
  end
@@ -114,8 +123,8 @@ module AwsRecord
114
123
  end
115
124
 
116
125
  def column_name
117
- if @name == "password_digest"
118
- "password"
126
+ if @name == 'password_digest'
127
+ 'password'
119
128
  else
120
129
  @name
121
130
  end
@@ -1,21 +1,25 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative '../base'
2
4
 
3
5
  module AwsRecord
4
6
  module Generators
5
7
  class ModelGenerator < Base
6
8
  def initialize(args, *options)
7
- self.class.source_root File.expand_path('../templates', __FILE__)
9
+ self.class.source_root File.expand_path('templates', __dir__)
8
10
  super
9
11
  end
10
12
 
11
13
  def create_model
12
- template "model.erb", File.join("app/models", class_path, "#{file_name}.rb")
14
+ template 'model.erb', File.join('app/models', class_path, "#{file_name}.rb")
13
15
  end
14
16
 
15
17
  def create_table_config
16
- template "table_config.erb", File.join("db/table_config", class_path, "#{file_name}_config.rb") if options["table_config"]
17
- end
18
+ return unless options['table_config']
18
19
 
20
+ template 'table_config.erb',
21
+ File.join('db/table_config', class_path, "#{file_name}_config.rb")
22
+ end
19
23
  end
20
24
  end
21
25
  end
@@ -1,8 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module AwsRecord
2
4
  module Generators
3
5
  class SecondaryIndex
4
-
5
- PROJ_TYPES = %w(ALL KEYS_ONLY INCLUDE)
6
+ PROJ_TYPES = %w[ALL KEYS_ONLY INCLUDE].freeze
6
7
  attr_reader :name, :hash_key, :range_key, :projection_type
7
8
 
8
9
  class << self
@@ -15,45 +16,50 @@ module AwsRecord
15
16
  end
16
17
 
17
18
  private
18
- def parse_raw_options(raw_opts)
19
- raw_opts = [] if not raw_opts
20
- raw_opts.map { |opt| get_option_value(opt) }.to_h
21
- end
22
19
 
23
- def get_option_value(raw_option)
24
- case raw_option
25
-
26
- when /hkey\{(\w+)\}/
27
- return :hash_key, $1
28
- when /rkey\{(\w+)\}/
29
- return :range_key, $1
30
- when /proj_type\{(\w+)\}/
31
- return :projection_type, $1
32
- else
33
- raise ArgumentError.new("Invalid option for secondary index #{raw_option}")
34
- end
20
+ def parse_raw_options(raw_opts)
21
+ raw_opts ||= []
22
+ raw_opts.map { |opt| get_option_value(opt) }.to_h
23
+ end
24
+
25
+ def get_option_value(raw_option)
26
+ case raw_option
27
+
28
+ when /hkey\{(\w+)\}/
29
+ [:hash_key, ::Regexp.last_match(1)]
30
+ when /rkey\{(\w+)\}/
31
+ [:range_key, ::Regexp.last_match(1)]
32
+ when /proj_type\{(\w+)\}/
33
+ [:projection_type, ::Regexp.last_match(1)]
34
+ else
35
+ raise ArgumentError, "Invalid option for secondary index #{raw_option}"
35
36
  end
37
+ end
36
38
  end
37
39
 
38
40
  def initialize(name, opts)
39
- raise ArgumentError.new("You must provide a name") if not name
40
- raise ArgumentError.new("You must provide a hash key") if not opts[:hash_key]
41
+ raise ArgumentError, 'You must provide a name' unless name
42
+ raise ArgumentError, 'You must provide a hash key' unless opts[:hash_key]
41
43
 
42
44
  if opts.key? :projection_type
43
- raise ArgumentError.new("Invalid projection type #{opts[:projection_type]}") if not PROJ_TYPES.include? opts[:projection_type]
44
- raise NotImplementedError.new("ALL is the only projection type currently supported") if opts[:projection_type] != "ALL"
45
+ unless PROJ_TYPES.include? opts[:projection_type]
46
+ raise ArgumentError, "Invalid projection type #{opts[:projection_type]}"
47
+ end
48
+ if opts[:projection_type] != 'ALL'
49
+ raise NotImplementedError, 'ALL is the only projection type currently supported'
50
+ end
45
51
  else
46
- opts[:projection_type] = "ALL"
52
+ opts[:projection_type] = 'ALL'
47
53
  end
48
54
 
49
55
  if opts[:hash_key] == opts[:range_key]
50
- raise ArgumentError.new("#{opts[:hash_key]} cannot be both the rkey and hkey for gsi #{name}")
56
+ raise ArgumentError, "#{opts[:hash_key]} cannot be both the rkey and hkey for gsi #{name}"
51
57
  end
52
58
 
53
59
  @name = name
54
60
  @hash_key = opts[:hash_key]
55
61
  @range_key = opts[:range_key]
56
- @projection_type = '"' + "#{opts[:projection_type]}" + '"'
62
+ @projection_type = "\"#{opts[:projection_type]}\""
57
63
  end
58
64
  end
59
65
  end