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,32 @@
1
+
2
+ ###
3
+ # Module used for common methods for attributes arrays.
4
+ #
5
+ module ::Persistence::Object::Complex::Attributes::AttributesArray
6
+
7
+ #####################
8
+ # has_attributes? #
9
+ #####################
10
+
11
+ ###
12
+ # Query whether this array includes attribute(s).
13
+ #
14
+ # @overload has_attributes?( attribute_name, ... )
15
+ #
16
+ # @param attribute_name [Symbol,String] Attribute to query.
17
+ #
18
+ # @return [true,false] Whether this hash/array includes attribute(s).
19
+ #
20
+ def has_attributes?( *attributes )
21
+
22
+ has_attributes = false
23
+
24
+ attributes.each do |this_attribute|
25
+ break unless has_attributes = include?( this_attribute )
26
+ end
27
+
28
+ return has_attributes
29
+
30
+ end
31
+
32
+ end
@@ -0,0 +1,187 @@
1
+
2
+ ###
3
+ # Module used for common methods for attributes hashes.
4
+ #
5
+ module ::Persistence::Object::Complex::Attributes::AttributesHash
6
+
7
+ include ::AccessorUtilities::AccessorMath
8
+
9
+ ##################
10
+ # pre_set_hook #
11
+ ##################
12
+
13
+ def pre_set_hook( key, value )
14
+
15
+ case value
16
+ when nil, :reader, :writer, :accessor
17
+ else
18
+ raise ArgumentError, 'Permitted values: :reader, :writer, :accessor.'
19
+ end
20
+
21
+ return value
22
+
23
+ end
24
+
25
+ ###################
26
+ # post_set_hook #
27
+ ###################
28
+
29
+ def post_set_hook( key, value )
30
+
31
+ # create method in configuration_instance
32
+
33
+ end
34
+
35
+ #########
36
+ # add #
37
+ #########
38
+
39
+ ###
40
+ # Adds :reader, :writer or :accessor to key.
41
+ #
42
+ def add( key, reader_writer_accessor )
43
+
44
+ # figure out actual addition value
45
+ existing_status = self[ key ]
46
+
47
+ if actual_status = status_minus_other_status( reader_writer_accessor, existing_status )
48
+
49
+ # if we have an addition value, do so directly
50
+ new_status = status_plus_other_status( existing_status, actual_status )
51
+
52
+ store_without_hooks( key, new_status )
53
+
54
+ # update corresponding structures for addition
55
+ unless @without_hooks
56
+ update_for_addition( key, actual_status )
57
+ end
58
+
59
+ end
60
+
61
+ return new_status
62
+
63
+ end
64
+
65
+ #######################
66
+ # add_without_hooks #
67
+ #######################
68
+
69
+ ###
70
+ # @private
71
+ #
72
+ # Adds :reader, :writer or :accessor to key.
73
+ # Used to prevent loops when array/hash relays to other arrays/hashes.
74
+ #
75
+ def add_without_hooks( key, reader_writer_accessor )
76
+
77
+ @without_hooks = true
78
+
79
+ add( key, reader_writer_accessor )
80
+
81
+ @without_hooks = false
82
+
83
+ end
84
+
85
+ ##############
86
+ # subtract #
87
+ ##############
88
+
89
+ ###
90
+ # Subtracts :reader, :writer or :accessor to key.
91
+ #
92
+ def subtract( key, reader_writer_accessor )
93
+
94
+ # figure out actual subtraction value
95
+ existing_status = self[ key ]
96
+
97
+ result_value = status_minus_other_status( existing_status, reader_writer_accessor )
98
+
99
+ if actual_status = status_minus_other_status( reader_writer_accessor, result_value )
100
+
101
+ # if we have an actual value we are subtracting, do so directly (no hooks)
102
+ if new_status = status_minus_other_status( existing_status, actual_status )
103
+ store_without_hooks( key, new_status )
104
+ elsif existing_status
105
+ delete( key )
106
+ end
107
+
108
+ # update corresponding structures for subtraction (pass actually-subtracted value)
109
+ unless @without_hooks
110
+ update_for_subtraction( key, actual_status )
111
+ end
112
+
113
+ end
114
+
115
+ return result_value
116
+
117
+ end
118
+
119
+ ############################
120
+ # subtract_without_hooks #
121
+ ############################
122
+
123
+ ###
124
+ # @private
125
+ #
126
+ # Subtracts :reader, :writer or :accessor from key.
127
+ # Used to prevent loops when array/hash relays to other arrays/hashes.
128
+ #
129
+ def subtract_without_hooks( key, reader_writer_accessor )
130
+
131
+ @without_hooks = true
132
+
133
+ subtract( key, reader_writer_accessor )
134
+
135
+ @without_hooks = false
136
+
137
+ end
138
+
139
+ ############
140
+ # delete #
141
+ ############
142
+
143
+ ###
144
+ # Deletes attribute and updates corresponding hashes/arrays.
145
+ #
146
+ # @param attribute Attribute to delete.
147
+ #
148
+ # @return [:reader,:writer,:accessor,nil] Setting removed.
149
+ #
150
+ def delete( attribute )
151
+
152
+ deleted_reader_writer_accessor_setting = super( attribute )
153
+
154
+ unless @without_hooks
155
+ update_for_subtraction( attribute, :accessor )
156
+ end
157
+
158
+ return deleted_reader_writer_accessor_setting
159
+
160
+ end
161
+
162
+ #####################
163
+ # has_attributes? #
164
+ #####################
165
+
166
+ ###
167
+ # Query whether this hash includes attribute(s).
168
+ #
169
+ # @overload has_attributes?( attribute_name, ... )
170
+ #
171
+ # @param attribute_name [Symbol,String] Attribute to query.
172
+ #
173
+ # @return [true,false] Whether this hash/array includes attribute(s).
174
+ #
175
+ def has_attributes?( *attributes )
176
+
177
+ has_attributes = false
178
+
179
+ attributes.each do |this_attribute|
180
+ break unless has_attributes = has_key?( this_attribute )
181
+ end
182
+
183
+ return has_attributes
184
+
185
+ end
186
+
187
+ end
@@ -0,0 +1,102 @@
1
+
2
+ ###
3
+ # Module used for common methods for persistent attributes hash and arrays.
4
+ #
5
+ module ::Persistence::Object::Complex::Attributes::DefaultAtomicNonAtomic
6
+
7
+ #####################
8
+ # default_atomic? #
9
+ #####################
10
+
11
+ ###
12
+ # Query whether attributes default to be atomic.
13
+ #
14
+ # @return [true,false] Whether default is atomic.
15
+ #
16
+ def default_atomic?
17
+
18
+ return @default_atomic
19
+
20
+ end
21
+
22
+ #########################
23
+ # default_non_atomic? #
24
+ #########################
25
+
26
+ ###
27
+ # Query whether attributes default to be non-atomic.
28
+ #
29
+ # @return [true,false] Whether default is non-atomic.
30
+ #
31
+ def default_non_atomic?
32
+
33
+ return ! @default_atomic
34
+
35
+ end
36
+
37
+ #####################
38
+ # default_atomic! #
39
+ #####################
40
+
41
+ ###
42
+ # Set attributes to default atomic.
43
+ #
44
+ def default_atomic!
45
+
46
+ @default_atomic = true
47
+
48
+ end
49
+
50
+ ###################################
51
+ # default_atomic_without_hooks! #
52
+ ###################################
53
+
54
+ ###
55
+ # @private
56
+ #
57
+ # Set attributes to default atomic.
58
+ # Used to prevent loops when array/hash relays to other arrays/hashes.
59
+ #
60
+ def default_atomic_without_hooks!
61
+
62
+ @without_hooks = true
63
+
64
+ default_atomic!
65
+
66
+ @without_hooks = false
67
+
68
+ end
69
+
70
+ #########################
71
+ # default_non_atomic! #
72
+ #########################
73
+
74
+ ###
75
+ # Set attributes to default non-atomic.
76
+ #
77
+ def default_non_atomic!
78
+
79
+ @default_atomic = false
80
+
81
+ end
82
+
83
+ #######################################
84
+ # default_non_atomic_without_hooks! #
85
+ #######################################
86
+
87
+ ###
88
+ # @private
89
+ #
90
+ # Set attributes to default non-atomic. Used to prevent loops when array/hash relays to other arrays/hashes.
91
+ #
92
+ def default_non_atomic_without_hooks!
93
+
94
+ @without_hooks = true
95
+
96
+ default_non_atomic!
97
+
98
+ @without_hooks = false
99
+
100
+ end
101
+
102
+ end
@@ -0,0 +1,40 @@
1
+
2
+ ###
3
+ # @private
4
+ #
5
+ # Hash subclass used for encapsulating common process of translation from Ruby key/value to storage key/value.
6
+ #
7
+ class ::Persistence::Object::Complex::Attributes::HashToPort < ::Hash
8
+
9
+ attr_accessor :persistence_object
10
+
11
+ #########
12
+ # []= #
13
+ #########
14
+
15
+ ###
16
+ #
17
+ # @private
18
+ #
19
+ # Automatically convert key/value to primary key/storage value.
20
+ #
21
+ def []=( key, value )
22
+
23
+ primary_key = nil
24
+ attribute_value_to_port = nil
25
+
26
+ # if we don't have a persistence port we want to compare objects by their properties
27
+ if persistence_object.persistence_port
28
+ attribute_key_to_port = persistence_object.persist_as_sub_object_or_attribute_and_return_id_or_value( key )
29
+ primary_key = persistence_object.persistence_bucket.primary_key_for_attribute_name( persistence_object, attribute_key_to_port )
30
+ attribute_value_to_port = persistence_object.persist_as_sub_object_or_attribute_and_return_id_or_value( value )
31
+ else
32
+ primary_key = key
33
+ attribute_value_to_port = value
34
+ end
35
+
36
+ super( primary_key, attribute_value_to_port )
37
+
38
+ end
39
+
40
+ end
@@ -0,0 +1,132 @@
1
+
2
+ ###
3
+ # Methods applied to both Class and Object instances of complex objects enabled with persistence capabilities.
4
+ #
5
+ module ::Persistence::Object::Complex::ClassAndObjectInstance
6
+
7
+ include ::CascadingConfiguration::Hash
8
+
9
+ ##########################
10
+ # attr_delete_cascades #
11
+ ##########################
12
+
13
+ ###
14
+ #
15
+ # @private
16
+ #
17
+ # @method delete_cascades
18
+ #
19
+ # @return [CompositingHash{Symbol,String=>true,false}] Hash containing cascading delete data for attributes.
20
+ #
21
+ attr_configuration_hash :delete_cascades
22
+
23
+ ###
24
+ # Declare that deleting object should also delete attribute(s).
25
+ #
26
+ # @overload attr_delete_cascades( attribute_name, ... )
27
+ #
28
+ # @param attribute_name Attribute(s) in question.
29
+ #
30
+ # @return self
31
+ #
32
+ def attr_delete_cascades( *attributes )
33
+
34
+ attributes.each do |this_attribute|
35
+ delete_cascades[ this_attribute.accessor_name ] = true
36
+ end
37
+
38
+ return self
39
+
40
+ end
41
+
42
+ ##################################
43
+ # attr_delete_does_not_cascade #
44
+ ##################################
45
+
46
+ ###
47
+ # Declare that deleting object should not delete attribute(s).
48
+ #
49
+ # @overload attr_delete_cascades( attribute_name, ... )
50
+ #
51
+ # @param attribute_name Attribute(s) in question.
52
+ #
53
+ # @return self
54
+ #
55
+ def attr_delete_does_not_cascade( *attributes )
56
+
57
+ attributes.each do |this_attribute|
58
+ delete_cascades[ this_attribute.accessor_name ] = false
59
+ end
60
+
61
+ return self
62
+
63
+ end
64
+
65
+ ###########################
66
+ # attr_delete_cascades! #
67
+ ###########################
68
+
69
+ ###
70
+ # Declare that deleting object should also delete declared attributes.
71
+ #
72
+ # @return self
73
+ #
74
+ def attr_delete_cascades!
75
+
76
+ return attr_delete_cascades( *persistent_attributes.keys )
77
+
78
+ end
79
+
80
+
81
+ ###################################
82
+ # attr_delete_does_not_cascade! #
83
+ ###################################
84
+
85
+ ###
86
+ # Declare that deleting object should not delete declared attributes.
87
+ #
88
+ # @return self
89
+ #
90
+ def attr_delete_does_not_cascade!
91
+
92
+ return attr_delete_does_not_cascade( *persistent_attributes.keys )
93
+
94
+ end
95
+
96
+ ######################
97
+ # delete_cascades? #
98
+ ######################
99
+
100
+ ###
101
+ # Query whether deleting object will also delete attribute
102
+ #
103
+ # @param attribute_name Attribute in question.
104
+ #
105
+ # @return [true,false] Whether deleting object will cascade to delete object at attribute.
106
+ #
107
+ def delete_cascades?( attribute_name )
108
+
109
+ should_cascade = false
110
+
111
+ accessor_name = attribute_name.accessor_name
112
+
113
+ # delete_cascades is a cascading array that automatically handles inheritance
114
+ if ( should_cascade = delete_cascades[ accessor_name ] ) == nil
115
+
116
+ if attribute_value = persistence_port.get_attribute( self, accessor_name ) and
117
+ attribute_value.is_a?( ::Persistence::Object::Complex::ComplexObject )
118
+
119
+ should_cascade = attribute_value.delete_cascades?
120
+
121
+ end
122
+
123
+ should_cascade = true if should_cascade.nil?
124
+ delete_cascades[ accessor_name ] = should_cascade
125
+
126
+ end
127
+
128
+ return should_cascade
129
+
130
+ end
131
+
132
+ end