dynamini 1.5.2 → 1.5.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: 1fdfa96c8bf677260145f5d6bb35de6cf667cf90
4
- data.tar.gz: 9044d8ce4cf6dfbaab3daa7003e0c5eab9862d43
3
+ metadata.gz: 6e3b7806d587712702fe4d97bfa6e61c30e31227
4
+ data.tar.gz: d9420a6dded6bdeb3116abc6498afff11a825c5b
5
5
  SHA512:
6
- metadata.gz: c73f11b146c731254765292c25a777d77efef22f50298db7e203480d1ac01e6cd58c12a585f777dfdea06fc2526fb21cad65d46198ebada01b8f480709c8f15e
7
- data.tar.gz: 6c586d97d5bafa884c5011020cfcd716ce3e8023ab807a51249a44d5cd3d605459f8b1350eac758b0bfdd7671bc50d1bfcfb42eaa7330b8e39fb7bf32e23e968
6
+ metadata.gz: 4f66f26a56d22e788797901d058183a087909e46545bfb3cc09ee2db0f23d5c351dbd472d5a6a373540925fc07f65ca57826dd57606585059f780f11f39b5529
7
+ data.tar.gz: a239e9829dda149d4a73e981b9d15eeee8d9281d70d83ed97620053259f099ca5d1cb3d807174833fde6ff910cf161021c9cfd7df6a5d33284a1177709ae0f3a
data/lib/dynamini/base.rb CHANGED
@@ -1,26 +1,27 @@
1
1
  module Dynamini
2
+ # Core db interface class.
2
3
  class Base
3
4
  include ActiveModel::Validations
4
5
  attr_reader :attributes
5
6
 
6
7
  BATCH_SIZE = 25
7
8
  GETTER_PROCS = {
8
- integer: Proc.new { |v| v.to_i },
9
- datetime: Proc.new { |v| Time.at(v.to_f) },
10
- float: Proc.new { |v| v.to_f },
11
- symbol: Proc.new { |v| v.to_sym },
12
- string: Proc.new { |v| v },
13
- boolean: Proc.new { |v| ['true', '1', '1.0'].include? v },
14
- array: Proc.new { |v| v ? JSON.parse(v) : [] }
9
+ integer: proc { |v| v.to_i },
10
+ datetime: proc { |v| Time.at(v.to_f) },
11
+ float: proc { |v| v.to_f },
12
+ symbol: proc { |v| v.to_sym },
13
+ string: proc { |v| v },
14
+ boolean: proc { |v| ['true', '1', '1.0'].include? v },
15
+ array: proc { |v| v ? (v.is_a?(String) ? JSON.parse(v) : v) : [] }
15
16
  }
16
17
  SETTER_PROCS = {
17
- datetime: Proc.new { |v| v.to_f },
18
- array: Proc.new { |v| v if v.is_a? Array }
18
+ datetime: proc { |v| v.to_f },
19
+ array: proc { |v| v if v.is_a? Array }
19
20
  }
20
21
 
21
22
  class << self
22
-
23
23
  attr_writer :batch_write_queue, :in_memory
24
+ attr_reader :range_key
24
25
 
25
26
  def table_name
26
27
  @table_name ||= name.demodulize.tableize
@@ -38,7 +39,7 @@ module Dynamini
38
39
  @range_key = key
39
40
  end
40
41
 
41
- def handle(column, format_class, options={})
42
+ def handle(column, format_class, options = {})
42
43
  define_handled_getter(column, format_class, options)
43
44
  define_handled_setter(column, format_class)
44
45
  end
@@ -47,10 +48,6 @@ module Dynamini
47
48
  @hash_key || :id
48
49
  end
49
50
 
50
- def range_key
51
- @range_key
52
- end
53
-
54
51
  def in_memory
55
52
  @in_memory || false
56
53
  end
@@ -66,57 +63,56 @@ module Dynamini
66
63
  @client ||= Aws::DynamoDB::Client.new(
67
64
  region: Dynamini.configuration.region,
68
65
  access_key_id: Dynamini.configuration.access_key_id,
69
- secret_access_key: Dynamini.configuration.secret_access_key)
66
+ secret_access_key: Dynamini.configuration.secret_access_key
67
+ )
70
68
  end
71
69
  end
72
70
 
73
- def create(attributes, options={})
74
- model = self.new(attributes, true)
71
+ def create(attributes, options = {})
72
+ model = new(attributes, true)
75
73
  model if model.save(options)
76
74
  end
77
75
 
78
- def create!(attributes, options={})
79
- model = self.new(attributes, true)
76
+ def create!(attributes, options = {})
77
+ model = new(attributes, true)
80
78
  model if model.save!(options)
