ocean-dynamo 0.4.3 → 0.4.4

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: e62e3f71a4c942cf37151bdaa588ce917c4fd269
4
- data.tar.gz: ec345bbecb5a322e74d196f5586e75997e717e24
3
+ metadata.gz: 3dc795167d56cef7e557c8f233b0e6e2fe3a205a
4
+ data.tar.gz: 4979ca24a5937658f00a325981dec200a81f0263
5
5
  SHA512:
6
- metadata.gz: 3ab10073d477aee182164feb1042cd5ea82dbe0aaac3db4ec5204f4d832b2a968d1799783ab662528be9472c12d382097f0cc3e915d5a3209a6eca4df8b96096
7
- data.tar.gz: 4b75d7ac49d8647f4183825b21c8f20177fc8a8eb3603f7c06637b19ff295099be0ef0c65ae54c579a745027a64cf95044dc28cf45750bd3a335b2c23b888133
6
+ metadata.gz: 4796a5bb3c5b216a96b10c9955ec6815ce676e869c7ec6367bb4534bb8f8f349535f96c77308dcaa18a49a786bdcfff631321787a01079bc356aa9f106a6d911
7
+ data.tar.gz: 132101d4bb782d609c75e912a658f19ba423f455e2be2b2bad4d4a720ddc7f45aee1c1ded129bb6713026af0ada9703b14f0539804d4a7dede8d9eb4d478ae99
@@ -104,7 +104,7 @@ The following example shows how to set up a +has_many+ / +belongs_to+ relation:
104
104
  attribute :that
105
105
  attribute :the_other
106
106
  end
107
- has_many :children
107
+ has_many :children, dependent: :destroy
108
108
  end
109
109
 
110
110
 
@@ -162,10 +162,10 @@ controllers. OceanDynamo implements much of the infrastructure of ActiveRecord;
162
162
  for instance, +read_attribute+, +write_attribute+, and much of the control logic and
163
163
  internal organisation.
164
164
 
165
- * +has_many+ now destroys all children before destroying itself. It thus behaves like
166
- <tt>dependent: :destroy</tt> was declared in ActiveRecord. Soon, +has_many+ will take
167
- a <tt>dependent:</tt> value of <tt>:destroy</tt>, <tt>:delete</tt>, or <tt>:nullify</tt>,
168
- for full compatibility.
165
+ * The +dependent:+ keyword arg may now be +:destroy+, +:delete+ or +:nullify+
166
+ with the same semantics as in ActiveRecord. With +:nullify+, however,
167
+ the hash key is set to the string "NULL" rather than binary NULL, as
168
+ DynamoDB doesn't permit storing empty fields.
169
169
 
170
170
  === Future milestones
171
171
 
@@ -18,16 +18,53 @@ module OceanDynamo
18
18
  #
19
19
  # Defines a has_many relation to a belongs_to class.
20
20
  #
21
- def has_many(children) # :children
21
+ # The +dependent:+ keyword arg may be +:destroy+, +:delete+ or +:nullify+
22
+ # and have the same semantics as in ActiveRecord. With +:nullify+, however,
23
+ # the hash key is set to the string "NULL" rather than binary NULL, as
24
+ # DynamoDB doesn't permit storing empty fields.
25
+ #
26
+ def has_many(children, dependent: :nullify) # :children
22
27
  children_attr = children.to_s.underscore # "children"
23
28
  child_class = children_attr.singularize.camelize.constantize # Child
24
29
  register_relation(child_class, :has_many)
25
30
 
26
- before_destroy do |p|
27
- map_children(child_class, &:destroy)
31
+ # Handle children= after create and update
32
+ after_save do |p|
33
+ new_children = instance_variable_get("@#{children_attr}")
34
+ if new_children # TODO: only do this for dirty collections
35
+ write_children child_class, new_children
36
+ map_children child_class do |c|
37
+ next if new_children.include?(c)
38
+ c.destroy
39
+ end
40
+ end
28
41
  true
29
42
  end
30
43
 
