dynamini 2.6.2 → 2.6.3

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
  SHA1:
3
- metadata.gz: eb80f52caa4a21c3f189d5427e7aa9ae90a1a2e0
4
- data.tar.gz: 1c2f76b9cd36ccba731f263efabceeeafeb8ae97
3
+ metadata.gz: 7075482c77f8b6cec60de580a672fed23b646f51
4
+ data.tar.gz: 03b4480b94b8e8c312885339d06ed86fd59687ad
5
5
  SHA512:
6
- metadata.gz: 0fc0ddf4c8c732c6943800a1fe735a1176203bb9f3740b2fb6cf762cfbe1d614bb684c7b34c32b9f04893668bc66f7745aa6d93addb55b9c199c09de81866a2e
7
- data.tar.gz: a658de15ef8a2b607b68f7799d3ed23262df8df223fbfc838039e310a3986cfba8a99392fe0b5642eb56de2b38b4aa3d221fa244b22af109a34cd5dc5968d7dc
6
+ metadata.gz: 49a1fff7890939d2cd39c8fb756c29cfd1c852155e90efa797f659d8488b26e720eedd7da0521734a047bb5e9f0ebf7e8c10cd090f8d2bed52337b55a1575b11
7
+ data.tar.gz: 1e0ece3e30f4c3d7acbc10a6f6a5ecf814f3b09efc4542776cc180c40a2c2e83a2f39fa33f9d3845f3a49155411fdd65e3282d287a47d786c2ae11111aa7c08d
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- dynamini (2.6.2)
4
+ dynamini (2.6.3)
5
5
  activemodel (>= 3, < 5.0)
6
6
  aws-sdk (~> 2)
7
7
 
data/README.md CHANGED
@@ -111,7 +111,7 @@ You can save arrays and sets to your Dynamini model. Optionally, you can have Dy
111
111
  ```ruby
112
112
  class Vehicle < Dynamini::Base
113
113
  set_hash_key :vin
114
- handle :parts, :array, of: :symbol # :of accepts the same types as :handle
114
+ handle :parts, :array, of: :symbol # :of accepts all types except :set and :array
115
115
  handle :other_array, :array
116
116
  end
117
117
 
@@ -119,7 +119,7 @@ car = Vehicle.new(vin: 'H3LL0')
119
119
  car.parts
120
120
  > []
121
121
 
122
- car.parts = 'wheel'
122
+ car.parts = ['wheel']
123
123
  car.parts
124
124
  > :wheel
125
125
 
@@ -130,7 +130,7 @@ car.parts
130
130
  # This line will raise an error since 5 cannot be converted to a symbol.
131
131
  car.parts = ['wheel', 'brakes', 5]
132
132
 
133
- # If you want a multitype array, invoke :handle without the :of option.
133
+ # If you want a multitype array, use :handle without the :of option.
134
134
  car.other_array = ['wheel', 'brakes', 5]
135
135
  car.other_array
136
136
  > ['wheel', 'brakes', 5]
@@ -140,7 +140,7 @@ Vehicle.find('H3LLO').other_array
140
140
  > ['wheel', 'brakes', BigDecimal(5)]
141
141
  ```
142
142
 
143
- Please note that changing enumerables in place using mutator methods like << or map! will not record a change to the object.
143
+ Please note that changing enumerables in place using mutator methods like << or map! will not record a change to the object.
144
144
 
145
145
  If you want to make changes like this, either clone it then use the assignment operator (e.g. model.array = model.array.dup << 'foo') or call model.mark(:attribute) after mutation and before saving to force Dynamini to write the change.
146
146
 
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'dynamini'
3
- s.version = '2.6.2'
3
+ s.version = '2.6.3'
4
4
  s.summary = 'DynamoDB interface'
5
5
  s.description = 'Lightweight DynamoDB interface gem designed as
6
6
  a drop-in replacement for ActiveRecord.
@@ -1,16 +1,16 @@
1
1
  module Dynamini
2
2
  module Adder
3
+
4
+ ADDABLE_TYPES = [:set, :array, :integer, :float, :time, :date]
5
+
3
6
  def add_to(attribute, value)
4
7
  complain_about(attribute) unless handles[attribute]
5
8
  old_value = read_attribute(attribute)
6
9
  add_value = attribute_callback(Dynamini::TypeHandler::SETTER_PROCS, handles[attribute], value)
7
- case handles[attribute][:format]
8
- when :set, :array
9
- @attributes[attribute] += add_value
10
- when :integer, :float, :time, :date
11
- @attributes[attribute] += add_value
12
- else
13
- complain_about(attribute)
10
+ if ADDABLE_TYPES.include? handles[attribute][:format]
11
+ @attributes[attribute] ? @attributes[attribute] += add_value : @attributes[attribute] = add_value
12
+ else
13
+ complain_about(attribute)
14
14
  end
15
15
  record_change(attribute, old_value, add_value, 'ADD')
16
16
  self
@@ -220,13 +220,11 @@ module Dynamini
220
220
  def handle_updates(args, hash_key_value, range_key_value, attribute_hash)
221
221
  table = get_table(args[:table_name])
222
222
  args[:attribute_updates].each do |k, v|
223
-
224
223
  if v[:action] == 'ADD' && table[hash_key_value]
225
224
  # if record has been saved
226
225
  data = table[hash_key_value]
227
226
  data = (data[range_key_value] ||= {}) if range_key_value
