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.
- data/CHANGELOG.md +4 -0
- data/README.md +260 -17
- data/lib/namespaces.rb +55 -0
- data/lib/persistence.rb +38 -3
- data/lib/persistence/adapter/abstract.rb +22 -0
- data/lib/persistence/adapter/abstract/enable_disable.rb +107 -0
- data/lib/persistence/adapter/abstract/primary_key/id_property_string.rb +33 -0
- data/lib/persistence/adapter/abstract/primary_key/simple.rb +29 -0
- data/lib/persistence/adapter/mock.rb +9 -0
- data/lib/persistence/adapter/mock/adapter_interface.rb +102 -0
- data/lib/persistence/adapter/mock/bucket.rb +9 -0
- data/lib/persistence/adapter/mock/bucket/bucket_interface.rb +260 -0
- data/lib/persistence/adapter/mock/bucket/index.rb +9 -0
- data/lib/persistence/adapter/mock/bucket/index/index_interface.rb +155 -0
- data/lib/persistence/adapter/mock/cursor.rb +9 -0
- data/lib/persistence/adapter/mock/cursor/cursor_interface.rb +238 -0
- data/lib/persistence/cursor.rb +11 -0
- data/lib/persistence/cursor/atomic.rb +110 -0
- data/lib/persistence/cursor/cursor_interface.rb +337 -0
- data/lib/persistence/exception/block_required.rb +7 -0
- data/lib/persistence/exception/conflicting_index_already_declared.rb +7 -0
- data/lib/persistence/exception/duplicate_violates_unique_index.rb +7 -0
- data/lib/persistence/exception/explicit_index_required.rb +7 -0
- data/lib/persistence/exception/indexing_block_failed_to_generate_keys.rb +7 -0
- data/lib/persistence/exception/indexing_object_requires_keys.rb +7 -0
- data/lib/persistence/exception/key_value_required.rb +7 -0
- data/lib/persistence/exception/no_port_enabled.rb +7 -0
- data/lib/persistence/object.rb +21 -0
- data/lib/persistence/object/autodetermine.rb +74 -0
- data/lib/persistence/object/class_instance.rb +1884 -0
- data/lib/persistence/object/complex.rb +17 -0
- data/lib/persistence/object/complex/array.rb +14 -0
- data/lib/persistence/object/complex/array/class_instance.rb +37 -0
- data/lib/persistence/object/complex/array/object_instance.rb +54 -0
- data/lib/persistence/object/complex/attributes.rb +1808 -0
- data/lib/persistence/object/complex/attributes/attributes_array.rb +32 -0
- data/lib/persistence/object/complex/attributes/attributes_hash.rb +187 -0
- data/lib/persistence/object/complex/attributes/default_atomic_non_atomic.rb +102 -0
- data/lib/persistence/object/complex/attributes/hash_to_port.rb +40 -0
- data/lib/persistence/object/complex/class_and_object_instance.rb +132 -0
- data/lib/persistence/object/complex/class_instance.rb +267 -0
- data/lib/persistence/object/complex/complex_object.rb +111 -0
- data/lib/persistence/object/complex/hash.rb +14 -0
- data/lib/persistence/object/complex/hash/class_instance.rb +40 -0
- data/lib/persistence/object/complex/hash/object_instance.rb +63 -0
- data/lib/persistence/object/complex/index/attribute_index.rb +10 -0
- data/lib/persistence/object/complex/index/attribute_index/attribute_index_interface.rb +43 -0
- data/lib/persistence/object/complex/object_instance.rb +469 -0
- data/lib/persistence/object/flat.rb +17 -0
- data/lib/persistence/object/flat/class_instance.rb +34 -0
- data/lib/persistence/object/flat/file.rb +14 -0
- data/lib/persistence/object/flat/file/class_instance.rb +122 -0
- data/lib/persistence/object/flat/file/contents.rb +7 -0
- data/lib/persistence/object/flat/file/file_persistence.rb +147 -0
- data/lib/persistence/object/flat/file/object_instance.rb +116 -0
- data/lib/persistence/object/flat/file/path.rb +9 -0
- data/lib/persistence/object/flat/object_instance.rb +24 -0
- data/lib/persistence/object/index.rb +479 -0
- data/lib/persistence/object/index/block_index.rb +10 -0
- data/lib/persistence/object/index/block_index/block_index_interface.rb +110 -0
- data/lib/persistence/object/index/explicit_index.rb +10 -0
- data/lib/persistence/object/index/explicit_index/explicit_index_interface.rb +57 -0
- data/lib/persistence/object/index_hash.rb +40 -0
- data/lib/persistence/object/object_instance.rb +322 -0
- data/lib/persistence/object/parse_persistence_args.rb +145 -0
- data/lib/persistence/port.rb +9 -0
- data/lib/persistence/port/bucket.rb +9 -0
- data/lib/persistence/port/bucket/bucket_index.rb +9 -0
- data/lib/persistence/port/bucket/bucket_interface.rb +685 -0
- data/lib/persistence/port/controller.rb +263 -0
- data/lib/persistence/port/port_interface.rb +417 -0
- data/lib/requires.rb +146 -0
- data/spec/Integration_spec.rb +53 -0
- data/spec/Persistence_spec.rb +175 -0
- data/spec/example_objects.rb +6 -0
- data/spec/example_objects/complex_object.rb +7 -0
- data/spec/example_objects/complex_object/array_object.rb +7 -0
- data/spec/example_objects/complex_object/hash_object.rb +7 -0
- data/spec/example_objects/flat_object.rb +7 -0
- data/spec/example_objects/flat_object/file_object.rb +7 -0
- data/spec/persistence/adapter/enable_disable_spec.rb +29 -0
- data/spec/persistence/adapter/mock/cursor_spec.rb +64 -0
- data/spec/persistence/adapter/mock_helpers.rb +27 -0
- data/spec/persistence/adapter/mock_helpers/bucket.rb +10 -0
- data/spec/persistence/adapter/mock_helpers/integration/dictionary_hash.rb +4 -0
- data/spec/persistence/adapter/mock_helpers/integration/note.rb +18 -0
- data/spec/persistence/adapter/mock_helpers/integration/notes_array.rb +4 -0
- data/spec/persistence/adapter/mock_helpers/integration/user.rb +44 -0
- data/spec/persistence/adapter/mock_helpers/integration/user/address.rb +18 -0
- data/spec/persistence/adapter/mock_helpers/integration/user/dictionary_entry.rb +12 -0
- data/spec/persistence/adapter/mock_helpers/integration/user/sub_account.rb +15 -0
- data/spec/persistence/adapter/mock_helpers/object.rb +87 -0
- data/spec/persistence/adapter/mock_helpers/port.rb +21 -0
- data/spec/persistence/adapter/mock_spec.rb +211 -0
- data/spec/persistence/adapter/primary_key/id_property_string_spec.rb +27 -0
- data/spec/persistence/adapter/primary_key/simple_spec.rb +19 -0
- data/spec/persistence/adapter/spec_abstract/adapter_spec.rb +223 -0
- data/spec/persistence/adapter/spec_abstract/cursor_spec.rb +116 -0
- data/spec/persistence/cursor/atomic_spec.rb +86 -0
- data/spec/persistence/cursor/object_and_class_instance_spec.rb +73 -0
- data/spec/persistence/cursor_spec.rb +128 -0
- data/spec/persistence/object/complex/attributes/persistence_hash/array_instance_spec.rb +51 -0
- data/spec/persistence/object/complex/attributes/persistence_hash/hash_instance_spec.rb +56 -0
- data/spec/persistence/object/complex/attributes_spec.rb +1717 -0
- data/spec/persistence/object/complex/complex_spec.rb +922 -0
- data/spec/persistence/object/complex/index/attribute_index_spec.rb +76 -0
- data/spec/persistence/object/flat/bignum_spec.rb +33 -0
- data/spec/persistence/object/flat/class_instance_spec.rb +30 -0
- data/spec/persistence/object/flat/class_spec.rb +38 -0
- data/spec/persistence/object/flat/complex_spec.rb +36 -0
- data/spec/persistence/object/flat/false_class_spec.rb +34 -0
- data/spec/persistence/object/flat/file/class_instance_spec.rb +54 -0
- data/spec/persistence/object/flat/file/object_instance_spec.rb +143 -0
- data/spec/persistence/object/flat/file_spec.rb +64 -0
- data/spec/persistence/object/flat/fixnum_spec.rb +32 -0
- data/spec/persistence/object/flat/float_spec.rb +32 -0
- data/spec/persistence/object/flat/indexing_spec.rb +38 -0
- data/spec/persistence/object/flat/rational_spec.rb +33 -0
- data/spec/persistence/object/flat/regexp_spec.rb +32 -0
- data/spec/persistence/object/flat/string_spec.rb +34 -0
- data/spec/persistence/object/flat/symbol_spec.rb +32 -0
- data/spec/persistence/object/flat/true_class_spec.rb +32 -0
- data/spec/persistence/object/indexes/block_index_spec.rb +119 -0
- data/spec/persistence/object/indexes/explicit_index_spec.rb +112 -0
- data/spec/persistence/object/parse_persistence_args_spec.rb +65 -0
- data/spec/persistence/object_spec.rb +310 -0
- data/spec/persistence/port/bucket/bucket_interface_spec.rb +146 -0
- data/spec/persistence/port/bucket/index/bucket_index_spec.rb +67 -0
- data/spec/persistence/port/bucket_spec.rb +20 -0
- data/spec/persistence/port/controller_spec.rb +60 -0
- data/spec/persistence/port/port_interface_spec.rb +105 -0
- metadata +178 -21
- data/.gitignore +0 -17
- data/Gemfile +0 -4
- data/LICENSE +0 -22
- data/Rakefile +0 -2
- data/lib/persistence/version.rb +0 -3
- data/persistence.gemspec +0 -17
@@ -0,0 +1,145 @@
|
|
1
|
+
|
2
|
+
###
|
3
|
+
# @private
|
4
|
+
#
|
5
|
+
# Internal helper for parsing args of the format: method, method( global_id ), method( index_name, value ),
|
6
|
+
# method( index_instance, value ), method( index_name => value ), method( index_instance => value ).
|
7
|
+
module ::Persistence::Object::ParsePersistenceArgs
|
8
|
+
|
9
|
+
#########################################
|
10
|
+
# parse_args_for_index_value_no_value #
|
11
|
+
#########################################
|
12
|
+
|
13
|
+
###
|
14
|
+
# Parse *args for index, key_value, no_value.
|
15
|
+
#
|
16
|
+
# @param args [Array] An array of args of the format: method, method( global_id ), method( index_name, value ),
|
17
|
+
# method( index_instance, value ), method( index_name => value ), method( index_instance => value ).
|
18
|
+
#
|
19
|
+
# @param require_value [true,false] Whether key value must be provided; will throw exception if true and
|
20
|
+
# key value is not provided.
|
21
|
+
#
|
22
|
+
# @return [Array] Array containing index instance, key value, whether key value was provided.
|
23
|
+
#
|
24
|
+
def parse_args_for_index_value_no_value( args, require_value = false )
|
25
|
+
|
26
|
+
# * nil
|
27
|
+
# - Cursor to primary bucket
|
28
|
+
# * :index
|
29
|
+
# - Cursor to index
|
30
|
+
# * :index => persistence_key
|
31
|
+
# - Object(s) for indexed key value
|
32
|
+
|
33
|
+
index = nil
|
34
|
+
key_value = nil
|
35
|
+
no_value = nil
|
36
|
+
case args.count
|
37
|
+
|
38
|
+
when 0
|
39
|
+
|
40
|
+
no_value = true
|
41
|
+
if require_value
|
42
|
+
raise ::Persistence::Exception::KeyValueRequired,
|
43
|
+
'Key value required.'
|
44
|
+
end
|
45
|
+
|
46
|
+
when 1
|
47
|
+
|
48
|
+
index_or_id = args[ 0 ]
|
49
|
+
if index_or_id.is_a?( Symbol ) or
|
50
|
+
index_or_id.is_a?( String )
|
51
|
+
|
52
|
+
index = indexes[ index_or_id ]
|
53
|
+
unless index
|
54
|
+
raise ::Persistence::Exception::ExplicitIndexRequired,
|
55
|
+
'Explicit index ' + index_or_id.to_s + ' did not exist.'
|
56
|
+
end
|
57
|
+
no_value = true
|
58
|
+
|
59
|
+
elsif index_or_id.respond_to?( :index_object )
|
60
|
+
|
61
|
+
index = index_or_id
|
62
|
+
no_value = true
|
63
|
+
|
64
|
+
elsif index_or_id.is_a?( Hash )
|
65
|
+
|
66
|
+
key_value = index_or_id.values[ 0 ]
|
67
|
+
index_name = index_or_id.keys[ 0 ]
|
68
|
+
if index_name.is_a?( Symbol ) or
|
69
|
+
index_name.is_a?( String )
|
70
|
+
|
71
|
+
index = indexes[ index_name ]
|
72
|
+
unless index
|
73
|
+
raise ::Persistence::Exception::ExplicitIndexRequired,
|
74
|
+
'Explicit index :' + index_name.to_s + ' did not exist.'
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
no_value = false
|
79
|
+
|
80
|
+
else
|
81
|
+
|
82
|
+
# persistence_id - anything other than Symbol, String, Hash
|
83
|
+
key_value = args[ 0 ]
|
84
|
+
no_value = false
|
85
|
+
|
86
|
+
end
|
87
|
+
|
88
|
+
when 2
|
89
|
+
|
90
|
+
index_or_name = args[ 0 ]
|
91
|
+
|
92
|
+
index = index_or_name.respond_to?( :index_object ) ? index_or_name : indexes[ index_or_name ]
|
93
|
+
key_value = args[ 1 ]
|
94
|
+
|
95
|
+
if ! index and ! key_value
|
96
|
+
raise ::Persistence::Exception::ExplicitIndexRequired,
|
97
|
+
'Index ' + index_or_name.to_s + ' did not exist.'
|
98
|
+
end
|
99
|
+
no_value = false
|
100
|
+
|
101
|
+
else
|
102
|
+
|
103
|
+
raise 'Unexpected arguments ' + args.inspect + '.'
|
104
|
+
|
105
|
+
end
|
106
|
+
|
107
|
+
# if we have a file we need to persist it like we would a sub-object
|
108
|
+
if key_value.is_a?( File )
|
109
|
+
key_value = process_file_key( key_value )
|
110
|
+
end
|
111
|
+
|
112
|
+
return index, key_value, no_value
|
113
|
+
|
114
|
+
end
|
115
|
+
|
116
|
+
######################
|
117
|
+
# process_file_key #
|
118
|
+
######################
|
119
|
+
|
120
|
+
###
|
121
|
+
# Internal helper method to handle instances of File as key.
|
122
|
+
#
|
123
|
+
# @param file_key [File] File instance to process as key.
|
124
|
+
#
|
125
|
+
# @return [Persistence::Object::Flat::File::Path,Persistence::Object::Flat::File::Contents] Processed key.
|
126
|
+
#
|
127
|
+
def process_file_key( file_key )
|
128
|
+
|
129
|
+
# do we have a file key? if so we need to replace it with File::Path or File::Contents
|
130
|
+
|
131
|
+
processed_key = nil
|
132
|
+
|
133
|
+
if persists_files_by_path?
|
134
|
+
processed_key = ::Persistence::Object::Flat::File::Path.new( file_key.path )
|
135
|
+
else
|
136
|
+
starting_pos = file_key.pos
|
137
|
+
processed_key = ::Persistence::Object::Flat::File::Contents.new( file_key.readlines.join )
|
138
|
+
file_key.pos = starting_pos
|
139
|
+
end
|
140
|
+
|
141
|
+
return processed_key
|
142
|
+
|
143
|
+
end
|
144
|
+
|
145
|
+
end
|
@@ -0,0 +1,685 @@
|
|
1
|
+
|
2
|
+
###
|
3
|
+
# Interface for Bucket implementation. Provided separately for easy overriding.
|
4
|
+
#
|
5
|
+
module ::Persistence::Port::Bucket::BucketInterface
|
6
|
+
|
7
|
+
include ::Persistence::Object::Flat::File::FilePersistence
|
8
|
+
|
9
|
+
include ::Enumerable
|
10
|
+
|
11
|
+
################
|
12
|
+
# initialize #
|
13
|
+
################
|
14
|
+
|
15
|
+
###
|
16
|
+
#
|
17
|
+
# @param parent_port Port where this bucket is active. Can be nil if no port is yet enabled.
|
18
|
+
#
|
19
|
+
# @param bucket_name Name of the bucket to open in port.
|
20
|
+
#
|
21
|
+
def initialize( parent_port, bucket_name )
|
22
|
+
|
23
|
+
@name = bucket_name
|
24
|
+
|
25
|
+
@indexes = { }
|
26
|
+
@pending_indexes = [ ]
|
27
|
+
|
28
|
+
if parent_port
|
29
|
+
initialize_for_port( parent_port )
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
#########################
|
35
|
+
# initialize_for_port #
|
36
|
+
#########################
|
37
|
+
|
38
|
+
###
|
39
|
+
# Initialize bucket for a port that has been enabled.
|
40
|
+
#
|
41
|
+
# @param port Parent port in which to initialize bucket.
|
42
|
+
#
|
43
|
+
def initialize_for_port( port )
|
44
|
+
|
45
|
+
if port = ::Persistence.port_for_name_or_port( port ) and port.enabled?
|
46
|
+
|
47
|
+
@parent_port = ::Persistence.port_for_name_or_port( port )
|
48
|
+
|
49
|
+
if @parent_port.enabled?
|
50
|
+
@adapter_bucket = @parent_port.adapter.persistence_bucket( @name )
|
51
|
+
end
|
52
|
+
|
53
|
+
@indexes.each do |this_index_name, this_index_instance|
|
54
|
+
this_index_instance.initialize_for_bucket( self )
|
55
|
+
end
|
56
|
+
|
57
|
+
@pending_indexes.delete_if do |this_pending_index|
|
58
|
+
this_pending_index.initialize_for_bucket( self )
|
59
|
+
true
|
60
|
+
end
|
61
|
+
|
62
|
+
else
|
63
|
+
|
64
|
+
disable
|
65
|
+
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
####################
|
71
|
+
# adapter_bucket #
|
72
|
+
####################
|
73
|
+
|
74
|
+
###
|
75
|
+
# Retrieve parallel adapter bucket instance.
|
76
|
+
#
|
77
|
+
# @return [Object] Adapter bucket instance.
|
78
|
+
#
|
79
|
+
def adapter_bucket
|
80
|
+
|
81
|
+
unless @adapter_bucket
|
82
|
+
raise 'Persistence port must be enabled first.'
|
83
|
+
end
|
84
|
+
|
85
|
+
return @adapter_bucket
|
86
|
+
|
87
|
+
end
|
88
|
+
|
89
|
+
##########
|
90
|
+
# name #
|
91
|
+
##########
|
92
|
+
|
93
|
+
###
|
94
|
+
# @!attribute [accessor] Name of bucket
|
95
|
+
#
|
96
|
+
# @return [Symbol,String] Name.
|
97
|
+
#
|
98
|
+
attr_accessor :name
|
99
|
+
|
100
|
+
#################
|
101
|
+
# parent_port #
|
102
|
+
#################
|
103
|
+
|
104
|
+
attr_accessor :parent_port
|
105
|
+
|
106
|
+
#############
|
107
|
+
# disable #
|
108
|
+
#############
|
109
|
+
|
110
|
+
###
|
111
|
+
# @private
|
112
|
+
#
|
113
|
+
# Disable bucket when port disables. Internal helper method necessary to ensure
|
114
|
+
# that old references don't stick around.
|
115
|
+
#
|
116
|
+
def disable
|
117
|
+
|
118
|
+
@adapter_bucket = nil
|
119
|
+
@parent_port = nil
|
120
|
+
|
121
|
+
@indexes.each do |this_index_name, this_index|
|
122
|
+
this_index.disable
|
123
|
+
end
|
124
|
+
|
125
|
+
end
|
126
|
+
|
127
|
+
##################
|
128
|
+
# create_index #
|
129
|
+
##################
|
130
|
+
|
131
|
+
###
|
132
|
+
# Create a bucket index, which is a block index that runs on each inserted object, regardless of type.
|
133
|
+
#
|
134
|
+
def create_index( index_name, sort_by_proc = nil, & indexing_block )
|
135
|
+
|
136
|
+
return create_bucket_index( index_name, false, sort_by_proc, & indexing_block )
|
137
|
+
|
138
|
+
end
|
139
|
+
|
140
|
+
##################################
|
141
|
+
# create_index_with_duplicates #
|
142
|
+
##################################
|
143
|
+
|
144
|
+
###
|
145
|
+
# Create a bucket index that permits duplicates.
|
146
|
+
#
|
147
|
+
def create_index_with_duplicates( index_name, sort_by_proc = nil, sort_duplicates_by_proc = nil, & indexing_block )
|
148
|
+
|
149
|
+
return create_bucket_index( index_name, true, sort_by_proc, sort_duplicates_by_proc, & indexing_block )
|
150
|
+
|
151
|
+
end
|
152
|
+
|
153
|
+
################
|
154
|
+
# pend_index #
|
155
|
+
################
|
156
|
+
|
157
|
+
###
|
158
|
+
# @private
|
159
|
+
#
|
160
|
+
# Pend index instance for port to be enabled.
|
161
|
+
#
|
162
|
+
# @param index_instance Instance of index that is waiting for port to be enabled.
|
163
|
+
#
|
164
|
+
def pend_index( index_instance )
|
165
|
+
|
166
|
+
@pending_indexes.push( index_instance )
|
167
|
+
|
168
|
+
end
|
169
|
+
|
170
|
+
###########
|
171
|
+
# index #
|
172
|
+
###########
|
173
|
+
|
174
|
+
###
|
175
|
+
# Retrieve index.
|
176
|
+
#
|
177
|
+
# @param index_name [Symbol,String] Name of index
|
178
|
+
#
|
179
|
+
# @param ensure_exists [true,false] Whether exception should be thrown if index does not exist.
|
180
|
+
#
|
181
|
+
# @return [Persistence::Object::Index] Index instance
|
182
|
+
#
|
183
|
+
def index( index_name, ensure_exists = false )
|
184
|
+
|
185
|
+
index_instance = nil
|
186
|
+
|
187
|
+
unless index_instance = @indexes[ index_name ]
|
188
|
+
if ensure_exists
|
189
|
+
raise ::ArgumentError, 'No index found by name ' << index_name.to_s + '.'
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
return index_instance
|
194
|
+
|
195
|
+
end
|
196
|
+
|
197
|
+
################
|
198
|
+
# has_index? #
|
199
|
+
################
|
200
|
+
|
201
|
+
###
|
202
|
+
# Query whether attribute index(es) exist for object.
|
203
|
+
#
|
204
|
+
# @overload has_attribute_index?( index_name, ... )
|
205
|
+
#
|
206
|
+
# @param index_name Name of requested index.
|
207
|
+
#
|
208
|
+
# @return [true,false] Whether index(es) exist.
|
209
|
+
#
|
210
|
+
def has_index?( *indexes )
|
211
|
+
|
212
|
+
has_index = false
|
213
|
+
|
214
|
+
indexes.each do |this_index|
|
215
|
+
break unless has_index = @indexes.has_key?( index_name )
|
216
|
+
end
|
217
|
+
|
218
|
+
return has_index
|
219
|
+
|
220
|
+
end
|
221
|
+
|
222
|
+
###########
|
223
|
+
# count #
|
224
|
+
###########
|
225
|
+
|
226
|
+
###
|
227
|
+
# Get the number of objects in index. See {::Enumerable}.
|
228
|
+
#
|
229
|
+
# @return [Integer] Number of objects in bucket.
|
230
|
+
#
|
231
|
+
def count( *args, & count_block )
|
232
|
+
|
233
|
+
return_value = 0
|
234
|
+
|
235
|
+
if block_given?
|
236
|
+
return_value = super( & count_block )
|
237
|
+
elsif args.empty?
|
238
|
+
return_value = adapter_bucket.count
|
239
|
+
else
|
240
|
+
return_value = super( *args )
|
241
|
+
end
|
242
|
+
|
243
|
+
return return_value
|
244
|
+
|
245
|
+
end
|
246
|
+
|
247
|
+
#############################
|
248
|
+
# delete_index_for_object #
|
249
|
+
#############################
|
250
|
+
|
251
|
+
###
|
252
|
+
# @private
|
253
|
+
#
|
254
|
+
# Delete indexed entries for object.
|
255
|
+
#
|
256
|
+
# @param object Object that owns indexed entries.
|
257
|
+
#
|
258
|
+
# @param index_name Name of index.
|
259
|
+
#
|
260
|
+
def delete_index_for_object( object, index_name )
|
261
|
+
|
262
|
+
return delete_index_for_object_id( object.persistence_id )
|
263
|
+
|
264
|
+
end
|
265
|
+
|
266
|
+
################################
|
267
|
+
# delete_index_for_object_id #
|
268
|
+
################################
|
269
|
+
|
270
|
+
###
|
271
|
+
# @private
|
272
|
+
#
|
273
|
+
# Delete indexed entries for object.
|
274
|
+
#
|
275
|
+
# @param global_id Object persistence ID that owns indexed entries.
|
276
|
+
#
|
277
|
+
# @param index_name Name of index.
|
278
|
+
#
|
279
|
+
def delete_index_for_object_id( global_id, index_name )
|
280
|
+
|
281
|
+
return adapter_bucket.delete_index_for_object_id( global_id )
|
282
|
+
|
283
|
+
end
|
284
|
+
|
285
|
+
###################
|
286
|
+
# get_attribute #
|
287
|
+
###################
|
288
|
+
|
289
|
+
###
|
290
|
+
# @private
|
291
|
+
#
|
292
|
+
# Get attribute for object from port.
|
293
|
+
#
|
294
|
+
# @param object Object that owns indexed entries.
|
295
|
+
#
|
296
|
+
# @param attribute_name Name of attribute.
|
297
|
+
#
|
298
|
+
def get_attribute( object, attribute_name )
|
299
|
+
|
300
|
+
primary_key = primary_key_for_attribute_name( object, attribute_name )
|
301
|
+
|
302
|
+
attribute_value = adapter_bucket.get_attribute( object, primary_key )
|
303
|
+
|
304
|
+
if attribute_value.is_a?( ::Persistence::Object::Complex::ComplexObject )
|
305
|
+
attribute_value.persistence_port = object.persistence_port
|
306
|
+
attribute_value = attribute_value.persist
|
307
|
+
end
|
308
|
+
|
309
|
+
return attribute_value
|
310
|
+
|
311
|
+
end
|
312
|
+
|
313
|
+
####################
|
314
|
+
# put_attribute! #
|
315
|
+
####################
|
316
|
+
|
317
|
+
###
|
318
|
+
# @private
|
319
|
+
#
|
320
|
+
# Put attribute for object to port.
|
321
|
+
#
|
322
|
+
# @param object Object that owns indexed entries.
|
323
|
+
#
|
324
|
+
# @param attribute_name Name of attribute.
|
325
|
+
#
|
326
|
+
# @param attribute_value Value to put.
|
327
|
+
#
|
328
|
+
def put_attribute!( object, attribute_name, attribute_value )
|
329
|
+
|
330
|
+
primary_key = primary_key_for_attribute_name( object, attribute_name )
|
331
|
+
|
332
|
+
return adapter_bucket.put_attribute!( object, primary_key, attribute_value )
|
333
|
+
|
334
|
+
end
|
335
|
+
|
336
|
+
#################
|
337
|
+
# put_object! #
|
338
|
+
#################
|
339
|
+
|
340
|
+
###
|
341
|
+
# @private
|
342
|
+
#
|
343
|
+
# Put object properties to persistence port.
|
344
|
+
#
|
345
|
+
# @param object Object to persist to port.
|
346
|
+
#
|
347
|
+
def put_object!( object )
|
348
|
+
|
349
|
+
return adapter_bucket.put_object!( object )
|
350
|
+
|
351
|
+
end
|
352
|
+
|
353
|
+
################
|
354
|
+
# get_object #
|
355
|
+
################
|
356
|
+
|
357
|
+
###
|
358
|
+
# @private
|
359
|
+
#
|
360
|
+
# Get object from persistence port.
|
361
|
+
#
|
362
|
+
# @param global_id Object persistence ID to persist from port.
|
363
|
+
#
|
364
|
+
# @return [Object] Persisted object instance.
|
365
|
+
#
|
366
|
+
def get_object( global_id )
|
367
|
+
|
368
|
+
object = nil
|
369
|
+
|
370
|
+
# get the class
|
371
|
+
if klass = @parent_port.get_class_for_object_id( global_id )
|
372
|
+
|
373
|
+
object = klass.new
|
374
|
+
|
375
|
+
object.persistence_id = global_id
|
376
|
+
|
377
|
+
# if we have non-atomic attributes, load them
|
378
|
+
unless klass.non_atomic_attribute_readers.empty?
|
379
|
+
|
380
|
+
if persistence_hash_from_port = get_object_hash( global_id )
|
381
|
+
|
382
|
+
object.load_persistence_hash( object.persistence_port, persistence_hash_from_port )
|
383
|
+
|
384
|
+
end
|
385
|
+
|
386
|
+
end
|
387
|
+
|
388
|
+
end
|
389
|
+
|
390
|
+
return object
|
391
|
+
|
392
|
+
end
|
393
|
+
|
394
|
+
#####################
|
395
|
+
# get_object_hash #
|
396
|
+
#####################
|
397
|
+
|
398
|
+
###
|
399
|
+
# @private
|
400
|
+
#
|
401
|
+
# Get object properties from persistence port.
|
402
|
+
#
|
403
|
+
# @param global_id Object persistence ID to persist from port.
|
404
|
+
#
|
405
|
+
# @return [Hash] Persistence hash from port.
|
406
|
+
#
|
407
|
+
def get_object_hash( global_id )
|
408
|
+
|
409
|
+
return adapter_bucket.get_object( global_id )
|
410
|
+
|
411
|
+
end
|
412
|
+
|
413
|
+
#####################
|
414
|
+
# get_flat_object #
|
415
|
+
#####################
|
416
|
+
|
417
|
+
###
|
418
|
+
# @private
|
419
|
+
#
|
420
|
+
# Get flat object from persistence port.
|
421
|
+
#
|
422
|
+
# @param global_id Object persistence ID to persist from port.
|
423
|
+
#
|
424
|
+
# @return [Object] Persisted object instance.
|
425
|
+
#
|
426
|
+
def get_flat_object( global_id )
|
427
|
+
|
428
|
+
flat_object = nil
|
429
|
+
|
430
|
+
if persistence_value_hash = adapter_bucket.get_object( global_id )
|
431
|
+
|
432
|
+
if persistence_value_key_data = persistence_value_hash.first
|
433
|
+
flat_object = persistence_value_key_data[ 1 ]
|
434
|
+
flat_object.persistence_id = global_id
|
435
|
+
end
|
436
|
+
end
|
437
|
+
|
438
|
+
return flat_object
|
439
|
+
|
440
|
+
end
|
441
|
+
|
442
|
+
####################
|
443
|
+
# delete_object! #
|
444
|
+
####################
|
445
|
+
|
446
|
+
###
|
447
|
+
# @private
|
448
|
+
#
|
449
|
+
# Delete object from persistence port.
|
450
|
+
#
|
451
|
+
# @param global_id Object persistence ID to delete from port.
|
452
|
+
#
|
453
|
+
# @return [Hash] Persistence hash from port.
|
454
|
+
#
|
455
|
+
def delete_object!( global_id )
|
456
|
+
|
457
|
+
return adapter_bucket.delete_object!( global_id )
|
458
|
+
|
459
|
+
end
|
460
|
+
|
461
|
+
#######################
|
462
|
+
# delete_attribute! #
|
463
|
+
#######################
|
464
|
+
|
465
|
+
###
|
466
|
+
# @private
|
467
|
+
#
|
468
|
+
# Delete attribute for object from port.
|
469
|
+
#
|
470
|
+
# @param object Object that owns indexed entries.
|
471
|
+
#
|
472
|
+
# @param attribute_name Name of attribute.
|
473
|
+
#
|
474
|
+
def delete_attribute!( object, attribute_name )
|
475
|
+
|
476
|
+
primary_key = primary_key_for_attribute_name( object, attribute_name )
|
477
|
+
|
478
|
+
return adapter_bucket.delete_attribute!( object, primary_key )
|
479
|
+
|
480
|
+
end
|
481
|
+
|
482
|
+
####################################
|
483
|
+
# primary_key_for_attribute_name #
|
484
|
+
####################################
|
485
|
+
|
486
|
+
###
|
487
|
+
# @private
|
488
|
+
#
|
489
|
+
# Generate primary key for storage for attribute name on object.
|
490
|
+
#
|
491
|
+
# @param object Object for which attribute is being stored.
|
492
|
+
#
|
493
|
+
# @param attribute_name Name of attribute.
|
494
|
+
#
|
495
|
+
# @return [String] Primary key.
|
496
|
+
#
|
497
|
+
def primary_key_for_attribute_name( object, attribute_name )
|
498
|
+
|
499
|
+
return adapter_bucket.primary_key_for_attribute_name( object, attribute_name )
|
500
|
+
|
501
|
+
end
|
502
|
+
|
503
|
+
################################
|
504
|
+
# persists_files_by_content? #
|
505
|
+
################################
|
506
|
+
|
507
|
+
def persists_files_by_content?
|
508
|
+
|
509
|
+
persists_files_by_content = nil
|
510
|
+
|
511
|
+
persists_files_by_content = super
|
512
|
+
|
513
|
+
if persists_files_by_content.nil?
|
514
|
+
persists_files_by_content = parent_port.persists_files_by_content?
|
515
|
+
end
|
516
|
+
|
517
|
+
return persists_files_by_content
|
518
|
+
|
519
|
+
end
|
520
|
+
|
521
|
+
#############################
|
522
|
+
# persists_files_by_path? #
|
523
|
+
#############################
|
524
|
+
|
525
|
+
def persists_files_by_path?
|
526
|
+
|
527
|
+
persists_files_by_path = nil
|
528
|
+
|
529
|
+
persists_files_by_path = super
|
530
|
+
|
531
|
+
if persists_files_by_path.nil?
|
532
|
+
persists_files_by_path = parent_port.persists_files_by_path?
|
533
|
+
end
|
534
|
+
|
535
|
+
return persists_files_by_path
|
536
|
+
|
537
|
+
end
|
538
|
+
|
539
|
+
#####################################
|
540
|
+
# persists_file_paths_as_objects? #
|
541
|
+
#####################################
|
542
|
+
|
543
|
+
def persists_file_paths_as_objects?
|
544
|
+
|
545
|
+
persists_file_paths_as_objects = nil
|
546
|
+
|
547
|
+
persists_file_paths_as_objects = super
|
548
|
+
|
549
|
+
if persists_file_paths_as_objects.nil?
|
550
|
+
persists_file_paths_as_objects = parent_port.persists_file_paths_as_objects?
|
551
|
+
end
|
552
|
+
|
553
|
+
return persists_file_paths_as_objects
|
554
|
+
|
555
|
+
end
|
556
|
+
|
557
|
+
#####################################
|
558
|
+
# persists_file_paths_as_strings? #
|
559
|
+
#####################################
|
560
|
+
|
561
|
+
def persists_file_paths_as_strings?
|
562
|
+
|
563
|
+
persists_file_paths_as_strings = nil
|
564
|
+
|
565
|
+
persists_file_paths_as_strings = super
|
566
|
+
|
567
|
+
if persists_file_paths_as_strings.nil?
|
568
|
+
persists_file_paths_as_strings = parent_port.persists_file_paths_as_strings?
|
569
|
+
end
|
570
|
+
|
571
|
+
return persists_file_paths_as_strings
|
572
|
+
|
573
|
+
end
|
574
|
+
|
575
|
+
############
|
576
|
+
# cursor #
|
577
|
+
############
|
578
|
+
|
579
|
+
###
|
580
|
+
# Create and return cursor instance for this bucket.
|
581
|
+
#
|
582
|
+
# @return [Persistence::Cursor] New cursor instance.
|
583
|
+
#
|
584
|
+
def cursor( *args, & block )
|
585
|
+
|
586
|
+
cursor_instance = ::Persistence::Cursor.new( self )
|
587
|
+
|
588
|
+
if args.count > 0
|
589
|
+
cursor_instance.persisted?( *args )
|
590
|
+
end
|
591
|
+
|
592
|
+
if block_given?
|
593
|
+
cursor_instance = cursor_instance.instance_eval( & block )
|
594
|
+
cursor_instance.close
|
595
|
+
end
|
596
|
+
|
597
|
+
return cursor_instance
|
598
|
+
|
599
|
+
end
|
600
|
+
|
601
|
+
###################
|
602
|
+
# atomic_cursor #
|
603
|
+
###################
|
604
|
+
|
605
|
+
###
|
606
|
+
# Create and return cursor instance for this index enabled to load all object properties as atomic.
|
607
|
+
# See Persistence::Cursor#atomize.
|
608
|
+
#
|
609
|
+
# @return [Persistence::Cursor] New cursor instance.
|
610
|
+
#
|
611
|
+
def atomic_cursor( *args )
|
612
|
+
|
613
|
+
return cursor( *args ).atomize
|
614
|
+
|
615
|
+
end
|
616
|
+
|
617
|
+
##########
|
618
|
+
# each #
|
619
|
+
##########
|
620
|
+
|
621
|
+
###
|
622
|
+
# Iterate objects in current bucket.
|
623
|
+
#
|
624
|
+
# @yield [object] Current object.
|
625
|
+
#
|
626
|
+
# @yieldparam object Object stored in bucket.
|
627
|
+
#
|
628
|
+
def each( & block )
|
629
|
+
|
630
|
+
return atomic_cursor.each( & block )
|
631
|
+
|
632
|
+
end
|
633
|
+
|
634
|
+
##################################################################################################
|
635
|
+
private ######################################################################################
|
636
|
+
##################################################################################################
|
637
|
+
|
638
|
+
#########################
|
639
|
+
# create_bucket_index #
|
640
|
+
#########################
|
641
|
+
|
642
|
+
###
|
643
|
+
# Internal helper method for common code to create bucket indexs.
|
644
|
+
#
|
645
|
+
# @param index_name Name of index to create.
|
646
|
+
#
|
647
|
+
# @param permits_duplicates Whether index should permit duplicates.
|
648
|
+
#
|
649
|
+
# @param sort_by_proc [Proc] Proc to use for sorting objects.
|
650
|
+
#
|
651
|
+
# @param sort_duplicates_by_proc [Proc] Proc to use for sorting duplicate objects.
|
652
|
+
#
|
653
|
+
# @yield [object] Block to create index keys on object.
|
654
|
+
# @yieldparam object [Object] Object to index.
|
655
|
+
#
|
656
|
+
# @return [Persistence::Port::Bucket::BucketIndex]
|
657
|
+
#
|
658
|
+
def create_bucket_index( index_name,
|
659
|
+
permits_duplicates,
|
660
|
+
sort_by_proc = nil,
|
661
|
+
sort_duplicates_by_proc = nil,
|
662
|
+
& indexing_block )
|
663
|
+
|
664
|
+
if index_instance = @indexes[ index_name ] and
|
665
|
+
index_instance.permits_duplicates? != permits_duplicates
|
666
|
+
|
667
|
+
raise 'Index ' << index_name.to_s + ' has already been declared, ' <<
|
668
|
+
'and new duplicates declaration does not match existing declaration.'
|
669
|
+
|
670
|
+
end
|
671
|
+
|
672
|
+
index_instance = ::Persistence::Port::Bucket::BucketIndex.new( index_name,
|
673
|
+
self,
|
674
|
+
permits_duplicates,
|
675
|
+
sort_by_proc,
|
676
|
+
sort_duplicates_by_proc,
|
677
|
+
& indexing_block )
|
678
|
+
|
679
|
+
@indexes[ index_name ] = index_instance
|
680
|
+
|
681
|
+
return index_instance
|
682
|
+
|
683
|
+
end
|
684
|
+
|
685
|
+
end
|