persistence 0.0.1.alpha → 0.0.1

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.
Files changed (138) hide show
  1. data/CHANGELOG.md +4 -0
  2. data/README.md +260 -17
  3. data/lib/namespaces.rb +55 -0
  4. data/lib/persistence.rb +38 -3
  5. data/lib/persistence/adapter/abstract.rb +22 -0
  6. data/lib/persistence/adapter/abstract/enable_disable.rb +107 -0
  7. data/lib/persistence/adapter/abstract/primary_key/id_property_string.rb +33 -0
  8. data/lib/persistence/adapter/abstract/primary_key/simple.rb +29 -0
  9. data/lib/persistence/adapter/mock.rb +9 -0
  10. data/lib/persistence/adapter/mock/adapter_interface.rb +102 -0
  11. data/lib/persistence/adapter/mock/bucket.rb +9 -0
  12. data/lib/persistence/adapter/mock/bucket/bucket_interface.rb +260 -0
  13. data/lib/persistence/adapter/mock/bucket/index.rb +9 -0
  14. data/lib/persistence/adapter/mock/bucket/index/index_interface.rb +155 -0
  15. data/lib/persistence/adapter/mock/cursor.rb +9 -0
  16. data/lib/persistence/adapter/mock/cursor/cursor_interface.rb +238 -0
  17. data/lib/persistence/cursor.rb +11 -0
  18. data/lib/persistence/cursor/atomic.rb +110 -0
  19. data/lib/persistence/cursor/cursor_interface.rb +337 -0
  20. data/lib/persistence/exception/block_required.rb +7 -0
  21. data/lib/persistence/exception/conflicting_index_already_declared.rb +7 -0
  22. data/lib/persistence/exception/duplicate_violates_unique_index.rb +7 -0
  23. data/lib/persistence/exception/explicit_index_required.rb +7 -0
  24. data/lib/persistence/exception/indexing_block_failed_to_generate_keys.rb +7 -0
  25. data/lib/persistence/exception/indexing_object_requires_keys.rb +7 -0
  26. data/lib/persistence/exception/key_value_required.rb +7 -0
  27. data/lib/persistence/exception/no_port_enabled.rb +7 -0
  28. data/lib/persistence/object.rb +21 -0
  29. data/lib/persistence/object/autodetermine.rb +74 -0
  30. data/lib/persistence/object/class_instance.rb +1884 -0
  31. data/lib/persistence/object/complex.rb +17 -0
  32. data/lib/persistence/object/complex/array.rb +14 -0
  33. data/lib/persistence/object/complex/array/class_instance.rb +37 -0
  34. data/lib/persistence/object/complex/array/object_instance.rb +54 -0
  35. data/lib/persistence/object/complex/attributes.rb +1808 -0
  36. data/lib/persistence/object/complex/attributes/attributes_array.rb +32 -0
  37. data/lib/persistence/object/complex/attributes/attributes_hash.rb +187 -0
  38. data/lib/persistence/object/complex/attributes/default_atomic_non_atomic.rb +102 -0
  39. data/lib/persistence/object/complex/attributes/hash_to_port.rb +40 -0
  40. data/lib/persistence/object/complex/class_and_object_instance.rb +132 -0
  41. data/lib/persistence/object/complex/class_instance.rb +267 -0
  42. data/lib/persistence/object/complex/complex_object.rb +111 -0
  43. data/lib/persistence/object/complex/hash.rb +14 -0
  44. data/lib/persistence/object/complex/hash/class_instance.rb +40 -0
  45. data/lib/persistence/object/complex/hash/object_instance.rb +63 -0
  46. data/lib/persistence/object/complex/index/attribute_index.rb +10 -0
  47. data/lib/persistence/object/complex/index/attribute_index/attribute_index_interface.rb +43 -0
  48. data/lib/persistence/object/complex/object_instance.rb +469 -0
  49. data/lib/persistence/object/flat.rb +17 -0
  50. data/lib/persistence/object/flat/class_instance.rb +34 -0
  51. data/lib/persistence/object/flat/file.rb +14 -0
  52. data/lib/persistence/object/flat/file/class_instance.rb +122 -0
  53. data/lib/persistence/object/flat/file/contents.rb +7 -0
  54. data/lib/persistence/object/flat/file/file_persistence.rb +147 -0
  55. data/lib/persistence/object/flat/file/object_instance.rb +116 -0
  56. data/lib/persistence/object/flat/file/path.rb +9 -0
  57. data/lib/persistence/object/flat/object_instance.rb +24 -0
  58. data/lib/persistence/object/index.rb +479 -0
  59. data/lib/persistence/object/index/block_index.rb +10 -0
  60. data/lib/persistence/object/index/block_index/block_index_interface.rb +110 -0
  61. data/lib/persistence/object/index/explicit_index.rb +10 -0
  62. data/lib/persistence/object/index/explicit_index/explicit_index_interface.rb +57 -0
  63. data/lib/persistence/object/index_hash.rb +40 -0
  64. data/lib/persistence/object/object_instance.rb +322 -0
  65. data/lib/persistence/object/parse_persistence_args.rb +145 -0
  66. data/lib/persistence/port.rb +9 -0
  67. data/lib/persistence/port/bucket.rb +9 -0
  68. data/lib/persistence/port/bucket/bucket_index.rb +9 -0
  69. data/lib/persistence/port/bucket/bucket_interface.rb +685 -0
  70. data/lib/persistence/port/controller.rb +263 -0
  71. data/lib/persistence/port/port_interface.rb +417 -0
  72. data/lib/requires.rb +146 -0
  73. data/spec/Integration_spec.rb +53 -0
  74. data/spec/Persistence_spec.rb +175 -0
  75. data/spec/example_objects.rb +6 -0
  76. data/spec/example_objects/complex_object.rb +7 -0
  77. data/spec/example_objects/complex_object/array_object.rb +7 -0
  78. data/spec/example_objects/complex_object/hash_object.rb +7 -0
  79. data/spec/example_objects/flat_object.rb +7 -0
  80. data/spec/example_objects/flat_object/file_object.rb +7 -0
  81. data/spec/persistence/adapter/enable_disable_spec.rb +29 -0
  82. data/spec/persistence/adapter/mock/cursor_spec.rb +64 -0
  83. data/spec/persistence/adapter/mock_helpers.rb +27 -0
  84. data/spec/persistence/adapter/mock_helpers/bucket.rb +10 -0
  85. data/spec/persistence/adapter/mock_helpers/integration/dictionary_hash.rb +4 -0
  86. data/spec/persistence/adapter/mock_helpers/integration/note.rb +18 -0
  87. data/spec/persistence/adapter/mock_helpers/integration/notes_array.rb +4 -0
  88. data/spec/persistence/adapter/mock_helpers/integration/user.rb +44 -0
  89. data/spec/persistence/adapter/mock_helpers/integration/user/address.rb +18 -0
  90. data/spec/persistence/adapter/mock_helpers/integration/user/dictionary_entry.rb +12 -0
  91. data/spec/persistence/adapter/mock_helpers/integration/user/sub_account.rb +15 -0
  92. data/spec/persistence/adapter/mock_helpers/object.rb +87 -0
  93. data/spec/persistence/adapter/mock_helpers/port.rb +21 -0
  94. data/spec/persistence/adapter/mock_spec.rb +211 -0
  95. data/spec/persistence/adapter/primary_key/id_property_string_spec.rb +27 -0
  96. data/spec/persistence/adapter/primary_key/simple_spec.rb +19 -0
  97. data/spec/persistence/adapter/spec_abstract/adapter_spec.rb +223 -0
  98. data/spec/persistence/adapter/spec_abstract/cursor_spec.rb +116 -0
  99. data/spec/persistence/cursor/atomic_spec.rb +86 -0
  100. data/spec/persistence/cursor/object_and_class_instance_spec.rb +73 -0
  101. data/spec/persistence/cursor_spec.rb +128 -0
  102. data/spec/persistence/object/complex/attributes/persistence_hash/array_instance_spec.rb +51 -0
  103. data/spec/persistence/object/complex/attributes/persistence_hash/hash_instance_spec.rb +56 -0
  104. data/spec/persistence/object/complex/attributes_spec.rb +1717 -0
  105. data/spec/persistence/object/complex/complex_spec.rb +922 -0
  106. data/spec/persistence/object/complex/index/attribute_index_spec.rb +76 -0
  107. data/spec/persistence/object/flat/bignum_spec.rb +33 -0
  108. data/spec/persistence/object/flat/class_instance_spec.rb +30 -0
  109. data/spec/persistence/object/flat/class_spec.rb +38 -0
  110. data/spec/persistence/object/flat/complex_spec.rb +36 -0
  111. data/spec/persistence/object/flat/false_class_spec.rb +34 -0
  112. data/spec/persistence/object/flat/file/class_instance_spec.rb +54 -0
  113. data/spec/persistence/object/flat/file/object_instance_spec.rb +143 -0
  114. data/spec/persistence/object/flat/file_spec.rb +64 -0
  115. data/spec/persistence/object/flat/fixnum_spec.rb +32 -0
  116. data/spec/persistence/object/flat/float_spec.rb +32 -0
  117. data/spec/persistence/object/flat/indexing_spec.rb +38 -0
  118. data/spec/persistence/object/flat/rational_spec.rb +33 -0
  119. data/spec/persistence/object/flat/regexp_spec.rb +32 -0
  120. data/spec/persistence/object/flat/string_spec.rb +34 -0
  121. data/spec/persistence/object/flat/symbol_spec.rb +32 -0
  122. data/spec/persistence/object/flat/true_class_spec.rb +32 -0
  123. data/spec/persistence/object/indexes/block_index_spec.rb +119 -0
  124. data/spec/persistence/object/indexes/explicit_index_spec.rb +112 -0
  125. data/spec/persistence/object/parse_persistence_args_spec.rb +65 -0
  126. data/spec/persistence/object_spec.rb +310 -0
  127. data/spec/persistence/port/bucket/bucket_interface_spec.rb +146 -0
  128. data/spec/persistence/port/bucket/index/bucket_index_spec.rb +67 -0
  129. data/spec/persistence/port/bucket_spec.rb +20 -0
  130. data/spec/persistence/port/controller_spec.rb +60 -0
  131. data/spec/persistence/port/port_interface_spec.rb +105 -0
  132. metadata +178 -21
  133. data/.gitignore +0 -17
  134. data/Gemfile +0 -4
  135. data/LICENSE +0 -22
  136. data/Rakefile +0 -2
  137. data/lib/persistence/version.rb +0 -3
  138. data/persistence.gemspec +0 -17