81
79
  end
82
80
 
83
81
  def find(hash_value, range_value = nil)
84
- raise "Range key can not be blank" if range_key && range_value.nil?
82
+ fail 'Range key cannot be blank.' if range_key && range_value.nil?
85
83
  response = client.get_item(table_name: table_name, key: create_key_hash(hash_value, range_value))
86
84
  raise 'Item not found.' unless response.item
87
- self.new(response.item.symbolize_keys, false)
85
+ new(response.item.symbolize_keys, false)
88
86
  end
89
87
 
90
88
  def exists?(key)
91
- response = client.get_item(table_name: table_name, key: {hash_key => key.to_s})
92
- response.item.present?
89
+ r = client.get_item(table_name: table_name, key: { hash_key => key.to_s })
90
+ r.item.present?
93
91
  end
94
92
 
95
93
  def find_or_new(key)
96
- response = client.get_item(table_name: table_name, key: {hash_key => key.to_s})
97
- if response.item
98
- self.new(response.item.symbolize_keys, false)
94
+ r = client.get_item(table_name: table_name, key: { hash_key => key.to_s })
95
+ if r.item
96
+ new(r.item.symbolize_keys, false)
99
97
  else
100
- self.new(hash_key => key.to_s)
98
+ new(hash_key => key.to_s)
101
99
  end
102
100
  end
103
101
 
104
102
  def batch_find(ids = [])
105
103
  return [] if ids.length < 1
106
104
  objects = []
107
- if ids.length > 100
108
- raise StandardError, 'Batch find is limited to 100 items'
109
- end
105
+ fail StandardError, 'Batch is limited to 100 items' if ids.length > 100
110
106
  key_structure = ids.map { |i| { hash_key => i.to_s } }
111
- response = self.dynamo_batch_get(key_structure)
107
+ response = dynamo_batch_get(key_structure)
112
108
  response.responses[table_name].each do |item|
113
- objects << self.new(item.symbolize_keys, false)
109
+ objects << new(item.symbolize_keys, false)
114
110
  end
115
111
  objects
116
112
  end
117
113
 
118
114
  def enqueue_for_save(attributes, options = {})
119
- model = self.new(attributes, true)
115
+ model = new(attributes, true)
120
116
  model.generate_timestamps! unless options[:skip_timestamps]
121
117
  if model.valid?
122
118
  batch_write_queue << model
@@ -127,7 +123,7 @@ module Dynamini
127
123
  end
128
124
 
129
125
  def flush_queue!
130
- response = self.dynamo_batch_save(batch_write_queue)
126
+ response = dynamo_batch_save(batch_write_queue)
131
127
  self.batch_write_queue = []
132
128
  response
133
129
  end
@@ -136,7 +132,7 @@ module Dynamini
136
132
 
137
133
  #### Instance Methods
138
134
 
139
- def initialize(attributes={}, new_record = true)
135
+ def initialize(attributes = {}, new_record = true)
140
136
  @changed = Set.new
141
137
  @new_record = new_record
142
138
  @attributes = {}
@@ -146,9 +142,8 @@ module Dynamini
146
142
  end
147
143
  end
148
144
 
149
-
150
- def ==(object)
151
- hash_key == object.hash_key if object.is_a?(self.class)
145
+ def ==(other)
146
+ hash_key == other.hash_key if other.is_a?(self.class)
152
147
  end
153
148
 
154
149
  def assign_attributes(attributes)
@@ -173,8 +168,7 @@ module Dynamini
173
168
  end
174
169
 
175
170
  def save!(options = {})
176
-
177
- options[:validate]= true if options[:validate].nil?
171
+ options[:validate] = true if options[:validate].nil?
178
172
 
179
173
  unless @changed.empty?
180
174
  if (options[:validate] && valid?) || !options[:validate]
@@ -207,7 +201,10 @@ module Dynamini
207
201
  end
208
202
 
209
203
  def changes
210
- @attributes.select { |attribute| @changed.include?(attribute.to_s) && attribute != self.class.hash_key && attribute != self.class.range_key }
204
+ @attributes.select { |attribute| @changed.include?(attribute.to_s) &&
205
+ attribute != self.class.hash_key &&
206
+ attribute != self.class.range_key
207
+ }
211
208
  end
212
209
 
213
210
  def changed
@@ -239,34 +236,57 @@ module Dynamini
239
236
  end
240
237
 
241
238
  def generate_timestamps!
