persistence-adapter-flat_file 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: