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.
- 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
data/CHANGELOG.md
ADDED
data/README.md
CHANGED
@@ -1,29 +1,272 @@
|
|
1
|
-
# Persistence
|
1
|
+
# Persistence #
|
2
2
|
|
3
|
-
|
3
|
+
http://rubygems.org/gems/persistence
|
4
4
|
|
5
|
-
|
5
|
+
# Summary #
|
6
6
|
|
7
|
-
|
7
|
+
Persistence layer designed to take advantage of Ruby's object model. The back-end is abstracted so that many different adapters can be created.
|
8
8
|
|
9
|
-
|
9
|
+
# Description #
|
10
10
|
|
11
|
-
|
11
|
+
Store and retrieve Ruby objects without thinking twice about how they are stored. Designed for maximum in flexibility and intuitive interface.
|
12
12
|
|
13
|
-
|
13
|
+
# Install #
|
14
14
|
|
15
|
-
|
15
|
+
Persistence is broken into the core 'persistence' gem and additional adapters. Persistence provides the Ruby interface, adapters provide the storage implementation.
|
16
16
|
|
17
|
-
|
17
|
+
## Pre-Beta Warning ##
|
18
18
|
|
19
|
-
|
19
|
+
This code is very early pre-beta non-production code. It *should* be near production ready but is offered with no promises.
|
20
20
|
|
21
|
-
|
21
|
+
If you find something broken, **please submit a failing test or code snippet and we will work on getting it fixed as soon as possible**.
|
22
22
|
|
23
|
-
##
|
23
|
+
## Persistence ##
|
24
24
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
25
|
+
* sudo gem install persistence
|
26
|
+
|
27
|
+
## Adapters ##
|
28
|
+
|
29
|
+
The persistence gem has a single "Mock" adapter built in. It also has abstract interfaces to assist in creating new adapters.
|
30
|
+
|
31
|
+
To actually use Persistence you will want to install a real adapter. Currently, two are available:
|
32
|
+
|
33
|
+
* <a href="https://rubygems.org/gems/persistence-adapter-kyotocabinet">KyotoCabinet Adapter</a> (<a href="https://github.com/RidiculousPower/persistence-adapter-kyotocabinet">on GitHub</a>).
|
34
|
+
* <a href="https://rubygems.org/gems/persistence-adapter-flat_file">Flat File Adapter</a> (<a href="https://github.com/RidiculousPower/persistence-adapter-flat_file">on GitHub</a>).
|
35
|
+
|
36
|
+
# Usage #
|
37
|
+
|
38
|
+
## Before Anything Else ##
|
39
|
+
|
40
|
+
Enable a port with an adapter:
|
41
|
+
|
42
|
+
```ruby
|
43
|
+
adapter_instance = Persistence::Adapter::Mock.new
|
44
|
+
port_name = :some_port
|
45
|
+
|
46
|
+
Persistence.enable_port( port_name, adapter_instance )
|
47
|
+
```
|
48
|
+
|
49
|
+
## The Basics ##
|
50
|
+
|
51
|
+
Enable a class for persistence:
|
52
|
+
|
53
|
+
```ruby
|
54
|
+
require 'persistence'
|
55
|
+
|
56
|
+
class SomeClass
|
57
|
+
include Persistence
|
58
|
+
end
|
59
|
+
```
|
60
|
+
|
61
|
+
Declare persistent properties:
|
62
|
+
|
63
|
+
```ruby
|
64
|
+
class SomeClass
|
65
|
+
|
66
|
+
# non-atomic properties will only update when explicitly told to do so via :persist!
|
67
|
+
attr_non_atomic_accessor :name, :some_non_atomic_property, :some_other_non_atomic_property
|
68
|
+
|
69
|
+
# atomic properties will update as they change
|
70
|
+
attr_atomic_accessor :some_atomic_property, :some_other_atomic_property
|
71
|
+
|
72
|
+
end
|
73
|
+
```
|
74
|
+
|
75
|
+
Assign some data to our object. First, symbols and string (or other basic types):
|
76
|
+
|
77
|
+
```ruby
|
78
|
+
object = SomeClass.new
|
79
|
+
object.name = :some_name
|
80
|
+
|
81
|
+
# Basic "flat" objects can be stored without declaring anything else
|
82
|
+
object.some_non_atomic_property = 'some string'
|
83
|
+
```
|
84
|
+
|
85
|
+
But let's also try out storing nested objects:
|
86
|
+
|
87
|
+
```ruby
|
88
|
+
# Other objects need to be enabled for persistence:
|
89
|
+
class SomeOtherClass
|
90
|
+
include Persistence
|
91
|
+
attr_atomic_accessor :some_atomic_property
|
92
|
+
end
|
93
|
+
|
94
|
+
object.some_other_non_atomic_property = SomeOtherClass.new
|
95
|
+
```
|
96
|
+
|
97
|
+
Now we want to store the object data for the first time:
|
98
|
+
|
99
|
+
```ruby
|
100
|
+
# Call :persist! to get our Object Persistence ID and store non-atomic data.
|
101
|
+
object.persist!
|
102
|
+
```
|
103
|
+
|
104
|
+
Once we have our Object Persistence ID atomic data will be instantly updated in the storage port as it changes.
|
105
|
+
|
106
|
+
At this point we can get a second copy of our object from the storage port:
|
107
|
+
|
108
|
+
```ruby
|
109
|
+
# Retrieving by Object Persistence ID isn't very useful, but we start with it for the basics
|
110
|
+
object_copy = SomeClass.persist( object.persistence_id )
|
111
|
+
|
112
|
+
# object_copy.should == object
|
113
|
+
# object_copy.name.should == object.name
|
114
|
+
# object_copy.some_non_atomic_property.should == object.some_non_atomic_property
|
115
|
+
# object_copy.some_other_non_atomic_property.should == object.some_other_non_atomic_property
|
116
|
+
# object_copy.some_atomic_property.should == object.some_atomic_property
|
117
|
+
# object_copy.some_other_atomic_property.should == object.some_other_atomic_property
|
118
|
+
```
|
119
|
+
|
120
|
+
Non-atomic properties do not update until :persist! is called:
|
121
|
+
|
122
|
+
```ruby
|
123
|
+
object.some_non_atomic_property = 'some other string'
|
124
|
+
# object_copy.some_non_atomic_property.should_not == object.some_non_atomic_property
|
125
|
+
```
|
126
|
+
|
127
|
+
Atomic properties update immediately (as long as object has a Persistence ID):
|
128
|
+
|
129
|
+
```ruby
|
130
|
+
object.some_atomic_property = 'some value'
|
131
|
+
# object_copy.some_atomic_property.should == object.some_atomic_property
|
132
|
+
|
133
|
+
object.some_other_atomic_property = SomeOtherClass.new
|
134
|
+
# object_copy.some_other_atomic_property.should == object.some_other_atomic_property
|
135
|
+
```
|
136
|
+
|
137
|
+
## Indexes ##
|
138
|
+
|
139
|
+
We could retrieve our object simply by its Object Persistence ID (a unique identifier created for each object), but most likely we will want to retrieve the object by way of some arbitrary descriptor (for instance a username).
|
140
|
+
|
141
|
+
To do this, we declare an index.
|
142
|
+
|
143
|
+
There are three types of indexes on objects: explicit indexes, block indexes, and attribute indexes. There is also a fourth type of index - the bucket index - but it is really just a block index owned by a bucket instead of by an object.
|
144
|
+
|
145
|
+
Once we have an indexed key, the object is retrieved in the same way regardless of index type:
|
146
|
+
|
147
|
+
```ruby
|
148
|
+
# if we already have an index called :name with an indexed value :some_name then we can retrieve the object:
|
149
|
+
object_copy = SomeClass.persist( :name, :some_name )
|
150
|
+
```
|
151
|
+
|
152
|
+
Indexes can be unique or permit duplicates. They can be unordered or ordered. Ordered indexes are only partially implemented at this point and will be available soon.
|
153
|
+
|
154
|
+
Unique indexes will throw an exception in the event a duplicate would be created.
|
155
|
+
|
156
|
+
### Explicit Indexes ###
|
157
|
+
|
158
|
+
Explicit indexes require that a key be provided explicitly. Any number of keys can refer to the same object.
|
159
|
+
|
160
|
+
```ruby
|
161
|
+
class SomeClass
|
162
|
+
explicit_index :name
|
163
|
+
end
|
164
|
+
|
165
|
+
object = SomeClass.new
|
166
|
+
object.name = :some_name
|
167
|
+
object.some_atomic_property = :some_value
|
168
|
+
object.persist!( :name, object.name )
|
169
|
+
|
170
|
+
object_copy = SomeClass.persist( :name, :some_value )
|
171
|
+
```
|
172
|
+
|
173
|
+
### Block Indexes ###
|
174
|
+
|
175
|
+
Block indexes take a block, which they then run on each object in order to generate index key(s).
|
176
|
+
|
177
|
+
```ruby
|
178
|
+
class SomeClass
|
179
|
+
block_index :name do |object|
|
180
|
+
object.name
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
object = SomeClass.new
|
185
|
+
object.name = :some_name
|
186
|
+
object.some_atomic_property = :some_value
|
187
|
+
object.persist!
|
188
|
+
|
189
|
+
object_copy = SomeClass.persist( :name, :some_value )
|
190
|
+
```
|
191
|
+
|
192
|
+
### Attribute Indexes ###
|
193
|
+
|
194
|
+
Attribute indexes refer to a getter/setter method on the object. This operates on the same principle as Ruby's attr_accessor.
|
195
|
+
|
196
|
+
```ruby
|
197
|
+
class SomeClass
|
198
|
+
attr_index :name
|
199
|
+
end
|
200
|
+
|
201
|
+
object = SomeClass.new
|
202
|
+
object.name = :some_name
|
203
|
+
object.some_atomic_property = :some_value
|
204
|
+
object.persist!
|
205
|
+
|
206
|
+
object_copy = SomeClass.persist( :name, :some_value )
|
207
|
+
```
|
208
|
+
|
209
|
+
### Bucket Indexes ###
|
210
|
+
|
211
|
+
Bucket indexes are block indexes owned by a bucket instead of an object. This permits multiple object types to be stored in the same bucket and to be indexed by the same block.
|
212
|
+
|
213
|
+
```ruby
|
214
|
+
class SomeClass
|
215
|
+
instance_persistence_bucket.create_index( :name ) do |object|
|
216
|
+
object.name
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
object = SomeClass.new
|
221
|
+
object.name = :some_name
|
222
|
+
object.some_atomic_property = :some_value
|
223
|
+
object.persist!
|
224
|
+
|
225
|
+
object_copy = SomeClass.persist( :name, :some_value )
|
226
|
+
```
|
227
|
+
|
228
|
+
# Outline of General Premises #
|
229
|
+
|
230
|
+
## Storage Ports and Adapters ##
|
231
|
+
|
232
|
+
* Storage is managed by a "port"
|
233
|
+
* Objects are stored in "buckets" owned by the port.
|
234
|
+
* Objects are stored by unique Global ID, which can be anything other than a {::Hash}. Currently adapters use {::Integer}s for Global IDs.
|
235
|
+
* Objects can be indexed, which allows any object to be used as a reference to the primary storage of the object's properties (by Global ID).
|
236
|
+
* Actual storage is provided by an "adapter", which implements the specific terms by which data is stored (ie a database, in files, etc.).
|
237
|
+
|
238
|
+
## Classes and Instances ##
|
239
|
+
|
240
|
+
* Persistence-enabled Classes act as controllers for their instances.
|
241
|
+
* Data storage takes place through instances.
|
242
|
+
* Data retrieval takes place through Class singleton.
|
243
|
+
|
244
|
+
## Properties ##
|
245
|
+
|
246
|
+
* Properties are either atomic or non-atomic.
|
247
|
+
* Objects can be nested to any degree.
|
248
|
+
|
249
|
+
# License #
|
250
|
+
|
251
|
+
(The MIT License)
|
252
|
+
|
253
|
+
Copyright (c) 2012, Asher, Ridiculous Power
|
254
|
+
|
255
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
256
|
+
a copy of this software and associated documentation files (the
|
257
|
+
'Software'), to deal in the Software without restriction, including
|
258
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
259
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
260
|
+
permit persons to whom the Software is furnished to do so, subject to
|
261
|
+
the following conditions:
|
262
|
+
|
263
|
+
The above copyright notice and this permission notice shall be
|
264
|
+
included in all copies or substantial portions of the Software.
|
265
|
+
|
266
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
267
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
268
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
269
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
270
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
271
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
272
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/lib/namespaces.rb
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
|
2
|
+
module ::Persistence
|
3
|
+
###
|
4
|
+
# Namespace module.
|
5
|
+
module Adapter
|
6
|
+
module Abstract
|
7
|
+
module PrimaryKey
|
8
|
+
end
|
9
|
+
end
|
10
|
+
class Mock
|
11
|
+
class Bucket
|
12
|
+
class Index
|
13
|
+
end
|
14
|
+
end
|
15
|
+
class Cursor
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
module Object
|
20
|
+
module Flat
|
21
|
+
module File
|
22
|
+
end
|
23
|
+
end
|
24
|
+
module Complex
|
25
|
+
module Array
|
26
|
+
end
|
27
|
+
module Hash
|
28
|
+
end
|
29
|
+
module Attributes
|
30
|
+
end
|
31
|
+
###
|
32
|
+
# Namespace module.
|
33
|
+
module Index
|
34
|
+
class AttributeIndex
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
module Index
|
39
|
+
class BlockIndex
|
40
|
+
end
|
41
|
+
class ExplicitIndex
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
class Port
|
46
|
+
class Bucket
|
47
|
+
end
|
48
|
+
end
|
49
|
+
class Cursor
|
50
|
+
end
|
51
|
+
###
|
52
|
+
# Namespace module.
|
53
|
+
module Exception
|
54
|
+
end
|
55
|
+
end
|
data/lib/persistence.rb
CHANGED
@@ -1,5 +1,40 @@
|
|
1
|
-
require "persistence/version"
|
2
1
|
|
3
|
-
module
|
4
|
-
|
2
|
+
require 'module-cluster'
|
3
|
+
|
4
|
+
require 'cascading-configuration'
|
5
|
+
#require_relative '../../ruby/cascading-configuration/lib/cascading-configuration.rb'
|
6
|
+
|
7
|
+
# namespaces that have to be declared ahead of time for proper load order
|
8
|
+
require_relative './namespaces'
|
9
|
+
|
10
|
+
# source file requires
|
11
|
+
require_relative './requires.rb'
|
12
|
+
|
13
|
+
###
|
14
|
+
# Primary interface for enabling persistence for a given object type.
|
15
|
+
#
|
16
|
+
# If object is a {::Bignum}, {::Fixnum}, {::Complex}, {::Rational}, {::TrueClass}, {::FalseClass},
|
17
|
+
# {::String}, {::Symbol}, {::Regexp}, or {::NilClass} then object will include
|
18
|
+
# {::Persistence::Object::Flat Persistence::Object::Flat}.
|
19
|
+
#
|
20
|
+
# If object is a File then object will include {::Persistence::Object::Flat::File Persistence::Object::Flat::File}.
|
21
|
+
#
|
22
|
+
# If object is an Array then object will include {::Persistence::Object::Complex::Array Persistence::Object::Complex::Array}.
|
23
|
+
#
|
24
|
+
# If object is a Hash then object will include {::Persistence::Object::Complex::Hash Persistence::Object::Complex::Hash}.
|
25
|
+
#
|
26
|
+
# If object is any other class then object will include {::Persistence::Object::Complex Persistence::Object::Complex}.
|
27
|
+
#
|
28
|
+
module ::Persistence
|
29
|
+
|
30
|
+
extend ::Persistence::Port::Controller
|
31
|
+
|
32
|
+
extend ::Persistence::Object::Autodetermine
|
33
|
+
|
34
|
+
extend ::Persistence::Object::Flat::File::FilePersistence
|
35
|
+
|
36
|
+
persist_files_by_path!
|
37
|
+
persist_file_paths_as_strings!
|
38
|
+
|
5
39
|
end
|
40
|
+
|
@@ -0,0 +1,22 @@
|
|
1
|
+
|
2
|
+
###
|
3
|
+
# @private
|
4
|
+
###
|
5
|
+
# Singleton providing helper methods for writing adapters.
|
6
|
+
#
|
7
|
+
module ::Persistence::Adapter::Abstract
|
8
|
+
|
9
|
+
########################
|
10
|
+
# self.spec_location #
|
11
|
+
########################
|
12
|
+
|
13
|
+
###
|
14
|
+
# Returns location of abstract adapter spec files. Intended for re-usable testing of adapter implementations.
|
15
|
+
#
|
16
|
+
# @return [String] Path to location of spec files.
|
17
|
+
#
|
18
|
+
def self.spec_location
|
19
|
+
return File.expand_path( File.dirname( __FILE__ ) + '/../../../spec/persistence/adapter/spec_abstract/' )
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
|
2
|
+
###
|
3
|
+
# @private
|
4
|
+
###
|
5
|
+
# Provides home directory and enable/disable methods to including adapter class instances.
|
6
|
+
#
|
7
|
+
module ::Persistence::Adapter::Abstract::EnableDisable
|
8
|
+
|
9
|
+
################
|
10
|
+
# initialize #
|
11
|
+
################
|
12
|
+
|
13
|
+
###
|
14
|
+
# Initialize with home directory. Creates directory if it does not exist.
|
15
|
+
#
|
16
|
+
# @param home_directory Directory where persistence data should be stored.
|
17
|
+
#
|
18
|
+
def initialize( home_directory = nil )
|
19
|
+
|
20
|
+
super() if defined?( super )
|
21
|
+
|
22
|
+
@enabled = false
|
23
|
+
|
24
|
+
# initialize home directory if necessary
|
25
|
+
if @home_directory = home_directory and ! ::File.exists?( home_directory )
|
26
|
+
::Dir.mkdir( home_directory )
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
####################
|
32
|
+
# home_directory #
|
33
|
+
####################
|
34
|
+
|
35
|
+
###
|
36
|
+
# Track directory where persistence data is stored.
|
37
|
+
#
|
38
|
+
# @!attribute[r]
|
39
|
+
# @return [String] Path to directory.
|
40
|
+
#
|
41
|
+
attr_accessor :home_directory
|
42
|
+
|
43
|
+
############
|
44
|
+
# enable #
|
45
|
+
############
|
46
|
+
|
47
|
+
###
|
48
|
+
# Enable adapter for use. Abstract method simply provides tracking of whether adapter is enabled or not.
|
49
|
+
#
|
50
|
+
# @return self
|
51
|
+
#
|
52
|
+
def enable
|
53
|
+
|
54
|
+
@enabled = true
|
55
|
+
|
56
|
+
return self
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
#############
|
61
|
+
# disable #
|
62
|
+
#############
|
63
|
+
|
64
|
+
###
|
65
|
+
# Disable adapter to prohibit use. Abstract method simply provides tracking of whether adapter is enabled or not.
|
66
|
+
#
|
67
|
+
# @return self
|
68
|
+
#
|
69
|
+
def disable
|
70
|
+
|
71
|
+
@enabled = false
|
72
|
+
|
73
|
+
return self
|
74
|
+
|
75
|
+
end
|
76
|
+
|
77
|
+
##############
|
78
|
+
# enabled? #
|
79
|
+
##############
|
80
|
+
|
81
|
+
###
|
82
|
+
# Reports whether adapter is enabled for use.
|
83
|
+
#
|
84
|
+
# @return [true/false] Whether adapter is enabled.
|
85
|
+
#
|
86
|
+
def enabled?
|
87
|
+
|
88
|
+
return @enabled
|
89
|
+
|
90
|
+
end
|
91
|
+
|
92
|
+
###############
|
93
|
+
# disabled? #
|
94
|
+
###############
|
95
|
+
|
96
|
+
###
|
97
|
+
# Reports whether adapter is disabled, prohibiting use.
|
98
|
+
#
|
99
|
+
# @return [true/false] Whether adapter is disabled.
|
100
|
+
#
|
101
|
+
def disabled?
|
102
|
+
|
103
|
+
return ! @enabled
|
104
|
+
|
105
|
+
end
|
106
|
+
|
107
|
+
end
|