@@ -0,0 +1,17 @@
1
+
2
+ ###
3
+ # Convenience module for extending complex object types (singletons and instances) with persistence capabilities.
4
+ # Complex object types include all objects except: Bignum, Fixnum, Complex, Rational, TrueClass, FalseClass,
5
+ # String, Symbol, Regexp, File, NilClass, File, Array, Hash.
6
+ #
7
+ module ::Persistence::Object::Complex
8
+
9
+ extend ModuleCluster::Define::ClusterCascades
10
+
11
+ include ::Persistence::Object::ObjectInstance
12
+ include_or_extend_cascades_prepend_extends ::Persistence::Object::ClassInstance
13
+
14
+ include ::Persistence::Object::Complex::ObjectInstance
15
+ include_or_extend_cascades_prepend_extends ::Persistence::Object::Complex::ClassInstance
16
+
17
+ end
@@ -0,0 +1,14 @@
1
+
2
+ ###
3
+ # Convenience module for extending array types (singletons and instances) with persistence capabilities.
4
+ #
5
+ module ::Persistence::Object::Complex::Array
6
+
7
+ extend ModuleCluster::Define::ClusterCascades
8
+
9
+ include ::Persistence::Object::Complex
10
+
11
+ include ::Persistence::Object::Complex::Array::ObjectInstance
12
+ include_or_extend_cascades_prepend_extends ::Persistence::Object::Complex::Array::ClassInstance
13
+
14
+ end
@@ -0,0 +1,37 @@
1
+
2
+ ###
3
+ # Class methods for array objects enabled with persistence capabilities.
4
+ #
5
+ module ::Persistence::Object::Complex::Array::ClassInstance
6
+
7
+ #############
8
+ # persist #
9
+ #############
10
+
11
+ def persist( *args )
12
+
13
+ index, key, no_key = parse_args_for_index_value_no_value( args, true )
14
+
15
+ if index
16
+ global_id = index.get_object_id( key )
17
+ else
18
+ global_id = key
19
+ end
20
+
21
+ object = new
22
+
23
+ object.persistence_id = global_id
24
+
25
+ instance_persistence_bucket.get_object_hash( global_id ).each do |this_key, this_value|
26
+ if this_value.is_a?( ::Persistence::Object::Complex::ComplexObject )
27
+ object.push( this_value.persist )
28
+ else
29
+ object.push( this_value )
30
+ end
31
+ end
32
+
33
+ return object
34
+
35
+ end
36
+
37
+ end
@@ -0,0 +1,54 @@
1
+
2
+ ###
3
+ # Instance methods for array objects enabled with persistence capabilities.
4
+ #
5
+ module ::Persistence::Object::Complex::Array::ObjectInstance
6
+
7
+ #############
8
+ # persist #
9
+ #############
10
+
11
+ def persist( *args )
12
+
13
+ index, key, no_key = parse_args_for_index_value_no_value( args, true )
14
+
15
+ if index
16
+ global_id = index.get_object_id( key )
17
+ else
18
+ global_id = key
19
+ end
20
+
21
+ persistence_bucket.adapter_bucket.get_object( global_id ).each do |this_index, this_value|
22
+ self[ this_index ] = this_value
23
+ end
24
+
25
+ return self
26
+
27
+ end
28
+
29
+ ##############################
30
+ # persistence_hash_to_port #
31
+ ##############################
32
+
33
+ def persistence_hash_to_port
34
+
35
+ persistence_hash_instance = ::Persistence::Object::Complex::Attributes::HashToPort.new
36
+ persistence_hash_instance.persistence_object = self
37
+
38
+ self.each_with_index do |attribute_value, index|
39
+ persistence_hash_instance[ index ] = attribute_value
40
+ end
41
+
42
+ return persistence_hash_instance
43
+
44
+ end
45
+
46
+ ############################
47
+ # load_persistence_value #
48
+ ############################
49
+
50
+ def load_persistence_value( attribute_name, attribute_value )
51
+ push( attribute_value )
52
+ end
53
+
54
+ end
@@ -0,0 +1,1808 @@
1
+
2
+ ###
3
+ # Module managing atomic/non-atomic attribute status to define how objects persist.
4
+ #
5
+ module ::Persistence::Object::Complex::Attributes
6
+
7
+ include ::CascadingConfiguration::Hash
8
+ include ::CascadingConfiguration::Array::Sorted::Unique
9
+ include ::CascadingConfiguration::Setting
10
+
11
+ ##########################
12
+ # attr_atomic_accessor #
13
+ ##########################
14
+
15
+ ###
16
+ # Declare one or more attributes to persist atomically.
17
+ #
18
+ # @overload attr_atomic_accessor( attribute_name, ... )
19
+ #
20
+ # @param attribute_name Name of attribute.
21
+ #
22
+ # @return self
23
+ #
24
+ def attr_atomic_accessor( *attributes )
25
+
26
+ attr_atomic_reader( *attributes )
27
+ attr_atomic_writer( *attributes )
28
+
29
+ return self
30
+
31
+ end
32
+
33
+ ########################
34
+ # attr_atomic_reader #
35
+ ########################
36
+
37
+ ###
38
+ # Declare one or more attributes to persist from the database atomically (but not write atomically).
39
+ #
40
+ # @overload attr_atomic_reader( attribute_name, ... )
41
+ #
42
+ # @param attribute_name Name of attribute.
43
+ #
44
+ # @return self
45
+ #
46
+ def attr_atomic_reader( *attributes )
47
+
48
+ atomic_attribute_readers.push( *attributes )
49
+
50
+ attributes.each do |this_attribute|
51
+ define_reader( this_attribute )
52
+ end
53
+
54
+ return self
55
+
56
+ end
57
+
58
+ ########################
59
+ # attr_atomic_writer #
60
+ ########################
61
+
62
+ ###
63
+ # Declare one or more attributes to persist to the database atomically (but not read atomically).
64
+ #
65
+ # @overload attr_atomic_writer( attribute_name, ... )
66
+ #
67
+ # @param attribute_name Name of attribute.
68
+ #
69
+ # @return self
70
+ #
71
+ def attr_atomic_writer( *attributes )
72
+
73
+ atomic_attribute_writers.push( *attributes )
74
+
75
+ attributes.each do |this_attribute|
76
+ define_writer( this_attribute )
77
+ end
78
+
79
+ return self
80
+
81
+ end
82
+
83
+ ##############################
84
+ # attr_non_atomic_accessor #
85
+ ##############################
86
+
87
+ ###
88
+ # Declare one or more attributes to persist only non-atomically.
89
+ #
90
+ # @overload attr_atomic_writer( attribute_name, ... )
91
+ #
92
+ # @param attribute_name Name of attribute.
93
+ #
94
+ # @return self
95
+ #
96
+ def attr_non_atomic_accessor( *attributes )
97
+
98
+ attr_non_atomic_reader( *attributes )
99
+ attr_non_atomic_writer( *attributes )
100
+
101
+ return self
102
+
103
+ end
104
+
105
+ ############################
106
+ # attr_non_atomic_reader #
107
+ ############################
108
+
109
+ ###
110
+ # Declare one or more attributes to read from the database (but not write to it) only non-atomically.
111
+ #
112
+ # @overload attr_non_atomic_reader( attribute_name, ... )
113
+ #
114
+ # @param attribute_name Name of attribute.
115
+ #
116
+ # @return self
117
+ #
118
+ def attr_non_atomic_reader( *attributes )
119
+
120
+ non_atomic_attribute_readers.push( *attributes )
121
+
122
+ attributes.each do |this_attribute|
123
+
124
+ define_reader( this_attribute )
125
+
126
+ end
127
+
128
+ return self
129
+
130
+ end
131
+
132
+ ############################
133
+ # attr_non_atomic_writer #
134
+ ############################
135
+
136
+ ###
137
+ # Declare one or more attributes to write to the database (but not read from it) only non-atomically.
138
+ #
139
+ # @overload attr_non_atomic_writer( attribute_name, ... )
140
+ #
141
+ # @param attribute_name Name of attribute.
142
+ #
143
+ # @return self
144
+ #
145
+ def attr_non_atomic_writer( *attributes )
146
+
147
+ non_atomic_attribute_writers.push( *attributes )
148
+
149
+ attributes.each do |this_attribute|
150
+
151
+ define_writer( this_attribute )
152
+
153
+ end
154
+
155
+ return self
156
+
157
+ end
158
+
159
+ ###################
160
+ # attrs_atomic! #
161
+ ###################
162
+
163
+ ###
164
+ # Declare all attributes to persist atomically.
165
+ #
166
+ def attrs_atomic!
167
+
168
+ return attr_atomic_accessor( *non_atomic_attributes.keys )
169
+
170
+ end
171
+
172
+ #######################
173
+ # attrs_non_atomic! #
174
+ #######################
175
+
176
+ ###
177
+ # Declare all attributes to persist non-atomically.
178
+ #
179
+ def attrs_non_atomic!
180
+
181
+ # move all declared elements from atomic into non-atomic
182
+ return attr_non_atomic_accessor( *atomic_attributes )
183
+
184
+ end
185
+
186
+ #######################
187
+ # atomic_attribute? #
188
+ #######################
189
+
190
+ ###
191
+ # Query whether attribute(s) has atomic reader or writer.
192
+ #
193
+ # @overload atomic_attribute?( attribute_name, ... )
194
+ #
195
+ # @param attribute_name Name of attribute.
196
+ #
197
+ # @return [true,false] Whether object has attribute(s) as atomic reader or writer.
198
+ #
199
+ def atomic_attribute?( *attributes )
200
+
201
+ return atomic_attributes.has_attributes?( *attributes )
202
+
203
+ end
204
+
205
+ ################################
206
+ # atomic_attribute_accessor? #
207
+ ################################
208
+
209
+ ###
210
+ # Query whether attribute(s) are both atomic readers and writers.
211
+ #
212
+ # @overload atomic_attribute_accessor?( attribute_name, ... )
213
+ #
214
+ # @param attribute_name Name of attribute.
215
+ #
216
+ # @return [true,false] Whether object has attribute(s) as both atomic readers and writers.
217
+ #
218
+ def atomic_attribute_accessor?( *attributes )
219
+
220
+ return atomic_attribute_accessors.has_attributes?( *attributes )
221
+
222
+ end
223
+
224
+ ##############################
225
+ # atomic_attribute_reader? #
226
+ ##############################
227
+
228
+ ###
229
+ # Query whether attribute(s) are atomic readers.
230
+ #
231
+ # @overload atomic_attribute_accessor?( attribute_name, ... )
232
+ #
233
+ # @param attribute_name Name of attribute.
234
+ #
235
+ # @return [true,false] Whether object has attribute(s) as atomic readers.
236
+ #
237
+ def atomic_attribute_reader?( *attributes )
238
+
239
+ return atomic_attribute_readers.has_attributes?( *attributes )
240
+
241
+ end
242
+
243
+ ##############################
244
+ # atomic_attribute_writer? #
245
+ ##############################
246
+
247
+ ###
248
+ # Query whether attribute(s) are atomic writers.
249
+ #
250
+ # @overload atomic_attribute_accessor?( attribute_name, ... )
251
+ #
252
+ # @param attribute_name Name of attribute.
253
+ #
254
+ # @return [true,false] Whether object has attribute(s) as atomic writers.
255
+ #
256
+ def atomic_attribute_writer?( *attributes )
257
+
258
+ return atomic_attribute_writers.has_attributes?( *attributes )
259
+
260
+ end
261
+
262
+ #############################
263
+ # atomic_attribute_status #
264
+ #############################
265
+
266
+ ###
267
+ # Query atomic attribute(s) status (:reader/:writer/:accessor/nil).
268
+ #
269
+ # @param attribute Name of attribute.
270
+ #
271
+ # @return [:reader/:writer/:accessor/nil] Atomic attribute status.
272
+ #
273
+ def atomic_attribute_status( attribute )
274
+
275
+ return atomic_attributes[ attribute ]
276
+
277
+ end
278
+
279
+ ###########################
280
+ # non_atomic_attribute? #
281
+ ###########################
282
+
283
+ ###
284
+ # Query whether attribute(s) has non-atomic reader or writer.
285
+ #
286
+ # @overload non_atomic_attribute?( attribute_name, ... )
287
+ #
288
+ # @param attribute_name Name of attribute.
289
+ #
290
+ # @return [true,false] Whether object has attribute(s) as non-atomic readers or writers.
291
+ #
292
+ def non_atomic_attribute?( *attributes )
293
+
294
+ return non_atomic_attributes.has_attributes?( *attributes )
295
+
296
+ end
297
+
298
+ ####################################
299
+ # non_atomic_attribute_accessor? #
300
+ ####################################
301
+
302
+ ###
303
+ # Query whether attribute(s) are both non-atomic readers and writers.
304
+ #
305
+ # @overload atomic_attribute_accessor?( attribute_name, ... )
306
+ #
307
+ # @param attribute_name Name of attribute.
308
+ #
309
+ # @return [true,false] Whether object has attribute(s) as non-atomic readers and writers.
310
+ #
311
+ def non_atomic_attribute_accessor?( *attributes )
312
+
313
+ return non_atomic_attribute_accessors.has_attributes?( *attributes )
314
+
315
+ end
316
+
317
+ ##################################
318
+ # non_atomic_attribute_reader? #
319
+ ##################################
320
+
321
+ ###
322
+ # Query whether attribute(s) are non-atomic readers.
323
+ #
324
+ # @overload atomic_attribute_accessor?( attribute_name, ... )
325
+ #
326
+ # @param attribute_name Name of attribute.
327
+ #
328
+ # @return [true,false] Whether object has attribute(s) as non-atomic readers.
329
+ #
330
+ def non_atomic_attribute_reader?( *attributes )
331
+
332
+ return non_atomic_attribute_readers.has_attributes?( *attributes )
333
+
334
+ end
335
+
336
+ ##################################
337
+ # non_atomic_attribute_writer? #
338
+ ##################################
339
+
340
+ ###
341
+ # Query whether attribute(s) are non-atomic writers.
342
+ #
343
+ # @overload atomic_attribute_accessor?( attribute_name, ... )
344
+ #
345
+ # @param attribute_name Name of attribute.
346
+ #
347
+ # @return [true,false] Whether object has attribute(s) as non-atomic writers.
348
+ #
349
+ def non_atomic_attribute_writer?( *attributes )
350
+
351
+ return non_atomic_attribute_writers.has_attributes?( *attributes )
352
+
353
+ end
354
+
355
+ #################################
356
+ # non_atomic_attribute_status #
357
+ #################################
358
+
359
+ ###
360
+ # Query non-atomic attribute(s) status (:reader/:writer/:accessor/nil).
361
+ #
362
+ # @param attribute Name of attribute.
363
+ #
364
+ # @return [:reader/:writer/:accessor/nil] Atomic attribute status.
365
+ #
366
+ def non_atomic_attribute_status( attribute )
367
+
368
+ return non_atomic_attributes[ attribute ]
369
+
370
+ end
371
+
372
+ ###########################
373
+ # persistent_attribute? #
374
+ ###########################
375
+
376
+ ###
377
+ # Query whether attribute(s) has atomic or non-atomic reader or writer.
378
+ #
379
+ # @overload persistent_attribute?( attribute_name, ... )
380
+ #
381
+ # @param attribute_name Name of attribute.
382
+ #
383
+ # @return [true,false] Whether object has attribute(s) as atomic or non-atomic readers or writers.
384
+ #
385
+ def persistent_attribute?( *attributes )
386
+
387
+ return persistent_attributes.has_attributes?( *attributes )
388
+
389
+ end
390
+
391
+ ####################################
392
+ # persistent_attribute_accessor? #
393
+ ####################################
394
+
395
+ ###
396
+ # Query whether attribute(s) are either atomic or non-atomic readers and writers.
397
+ #
398
+ # @overload persistent_attribute_accessor?( attribute_name, ... )
399
+ #
400
+ # @param attribute_name Name of attribute.
401
+ #
402
+ # @return [true,false] Whether object has attribute(s) as either atomic or non-atomic readers and writers.
403
+ #
404
+ def persistent_attribute_accessor?( *attributes )
405
+
406
+ return persistent_attribute_accessors.has_attributes?( *attributes )
407
+
408
+ end
409
+
410
+ ##################################
411
+ # persistent_attribute_reader? #
412
+ ##################################
413
+
414
+ ###
415
+ # Query whether attribute(s) are atomic or non-atomic readers.
416
+ #
417
+ # @overload persistent_attribute_reader?( attribute_name, ... )
418
+ #
419
+ # @param attribute_name Name of attribute.
420
+ #
421
+ # @return [true,false] Whether object has attribute(s) as atomic or non-atomic readers.
422
+ #
423
+ def persistent_attribute_reader?( *attributes )
424
+
425
+ return persistent_attribute_readers.has_attributes?( *attributes )
426
+
427
+ end
428
+
429
+ ##################################
430
+ # persistent_attribute_writer? #
431
+ ##################################
432
+
433
+ ###
434
+ # Query whether attribute(s) are atomic or non-atomic writers.
435
+ #
436
+ # @overload persistent_attribute_reader?( attribute_name, ... )
437
+ #
438
+ # @param attribute_name Name of attribute.
439
+ #
440
+ # @return [true,false] Whether object has attribute(s) as atomic or non-atomic writers.
441
+ #
442
+ def persistent_attribute_writer?( *attributes )
443
+
444
+ return persistent_attribute_writers.has_attributes?( *attributes )
445
+
446
+ end
447
+
448
+ #################################
449
+ # persistent_attribute_status #
450
+ #################################
451
+
452
+ ###
453
+ # Query persistent attribute(s) status (:reader/:writer/:accessor/nil).
454
+ #
455
+ # @param attribute Name of attribute.
456
+ #
457
+ # @return [:reader/:writer/:accessor/nil] Persistent attribute status.
458
+ #
459
+ def persistent_attribute_status( attribute )
460
+
461
+ return persistent_attributes[ attribute ]
462
+
463
+ end
464
+
465
+ #######################
466
+ # atomic_attributes #
467
+ #######################
468
+
469
+ ###
470
+ #
471
+ # @method atomic_attributes
472
+ #
473
+ # Hash tracking atomic attribute status
474
+ #
475
+ # @return [CompositingHash] Hash extended with {::Persistence::Object::Complex::Attributes::AttributesHash
476
+ # Persistence::Object::Complex::Attributes::AttributesHash}.
477
+ #
478
+ attr_hash :atomic_attributes, AttributesHash do
479
+
480
+ #=======================#
481
+ # update_for_addition #
482
+ #=======================#
483
+
484
+ def update_for_addition( key, reader_writer_accessor )
485
+
486
+ configuration_instance.instance_eval do
487
+
488
+ # remove from non-atomic attributes
489
+ non_atomic_attributes.subtract_without_hooks( key, reader_writer_accessor )
490
+
491
+ # add to persistent attributes
492
+ persistent_attributes.add_without_hooks( key, reader_writer_accessor )
493
+
494
+ non_atomic_attribute_accessors.delete_without_hooks( key )
495
+
496
+ case reader_writer_accessor
497
+
498
+ when :reader
499
+
500
+ atomic_attribute_readers.push_without_hooks( key )
501
+
502
+ persistent_attribute_readers.push_without_hooks( key )
503
+
504
+ non_atomic_attribute_readers.delete_without_hooks( key )
505
+
506
+ if atomic_attribute_writers.include?( key )
507
+ atomic_attribute_accessors.push_without_hooks( key )
508
+ end
509
+
510
+ when :writer
511
+
512
+ atomic_attribute_writers.push_without_hooks( key )
513
+
514
+ persistent_attribute_writers.push_without_hooks( key )
515
+
516
+ non_atomic_attribute_writers.delete_without_hooks( key )
517
+
518
+ if atomic_attribute_readers.include?( key )
519
+ atomic_attribute_accessors.push_without_hooks( key )
520
+ end
521
+
522
+ when :accessor
523
+
524
+ atomic_attribute_readers.push_without_hooks( key )
525
+ atomic_attribute_writers.push_without_hooks( key )
526
+ atomic_attribute_accessors.push_without_hooks( key )
527
+
528
+ persistent_attribute_readers.push_without_hooks( key )
529
+ persistent_attribute_writers.push_without_hooks( key )
530
+ persistent_attribute_accessors.push_without_hooks( key )
531
+
532
+ non_atomic_attribute_writers.delete_without_hooks( key )
533
+ non_atomic_attribute_readers.delete_without_hooks( key )
534
+ non_atomic_attribute_accessors.delete_without_hooks( key )
535
+
536
+ end
537
+
538
+ end
539
+
540
+ end
541
+
542
+ #==========================#
543
+ # update_for_subtraction #
544
+ #==========================#
545
+
546
+ def update_for_subtraction( key, reader_writer_accessor )
547
+
548
+ configuration_instance.instance_eval do
549
+
550
+ # subtract from persistent attributes
551
+ persistent_attributes.subtract_without_hooks( key, reader_writer_accessor )
552
+
553
+ atomic_attribute_accessors.delete_without_hooks( key )
554
+
555
+ case reader_writer_accessor
556
+ when :reader
557
+ atomic_attribute_readers.delete_without_hooks( key )
558
+ when :writer
559
+ atomic_attribute_writers.delete_without_hooks( key )
560
+ when :accessor
561
+ atomic_attribute_writers.delete_without_hooks( key )
562
+ atomic_attribute_readers.delete_without_hooks( key )
563
+ end
564
+
565
+ end
566
+
567
+ end
568
+
569
+ #=======#
570
+ # []= #
571
+ #=======#
572
+
573
+ def []=( key, reader_writer_accessor )
574
+
575
+ if reader_writer_accessor
576
+
577
+ super( key, reader_writer_accessor )
578
+
579
+ unless @without_hooks
580
+
581
+ configuration_instance.persistent_attributes.add_without_hooks( key,
582
+ reader_writer_accessor )
583
+
584
+ case reader_writer_accessor
585
+
586
+ when :reader
587
+
588
+ configuration_instance.instance_eval do
589
+
590
+ atomic_attribute_readers.push_without_hooks( key )
591
+
592
+ persistent_attribute_readers.push_without_hooks( key )
593
+
594
+ non_atomic_attributes.subtract_without_hooks( key, :reader )
595
+ non_atomic_attribute_readers.delete_without_hooks( key )
596
+ non_atomic_attribute_accessors.delete_without_hooks( key )
597
+
598
+ end
599
+
600
+ when :writer
601
+
602
+ configuration_instance.instance_eval do
603
+
604
+ atomic_attribute_writers.push_without_hooks( key )
605
+
606
+ persistent_attribute_writers.push_without_hooks( key )
607
+
608
+ non_atomic_attributes.subtract_without_hooks( key, :writer )
609
+ non_atomic_attribute_writers.delete_without_hooks( key )
610
+ non_atomic_attribute_accessors.delete_without_hooks( key )
611
+
612
+ end
613
+
614
+ when :accessor
615
+
616
+ configuration_instance.instance_eval do
617
+
618
+ atomic_attribute_writers.push_without_hooks( key )
619
+ atomic_attribute_readers.push_without_hooks( key )
620
+ atomic_attribute_accessors.push_without_hooks( key )
621
+
622
+ persistent_attribute_readers.push_without_hooks( key )
623
+ persistent_attribute_writers.push_without_hooks( key )
624
+ persistent_attribute_accessors.push_without_hooks( key )
625
+
626
+ non_atomic_attributes.subtract_without_hooks( key, :accessor )
627
+ non_atomic_attribute_readers.delete_without_hooks( key )
628
+ non_atomic_attribute_writers.delete_without_hooks( key )
629
+ non_atomic_attribute_accessors.delete_without_hooks( key )
630
+
631
+ end
632
+ end
633
+
634
+ end
635
+
636
+ else
637
+
638
+ # if we have nil we are actually deleting
639
+ delete( key )
640
+
641
+ end
642
+
643
+ return reader_writer_accessor
644
+
645
+ end
646
+
647
+ end
648
+
649
+ ###########################
650
+ # non_atomic_attributes #
651
+ ###########################
652
+
653
+ ###
654
+ #
655
+ # @method non_atomic_attributes
656
+ #
657
+ # Hash tracking non-atomic attribute status
658
+ #
659
+ # @return [CompositingHash] CompositingHash extended with {::Persistence::Object::Complex::Attributes::AttributesHash
660
+ # Persistence::Object::Complex::Attributes::AttributesHash}.
661
+ #
662
+ attr_hash :non_atomic_attributes, AttributesHash do
663
+
664
+ #=======================#
665
+ # update_for_addition #
666
+ #=======================#
667
+
668
+ def update_for_addition( key, reader_writer_accessor )
669
+
670
+ configuration_instance.instance_eval do
671
+
672
+ # remove from non-atomic attributes
673
+ atomic_attributes.subtract( key, reader_writer_accessor )
674
+
675
+ # add to persistent attributes
676
+ persistent_attributes.add_without_hooks( key, reader_writer_accessor )
677
+
678
+ atomic_attribute_accessors.delete( key )
679
+
680
+ case reader_writer_accessor
681
+
682
+ when :reader
683
+
684
+ non_atomic_attribute_readers.push( key )
685
+
686
+ persistent_attribute_readers.push_without_hooks( key )
687
+
688
+ atomic_attribute_readers.delete( key )
689
+
690
+ if non_atomic_attribute_writers.include?( key )
691
+ non_atomic_attribute_accessors.push_without_hooks( key )
692
+ end
693
+
694
+ when :writer
695
+
696
+ non_atomic_attribute_writers.push( key )
697
+
698
+ persistent_attribute_writers.push_without_hooks( key )
699
+
700
+ atomic_attribute_writers.delete( key )
701
+
702
+ if non_atomic_attribute_readers.include?( key )
703
+ non_atomic_attribute_accessors.push_without_hooks( key )
704
+ end
705
+
706
+ when :accessor
707
+
708
+ non_atomic_attribute_accessors.push( key )
709
+ non_atomic_attribute_writers.push( key )
710
+ non_atomic_attribute_readers.push( key )
711
+
712
+ persistent_attribute_readers.push_without_hooks( key )
713
+ persistent_attribute_writers.push_without_hooks( key )
714
+ persistent_attribute_accessors.push_without_hooks( key )
715
+
716
+ atomic_attribute_writers.delete( key )
717
+ atomic_attribute_readers.delete( key )
718
+
719
+ end
720
+
721
+ end
722
+
723
+ end
724
+
725
+ #==========================#
726
+ # update_for_subtraction #
727
+ #==========================#
728
+
729
+ def update_for_subtraction( key, reader_writer_accessor )
730
+
731
+ configuration_instance.instance_eval do
732
+
733
+ # subtract from persistent attributes
734
+ persistent_attributes.subtract_without_hooks( key, reader_writer_accessor )
735
+
736
+ non_atomic_attribute_accessors.delete_without_hooks( key )
737
+
738
+ case reader_writer_accessor
739
+ when :reader
740
+ non_atomic_attribute_readers.delete_without_hooks( key )
741
+ when :writer
742
+ non_atomic_attribute_writers.delete_without_hooks( key )
743
+ when :accessor
744
+ non_atomic_attribute_writers.delete_without_hooks( key )
745
+ non_atomic_attribute_readers.delete_without_hooks( key )
746
+ end
747
+
748
+ end
749
+
750
+ end
751
+
752
+ #=======#
753
+ # []= #
754
+ #=======#
755
+
756
+ def []=( key, reader_writer_accessor )
757
+
758
+ if reader_writer_accessor
759
+
760
+ super( key, reader_writer_accessor )
761
+
762
+ unless @without_hooks
763
+
764
+ configuration_instance.persistent_attributes.add_without_hooks( key,
765
+ reader_writer_accessor )
766
+ case reader_writer_accessor
767
+
768
+ when :reader
769
+
770
+ configuration_instance.instance_eval do
771
+
772
+ non_atomic_attribute_readers.push_without_hooks( key )
773
+
774
+ persistent_attribute_readers.push_without_hooks( key )
775
+
776
+ atomic_attributes.subtract_without_hooks( key, :reader )
777
+ atomic_attribute_readers.delete_without_hooks( key )
778
+ atomic_attribute_accessors.delete_without_hooks( key )
779
+
780
+
781
+ end
782
+
783
+ when :writer
784
+
785
+ configuration_instance.instance_eval do
786
+
787
+ non_atomic_attribute_writers.push_without_hooks( key )
788
+
789
+ persistent_attribute_writers.push_without_hooks( key )
790
+
791
+ atomic_attributes.subtract_without_hooks( key, :writer )
792
+ atomic_attribute_writers.delete_without_hooks( key )
793
+ atomic_attribute_accessors.delete_without_hooks( key )
794
+
795
+ end
796
+
797
+ when :accessor
798
+
799
+ configuration_instance.instance_eval do
800
+
801
+ non_atomic_attribute_writers.push_without_hooks( key )
802
+ non_atomic_attribute_readers.push_without_hooks( key )
803
+ non_atomic_attribute_accessors.push_without_hooks( key )
804
+
805
+ persistent_attribute_readers.push_without_hooks( key )
806
+ persistent_attribute_writers.push_without_hooks( key )
807
+ persistent_attribute_accessors.push_without_hooks( key )
808
+
809
+ atomic_attributes.subtract_without_hooks( key, :accessor )
810
+ atomic_attribute_readers.delete_without_hooks( key )
811
+ atomic_attribute_writers.delete_without_hooks( key )
812
+ atomic_attribute_accessors.delete_without_hooks( key )
813
+
814
+ end
815
+ end
816
+
817
+ end
818
+
819
+ else
820
+
821
+ # if we have nil we are actually deleting
822
+ delete( key )
823
+
824
+ end
825
+
826
+ return reader_writer_accessor
827
+
828
+ end
829
+
830
+ end
831
+
832
+ ###########################
833
+ # persistent_attributes #
834
+ ###########################
835
+
836
+ ###
837
+ #
838
+ # @method persistent_attributes
839
+ #
840
+ # Hash tracking persistent attribute status
841
+ #
842
+ # @return [CompositingHash] CompositingHash extended with {::Persistence::Object::Complex::Attributes::AttributesHash
843
+ # Persistence::Object::Complex::Attributes::AttributesHash} and {::Persistence::Object::Complex::Attributes::AttributesHash
844
+ # Persistence::Object::Complex::Attributes::DefaultAtomicNonAtomic}.
845
+ #
846
+ attr_hash :persistent_attributes, AttributesHash, DefaultAtomicNonAtomic do
847
+
848
+ #===================#
849
+ # default_atomic! #
850
+ #===================#
851
+
852
+ def default_atomic!
853
+
854
+ super
855
+
856
+ unless @without_hooks
857
+
858
+ configuration_instance.instance_eval do
859
+
860
+ persistent_attribute_accessors.default_atomic_without_hooks!
861
+ persistent_attribute_writers.default_atomic_without_hooks!
862
+ persistent_attribute_readers.default_atomic_without_hooks!
863
+
864
+ end
865
+
866
+ end
867
+
868
+ end
869
+
870
+ #=======================#
871
+ # default_non_atomic! #
872
+ #=======================#
873
+
874
+ def default_non_atomic!
875
+
876
+ super
877
+
878
+ unless @without_hooks
879
+
880
+ configuration_instance.instance_eval do
881
+
882
+ persistent_attribute_accessors.default_non_atomic_without_hooks!
883
+ persistent_attribute_writers.default_non_atomic_without_hooks!
884
+ persistent_attribute_readers.default_non_atomic_without_hooks!
885
+
886
+ end
887
+
888
+ end
889
+
890
+ end
891
+
892
+ #=======================#
893
+ # update_for_addition #
894
+ #=======================#
895
+
896
+ def update_for_addition( key, reader_writer_accessor )
897
+ end
898
+
899
+ #==========================#
900
+ # update_for_subtraction #
901
+ #==========================#
902
+
903
+ def update_for_subtraction( key, reader_writer_accessor )
904
+ end
905
+
906
+ #=======#
907
+ # add #
908
+ #=======#
909
+
910
+ def add( key, reader_writer_accessor )
911
+
912
+ return_value = nil
913
+
914
+ if @without_hooks or @redirecting_to_atomic_or_non_atomic
915
+
916
+ return_value = super( key, reader_writer_accessor )
917
+
918
+ else
919
+
920
+ @redirecting_to_atomic_or_non_atomic = true
921
+
922
+ if @default_atomic
923
+ atomic_attributes = configuration_instance.atomic_attributes
924
+ return_value = atomic_attributes.add( key, reader_writer_accessor )
925
+ else
926
+ non_atomic_attributes = configuration_instance.non_atomic_attributes
927
+ return_value = non_atomic_attributes.add( key, reader_writer_accessor )
928
+ end
929
+
930
+ @redirecting_to_atomic_or_non_atomic = false
931
+
932
+ end
933
+
934
+ return return_value
935
+
936
+ end
937
+
938
+ #============#
939
+ # subtract #
940
+ #============#
941
+
942
+ def subtract( key, reader_writer_accessor )
943
+
944
+ return_value = nil
945
+
946
+ if @without_hooks or @redirecting_to_atomic_or_non_atomic
947
+
948
+ return_value = super( key, reader_writer_accessor )
949
+
950
+ else
951
+
952
+ @redirecting_to_atomic_or_non_atomic = true
953
+
954
+ if @default_atomic
955
+ atomic_attributes = configuration_instance.atomic_attributes
956
+ return_value = atomic_attributes.subtract( key, reader_writer_accessor )
957
+ else
958
+ non_atomic_attributes = configuration_instance.non_atomic_attributes
959
+ return_value = non_atomic_attributes.subtract( key, reader_writer_accessor )
960
+ end
961
+
962
+ @redirecting_to_atomic_or_non_atomic = false
963
+
964
+ end
965
+
966
+ return return_value
967
+
968
+ end
969
+
970
+ #=======#
971
+ # []= #
972
+ #=======#
973
+
974
+ def []=( key, reader_writer_accessor )
975
+
976
+ return_value = nil
977
+
978
+ if @without_hooks or @redirecting_to_atomic_or_non_atomic
979
+
980
+ return_value = super( key, reader_writer_accessor )
981
+
982
+ else
983
+
984
+ @redirecting_to_atomic_or_non_atomic = true
985
+
986
+ if @default_atomic
987
+ return_value = configuration_instance.atomic_attributes[ key ] = reader_writer_accessor
988
+ else
989
+ return_value = configuration_instance.non_atomic_attributes[ key ] = reader_writer_accessor
990
+ end
991
+
992
+ @redirecting_to_atomic_or_non_atomic = false
993
+
994
+ end
995
+
996
+ return return_value
997
+
998
+ end
999
+
1000
+ end
1001
+
1002
+ ##############################
1003
+ # atomic_attribute_readers #
1004
+ ##############################
1005
+
1006
+ ###
1007
+ #
1008
+ # @method atomic_attribute_readers
1009
+ #
1010
+ # Array tracking atomic attribute readers
1011
+ #
1012
+ # @return [CompositingHash] CompositingHash extended with {::Persistence::Object::Complex::Attributes::AttributesArray
1013
+ # Persistence::Object::Complex::Attributes::AttributesArray}.
1014
+ #
1015
+ attr_sorted_unique_array :atomic_attribute_readers, AttributesArray do
1016
+
1017
+ #=================#
1018
+ # post_set_hook #
1019
+ #=================#
1020
+
1021
+ def post_set_hook( index, object, is_insert )
1022
+
1023
+ configuration_instance.instance_eval do
1024
+
1025
+ atomic_attributes.add_without_hooks( object, :reader )
1026
+ non_atomic_attributes.subtract_without_hooks( object, :reader )
1027
+
1028
+ non_atomic_attribute_readers.delete_without_hooks( object )
1029
+
1030
+ end
1031
+
1032
+ return object
1033
+
1034
+ end
1035
+
1036
+ #====================#
1037
+ # post_delete_hook #
1038
+ #====================#
1039
+
1040
+ def post_delete_hook( index, object )
1041
+
1042
+ configuration_instance.instance_eval do
1043
+
1044
+ atomic_attributes.subtract_without_hooks( object, :reader )
1045
+
1046
+ atomic_attribute_accessors.delete( object )
1047
+
1048
+ unless non_atomic_attribute_readers.include?( object )
1049
+
1050
+ persistent_attributes.subtract_without_hooks( object, :reader )
1051
+ persistent_attribute_readers.delete_without_hooks( object )
1052
+
1053
+ end
1054
+
1055
+ end
1056
+
1057
+ return object
1058
+
1059
+ end
1060
+
1061
+ end
1062
+
1063
+ ##############################
1064
+ # atomic_attribute_writers #
1065
+ ##############################
1066
+
1067
+ ###
1068
+ #
1069
+ # @method atomic_attribute_writers
1070
+ #
1071
+ # Array tracking atomic attribute writers.
1072
+ #
1073
+ # @return [CompositingHash] CompositingHash extended with {::Persistence::Object::Complex::Attributes::AttributesArray
1074
+ # Persistence::Object::Complex::Attributes::AttributesArray}.
1075
+ #
1076
+ attr_sorted_unique_array :atomic_attribute_writers, AttributesArray do
1077
+
1078
+ #=================#
1079
+ # post_set_hook #
1080
+ #=================#
1081
+
1082
+ def post_set_hook( index, object, is_insert )
1083
+
1084
+ configuration_instance.instance_eval do
1085
+
1086
+ atomic_attributes.add_without_hooks( object, :writer )
1087
+ non_atomic_attributes.subtract_without_hooks( object, :writer )
1088
+
1089
+ non_atomic_attribute_writers.delete_without_hooks( object )
1090
+
1091
+ end
1092
+
1093
+ return object
1094
+
1095
+ end
1096
+
1097
+ #====================#
1098
+ # post_delete_hook #
1099
+ #====================#
1100
+
1101
+ def post_delete_hook( index, object )
1102
+
1103
+ configuration_instance.instance_eval do
1104
+
1105
+ atomic_attributes.subtract_without_hooks( object, :writer )
1106
+
1107
+ atomic_attribute_accessors.delete( object )
1108
+
1109
+ unless non_atomic_attribute_writers.include?( object )
1110
+
1111
+ persistent_attributes.subtract_without_hooks( object, :writer )
1112
+ persistent_attribute_writers.delete_without_hooks( object )
1113
+
1114
+ end
1115
+
1116
+ end
1117
+
1118
+ return object
1119
+
1120
+ end
1121
+
1122
+ end
1123
+
1124
+ ################################
1125
+ # atomic_attribute_accessors #
1126
+ ################################
1127
+
1128
+ ###
1129
+ #
1130
+ # @method atomic_attribute_accessors
1131
+ #
1132
+ # Array tracking atomic attribute accessors.
1133
+ #
1134
+ # @return [CompositingHash] CompositingHash extended with {::Persistence::Object::Complex::Attributes::AttributesArray
1135
+ # Persistence::Object::Complex::Attributes::AttributesArray}.
1136
+ #
1137
+ attr_sorted_unique_array :atomic_attribute_accessors, AttributesArray do
1138
+
1139
+ #=================#
1140
+ # post_set_hook #
1141
+ #=================#
1142
+
1143
+ def post_set_hook( index, object, is_insert )
1144
+
1145
+ configuration_instance.instance_eval do
1146
+
1147
+ atomic_attributes.add_without_hooks( object, :accessor )
1148
+ non_atomic_attributes.subtract_without_hooks( object, :accessor )
1149
+
1150
+ non_atomic_attribute_writers.delete_without_hooks( object )
1151
+
1152
+ end
1153
+
1154
+ return object
1155
+
1156
+ end
1157
+
1158
+ #====================#
1159
+ # post_delete_hook #
1160
+ #====================#
1161
+
1162
+ def post_delete_hook( index, object )
1163
+
1164
+ configuration_instance.instance_eval do
1165
+
1166
+ atomic_attributes.delete_without_hooks( object )
1167
+
1168
+ atomic_attribute_accessors.delete_without_hooks( object )
1169
+ atomic_attribute_readers.delete_without_hooks( object )
1170
+ atomic_attribute_writers.delete_without_hooks( object )
1171
+
1172
+ persistent_attributes.delete_without_hooks( object )
1173
+ persistent_attribute_readers.delete_without_hooks( object )
1174
+ persistent_attribute_writers.delete_without_hooks( object )
1175
+
1176
+ end
1177
+
1178
+ return object
1179
+
1180
+ end
1181
+
1182
+ end
1183
+
1184
+ ##################################
1185
+ # non_atomic_attribute_readers #
1186
+ ##################################
1187
+
1188
+ ###
1189
+ #
1190
+ # @method non_atomic_attribute_readers
1191
+ #
1192
+ # Array tracking non-atomic attribute readers.
1193
+ #
1194
+ # @return [CompositingHash] CompositingHash extended with {::Persistence::Object::Complex::Attributes::AttributesArray
1195
+ # Persistence::Object::Complex::Attributes::AttributesArray}.
1196
+ #
1197
+ attr_sorted_unique_array :non_atomic_attribute_readers, AttributesArray do
1198
+
1199
+ #=================#
1200
+ # post_set_hook #
1201
+ #=================#
1202
+
1203
+ def post_set_hook( index, object, is_insert )
1204
+
1205
+ configuration_instance.instance_eval do
1206
+
1207
+ non_atomic_attributes.add_without_hooks( object, :reader )
1208
+ atomic_attributes.subtract_without_hooks( object, :reader )
1209
+
1210
+ atomic_attribute_readers.delete_without_hooks( object )
1211
+
1212
+ end
1213
+
1214
+ return object
1215
+
1216
+ end
1217
+
1218
+ #====================#
1219
+ # post_delete_hook #
1220
+ #====================#
1221
+
1222
+ def post_delete_hook( index, object )
1223
+
1224
+ configuration_instance.instance_eval do
1225
+
1226
+ non_atomic_attributes.subtract_without_hooks( object, :reader )
1227
+
1228
+ non_atomic_attribute_accessors.delete( object )
1229
+
1230
+ unless atomic_attribute_readers.include?( object )
1231
+
1232
+ persistent_attributes.subtract_without_hooks( object, :reader )
1233
+ persistent_attribute_readers.delete_without_hooks( object )
1234
+
1235
+ end
1236
+
1237
+ end
1238
+
1239
+ return object
1240
+
1241
+ end
1242
+
1243
+ end
1244
+
1245
+ ##################################
1246
+ # non_atomic_attribute_writers #
1247
+ ##################################
1248
+
1249
+ ###
1250
+ #
1251
+ # @method non_atomic_attribute_writers
1252
+ #
1253
+ # Array tracking non-atomic attribute writers.
1254
+ #
1255
+ # @return [CompositingHash] CompositingHash extended with {::Persistence::Object::Complex::Attributes::AttributesArray
1256
+ # Persistence::Object::Complex::Attributes::AttributesArray}.
1257
+ #
1258
+ attr_sorted_unique_array :non_atomic_attribute_writers, AttributesArray do
1259
+
1260
+ #=================#
1261
+ # post_set_hook #
1262
+ #=================#
1263
+
1264
+ def post_set_hook( index, object, is_insert )
1265
+
1266
+ configuration_instance.instance_eval do
1267
+
1268
+ non_atomic_attributes.add_without_hooks( object, :writer )
1269
+ atomic_attributes.subtract_without_hooks( object, :writer )
1270
+
1271
+ atomic_attribute_writers.delete_without_hooks( object )
1272
+
1273
+ end
1274
+
1275
+ return object
1276
+
1277
+ end
1278
+
1279
+ #====================#
1280
+ # post_delete_hook #
1281
+ #====================#
1282
+
1283
+ def post_delete_hook( index, object )
1284
+
1285
+ configuration_instance.instance_eval do
1286
+
1287
+ non_atomic_attributes.subtract_without_hooks( object, :writer )
1288
+
1289
+ non_atomic_attribute_accessors.delete( object )
1290
+
1291
+ unless atomic_attribute_writers.include?( object )
1292
+
1293
+ persistent_attributes.subtract_without_hooks( object, :writer )
1294
+ persistent_attribute_writers.delete_without_hooks( object )
1295
+
1296
+ end
1297
+
1298
+ end
1299
+
1300
+ return object
1301
+
1302
+ end
1303
+
1304
+ end
1305
+
1306
+ ####################################
1307
+ # non_atomic_attribute_accessors #
1308
+ ####################################
1309
+
1310
+ ###
1311
+ #
1312
+ # @method non_atomic_attribute_accessors
1313
+ #
1314
+ # Array tracking non-atomic attribute accessors.
1315
+ #
1316
+ # @return [CompositingHash] CompositingHash extended with {::Persistence::Object::Complex::Attributes::AttributesArray
1317
+ # Persistence::Object::Complex::Attributes::AttributesArray}.
1318
+ #
1319
+ attr_sorted_unique_array :non_atomic_attribute_accessors, AttributesArray do
1320
+
1321
+ #=================#
1322
+ # post_set_hook #
1323
+ #=================#
1324
+
1325
+ def post_set_hook( index, object, is_insert )
1326
+
1327
+ configuration_instance.instance_eval do
1328
+
1329
+ non_atomic_attributes.add_without_hooks( object, :accessor )
1330
+ atomic_attributes.subtract_without_hooks( object, :accessor )
1331
+
1332
+ atomic_attribute_writers.delete_without_hooks( object )
1333
+
1334
+ end
1335
+
1336
+ return object
1337
+
1338
+ end
1339
+
1340
+ #====================#
1341
+ # post_delete_hook #
1342
+ #====================#
1343
+
1344
+ def post_delete_hook( index, object )
1345
+
1346
+ configuration_instance.instance_eval do
1347
+
1348
+ non_atomic_attributes.delete_without_hooks( object )
1349
+
1350
+ non_atomic_attribute_accessors.delete_without_hooks( object )
1351
+ non_atomic_attribute_readers.delete_without_hooks( object )
1352
+ non_atomic_attribute_writers.delete_without_hooks( object )
1353
+
1354
+ persistent_attributes.delete_without_hooks( object )
1355
+ persistent_attribute_readers.delete_without_hooks( object )
1356
+ persistent_attribute_writers.delete_without_hooks( object )
1357
+
1358
+ end
1359
+
1360
+ return object
1361
+
1362
+ end
1363
+
1364
+ end
1365
+
1366
+ ##################################
1367
+ # persistent_attribute_readers #
1368
+ ##################################
1369
+
1370
+ ###
1371
+ #
1372
+ # @method persistent_attribute_readers
1373
+ #
1374
+ # Array tracking persistent attribute readers.
1375
+ #
1376
+ # @return [CompositingHash] CompositingHash extended with {::Persistence::Object::Complex::Attributes::AttributesArray
1377
+ # Persistence::Object::Complex::Attributes::AttributesArray} and
1378
+ # {::Persistence::Object::Complex::Attributes::DefaultAtomicNonAtomic
1379
+ # Persistence::Object::Complex::Attributes::DefaultAtomicNonAtomic}.
1380
+ #
1381
+ attr_sorted_unique_array :persistent_attribute_readers, AttributesArray, DefaultAtomicNonAtomic do
1382
+
1383
+ #===================#
1384
+ # default_atomic! #
1385
+ #===================#
1386
+
1387
+ def default_atomic!
1388
+
1389
+ super
1390
+
1391
+ unless @without_hooks
1392
+
1393
+ configuration_instance.instance_eval do
1394
+
1395
+ persistent_attributes.default_atomic_without_hooks!
1396
+ persistent_attribute_writers.default_atomic_without_hooks!
1397
+ persistent_attribute_accessors.default_atomic_without_hooks!
1398
+
1399
+ end
1400
+
1401
+ end
1402
+
1403
+ end
1404
+
1405
+ #=======================#
1406
+ # default_non_atomic! #
1407
+ #=======================#
1408
+
1409
+ def default_non_atomic!
1410
+
1411
+ super
1412
+
1413
+ unless @without_hooks
1414
+
1415
+ configuration_instance.instance_eval do
1416
+
1417
+ persistent_attributes.default_non_atomic_without_hooks!
1418
+ persistent_attribute_writers.default_non_atomic_without_hooks!
1419
+ persistent_attribute_accessors.default_non_atomic_without_hooks!
1420
+
1421
+ end
1422
+
1423
+ end
1424
+
1425
+ end
1426
+
1427
+ #=======#
1428
+ # []= #
1429
+ #=======#
1430
+
1431
+ def []=( index, reader_writer_accessor )
1432
+
1433
+ return_value = nil
1434
+
1435
+ if @without_hooks or @redirecting_to_atomic_or_non_atomic
1436
+
1437
+ return_value = super( index, reader_writer_accessor )
1438
+
1439
+ else
1440
+
1441
+ @redirecting_to_atomic_or_non_atomic = true
1442
+
1443
+ if @default_atomic
1444
+ atomic_attribute_readers = configuration_instance.atomic_attribute_readers
1445
+ return_value = atomic_attribute_readers[ index ] = reader_writer_accessor
1446
+ else
1447
+ non_atomic_attribute_readers = configuration_instance.non_atomic_attribute_readers
1448
+ return_value = non_atomic_attribute_readers[ index ] = reader_writer_accessor
1449
+ end
1450
+
1451
+ @redirecting_to_atomic_or_non_atomic = false
1452
+
1453
+ end
1454
+
1455
+ return return_value
1456
+
1457
+ end
1458
+
1459
+ #==========#
1460
+ # insert #
1461
+ #==========#
1462
+
1463
+ def insert( index, *reader_writer_accessors )
1464
+
1465
+ return_value = nil
1466
+
1467
+ if @without_hooks or @redirecting_to_atomic_or_non_atomic
1468
+
1469
+ return_value = super( index, *reader_writer_accessors )
1470
+
1471
+ else
1472
+
1473
+ @redirecting_to_atomic_or_non_atomic = true
1474
+
1475
+ if @default_atomic
1476
+ atomic_attribute_readers = configuration_instance.atomic_attribute_readers
1477
+ return_value = atomic_attribute_readers.insert( index, *reader_writer_accessors )
1478
+ else
1479
+ non_atomic_attribute_readers = configuration_instance.non_atomic_attribute_readers
1480
+ return_value = non_atomic_attribute_readers.insert( index, *reader_writer_accessors )
1481
+ end
1482
+
1483
+ @redirecting_to_atomic_or_non_atomic = false
1484
+
1485
+ end
1486
+
1487
+ return return_value
1488
+
1489
+ end
1490
+
1491
+ end
1492
+
1493
+ ##################################
1494
+ # persistent_attribute_writers #
1495
+ ##################################
1496
+
1497
+ ###
1498
+ #
1499
+ # @method persistent_attribute_writers
1500
+ #
1501
+ # Array tracking persistent attribute writers.
1502
+ #
1503
+ # @return [CompositingHash] CompositingHash extended with {::Persistence::Object::Complex::Attributes::AttributesArray
1504
+ # Persistence::Object::Complex::Attributes::AttributesArray} and
1505
+ # {::Persistence::Object::Complex::Attributes::DefaultAtomicNonAtomic
1506
+ # Persistence::Object::Complex::Attributes::DefaultAtomicNonAtomic}.
1507
+ #
1508
+ attr_sorted_unique_array :persistent_attribute_writers, AttributesArray, DefaultAtomicNonAtomic do
1509
+
1510
+ #===================#
1511
+ # default_atomic! #
1512
+ #===================#
1513
+
1514
+ def default_atomic!
1515
+
1516
+ super
1517
+
1518
+ unless @without_hooks
1519
+
1520
+ configuration_instance.instance_eval do
1521
+
1522
+ persistent_attributes.default_atomic_without_hooks!
1523
+ persistent_attribute_readers.default_atomic_without_hooks!
1524
+ persistent_attribute_accessors.default_atomic_without_hooks!
1525
+
1526
+ end
1527
+
1528
+ end
1529
+
1530
+ end
1531
+
1532
+ #=======================#
1533
+ # default_non_atomic! #
1534
+ #=======================#
1535
+
1536
+ def default_non_atomic!
1537
+
1538
+ super
1539
+
1540
+ unless @without_hooks
1541
+
1542
+ configuration_instance.instance_eval do
1543
+
1544
+ persistent_attributes.default_non_atomic_without_hooks!
1545
+ persistent_attribute_readers.default_non_atomic_without_hooks!
1546
+ persistent_attribute_accessors.default_non_atomic_without_hooks!
1547
+
1548
+ end
1549
+
1550
+ end
1551
+
1552
+ end
1553
+
1554
+ #=======#
1555
+ # []= #
1556
+ #=======#
1557
+
1558
+ def []=( index, reader_writer_accessor )
1559
+
1560
+ return_value = nil
1561
+
1562
+ if @without_hooks or @redirecting_to_atomic_or_non_atomic
1563
+
1564
+ return_value = super( index, reader_writer_accessor )
1565
+
1566
+ else
1567
+
1568
+ @redirecting_to_atomic_or_non_atomic = true
1569
+
1570
+ if @default_atomic
1571
+ atomic_attribute_writers = configuration_instance.atomic_attribute_writers
1572
+ return_value = atomic_attribute_writers[ index ] = reader_writer_accessor
1573
+ else
1574
+ non_atomic_attribute_writers = configuration_instance.non_atomic_attribute_writers
1575
+ return_value = non_atomic_attribute_writers[ index ] = reader_writer_accessor
1576
+ end
1577
+
1578
+ @redirecting_to_atomic_or_non_atomic = false
1579
+
1580
+ end
1581
+
1582
+ return return_value
1583
+
1584
+ end
1585
+
1586
+ #==========#
1587
+ # insert #
1588
+ #==========#
1589
+
1590
+ def insert( index, *reader_writer_accessors )
1591
+
1592
+ return_value = nil
1593
+
1594
+ if @without_hooks or @redirecting_to_atomic_or_non_atomic
1595
+
1596
+ return_value = super( index, *reader_writer_accessors )
1597
+
1598
+ else
1599
+
1600
+ @redirecting_to_atomic_or_non_atomic = true
1601
+
1602
+ if @default_atomic
1603
+ atomic_attribute_writers = configuration_instance.atomic_attribute_writers
1604
+ return_value = atomic_attribute_writers.insert( index, *reader_writer_accessors )
1605
+ else
1606
+ non_atomic_attribute_writers = configuration_instance.non_atomic_attribute_writers
1607
+ return_value = non_atomic_attribute_writers.insert( index, *reader_writer_accessors )
1608
+ end
1609
+
1610
+ @redirecting_to_atomic_or_non_atomic = false
1611
+
1612
+ end
1613
+
1614
+ return return_value
1615
+
1616
+ end
1617
+
1618
+ end
1619
+
1620
+ ####################################
1621
+ # persistent_attribute_accessors #
1622
+ ####################################
1623
+
1624
+ ###
1625
+ #
1626
+ # @method persistent_attribute_accessors
1627
+ #
1628
+ # Array tracking persistent attribute accessors.
1629
+ #
1630
+ # @return [CompositingHash] CompositingHash extended with {::Persistence::Object::Complex::Attributes::AttributesArray
1631
+ # Persistence::Object::Complex::Attributes::AttributesArray} and
1632
+ # {::Persistence::Object::Complex::Attributes::DefaultAtomicNonAtomic
1633
+ # Persistence::Object::Complex::Attributes::DefaultAtomicNonAtomic}.
1634
+ #
1635
+ attr_sorted_unique_array :persistent_attribute_accessors, AttributesArray, DefaultAtomicNonAtomic do
1636
+
1637
+ #===================#
1638
+ # default_atomic! #
1639
+ #===================#
1640
+
1641
+ def default_atomic!
1642
+
1643
+ super
1644
+
1645
+ unless @without_hooks
1646
+
1647
+ configuration_instance.instance_eval do
1648
+
1649
+ persistent_attributes.default_atomic_without_hooks!
1650
+ persistent_attribute_writers.default_atomic_without_hooks!
1651
+ persistent_attribute_readers.default_atomic_without_hooks!
1652
+
1653
+ end
1654
+
1655
+ end
1656
+
1657
+ end
1658
+
1659
+ #=======================#
1660
+ # default_non_atomic! #
1661
+ #=======================#
1662
+
1663
+ def default_non_atomic!
1664
+
1665
+ super
1666
+
1667
+ unless @without_hooks
1668
+
1669
+ configuration_instance.instance_eval do
1670
+
1671
+ persistent_attributes.default_non_atomic_without_hooks!
1672
+ persistent_attribute_writers.default_non_atomic_without_hooks!
1673
+ persistent_attribute_readers.default_non_atomic_without_hooks!
1674
+
1675
+ end
1676
+
1677
+ end
1678
+
1679
+ end
1680
+
1681
+ #=======#
1682
+ # []= #
1683
+ #=======#
1684
+
1685
+ def []=( index, reader_writer_accessor )
1686
+
1687
+ return_value = nil
1688
+
1689
+ if @without_hooks or @redirecting_to_atomic_or_non_atomic
1690
+
1691
+ return_value = super( index, reader_writer_accessor )
1692
+
1693
+ else
1694
+
1695
+ @redirecting_to_atomic_or_non_atomic = true
1696
+
1697
+ if @default_atomic
1698
+ atomic_attribute_accessors = configuration_instance.atomic_attribute_accessors
1699
+ return_value = atomic_attribute_accessors[ index ] = reader_writer_accessor
1700
+ else
1701
+ non_atomic_attribute_accessors = configuration_instance.non_atomic_attribute_accessors
1702
+ return_value = non_atomic_attribute_accessors[ index ] = reader_writer_accessor
1703
+ end
1704
+
1705
+ @redirecting_to_atomic_or_non_atomic = false
1706
+
1707
+ end
1708
+
1709
+ return return_value
1710
+
1711
+ end
1712
+
1713
+ #==========#
1714
+ # insert #
1715
+ #==========#
1716
+
1717
+ def insert( index, *reader_writer_accessors )
1718
+
1719
+ return_value = nil
1720
+
1721
+ if @without_hooks or @redirecting_to_atomic_or_non_atomic
1722
+
1723
+ return_value = super( index, *reader_writer_accessors )
1724
+
1725
+ else
1726
+
1727
+ @redirecting_to_atomic_or_non_atomic = true
1728
+
1729
+ if @default_atomic
1730
+ atomic_attribute_accessors = configuration_instance.atomic_attribute_accessors
1731
+ return_value = atomic_attribute_accessors.insert( index, *reader_writer_accessors )
1732
+ else
1733
+ non_atomic_attribute_accessors = configuration_instance.non_atomic_attribute_accessors
1734
+ return_value = non_atomic_attribute_accessors.insert( index, *reader_writer_accessors )
1735
+ end
1736
+
1737
+ @redirecting_to_atomic_or_non_atomic = false
1738
+
1739
+ end
1740
+
1741
+ return return_value
1742
+
1743
+ end
1744
+
1745
+ end
1746
+
1747
+ ##################################################################################################
1748
+ private ######################################################################################
1749
+ ##################################################################################################
1750
+
1751
+ ###################
1752
+ # define_reader #
1753
+ ###################
1754
+
1755
+ ###
1756
+ # Define attribute reader.
1757
+ #
1758
+ def define_reader( attribute )
1759
+
1760
+ instance_controller = ::CascadingConfiguration::Core::InstanceController.create_instance_controller( self )
1761
+
1762
+ instance_controller.define_instance_method( attribute ) do
1763
+
1764
+ return get_attribute( attribute )
1765
+
1766
+ end
1767
+
1768
+ return self
1769
+
1770
+ end
1771
+
1772
+ ###################
1773
+ # define_writer #
1774
+ ###################
1775
+
1776
+ ###
1777
+ # Define attribute writer.
1778
+ #
1779
+ def define_writer( attribute )
1780
+
1781
+ write_accessor_name = attribute.write_accessor_name
1782
+
1783
+ instance_controller = ::CascadingConfiguration::Core::InstanceController.create_instance_controller( self )
1784
+
1785
+ instance_controller.define_instance_method( write_accessor_name ) do |value|
1786
+
1787
+ return set_attribute( attribute, value )
1788
+
1789
+ end
1790
+
1791
+ return self
1792
+
1793
+ end
1794
+
1795
+ ############################
1796
+ # define_atomic_accessor #
1797
+ ############################
1798
+
1799
+ ###
1800
+ # Define attribute accessor.
1801
+ #
1802
+ def define_atomic_accessor( attribute )
1803
+ define_reader( attribute )
1804
+ define_writer( attribute )
1805
+ return self
1806
+ end
1807
+
1808
+ end