242
- self.updated_at= Time.now.to_f
243
- self.created_at= Time.now.to_f if new_record?
239
+ self.updated_at = Time.now.to_f
240
+ self.created_at = Time.now.to_f if new_record?
244
241
  end
245
242
 
246
243
  def save_to_dynamo
247
- self.class.client.update_item(table_name: self.class.table_name, key: key, attribute_updates: attribute_updates)
244
+ self.class.client.update_item(
245
+ table_name: self.class.table_name,
246
+ key: key,
247
+ attribute_updates: attribute_updates
248
+ )
248
249
  end
249
250
 
250
251
  def touch_to_dynamo
251
- self.class.client.update_item(table_name: self.class.table_name, key: key, attribute_updates: {updated_at: {value: Time.now.to_f, action: 'PUT'}})
252
+ self.class.client.update_item(
253
+ table_name: self.class.table_name,
254
+ key: key,
255
+ attribute_updates:
256
+ { updated_at:
257
+ { value: Time.now.to_f,
258
+ action: 'PUT'
259
+ }
260
+ }
261
+ )
252
262
  end
253
263
 
254
264
  def delete_from_dynamo
255
265
  self.class.client.delete_item(table_name: self.class.table_name, key: key)
256
266
  end
257
267
 
258
- def increment_to_dynamo(attribute_increments, opts={})
259
- self.class.client.update_item(table_name: self.class.table_name, key: key, attribute_updates: increment_updates(attribute_increments, opts))
268
+ def increment_to_dynamo(attribute_increments, opts = {})
269
+ self.class.client.update_item(
270
+ table_name: self.class.table_name,
271
+ key: key,
272
+ attribute_updates: increment_updates(attribute_increments, opts)
273
+ )
260
274
  end
261
275
 
262
- def self.dynamo_batch_get(key_structure)
263
- client.batch_get_item(request_items: {table_name => {keys: key_structure}})
276
+ def self.dynamo_batch_get(key_struct)
277
+ client.batch_get_item(
278
+ request_items: {
279
+ table_name => { keys: key_struct }
280
+ }
281
+ )
264
282
  end
265
283
 
266
284
  def self.dynamo_batch_save(model_array)
267
285
  put_requests = []
268
286
  model_array.each do |model|
269
- put_requests << { put_request: { item: model.attributes.reject{|_k, v| v.blank? }.stringify_keys } }
287
+ put_requests << { put_request: {
288
+ item: model.attributes.reject{ |_k, v| v.blank? }.stringify_keys
289
+ } }
270
290
  end
