persistence-adapter-flat_file 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.
@@ -0,0 +1,29 @@
1
+
2
+ # We use the file-system for a storage port in place of a database
3
+ #
4
+ # Global ID Sequence: <home_directory>/global_id_sequence.ruby_yaml.txt
5
+ # Global IDs: <home_directory>/global_ids/bucket/key_class/key/global_id.ruby_yaml.txt
6
+ # Bucket/key/class: <home_directory>/bucket_class/id.ruby_yaml.txt
7
+ # Objects:
8
+ # Attributes: <home_directory>/objects/bucket/id#/flat_properties/attribute.ruby_yaml.txt
9
+ # Delete Cascades: <home_directory>/objects/bucket/id#/delete_cascades.ruby_yaml.txt
10
+ #
11
+ # [ Indexes: <home_directory>/indexes/index/soft_link_to_key_in_bucket ] - not yet implemented
12
+
13
+ # FIX - when concerned with multi-threading, Files will need to be locked while attribute modifications occur
14
+ # (or otherwise virtually locked using corresponding lock files).
15
+ # FIX - add :lock_non_atomic option and corresponding :release to declare modifications to a non-atomic object complete
16
+ # FIX - add transactions
17
+
18
+ class ::Persistence::Adapter::FlatFile::Marshal
19
+
20
+ include ::Persistence::Adapter::FlatFile::AdapterInterface
21
+
22
+ SerializationClass = ::Marshal
23
+ SerializationMethod = :dump
24
+ UnserializationMethod = :load
25
+ StringifyClassnames = false
26
+ FileContentsAreTextNotBinary = false
27
+ SerializationExtension = '.ruby_marshal.bin'
28
+
29
+ end
@@ -0,0 +1,63 @@
1
+
2
+ module ::Persistence::Adapter::FlatFile::PathHelpers
3
+
4
+ ##################################################################################################
5
+ private ######################################################################################
6
+ ##################################################################################################
7
+
8
+ ######################################
9
+ # file__path_encoded_name_from_key #
10
+ ######################################
11
+
12
+ def file__path_encoded_name_from_key( key )
13
+
14
+ serialized_key = adapter_class::SerializationClass.__send__( adapter_class::SerializationMethod, key )
15
+
16
+ return ::Base64.encode64( serialized_key )
17
+
18
+ end
19
+
20
+ ######################################
21
+ # file__key_from_path_encoded_name #
22
+ ######################################
23
+
24
+ def file__key_from_path_encoded_name( digest )
25
+
26
+ serialized_key = ::Base64.decode64( digest )
27
+ unserialized_key = adapter_class::SerializationClass.__send__( adapter_class::UnserializationMethod, serialized_key )
28
+
29
+ return unserialized_key
30
+
31
+ end
32
+
33
+ ##################################
34
+ # ensure_directory_path_exists #
35
+ ##################################
36
+
37
+ def ensure_directory_path_exists( file_path )
38
+
39
+ unless ::File.exists?( file_path )
40
+
41
+ path_parts = File.expand_path( file_path ).split( '/' )
42
+ # get rid of the first empty part from '/'
43
+ path_parts.shift
44
+ part = 0
45
+
46
+ while part < path_parts.count
47
+
48
+ directory = '/' + File.join( *path_parts[ 0 .. part ] )
49
+ unless ::Dir.exist?( directory )
50
+ ::Dir.mkdir( directory )
51
+ end
52
+
53
+ part += 1
54
+
55
+ end
56
+
57
+ end
58
+
59
+ return self
60
+
61
+ end
62
+
63
+ end
@@ -0,0 +1,85 @@
1
+
2
+ module ::Persistence::Adapter::FlatFile::Serialization
3
+
4
+ ##################################################################################################
5
+ private ######################################################################################
6
+ ##################################################################################################
7
+
8
+ ################################################
9
+ # create_or_update_value_serialize_and_write #
10
+ ################################################
11
+
12
+ def create_or_update_value_serialize_and_write( file_path, value )
13
+
14
+ if value.is_a?( Class )
15
+ value = ::Persistence::Adapter::FlatFile::ClassName.new( value.to_s )
16
+ end
17
+
18
+ # open file, get data, perform action, rewrite data if appropriate, close file
19
+ mode = 'w' + ( adapter_class::FileContentsAreTextNotBinary ? 't' : 'b' )
20
+ File.open( file_path, mode ) do |file|
21
+ serialized_value = adapter_class::SerializationClass.__send__( adapter_class::SerializationMethod, value )
22
+ file.write( serialized_value )
23
+ end
24
+
25
+ return self
26
+
27
+ end
28
+
29
+ #####################################
30
+ # open_read_unserialize_and_close #
31
+ #####################################
32
+
33
+ def open_read_unserialize_and_close( file_path )
34
+
35
+ return open_read_unserialize_perform_action_serialize_write_and_close( file_path )
36
+
37
+ end
38
+
39
+ ####################################################################
40
+ # open_read_unserialize_perform_action_serialize_write_and_close #
41
+ ####################################################################
42
+
43
+ def open_read_unserialize_perform_action_serialize_write_and_close( file_path )
44
+
45
+ unserialized_value = nil
46
+
47
+ # if we don't have a file we obviously don't have a value - return nil
48
+ if File.exists?( file_path )
49
+
50
+ # open file, get data, perform action, rewrite data if appropriate, close file
51
+ mode = 'r+' + ( adapter_class::FileContentsAreTextNotBinary ? 't' : 'b' )
52
+ File.open( file_path, mode ) do |file|
53
+
54
+ # get serializeled version of last persistence ID assigned
55
+ serialized_value = file.read( file.size )
56
+ if serialized_value
57
+ unserialized_value = adapter_class::SerializationClass.__send__( adapter_class::UnserializationMethod, serialized_value )
58
+ end
59
+
60
+ if unserialized_value.is_a?( ::Persistence::Adapter::FlatFile::ClassName )
61
+ unserialized_value = unserialized_value.split( '::' ).inject( Object ) { |namespace, next_part| namespace.const_get( next_part ) }
62
+ end
63
+
64
+ # perform action if provided and write new data back
65
+ if block_given?
66
+
67
+ serialized_value = adapter_class::SerializationClass.__send__( adapter_class::SerializationMethod, yield( unserialized_value ) )
68
+ if serialized_value.is_a?( Class )
69
+ serialized_value = ::Persistence::Adapter::FlatFile::ClassName.new( serialized_value.to_s )
70
+ end
71
+ file.rewind
72
+ file.truncate( 0 )
73
+ file.write( serialized_value )
74
+
75
+ end
76
+
77
+ end
78
+
79
+ end
80
+
81
+ return unserialized_value
82
+
83
+ end
84
+
85
+ end
@@ -0,0 +1,31 @@
1
+
2
+ # We use the file-system for a storage port in place of a database
3
+ #
4
+ # Global ID Sequence: <home_directory>/global_id_sequence.ruby_yaml.txt
5
+ # Global IDs: <home_directory>/global_ids/bucket/key_class/key/global_id.ruby_yaml.txt
6
+ # Bucket/key/class: <home_directory>/bucket_class/id.ruby_yaml.txt
7
+ # Objects:
8
+ # Attributes: <home_directory>/objects/bucket/id#/flat_properties/attribute.ruby_yaml.txt
9
+ # Delete Cascades: <home_directory>/objects/bucket/id#/delete_cascades.ruby_yaml.txt
10
+ #
11
+ # [ Indexes: <home_directory>/indexes/index/soft_link_to_key_in_bucket ] - not yet implemented
12
+
13
+ # FIX - when concerned with multi-threading, Files will need to be locked while attribute modifications occur
14
+ # (or otherwise virtually locked using corresponding lock files).
15
+ # FIX - add :lock_non_atomic option and corresponding :release to declare modifications to a non-atomic object complete
16
+ # FIX - add transactions
17
+
18
+ require 'yaml'
19
+
20
+ class ::Persistence::Adapter::FlatFile::YAML
21
+
22
+ include ::Persistence::Adapter::FlatFile::YAML::AdapterInterface
23
+
24
+ SerializationClass = ::YAML
25
+ SerializationMethod = :dump
26
+ UnserializationMethod = :load
27
+ StringifyClassnames = true
28
+ FileContentsAreTextNotBinary = true
29
+ SerializationExtension = '.yaml'
30
+
31
+ end
@@ -0,0 +1,21 @@
1
+
2
+ module ::Persistence::Adapter::FlatFile::YAML::AdapterInterface
3
+
4
+ include ::Persistence::Adapter::FlatFile::AdapterInterface
5
+
6
+ #############################
7
+ # get_class_for_object_id #
8
+ #############################
9
+
10
+ def get_class_for_object_id( global_id )
11
+
12
+ klass_string = open_read_unserialize_and_close( file__class_for_id( global_id ) )
13
+
14
+ # for YAML - can't store anonymous Class, but sometimes we need to store "Class", so we store all class as string and get back
15
+ klass = klass_string.split( '::' ).inject( Object ) { |namespace, next_part| namespace.const_get( next_part ) }
16
+
17
+ return klass
18
+
19
+ end
20
+
21
+ end
@@ -0,0 +1,15 @@
1
+
2
+ module ::Persistence
3
+ module Adapter
4
+ class FlatFile
5
+ class Bucket
6
+ class Index
7
+ end
8
+ end
9
+ class Cursor
10
+ end
11
+ class YAML
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,32 @@
1
+
2
+ basepath = 'flat_file'
3
+
4
+ files = [
5
+
6
+ 'path_helpers',
7
+ 'serialization',
8
+
9
+ 'class_name',
10
+
11
+ 'bucket/index/index_interface',
12
+ 'bucket/index',
13
+
14
+ 'bucket/bucket_interface',
15
+ 'bucket',
16
+
17
+ 'cursor/cursor_interface',
18
+ 'cursor',
19
+
20
+ 'adapter_interface',
21
+
22
+ 'marshal',
23
+ 'yaml/adapter_interface',
24
+ 'yaml'
25
+
26
+ ]
27
+
28
+ files.each do |this_file|
29
+ require_relative( File.join( basepath, this_file ) + '.rb' )
30
+ end
31
+
32
+ require_relative( basepath + '.rb' )
@@ -0,0 +1,28 @@
1
+
2
+ require_relative '../../../../lib/persistence/adapter/flat_file.rb'
3
+
4
+ describe ::Persistence::Adapter::FlatFile::Cursor do
5
+
6
+ # we have to specify a serialization class; we use Marshal for our example
7
+ unless $__persistence__spec__development__initialized_flatfile
8
+ class ::Persistence::Adapter::FlatFile
9
+ SerializationClass = ::Marshal
10
+ SerializationMethod = :dump
11
+ UnserializationMethod = :load
12
+ SerializationExtension = '.ruby_marshal.bin'
13
+ FileContentsAreTextNotBinary = false
14
+ StringifyClassnames = false
15
+ end
16
+ $__persistence__spec__development__initialized_flatfile = true
17
+ end
18
+
19
+ temp_test_path = "/tmp/persistence-adapter-flat_file"
20
+
21
+ ::FileUtils.rm_rf( temp_test_path ) if ::Dir.exist?( temp_test_path )
22
+
23
+ $__persistence__spec__adapter__ = ::Persistence::Adapter::FlatFile.new( temp_test_path )
24
+
25
+ # adapter spec
26
+ require_relative File.join( ::Persistence::Adapter::Abstract.spec_location, 'Cursor_spec.rb' )
27
+
28
+ end
@@ -0,0 +1,28 @@
1
+
2
+ require_relative '../../../lib/persistence/adapter/flat_file.rb'
3
+
4
+ describe ::Persistence::Adapter::FlatFile do
5
+
6
+ # we have to specify a serialization class; we use Marshal for our example
7
+ unless $__persistence__spec__development__initialized_flatfile
8
+ class ::Persistence::Adapter::FlatFile
9
+ SerializationClass = ::Marshal
10
+ SerializationMethod = :dump
11
+ UnserializationMethod = :load
12
+ SerializationExtension = '.ruby_marshal.bin'
13
+ FileContentsAreTextNotBinary = false
14
+ StringifyClassnames = false
15
+ end
16
+ $__persistence__spec__development__initialized_flatfile = true
17
+ end
18
+
19
+ temp_test_path = "/tmp/persistence-adapter-flat_file"
20
+
21
+ ::FileUtils.rm_rf( temp_test_path ) if ::Dir.exist?( temp_test_path )
22
+
23
+ $__persistence__spec__adapter__ = ::Persistence::Adapter::FlatFile.new( temp_test_path )
24
+
25
+ # adapter spec
26
+ require_relative File.join( ::Persistence::Adapter::Abstract.spec_location, 'Adapter_spec.rb' )
27
+
28
+ end
@@ -0,0 +1,15 @@
1
+
2
+ require_relative '../../../../lib/persistence/adapter/flat_file.rb'
3
+
4
+ describe ::Persistence::Adapter::FlatFile::Marshal do
5
+
6
+ temp_test_path = "/tmp/persistence-adapter-flat_file"
7
+
8
+ ::FileUtils.rm_rf( temp_test_path ) if ::Dir.exist?( temp_test_path )
9
+
10
+ $__persistence__spec__adapter__ = ::Persistence::Adapter::FlatFile::Marshal.new( temp_test_path )
11
+
12
+ # adapter spec
13
+ require_relative File.join( ::Persistence::Adapter::Abstract.spec_location, 'Cursor_spec.rb' )
14
+
15
+ end
@@ -0,0 +1,15 @@
1
+
2
+ require_relative '../../../lib/persistence/adapter/flat_file.rb'
3
+
4
+ describe ::Persistence::Adapter::FlatFile::Marshal do
5
+
6
+ temp_test_path = "/tmp/persistence-adapter-flat_file"
7
+
8
+ ::FileUtils.rm_rf( temp_test_path ) if ::Dir.exist?( temp_test_path )
9
+
10
+ $__persistence__spec__adapter__ = ::Persistence::Adapter::FlatFile::Marshal.new( temp_test_path )
11
+
12
+ # adapter spec
13
+ require_relative File.join( ::Persistence::Adapter::Abstract.spec_location, 'Adapter_spec.rb' )
14
+
15
+ end
@@ -0,0 +1,15 @@
1
+
2
+ require_relative '../../../../lib/persistence/adapter/flat_file.rb'
3
+
4
+ describe ::Persistence::Adapter::FlatFile::YAML do
5
+
6
+ temp_test_path = "/tmp/persistence-adapter-flat_file"
7
+
8
+ ::FileUtils.rm_rf( temp_test_path ) if ::Dir.exist?( temp_test_path )
9
+
10
+ $__persistence__spec__adapter__ = ::Persistence::Adapter::FlatFile::YAML.new( temp_test_path )
11
+
12
+ # adapter spec
13
+ require_relative File.join( ::Persistence::Adapter::Abstract.spec_location, 'Cursor_spec.rb' )
14
+
15
+ end
@@ -0,0 +1,15 @@
1
+
2
+ require_relative '../../../lib/persistence/adapter/flat_file.rb'
3
+
4
+ describe ::Persistence::Adapter::FlatFile::YAML do
5
+
6
+ temp_test_path = "/tmp/persistence-adapter-flat_file"
7
+
8
+ ::FileUtils.rm_rf( temp_test_path ) if ::Dir.exist?( temp_test_path )
9
+
10
+ $__persistence__spec__adapter__ = ::Persistence::Adapter::FlatFile::YAML.new( temp_test_path )
11
+
12
+ # adapter spec
13
+ require_relative File.join( ::Persistence::Adapter::Abstract.spec_location, 'Adapter_spec.rb' )
14
+
15
+ end
metadata ADDED
@@ -0,0 +1,86 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: persistence-adapter-flat_file
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Asher
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-06-26 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: persistence
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ description: Implements necessary methods to run Persistence on top of the file system
31
+ without a database.
32
+ email: asher@ridiculouspower.com
33
+ executables: []
34
+ extensions: []
35
+ extra_rdoc_files: []
36
+ files:
37
+ - lib/persistence/adapter/flat_file/adapter_interface.rb
38
+ - lib/persistence/adapter/flat_file/bucket/bucket_interface.rb
39
+ - lib/persistence/adapter/flat_file/bucket/index/index_interface.rb
40
+ - lib/persistence/adapter/flat_file/bucket/index.rb
41
+ - lib/persistence/adapter/flat_file/bucket.rb
42
+ - lib/persistence/adapter/flat_file/class_name.rb
43
+ - lib/persistence/adapter/flat_file/cursor/cursor_interface.rb
44
+ - lib/persistence/adapter/flat_file/cursor.rb
45
+ - lib/persistence/adapter/flat_file/marshal.rb
46
+ - lib/persistence/adapter/flat_file/path_helpers.rb
47
+ - lib/persistence/adapter/flat_file/serialization.rb
48
+ - lib/persistence/adapter/flat_file/yaml/adapter_Interface.rb
49
+ - lib/persistence/adapter/flat_file/yaml.rb
50
+ - lib/persistence/adapter/flat_file.rb
51
+ - lib/persistence/adapter/namespaces.rb
52
+ - lib/persistence/adapter/requires.rb
53
+ - spec/Persistence/Adapter/flat_file/cursor_spec.rb
54
+ - spec/Persistence/Adapter/flat_file_spec.rb
55
+ - spec/Persistence/Adapter/marshal/cursor_spec.rb
56
+ - spec/Persistence/Adapter/marshal_spec.rb
57
+ - spec/Persistence/Adapter/yaml/cursor_spec.rb
58
+ - spec/Persistence/Adapter/yaml_spec.rb
59
+ - README.md
60
+ - CHANGELOG.rdoc
61
+ homepage: http://rubygems.org/gems/persistence-adapter-flat_file
62
+ licenses: []
63
+ post_install_message:
64
+ rdoc_options: []
65
+ require_paths:
66
+ - lib
67
+ required_ruby_version: !ruby/object:Gem::Requirement
68
+ none: false
69
+ requirements:
70
+ - - ! '>='
71
+ - !ruby/object:Gem::Version
72
+ version: '0'
73
+ required_rubygems_version: !ruby/object:Gem::Requirement
74
+ none: false
75
+ requirements:
76
+ - - ! '>='
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
79
+ requirements: []
80
+ rubyforge_project: persistence-adapter-flat_file
81
+ rubygems_version: 1.8.23
82
+ signing_key:
83
+ specification_version: 3
84
+ summary: Adapter to use flat files as storage port for Persistence.
85
+ test_files: []
86
+ has_rdoc: