jsl-hashpipe 0.0.3 → 0.0.4

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/hashpipe.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "hashpipe"
3
- s.version = "0.0.3"
3
+ s.version = "0.0.4"
4
4
  s.date = "2009-05-12"
5
5
  s.summary = "ActiveRecord plugin to save content to a pluggable, hash-style backend"
6
6
  s.email = "justin@phq.org"
@@ -16,18 +16,14 @@ Gem::Specification.new do |s|
16
16
  "lib/hashpipe.rb",
17
17
  "lib/hashpipe/archived_attribute.rb",
18
18
  "lib/hashpipe/global_configuration.rb",
19
- "lib/hashpipe/backends/s3.rb",
20
- "lib/hashpipe/backends/memcache.rb",
21
- "lib/hashpipe/backends/filesystem.rb"
19
+ "lib/hashpipe/moneta_backend.rb"
22
20
  ]
23
21
  s.test_files = [
24
22
  "spec/hashpipe/global_configuration_spec.rb",
25
23
  "spec/hashpipe/archived_attribute_spec.rb",
26
- "spec/hashpipe/backends/filesystem_spec.rb",
27
- "spec/hashpipe/backends/s3_spec.rb",
28
- "spec/hashpipe/backends/memcache_spec.rb"
24
+ "spec/hashpipe/moneta_backend_spec.rb"
29
25
  ]
26
+ s.add_dependency("wycats-moneta", ["> 0.0.0"])
30
27
  s.add_dependency("activesupport", ["> 0.0.0"])
31
- s.add_dependency("right_aws", ["> 0.0.0"])
32
28
  s.add_dependency("assaf-uuid", ["> 0.0.0"])
33
29
  end
@@ -1,8 +1,7 @@
1
1
  require 'activesupport'
2
+ require 'moneta'
2
3
 
3
- require File.expand_path(File.join(File.dirname(__FILE__), %w[ backends filesystem ]))
4
- require File.expand_path(File.join(File.dirname(__FILE__), %w[ backends s3 ]))
5
- require File.expand_path(File.join(File.dirname(__FILE__), %w[ backends memcache ]))
4
+ require File.expand_path(File.join(File.dirname(__FILE__), 'moneta_backend'))
6
5
 
7
6
  module HashPipe
8
7
 
@@ -13,11 +12,8 @@ module HashPipe
13
12
  @name = name
14
13
  @instance = instance
15
14
  @dirty = false
16
-
17
- @_options = HashPipe::GlobalConfiguration.instance.to_hash.
18
- merge(opts)
19
-
20
- @backend = instantiate_backend_from(options)
15
+ @_options = HashPipe::GlobalConfiguration.instance.to_hash.merge(opts)
16
+ @backend = instantiate_backend_from(options)
21
17
  end
22
18
 
23
19
  def value
@@ -51,8 +47,7 @@ module HashPipe
51
47
  # Returns a backend object based on the options given (e.g., filesystem,
52
48
  # s3).
53
49
  def instantiate_backend_from(options)
54
- "HashPipe::Backends::#{options[:storage].to_s.camelize}".
55
- constantize.new(self)
50
+ HashPipe::MonetaBackend.new(self)
56
51
  end
57
52
 
58
53
  def options
@@ -6,19 +6,9 @@ module HashPipe
6
6
  include Singleton
7
7
 
8
8
  DEFAULTS = HashWithIndifferentAccess.new({
9
- :storage => 'filesystem',
10
- :marshal => false,
11
- :compress => false,
12
- :s3 => {
13
- :protocol => 'https'
14
- },
15
- :filesystem => {
16
- :archive_root => nil
17
- },
18
- :memcache => {
19
- :port => 1978,
20
- :server => 'localhost'
21
- }
9
+ :moneta_klass => 'Moneta::Memory',
10
+ :marshal => false,
11
+ :compress => false
22
12
  })
23
13
 
24
14
  def [](val)