44
+ if dependent == :destroy
45
+ before_destroy do |p|
46
+ map_children(child_class, &:destroy)
47
+ p.instance_variable_set "@#{children_attr}", nil
48
+ true
49
+ end
50
+
51
+ elsif dependent == :delete
52
+ before_destroy do |p|
53
+ delete_children(child_class)
54
+ p.instance_variable_set "@#{children_attr}", nil
55
+ end
56
+
57
+ elsif dependent == :nullify
58
+ before_destroy do |p|
59
+ nullify_children(child_class)
60
+ p.instance_variable_set "@#{children_attr}", nil
61
+ true
62
+ end
63
+
64
+ else
65
+ raise ArgumentError, ":dependent must be :destroy, :delete, or :nullify"
66
+ end
67
+
31
68
  # Define accessors for instances
32
69
  attr_accessor children_attr
33
70
  self.class_eval "def #{children_attr}(force_reload=false)
@@ -70,31 +107,6 @@ module OceanDynamo
70
107
 
71
108
  protected
72
109
 
73
- #
74
- # This version also writes back any relations. TODO: only
75
- # dirty relations should be persisted. Introduce a dirty flag.
76
- # Easiest done via an collection proxy object.
77
- #
78
- def dynamo_persist(*) # :nodoc:
79
- result = super
80
-
81
- self.class.relations_of_type(:has_many).each do |klass|
82
- attr_name = klass.to_s.pluralize.underscore
83
- # First create or update the children in the new set
84
- new_children = instance_variable_get("@#{attr_name}")
85
- next unless new_children
86
- write_children klass, new_children
87
- # Destroy all children not in the new set (this is not yet scalable)
88
- read_children(klass).each do |c|
89
- next if new_children.include?(c)
90
- c.destroy
91
- end
92
- end
93
-
94
- result
95
- end
96
-
97
-
98
110
  #
99
111
  # Reads all children of a has_many relation.
100
112
  #
@@ -105,7 +117,8 @@ module OceanDynamo
105
117
  result = Array.new
106
118
  _late_connect?
107
119
  child_items = child_class.dynamo_items
108
- child_items.query(hash_value: id, range_gte: "0") do |item_data|
120
+ child_items.query(hash_value: id, range_gte: "0",
121
+ batch_size: 1000, select: :all) do |item_data|
109
122
  result << child_class.new._setup_from_dynamo(item_data)
110
123
  end
111
124
  result
@@ -132,10 +145,42 @@ module OceanDynamo
132
145
  def map_children(child_class)
133
146
  return if new_record?
134
147
  child_items = child_class.dynamo_items
135
- child_items.query(hash_value: id, range_gte: "0", batch_size: 1000) do |item_data|
148
+ child_items.query(hash_value: id, range_gte: "0",
149
+ batch_size: 1000, select: :all) do |item_data|
136
150
  yield child_class.new._setup_from_dynamo(item_data)
137
151
  end
138
152
  end
139
153
 
154
+
155
+ #
156
+ # Delete all children without instantiating them first.
157
+ #
158
+ def delete_children(child_class)
159
+ return if new_record?
160
+ child_items = child_class.dynamo_items
161
+ child_items.query(hash_value: id, range_gte: "0",
162
+ batch_size: 1000) do |item|
163
+ item.delete
164
+ end
165
+ end
166
+
167
+
168
+ #
169
+ # Set the hash key values of all children to the string "NULL", thereby turning them
170
+ # into orphans. Note that we're not setting the key to NULL as this isn't possible
171
+ # in DynamoDB. Instead, we're using the literal string "NULL".
172
+ #
173
+ def nullify_children(child_class)
174
+ return if new_record?
175
+ child_items = child_class.dynamo_items
176
+ child_items.query(hash_value: id, range_gte: "0",
177
+ batch_size: 1000, select: :all) do |item_data|
178
+ attrs = item_data.attributes
179
+ item_data.item.delete
180
+ attrs[child_class.table_hash_key.to_s] = "NULL"
181
+ child_items.create attrs
182
+ end
183
+ end
184
+
140
185
  end
141
186
  end
@@ -1,3 +1,3 @@
1
1
  module OceanDynamo
2
- VERSION = "0.4.3"
2
+ VERSION = "0.4.4"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ocean-dynamo
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.3
4
+ version: 0.4.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter Bengtson