271
291
  request_options = { request_items: {
272
292
  "#{table_name}" => put_requests }
@@ -293,13 +313,13 @@ module Dynamini
293
313
  end
294
314
  end
295
315
 
296
- def increment_updates(attribute_increments, opts={})
316
+ def increment_updates(attribute_increments, opts = {})
297
317
  updates = {}
298
318
  attribute_increments.each do |k,v|
299
- updates[k] = {value: v, action: 'ADD'}
319
+ updates[k] = { value: v, action: 'ADD' }
300
320
  end
301
- updates[:updated_at] = {value: Time.now.to_f, action: 'PUT'} unless opts[:skip_timestamps]
302
- updates[:created_at] = {value: Time.now.to_f, action: 'PUT'} unless attributes[:created_at]
321
+ updates[:updated_at] = { value: Time.now.to_f, action: 'PUT' } unless opts[:skip_timestamps]
322
+ updates[:created_at] = { value: Time.now.to_f, action: 'PUT' } unless attributes[:created_at]
303
323
  updates
304
324
  end
305
325
 
@@ -307,10 +327,14 @@ module Dynamini
307
327
  if value.is_a?(Integer) || value.is_a?(Float)
308
328
  current_value = self.send(attribute)
309
329
  unless current_value.nil? || current_value.is_a?(Integer) || current_value.is_a?(Float)
310
- raise StandardError, "You cannot increment a non-numeric non-nil value: #{attribute} is currently #{current_value}. If your current value is a numeric string, use :handle to autocast it as a number."
330
+ fail StandardError, "Cannot increment a non-numeric non-nil value:
331
+ #{attribute} is currently #{current_value}.
332
+ If your current value is a numeric string,
333
+ use :handle to autocast it as a number."
311
334
  end
312
335
  else
313
- raise StandardError, "You cannot increment an attribute by a non-numeric value: #{value}"
336
+ fail StandardError, "You cannot increment an attribute by a
337
+ non-numeric value: #{value}"
314
338
  end
315
339
  end
316
340
 
@@ -338,11 +362,11 @@ module Dynamini
338
362
  name =~ /^([a-zA-Z][-_\w]*)=.*$/
339
363
  end
340
364
 
341
- def self.define_handled_getter(column, format_class, options={})
365
+ def self.define_handled_getter(column, format_class, options = {})
342
366
  proc = GETTER_PROCS[format_class]
343
- raise 'Unsupported data type: ' + format_class.to_s if proc.nil?
367
+ fail 'Unsupported data type: ' + format_class.to_s if proc.nil?
344
368
  define_method(column) do
345
- if @attributes.has_key?(column)
369
+ if @attributes.key?(column)
346
370
  proc.call(read_attribute(column))
347
371
  else
348
372
  options[:default] || nil
@@ -364,14 +388,14 @@ module Dynamini
364
388
  end
365
389
  end
366
390
 
367
- def respond_to_missing?(name, include_private=false)
391
+ def respond_to_missing?(name, include_private = false)
368
392
  @attributes.keys.include?(name) || write_method?(name) || super
369
393
  end
370
394
 
371
- def write_attribute(attribute, new_value, record_change=true)
395
+ def write_attribute(attribute, new_value, record_change = true)
372
396
  old_value = @attributes[attribute]
373
- @attributes[attribute] = (new_value.nil? ? nil : new_value.to_s)
374
- record_change(attribute, new_value.to_s, old_value) if record_change
397
+ @attributes[attribute] = (new_value.nil? ? nil : new_value)
398
+ record_change(attribute, new_value, old_value) if record_change
375
399
  end
376
400
 
377
401
  def record_change(attribute, new_value, old_value)
@@ -1,5 +1,6 @@
1
1
  module Dynamini
2
+ # Config class to be used with initializers.
2
3
  class Configuration
3
4
  attr_accessor :region, :access_key_id, :secret_access_key
4
5
  end
5
- end
6
+ end
@@ -1,6 +1,7 @@
1
1
  module Dynamini
2
2
  require 'ostruct'
3
3
 
4
+ # In-memory database client for test purposes.
4
5
  class TestClient
5
6
 
6
7
  attr_reader :hash_key
@@ -12,12 +13,14 @@ module Dynamini
12
13
 
13
14
  def update_item(args = {})
14
15
  table = args[:table_name]
15
- updates = flatten_attribute_updates(args).merge({hash_key => args[:key][hash_key]})
16
+ updates = flatten_attribute_updates(args).merge(
17
+ hash_key => args[:key][hash_key].to_s
18
+ )
16
19
  @data[table] ||= {}
17
- if @data[table][args[:key][hash_key]].present?
18
- @data[table][args[:key][hash_key]].merge!(updates)
20
+ if @data[table][args[:key][hash_key].to_s].present?
21
+ @data[table][args[:key][hash_key].to_s].merge!(updates)
19
22
  else
20
- @data[table][args[:key][hash_key]] = updates
23
+ @data[table][args[:key][hash_key].to_s] = updates
21
24
  end
22
25
  end
23
26
 
@@ -68,14 +71,14 @@ module Dynamini
68
71
  attribute_hash = {}
69
72
 
70
73
  args[:attribute_updates].each do |k, v|
71
- if v[:action] == 'ADD' && @data[args[:table_name]][args[:key][hash_key]] #if record has been saved
72
- attribute_hash[k] = v[:value] + @data[args[:table_name]][args[:key][hash_key]][k].to_f
74
+ if v[:action] == 'ADD' && @data[args[:table_name]][args[:key][hash_key]]
75
+ # if record has been saved
76
+ attribute_hash[k] = (v[:value] + @data[args[:table_name]][args[:key][hash_key]][k].to_f).to_s
73
77
  else
74
- attribute_hash[k] = v[:value]
78
+ attribute_hash[k] = v[:value].to_s
75
79
  end
76
80
  end
77
81
  attribute_hash
78
82
  end
79
-
80
83
  end
81
- end
84
+ 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: 1.5.2
4
+ version: 1.5.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: 2015-10-21 00:00:00.000000000 Z
18
+ date: 2015-10-22 00:00:00.000000000 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: activemodel
@@ -94,8 +94,9 @@ dependencies:
94
94
  - !ruby/object:Gem::Version
95
95
  version: '2'
96
96
  description: |-
97
- Lightweight DynamoDB interface gem designed as a drop-in replacement for ActiveRecord.
98
- Built & maintained by the team at yroo.com.
97
+ Lightweight DynamoDB interface gem designed as
98
+ a drop-in replacement for ActiveRecord.
99
+ Built & maintained by the team at yroo.com.
99
100
  email: dev@retailcommon.com
100
101
  executables: []
101
102
  extensions: []