@@ -0,0 +1,44 @@
1
+ module HashPipe
2
+ class MonetaBackend
3
+
4
+ def initialize(archived_attribute)
5
+ @archived_attribute = archived_attribute
6
+ @options = HashPipe::GlobalConfiguration.instance[:moneta_options]
7
+ @cache = initialize_cache_klass(HashPipe::GlobalConfiguration.instance[:moneta_klass])
8
+ end
9
+
10
+ def save(content)
11
+ @cache[key_name] = content
12
+ end
13
+
14
+ def destroy
15
+ @cache.delete(key_name)
16
+ end
17
+
18
+ def load
19
+ @cache[key_name]
20
+ end
21
+
22
+ private
23
+
24
+ def initialize_cache_klass(cache_klass)
25
+ require_moneta_library_for(cache_klass)
26
+ klass_const = cache_klass.respond_to?(:constantize) ? cache_klass.constantize : cache_klass
27
+ klass_const.new(@options)
28
+ end
29
+
30
+ def require_moneta_library_for(cache_klass)
31
+ require cache_klass.to_s.gsub(/::/, '/').downcase
32
+ end
33
+
34
+ def key_name
35
+ [ table_name_from(@archived_attribute),
36
+ @archived_attribute.name,
37
+ @archived_attribute.instance.uuid ].join('/')
38
+ end
39
+
40
+ def table_name_from(archived_attribute)
41
+ archived_attribute.instance.class.table_name
42
+ end
43
+ end
44
+ end
@@ -2,9 +2,9 @@ require File.join(File.dirname(__FILE__), %w[ .. spec_helper ])
2
2
 
3
3
  describe HashPipe::ArchivedAttribute do
4
4
  before do
5
- options = { :storage => 'filesystem' }
6
5
  stub_model = stub(:uuid => '43')
7
- @aa = HashPipe::ArchivedAttribute.new(:glorp, stub_model, options)
6
+ @aa = HashPipe::ArchivedAttribute.new(:glorp, stub_model)
7
+ HashPipe::MonetaBackend.any_instance.stubs(:table_name_from).returns('foo_table')
8
8
  end
9
9
 
10
10
  describe "#dirty?" do
@@ -0,0 +1,5 @@
1
+ require File.join(File.dirname(__FILE__), %w[ .. spec_helper ])
2
+
3
+ describe HashPipe::MonetaBackend do
4
+ it "should have specs written"
5
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jsl-hashpipe
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin Leitgeb
@@ -13,7 +13,7 @@ date: 2009-05-12 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
- name: activesupport
16
+ name: wycats-moneta
17
17
  type: :runtime
18
18
  version_requirement:
19
19
  version_requirements: !ruby/object:Gem::Requirement
@@ -23,7 +23,7 @@ dependencies:
23
23
  version: 0.0.0
24
24
  version:
25
25
  - !ruby/object:Gem::Dependency
26
- name: right_aws
26
+ name: activesupport
27
27
  type: :runtime
28
28
  version_requirement:
29
29
  version_requirements: !ruby/object:Gem::Requirement
@@ -58,9 +58,7 @@ files:
58
58
  - lib/hashpipe.rb
59
59
  - lib/hashpipe/archived_attribute.rb
60
60
  - lib/hashpipe/global_configuration.rb
61
- - lib/hashpipe/backends/s3.rb
62
- - lib/hashpipe/backends/memcache.rb
63
- - lib/hashpipe/backends/filesystem.rb
61
+ - lib/hashpipe/moneta_backend.rb
64
62
  has_rdoc: true
65
63
  homepage: http://github.com/jsl/hashpipe
66
64
  post_install_message:
@@ -90,6 +88,4 @@ summary: ActiveRecord plugin to save content to a pluggable, hash-style backend
90
88
  test_files:
91
89
  - spec/hashpipe/global_configuration_spec.rb
92
90
  - spec/hashpipe/archived_attribute_spec.rb
