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,267 @@
1
+
2
+ ###
3
+ # Methods applied to Class instances of complex objects enabled with persistence capabilities.
4
+ #
5
+ module ::Persistence::Object::Complex::ClassInstance
6
+
7
+ include ::Persistence::Object::Complex::Attributes
8
+
9
+ include ::Persistence::Object::Complex::ClassAndObjectInstance
10
+
11
+ include ::CascadingConfiguration::Array::Unique
12
+
13
+ ################
14
+ # attr_index #
15
+ ################
16
+
17
+ ###
18
+ # Declare an index on attribute(s).
19
+ #
20
+ # @overload attr_index( attribute_name, ... )
21
+ #
22
+ # @param attribute_name Name of object property to index. Creates accessor if method by name
23
+ # does not already exist.
24
+ #
25
+ # @return self
26
+ #
27
+ def attr_index( *attributes )
28
+
29
+ parent_bucket = instance_persistence_bucket
30
+
31
+ attributes.each do |this_attribute|
32
+ index_instance = ::Persistence::Object::Complex::Index::AttributeIndex.new( this_attribute, parent_bucket, false )
33
+ index_instance.attribute_name = this_attribute
34
+ indexes[ this_attribute ] = attribute_indexes[ this_attribute ] = index_instance
35
+ end
36
+
37
+ return self
38
+
39
+ end
40
+
41
+ ########################
42
+ # attr_index_ordered #
43
+ ########################
44
+
45
+ ###
46
+ # Declare an ordered index on attribute(s). PENDING.
47
+ #
48
+ # @overload attr_index( attribute_name, ... )
49
+ #
50
+ # @param attribute_name Name of object property to index. Creates accessor if method by name
51
+ # does not already exist.
52
+ #
53
+ # @return self
54
+ #
55
+ def attr_index_ordered( attributes, & ordering_block )
56
+
57
+ raise 'pending'
58
+
59
+ parent_bucket = instance_persistence_bucket
60
+
61
+ attributes.each do |this_attribute|
62
+ index_instance = ::Persistence::Object::Complex::Index::AttributeIndex.new( this_attribute,
63
+ parent_bucket,
64
+ true,
65
+ ordering_block )
66
+ index_instance.attribute_name = this_attribute
67
+ indexes[ this_attribute ] = attribute_indexes[ this_attribute ] = index_instance
68
+ end
69
+
70
+ return self
71
+
72
+ end
73
+
74
+ ################################
75
+ # attr_index_with_duplicates #
76
+ ################################
77
+
78
+ ###
79
+ # Declare an index permitting duplicates on attribute(s).
80
+ #
81
+ # @overload attr_index_with_duplicates( attribute_name, ... )
82
+ #
83
+ # @param attribute_name Name of object property to index. Creates accessor if method by name
84
+ # does not already exist.
85
+ #
86
+ # @return self
87
+ #
88
+ def attr_index_with_duplicates( attribute )
89
+
90
+ index_instance = ::Persistence::Object::Complex::Index::AttributeIndex.new( attribute,
91
+ instance_persistence_bucket,
92
+ true )
93
+ index_instance.attribute_name = attribute
94
+ indexes[ attribute ] = attribute_indexes[ attribute ] = index_instance
95
+
96
+ return self
97
+
98
+ end
99
+
100
+ ########################################
101
+ # attr_index_ordered_with_duplicates #
102
+ ########################################
103
+
104
+ ###
105
+ # Declare an ordered index permitting duplicates on attribute(s). PENDING.
106
+ #
107
+ # @overload attr_index_ordered_with_duplicates( attribute_name, ... )
108
+ #
109
+ # @param attribute_name Name of object property to index. Creates accessor if method by name
110
+ # does not already exist.
111
+ #
112
+ # @return self
113
+ #
114
+ def attr_index_ordered_with_duplicates( attribute, duplicates_ordering_proc = nil, & ordering_block )
115
+
116
+ raise 'pending'
117
+
118
+ index_instance = ::Persistence::Object::Complex::Index::AttributeIndex.new( attribute,
119
+ parent_bucket,
120
+ true,
121
+ ordering_block,
122
+ duplicates_ordering_proc )
123
+ index_instance.attribute_name = attribute
124
+ indexes[ attribute ] = attribute_indexes[ attribute ] = index_instance
125
+
126
+ return self
127
+
128
+ end
129
+
130
+ ##########################
131
+ # has_attribute_index? #
132
+ ##########################
133
+
134
+ ###
135
+ # Query whether attribute index(es) exist for object.
136
+ #
137
+ # @overload has_attribute_index?( index_name, ... )
138
+ #
139
+ # @param index_name Name of requested index.
140
+ #
141
+ # @return [true,false] Whether index(es) exist.
142
+ #
143
+ def has_attribute_index?( *attributes )
144
+
145
+ has_index = false
146
+
147
+ attributes.each do |this_attribute|
148
+ break unless has_index = attribute_indexes.has_key?( this_attribute.accessor_name )
149
+ end
150
+
151
+ return has_index
152
+
153
+ end
154
+
155
+ ############
156
+ # cease! #
157
+ ############
158
+
159
+ def cease!( *args )
160
+
161
+ if persistence_hash_in_port = super
162
+
163
+ persistence_hash_in_port.each do |this_attribute, this_value|
164
+
165
+ if this_value.is_a?( ::Persistence::Object::Complex::ComplexObject ) and
166
+ delete_cascades?( global_id, this_value.persistence_id )
167
+
168
+ this_value.cease!
169
+
170
+ end
171
+
172
+ end
173
+
174
+ end
175
+
176
+ return persistence_hash_in_port
177
+
178
+ end
179
+
180
+ ###############
181
+ # attr_flat #
182
+ ###############
183
+
184
+ ###
185
+ # Declare that an attribute should be treated as a flat object by persistence port, regardless whether it
186
+ # actually is a flat object.
187
+ #
188
+ # @overload attr_flat( attribute_name, ... )
189
+ #
190
+ # @param attribute_name Name of attribute to treat as flat object.
191
+ #
192
+ # @return self
193
+ #
194
+ def attr_flat( *attributes )
195
+
196
+ if attributes.empty?
197
+ persists_flat[ nil ] = true
198
+ else
199
+ attributes.each do |this_attribute|
200
+ persists_flat.push( this_attribute )
201
+ end
202
+ end
203
+
204
+ return self
205
+
206
+ end
207
+
208
+ ################
209
+ # attr_flat! #
210
+ ################
211
+
212
+ ###
213
+ # Declare {self#attr_flat} on all attributes.
214
+ #
215
+ # @return self
216
+ #
217
+ def attr_flat!
218
+
219
+ attr_flat( *persistent_attribute_writers )
220
+
221
+ return self
222
+
223
+ end
224
+
225
+ ####################
226
+ # persists_flat? #
227
+ ####################
228
+
229
+ ###
230
+ # Query whether attribute(s) are being treated explicitly as flat objects.
231
+ #
232
+ # @overload has_attribute_index?( attribute_name, ... )
233
+ #
234
+ # @param attribute_name Attribute(s) in question.
235
+ #
236
+ # @return [true,false] Whether attributes(es) are being treated explicitly as flat objects.
237
+ #
238
+ def persists_flat?( *attributes )
239
+
240
+ should_persist_flat = false
241
+
242
+ if attributes.empty?
243
+ should_persist_flat = persists_flat.include?( nil )
244
+ else
245
+ attributes.each do |this_attribute|
246
+ break unless should_persist_flat = persists_flat.include?( this_attribute )
247
+ end
248
+ end
249
+
250
+ return should_persist_flat
251
+
252
+ end
253
+
254
+ ###################
255
+ # persists_flat #
256
+ ###################
257
+
258
+ ###
259
+ # @method persists_flat
260
+ #
261
+ # Hash that tracks attributes specified to persist as if they are flat objects.
262
+ #
263
+ # @return [CompositingHash{Symbol,String=>true}] Hash with attribute details.
264
+ #
265
+ attr_unique_array :persists_flat
266
+
267
+ end
@@ -0,0 +1,111 @@
1
+
2
+ ###
3
+ # Class used for persisting references to other complex objects nested inside a complex object.
4
+ #
5
+ class ::Persistence::Object::Complex::ComplexObject < ::String
6
+
7
+ include CascadingConfiguration::Setting
8
+
9
+ ################
10
+ # initialize #
11
+ ################
12
+
13
+ ###
14
+ #
15
+ # @param object Object for which ComplexObject instance is used.
16
+ #
17
+ def initialize( object )
18
+
19
+ super( object.persistence_id.to_s )
20
+
21
+ self.persistence_port = object.persistence_port
22
+ self.persistence_bucket = object.persistence_bucket
23
+
24
+ end
25
+
26
+ #####################
27
+ # delete_cascades #
28
+ #####################
29
+
30
+ ###
31
+ # @!attribute [writer] Whether this object should be deleted when its parent is deleted.
32
+ #
33
+ attr_writer :delete_cascades
34
+
35
+ #############
36
+ # persist #
37
+ #############
38
+
39
+ ###
40
+ # Store object to persistence bucket.
41
+ #
42
+ def persist
43
+
44
+ global_id = persistence_id
45
+ klass = persistence_port.get_class_for_object_id( global_id )
46
+
47
+ return klass.persist( global_id )
48
+
49
+ end
50
+
51
+ ####################
52
+ # persistence_id #
53
+ ####################
54
+
55
+ ###
56
+ # Get persistence ID.
57
+ #
58
+ def persistence_id
59
+
60
+ return to_i
61
+
62
+ end
63
+
64
+ ######################
65
+ # persistence_port #
66
+ ######################
67
+
68
+ ###
69
+ # @method persistence_port
70
+ #
71
+ # Get object's persistence port.
72
+ #
73
+ attr_instance_setting :persistence_port
74
+
75
+ ########################
76
+ # persistence_bucket #
77
+ ########################
78
+
79
+ attr_instance_setting :persistence_bucket
80
+
81
+ ###
82
+ # Get object's persistence bucket.
83
+ #
84
+ def persistence_bucket
85
+
86
+ unless return_bucket = super
87
+ return_bucket = persistence_port.get_bucket_name_for_object_id( persistence_id )
88
+ self.persistence_bucket = return_bucket
89
+ end
90
+
91
+ return return_bucket
92
+
93
+ end
94
+
95
+ ######################
96
+ # delete_cascades? #
97
+ ######################
98
+
99
+ ###
100
+ # Query whether object should be deleted when parent object is deleted.
101
+ #
102
+ # @return [true,false] Whether object delete should cascade.
103
+ #
104
+ def delete_cascades?
105
+
106
+ return @delete_cascades
107
+
108
+ end
109
+
110
+ end
111
+
@@ -0,0 +1,14 @@
1
+
2
+ ###
3
+ # Convenience module for extending hash types (singletons and instances) with persistence capabilities.
4
+ #
5
+ module ::Persistence::Object::Complex::Hash
6
+
7
+ extend ModuleCluster::Define::ClusterCascades
8
+
9
+ include ::Persistence::Object::Complex
10
+
11
+ include ::Persistence::Object::Complex::Hash::ObjectInstance
12
+ include_or_extend_cascades_prepend_extends ::Persistence::Object::Complex::Hash::ClassInstance
13
+
14
+ end
@@ -0,0 +1,40 @@
1
+
2
+ ###
3
+ # Class methods for hash objects enabled with persistence capabilities.
4
+ #
5
+ module ::Persistence::Object::Complex::Hash::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
+ hash_from_port = instance_persistence_bucket.get_object_hash( global_id )
26
+
27
+ hash_from_port.each do |this_key, this_value|
28
+ if this_value.is_a?( ::Persistence::Object::Complex::ComplexObject )
29
+ this_value = this_value.persist
30
+ object[ this_key ] = this_value
31
+ else
32
+ object[ this_key ] = this_value
33
+ end
34
+ end
35
+
36
+ return object
37
+
38
+ end
39
+
40
+ end
@@ -0,0 +1,63 @@
1
+
2
+ ###
3
+ # Instance methods for hash objects enabled with persistence capabilities.
4
+ #
5
+ module ::Persistence::Object::Complex::Hash::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
+ elsif key
18
+ global_id = key
19
+ else
20
+ global_id = persistence_id
21
+ end
22
+
23
+ port_hash = persistence_bucket.adapter_bucket.get_object( global_id )
24
+
25
+ port_hash.each do |this_key, this_value|
26
+ if this_value.is_a?( ::Persistence::Object::Complex::ComplexObject )
27
+ self[ this_key ] = this_value.persist
28
+ else
29
+ self[ this_key ] = this_value
30
+ end
31
+ end
32
+
33
+ return self
34
+
35
+ end
36
+
37
+ ##############################
38
+ # persistence_hash_to_port #
39
+ ##############################
40
+
41
+ def persistence_hash_to_port
42
+
43
+ hash_to_port = ::Persistence::Object::Complex::Attributes::HashToPort.new
44
+ hash_to_port.persistence_object = self
45
+
46
+ self.each do |key, data|
47
+ key = persist_as_sub_object_or_attribute_and_return_id_or_value( key )
48
+ hash_to_port[ key ] = data
49
+ end
50
+
51
+ return hash_to_port
52
+
53
+ end
54
+
55
+ ############################
56
+ # load_persistence_value #
57
+ ############################
58
+
59
+ def load_persistence_value( attribute_name, attribute_value )
60
+ self[ attribute_name ] = attribute_value
61
+ end
62
+
63
+ end