persistence 0.0.1.alpha → 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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