93
- - spec/hashpipe/backends/filesystem_spec.rb
94
- - spec/hashpipe/backends/s3_spec.rb
95
- - spec/hashpipe/backends/memcache_spec.rb
91
+ - spec/hashpipe/moneta_backend_spec.rb
@@ -1,60 +0,0 @@
1
- module HashPipe
2
- module Backends
3
-
4
- # The filesystem backend is mostly useful for development or test work. It's not currently sharded
5
- # in any way, so would probably have serious issues for production use. You have been warned.
6
- class Filesystem
7
-
8
- def initialize(archived_attribute)
9
- @archived_attribute = archived_attribute
10
- end
11
-
12
- def save(content)
13
- create_filesystem_path unless File.exist?(filepath)
14
- write_to_disk(content)
15
- end
16
-
17
- def destroy
18
- FileUtils.rm_f(filename)
19
- end
20
-
21
- def load
22
- File.read( filename ) if File.exist?( filename )
23
- end
24
-
25
- # Returns the full file path + name of this archived attribute
26
- def filename
27
- File.join(filepath, @archived_attribute.name.to_s)
28
- end
29
-
30
- private
31
-
32
- # Writes content to disk, or raises an error if the content is unable to
33
- # be saved
34
- def write_to_disk(content)
35
- File.open(filename, 'w') { |f| f.write(content) }
36
- end
37
-
38
- def create_filesystem_path
39
- FileUtils.mkdir_p(filepath)
40
- end
41
-
42
- # The file path used for archiving this attribute. Includes either the
43
- # options[:filesystem][:archive_root] attribute, if available, or the
44
- # RAILS_ROOT/tmp/archived_attribute_archive/attribute_name.
45
- def filepath
46
- config_path = @archived_attribute.options[:filesystem][:archive_root]
47
-
48
- base_path = config_path || File.join(
49
- %W[#{RAILS_ROOT} tmp hashpipe_stash]
50
- )
51
-
52
- File.expand_path( File.join(base_path,
53
- @archived_attribute.name.to_s,
54
- @archived_attribute.instance.uuid ))
55
- end
56
-
57
- end
58
-
59
- end
60
- end
@@ -1,42 +0,0 @@
1
- module HashPipe
2
- module Backends
3
-
4
- class Memcache
5
-
6
- def initialize(archived_attribute)
7
- @archived_attribute = archived_attribute
8
- @config = HashPipe::GlobalConfiguration.instance[:memcache]
9
- end
10
-
11
- def save(content)
12
- cache.write( key_name, content ) unless content.nil?
13
- end
14
-
15
- def destroy
16
- cache.delete(key_name)
17
- end
18
-
19
- def load
20
- cache.read(key_name)
21
- end
22
-
23
- private
24
-
25
- def cache
26
- @cache ||= ActiveSupport::Cache::MemCacheStore.new(server)
27
- end
28
-
29
- def key_name
30
- [ @archived_attribute.instance.class.table_name,
31
- @archived_attribute.name,
32
- @archived_attribute.instance.uuid ].join('/')
33
- end
34
-
35
- def server
36
- "#{@config[:server]}:#{@config[:port]}"
37
- end
38
-
39
- end
40
-
41
- end
42
- end
@@ -1,58 +0,0 @@
1
- require 'right_aws'
2
-
3
- module HashPipe
4
- module Backends
5
-
6
- class S3
7
-
8
- def initialize(archived_attribute)
9
- @archived_attribute = archived_attribute
10
- @config = HashPipe::GlobalConfiguration.instance[:s3]
11
- end
12
-
13
- def save(content)
14
- bucket.put( key_name, StringIO.new( content ) ) unless content.nil?
15
- end
16
-
17
- def destroy
18
- bucket.key(key_name).delete
19
- end
20
-
21
- def load
22
- bucket.get(key_name)
23
- end
24
-
25
- private
26
-
27
- def bucket
28
- @bucket ||= right_aws_s3.bucket(bucket_name)
29
- end
30
-
31
- def right_aws_s3
32
- @s3 ||= RightAws::S3.new(
33
- @config[:access_key],
34
- @config[:secret_key]
35
- )
36
- end
37
-
38
- # Returns the bucket name to be used based on attributes of the archived
39
- # attribute.
40
- def bucket_name
41
- @config[:bucket]
42
- end
43
-
44
- def key_name
45
- [ @archived_attribute.instance.class.table_name,
46
- @archived_attribute.name,
47
- @archived_attribute.instance.uuid ].join('/')
48
- end
49
-
50
- # Returns a string representing whether we use http or https for this
51
- # connection.
52
- def protocol
53
- @config[:protocol] || 'https'
54
- end
55
- end
56
-
57
- end
58
- end
@@ -1,82 +0,0 @@
1
- require File.join(File.dirname(__FILE__), %w[ .. .. spec_helper ])
2
-
3
- require 'tmpdir'
4
-
5
- describe HashPipe::Backends::Filesystem do
6
-
7
- before do
8
- @unique_path_part = 'archived_attributes_test'
9
- @path = File.join(Dir.tmpdir, @unique_path_part)
10
-
11
-
12
- @instance = stub('http_retrieval',
13
- :uuid => '63d3a120-caca-012b-d468-002332d4f91e',
14
- :name => :foo
15
- )
16
-
17
- aa = HashPipe::ArchivedAttribute.new(:content, @instance,
18
- :filesystem => { :archive_root => @path } )
19
-
20
- @fs = HashPipe::Backends::Filesystem.new(aa)
21
- end
22
-
23
- it "should write to the correct path" do
24
- @fs.__send__(:filepath).should ==
25
- File.expand_path(File.join(@path, 'content', @instance.uuid))
26
- end
27
-
28
- describe "#save" do
29
- before do
30
- if File.exist?(@path)
31
- err = <<-EOS
32
- Test directory #{@path} already exists. Please remove it and run the
33
- test suite again.
34
- EOS
35
- raise RuntimeError, err
36
- else
37
- @remove_path = true
38
- FileUtils.mkdir(@path)
39
- end
40
- end
41
-
42
- it "should call methods to create path and save file to disk" do
43
- @fs.save('test')
44
- File.exist?(@fs.filename).should be_true
45
- end
46
-
47
- after(:all) do
48
- FileUtils.rm_rf(@path) if @remove_path
49
- end
50
-
51
- end
52
-
53
- describe "#destroy" do
54
- before do
55
- if File.exist?(@path)
56
- err = <<-EOS
57
- Test directory #{@path} already exists. Please remove it and run the
58
- test suite again.
59
- EOS
60
- raise RuntimeError, err
61
- else
62
- @remove_path = true
63
- FileUtils.mkdir(@path)
64
- end
65
- end
66
-
67
- it "should call methods to remove path and file" do
68
- @fs.save('test')
69
- File.exist?(@fs.filename).should be_true
70
-
71
- @fs.destroy
72
- File.exist?(@fs.filename).should be_false
73
- end
74
-
75
- after(:all) do
76
- FileUtils.rm_rf(@path) if @remove_path
77
- end
78
-
79
- end
80
-
81
-
82
- end
@@ -1,56 +0,0 @@
1
- require File.join(File.dirname(__FILE__), %w[ .. .. spec_helper ])
2
-
3
- describe HashPipe::Backends::Memcache do
4
-
5
- before do
6
- @instance = stub('ar_instance',
7
- :uuid => '63d3a120-caca-012b-d468-002332d4f91e',
8
- :table_name => 'glorps'
9
- )
10
-
11
- @aa = HashPipe::ArchivedAttribute.new(:stuff, @instance)
12
- @mc = HashPipe::Backends::Memcache.new(@aa)
13
- @mc.stubs(:key_name).returns('foo-key')
14
-
15
- @mock_store = mock('memcache_store')
16
- @mc.stubs(:cache).returns(@mock_store)
17
- end
18
-
19
- describe "#initialize" do
20
- it "should initialize a memcached object without error" do
21
- lambda { HashPipe::Backends::Memcache.new(@aa) }.should_not raise_error
22
- end
23
- end
24
-
25
- describe "#load" do
26
- it "should call method to load data from memcached" do
27
- @mock_store.expects(:read)
28
- @mc.load
29
- end
30
- end
31
-
32
- describe "#save" do
33
- it "should call method to store data in memcached" do
34
- @mock_store.expects(:write)
35
- @mc.save('content')
36
- end
37
- end
38
-
39
- describe "#destroy" do
40
- it "should call method to delete key" do
41
- @mock_store.expects(:delete)
42
- @mc.destroy
43
- end
44
- end
45
-
46
- describe "#server" do
47
- before do
48
- @backend = HashPipe::Backends::Memcache.new(:foo)
49
- end
50
-
51
- it "should return server:port" do
52
- @backend.instance_variable_set(:@config, :memcache => {:server => 'foo', :port => 1978})
53
- @backend.__send__(:server).should == "foo:1978"
54
- end
55
- end
56
- end
@@ -1,79 +0,0 @@
1
- require File.join(File.dirname(__FILE__), %w[ .. .. spec_helper ])
2
-
3
- describe HashPipe::Backends::S3 do
4
-
5
- before do
6
- @instance = stub('ar_instance',
7
- :uuid => '63d3a120-caca-012b-d468-002332d4f91e',
8
- :table_name => 'glorps'
9
- )
10
-
11
- @aa = HashPipe::ArchivedAttribute.new(:stuff, @instance)
12
- @s3 = HashPipe::Backends::S3.new(@aa)
13
- @config = HashPipe::GlobalConfiguration.instance
14
- end
15
-
16
- describe "#initialize" do
17
- it "should initialize an s3 object without error" do
18
- lambda { HashPipe::Backends::S3.new(@aa) }.should_not raise_error
19
- end
20
- end
21
-
22
- describe "#protocol" do
23
- it "should be https by default" do
24
- @s3.__send__(:protocol).should == "https"
25
- end
26
-
27
- it "should use http if specified in the configuration object" do
28
- config = { :protocol => 'http' }
29
- @s3.instance_variable_set(:"@config", config)
30
-
31
- @s3.__send__(:protocol).should == "http"
32
- end
33
-
34
- end
35
-
36
- describe "#load" do
37
- it "should call method to load data from s3" do
38
- bucket = mock('bucket')
39
- bucket.expects(:get).once
40
- aws_s3 = mock('aws_s3')
41
- aws_s3.expects(:bucket).returns(bucket)
42
- @s3.expects(:key_name).returns('some-key')
43
- @s3.expects(:right_aws_s3).returns(aws_s3)
44
- @s3.load
45
- end
46
- end
47
-
48
- describe "#save" do
49
- it "should call method to store data in s3" do
50
- bucket = mock('bucket')
51
- content = 'hey'
52
- key = 'fookey'
53
- @s3.expects(:key_name).returns(key)
54
- bucket.expects(:put).once
55
- aws_s3 = mock('aws_s3')
56
- aws_s3.expects(:bucket).returns(bucket)
57
- @s3.expects(:right_aws_s3).returns(aws_s3)
58
- @s3.save(content)
59
- end
60
- end
61
-
62
- describe "#destroy" do
63
- it "should call method to delete key" do
64
- key = mock('key', :delete => true)
65
- bucket = mock('bucket', :key => key)
66
- aws_s3 = mock('aws_s3')
67
- aws_s3.expects(:bucket).returns(bucket)
68
- @s3.expects(:right_aws_s3).returns(aws_s3)
69
- @s3.expects(:key_name).returns('foo-key')
70
- @s3.destroy
71
- end
72
- end
73
-
74
- describe "#bucket_name" do
75
- it "should be based on the attribute class and model" do
76
- @s3.__send__(:bucket_name).should == @config[:s3]['bucket']
77
- end
78
- end
79
- end