persistence 0.0.1.alpha → 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (138) hide show
  1. data/CHANGELOG.md +4 -0
  2. data/README.md +260 -17
  3. data/lib/namespaces.rb +55 -0
  4. data/lib/persistence.rb +38 -3
  5. data/lib/persistence/adapter/abstract.rb +22 -0
  6. data/lib/persistence/adapter/abstract/enable_disable.rb +107 -0
  7. data/lib/persistence/adapter/abstract/primary_key/id_property_string.rb +33 -0
  8. data/lib/persistence/adapter/abstract/primary_key/simple.rb +29 -0
  9. data/lib/persistence/adapter/mock.rb +9 -0
  10. data/lib/persistence/adapter/mock/adapter_interface.rb +102 -0
  11. data/lib/persistence/adapter/mock/bucket.rb +9 -0
  12. data/lib/persistence/adapter/mock/bucket/bucket_interface.rb +260 -0
  13. data/lib/persistence/adapter/mock/bucket/index.rb +9 -0
  14. data/lib/persistence/adapter/mock/bucket/index/index_interface.rb +155 -0
  15. data/lib/persistence/adapter/mock/cursor.rb +9 -0
  16. data/lib/persistence/adapter/mock/cursor/cursor_interface.rb +238 -0
  17. data/lib/persistence/cursor.rb +11 -0
  18. data/lib/persistence/cursor/atomic.rb +110 -0
  19. data/lib/persistence/cursor/cursor_interface.rb +337 -0
  20. data/lib/persistence/exception/block_required.rb +7 -0
  21. data/lib/persistence/exception/conflicting_index_already_declared.rb +7 -0
  22. data/lib/persistence/exception/duplicate_violates_unique_index.rb +7 -0
  23. data/lib/persistence/exception/explicit_index_required.rb +7 -0
  24. data/lib/persistence/exception/indexing_block_failed_to_generate_keys.rb +7 -0
  25. data/lib/persistence/exception/indexing_object_requires_keys.rb +7 -0
  26. data/lib/persistence/exception/key_value_required.rb +7 -0
  27. data/lib/persistence/exception/no_port_enabled.rb +7 -0
  28. data/lib/persistence/object.rb +21 -0
  29. data/lib/persistence/object/autodetermine.rb +74 -0
  30. data/lib/persistence/object/class_instance.rb +1884 -0
  31. data/lib/persistence/object/complex.rb +17 -0
  32. data/lib/persistence/object/complex/array.rb +14 -0
  33. data/lib/persistence/object/complex/array/class_instance.rb +37 -0
  34. data/lib/persistence/object/complex/array/object_instance.rb +54 -0
  35. data/lib/persistence/object/complex/attributes.rb +1808 -0
  36. data/lib/persistence/object/complex/attributes/attributes_array.rb +32 -0
  37. data/lib/persistence/object/complex/attributes/attributes_hash.rb +187 -0
  38. data/lib/persistence/object/complex/attributes/default_atomic_non_atomic.rb +102 -0
  39. data/lib/persistence/object/complex/attributes/hash_to_port.rb +40 -0
  40. data/lib/persistence/object/complex/class_and_object_instance.rb +132 -0
  41. data/lib/persistence/object/complex/class_instance.rb +267 -0
  42. data/lib/persistence/object/complex/complex_object.rb +111 -0
  43. data/lib/persistence/object/complex/hash.rb +14 -0
  44. data/lib/persistence/object/complex/hash/class_instance.rb +40 -0
  45. data/lib/persistence/object/complex/hash/object_instance.rb +63 -0
  46. data/lib/persistence/object/complex/index/attribute_index.rb +10 -0
  47. data/lib/persistence/object/complex/index/attribute_index/attribute_index_interface.rb +43 -0
  48. data/lib/persistence/object/complex/object_instance.rb +469 -0
  49. data/lib/persistence/object/flat.rb +17 -0
  50. data/lib/persistence/object/flat/class_instance.rb +34 -0
  51. data/lib/persistence/object/flat/file.rb +14 -0
  52. data/lib/persistence/object/flat/file/class_instance.rb +122 -0
  53. data/lib/persistence/object/flat/file/contents.rb +7 -0
  54. data/lib/persistence/object/flat/file/file_persistence.rb +147 -0
  55. data/lib/persistence/object/flat/file/object_instance.rb +116 -0
  56. data/lib/persistence/object/flat/file/path.rb +9 -0
  57. data/lib/persistence/object/flat/object_instance.rb +24 -0
  58. data/lib/persistence/object/index.rb +479 -0
  59. data/lib/persistence/object/index/block_index.rb +10 -0
  60. data/lib/persistence/object/index/block_index/block_index_interface.rb +110 -0
  61. data/lib/persistence/object/index/explicit_index.rb +10 -0
  62. data/lib/persistence/object/index/explicit_index/explicit_index_interface.rb +57 -0
  63. data/lib/persistence/object/index_hash.rb +40 -0
  64. data/lib/persistence/object/object_instance.rb +322 -0
  65. data/lib/persistence/object/parse_persistence_args.rb +145 -0
  66. data/lib/persistence/port.rb +9 -0
  67. data/lib/persistence/port/bucket.rb +9 -0
  68. data/lib/persistence/port/bucket/bucket_index.rb +9 -0
  69. data/lib/persistence/port/bucket/bucket_interface.rb +685 -0
  70. data/lib/persistence/port/controller.rb +263 -0
  71. data/lib/persistence/port/port_interface.rb +417 -0
  72. data/lib/requires.rb +146 -0
  73. data/spec/Integration_spec.rb +53 -0
  74. data/spec/Persistence_spec.rb +175 -0
  75. data/spec/example_objects.rb +6 -0
  76. data/spec/example_objects/complex_object.rb +7 -0
  77. data/spec/example_objects/complex_object/array_object.rb +7 -0
  78. data/spec/example_objects/complex_object/hash_object.rb +7 -0
  79. data/spec/example_objects/flat_object.rb +7 -0
  80. data/spec/example_objects/flat_object/file_object.rb +7 -0
  81. data/spec/persistence/adapter/enable_disable_spec.rb +29 -0
  82. data/spec/persistence/adapter/mock/cursor_spec.rb +64 -0
  83. data/spec/persistence/adapter/mock_helpers.rb +27 -0
  84. data/spec/persistence/adapter/mock_helpers/bucket.rb +10 -0
  85. data/spec/persistence/adapter/mock_helpers/integration/dictionary_hash.rb +4 -0
  86. data/spec/persistence/adapter/mock_helpers/integration/note.rb +18 -0
  87. data/spec/persistence/adapter/mock_helpers/integration/notes_array.rb +4 -0
  88. data/spec/persistence/adapter/mock_helpers/integration/user.rb +44 -0
  89. data/spec/persistence/adapter/mock_helpers/integration/user/address.rb +18 -0
  90. data/spec/persistence/adapter/mock_helpers/integration/user/dictionary_entry.rb +12 -0
  91. data/spec/persistence/adapter/mock_helpers/integration/user/sub_account.rb +15 -0
  92. data/spec/persistence/adapter/mock_helpers/object.rb +87 -0
  93. data/spec/persistence/adapter/mock_helpers/port.rb +21 -0
  94. data/spec/persistence/adapter/mock_spec.rb +211 -0
  95. data/spec/persistence/adapter/primary_key/id_property_string_spec.rb +27 -0
  96. data/spec/persistence/adapter/primary_key/simple_spec.rb +19 -0
  97. data/spec/persistence/adapter/spec_abstract/adapter_spec.rb +223 -0
  98. data/spec/persistence/adapter/spec_abstract/cursor_spec.rb +116 -0
  99. data/spec/persistence/cursor/atomic_spec.rb +86 -0
  100. data/spec/persistence/cursor/object_and_class_instance_spec.rb +73 -0
  101. data/spec/persistence/cursor_spec.rb +128 -0
  102. data/spec/persistence/object/complex/attributes/persistence_hash/array_instance_spec.rb +51 -0
  103. data/spec/persistence/object/complex/attributes/persistence_hash/hash_instance_spec.rb +56 -0
  104. data/spec/persistence/object/complex/attributes_spec.rb +1717 -0
  105. data/spec/persistence/object/complex/complex_spec.rb +922 -0
  106. data/spec/persistence/object/complex/index/attribute_index_spec.rb +76 -0
  107. data/spec/persistence/object/flat/bignum_spec.rb +33 -0
  108. data/spec/persistence/object/flat/class_instance_spec.rb +30 -0
  109. data/spec/persistence/object/flat/class_spec.rb +38 -0
  110. data/spec/persistence/object/flat/complex_spec.rb +36 -0
  111. data/spec/persistence/object/flat/false_class_spec.rb +34 -0
  112. data/spec/persistence/object/flat/file/class_instance_spec.rb +54 -0
  113. data/spec/persistence/object/flat/file/object_instance_spec.rb +143 -0
  114. data/spec/persistence/object/flat/file_spec.rb +64 -0
  115. data/spec/persistence/object/flat/fixnum_spec.rb +32 -0
  116. data/spec/persistence/object/flat/float_spec.rb +32 -0
  117. data/spec/persistence/object/flat/indexing_spec.rb +38 -0
  118. data/spec/persistence/object/flat/rational_spec.rb +33 -0
  119. data/spec/persistence/object/flat/regexp_spec.rb +32 -0
  120. data/spec/persistence/object/flat/string_spec.rb +34 -0
  121. data/spec/persistence/object/flat/symbol_spec.rb +32 -0
  122. data/spec/persistence/object/flat/true_class_spec.rb +32 -0
  123. data/spec/persistence/object/indexes/block_index_spec.rb +119 -0
  124. data/spec/persistence/object/indexes/explicit_index_spec.rb +112 -0
  125. data/spec/persistence/object/parse_persistence_args_spec.rb +65 -0
  126. data/spec/persistence/object_spec.rb +310 -0
  127. data/spec/persistence/port/bucket/bucket_interface_spec.rb +146 -0
  128. data/spec/persistence/port/bucket/index/bucket_index_spec.rb +67 -0
  129. data/spec/persistence/port/bucket_spec.rb +20 -0
  130. data/spec/persistence/port/controller_spec.rb +60 -0
  131. data/spec/persistence/port/port_interface_spec.rb +105 -0
  132. metadata +178 -21
  133. data/.gitignore +0 -17
  134. data/Gemfile +0 -4
  135. data/LICENSE +0 -22
  136. data/Rakefile +0 -2
  137. data/lib/persistence/version.rb +0 -3
  138. data/persistence.gemspec +0 -17
data/CHANGELOG.md ADDED
@@ -0,0 +1,4 @@
1
+
2
+ ## 6/25/2012 ##
3
+
4
+ Initial release.
data/README.md CHANGED
@@ -1,29 +1,272 @@
1
- # Persistence
1
+ # Persistence #
2
2
 
3
- TODO: Write a gem description
3
+ http://rubygems.org/gems/persistence
4
4
 
5
- ## Installation
5
+ # Summary #
6
6
 
7
- Add this line to your application's Gemfile:
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
- gem 'persistence'
9
+ # Description #
10
10
 
11
- And then execute:
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
- $ bundle
13
+ # Install #
14
14
 
15
- Or install it yourself as:
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
- $ gem install persistence
17
+ ## Pre-Beta Warning ##
18
18
 
19
- ## Usage
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
- TODO: Write usage instructions here
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
- ## Contributing
23
+ ## Persistence ##
24
24
 
25
- 1. Fork it
26
- 2. Create your feature branch (`git checkout -b my-new-feature`)
27
- 3. Commit your changes (`git commit -am 'Added some feature'`)
28
- 4. Push to the branch (`git push origin my-new-feature`)
29
- 5. Create new Pull Request
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 Persistence
4
- # Your code goes here...
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