228
-
229
- attribute_hash[k] = (v[:value] + data[k].to_f)
227
+ attribute_hash[k] = data[k] ? data[k] + v[:value] : v[:value]
230
228
  else
231
229
  attribute_hash[k] = v[:value]
232
230
  end
@@ -27,6 +27,8 @@ module Dynamini
27
27
 
28
28
  module ClassMethods
29
29
  def handle(column, format_class, options = {})
30
+ validate_handle(format_class, options)
31
+
30
32
  options[:default] ||= format_default(format_class)
31
33
  options[:default] ||= Set.new if format_class == :set
32
34
 
@@ -62,6 +64,14 @@ module Dynamini
62
64
  Set.new
63
65
  end
64
66
  end
67
+
68
+ def validate_handle(format, options)
69
+ if format == :set
70
+ if options[:of] && [:set, :array].include?(options[:of])
71
+ raise ArgumentError, 'Invalid handle: cannot store non-primitive datatypes within a set.'
72
+ end
73
+ end
74
+ end
65
75
  end
66
76
 
67
77
  private
@@ -101,6 +111,5 @@ module Dynamini
101
111
  def convert_elements(enumerable, callback)
102
112
  enumerable.map { |e| callback.call(e) }
103
113
  end
104
-
105
114
  end
106
115
  end
@@ -9,6 +9,8 @@ describe Dynamini::Adder do
9
9
  handle :when, :date
10
10
  handle :what_time, :time
11
11
  handle :widget_count, :integer
12
+ handle :new_set, :set
13
+ handle :new_array, :array
12
14
  end
13
15
 
14
16
  let(:model_attributes) {
@@ -22,7 +24,7 @@ describe Dynamini::Adder do
22
24
  }
23
25
  }
24
26
 
25
- let(:model) { AddHandledModel.new(model_attributes, false) }
27
+ let(:model) { AddHandledModel.new(model_attributes) }
26
28
 
27
29
 
28
30
  describe '.add_to' do
@@ -63,6 +65,12 @@ describe Dynamini::Adder do
63
65
  expect{ model.add_to(:things, 4) }.to raise_error ArgumentError
64
66
  end
65
67
  end
68
+ context 'adding to an uninitialized set' do
69
+ it 'creates the set' do
70
+ model.add_to(:new_set, Set.new([4]))
71
+ expect(model.new_set).to eq(Set.new([4]))
72
+ end
73
+ end
66
74
  end
67
75
 
68
76
  context 'adding to an array' do
@@ -77,6 +85,22 @@ describe Dynamini::Adder do
77
85
  expect{ model.add_to(:stuff, 4) }.to raise_error ArgumentError
78
86
  end
79
87
  end
88
+ context 'adding to an empty array' do
89
+ it 'creates the array' do
90
+ model.add_to(:new_array, [4])
91
+ expect(model.new_array).to eq([4])
92
+ end
93
+ end
94
+ end
95
+
96
+ context 'without reading a previously saved item' do
97
+ it 'still adds' do
98
+ model.save
99
+ model2 = AddHandledModel.new(id: model_attributes[:id])
100
+ model2.add_to(:price, 2)
101
+ model2.save
102
+ expect(AddHandledModel.find(model_attributes[:id]).price).to eq(11.99)
103
+ end
80
104
  end
81
105
  end
82
106
  end
@@ -26,6 +26,13 @@ describe Dynamini::TestClient do
26
26
  test_client.update_item(table_name: table_name, key: {hash_key_name: 'hash_key_value'}, attribute_updates: {abc: {value: 1, action: 'ADD'}})
27
27
  expect(test_client.data[table_name]['hash_key_value']).to eq(abc: 2, hash_key_name: 'hash_key_value')
28
28
  end
29
+
30
+ it 'should be able to add to an existing set' do
31
+ test_client = Dynamini::TestClient.new(:hash_key_name)
32
+ test_client.update_item(table_name: table_name, key: {hash_key_name: 'hash_key_value'}, attribute_updates: {abc: {value: Set.new([1]), action: 'PUT'}})
33
+ test_client.update_item(table_name: table_name, key: {hash_key_name: 'hash_key_value'}, attribute_updates: {abc: {value: Set.new([2]), action: 'ADD'}})
34
+ expect(test_client.data[table_name]['hash_key_value']).to eq(abc: Set.new([1, 2]), hash_key_name: 'hash_key_value')
35
+ end
29
36
  end
30
37
 
31
38
  context 'with Hash key and range key' do
@@ -127,5 +127,13 @@ describe Dynamini::TypeHandler do
127
127
  handle_model.float_set = [12,24,48]
128
128
  expect(handle_model.float_set).to_not be_a(Array)
129
129
  end
130
+
131
+ it 'should complain if trying to cast elements as arrays' do
132
+ expect{ HandleModel.handle :invalid, :set, of: :array}.to raise_error ArgumentError
133
+ end
134
+
135
+ it 'should complain if trying to cast elements as sets' do
136
+ expect{ HandleModel.handle :invalid, :set, of: :set}.to raise_error ArgumentError
137
+ end
130
138
  end
131
139
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dynamini
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.6.2
4
+ version: 2.6.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Greg Ward
@@ -15,7 +15,7 @@ authors:
15
15
  autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
- date: 2016-09-22 00:00:00.000000000 Z
18
+ date: 2016-09-27 00:00:00.000000000 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: activemodel