dkastner-moneta 0.7.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,67 @@
1
+ module Moneta
2
+ # A meta-store that is backed by one or more Moneta stores.
3
+ # Read operations select a random store, write operations write to all stores.
4
+ class Monetas
5
+ def initialize(options = {})
6
+ @caches = options[:stores] || raise("You must provide the :stores options")
7
+ end
8
+
9
+ module Implementation
10
+ def key?(key)
11
+ read_cache.key?(key)
12
+ end
13
+
14
+ def has_key?(key)
15
+ key?(key)
16
+ end
17
+
18
+ def [](key)
19
+ read_cache[key]
20
+ end
21
+
22
+ def fetch(key, value = nil)
23
+ value ||= block_given? ? yield(key) : default # TODO: Shouldn't yield if key is present?
24
+ read_cache[key] || value
25
+ end
26
+
27
+ def []=(key, value)
28
+ @caches.map do |cache|
29
+ cache[key] = value
30
+ end.first
31
+ end
32
+
33
+ def delete(key)
34
+ @caches.map do |cache|
35
+ cache.delete(key)
36
+ end.first
37
+ end
38
+
39
+ def store(*args)
40
+ @caches.map do |cache|
41
+ cache.store(*args)
42
+ end.first
43
+ end
44
+
45
+ def clear(*args)
46
+ @caches.map do |cache|
47
+ cache.clear(*args)
48
+ end.first
49
+ end
50
+ end
51
+
52
+ # Unimplemented
53
+ module Expiration
54
+ def update_key(key, options)
55
+ end
56
+ end
57
+
58
+ include Implementation
59
+ include Expiration
60
+
61
+ protected
62
+
63
+ def read_cache
64
+ @caches[rand(@caches.size)]
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,3 @@
1
+ module Moneta
2
+ VERSION = '1.0.0'
3
+ end
data/script/destroy ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
3
+
4
+ begin
5
+ require 'rubigen'
6
+ rescue LoadError
7
+ require 'rubygems'
8
+ require 'rubigen'
9
+ end
10
+ require 'rubigen/scripts/destroy'
11
+
12
+ ARGV.shift if ['--help', '-h'].include?(ARGV[0])
13
+ RubiGen::Base.use_component_sources! [:newgem_simple, :test_unit]
14
+ RubiGen::Scripts::Destroy.new.run(ARGV)
data/script/generate ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
3
+
4
+ begin
5
+ require 'rubigen'
6
+ rescue LoadError
7
+ require 'rubygems'
8
+ require 'rubigen'
9
+ end
10
+ require 'rubigen/scripts/generate'
11
+
12
+ ARGV.shift if ['--help', '-h'].include?(ARGV[0])
13
+ RubiGen::Base.use_component_sources! [:newgem_simple, :test_unit]
14
+ RubiGen::Scripts::Generate.new.run(ARGV)
@@ -0,0 +1,21 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ require 'moneta/adapters/active_record'
4
+
5
+ if defined?(ActiveRecord)
6
+ describe 'Moneta::ActiveRecord' do
7
+ before(:each) do
8
+ @cache = Moneta::ActiveRecord.new(:connection => {
9
+ :adapter => 'sqlite3',
10
+ :database => 'reports_test.sqlite3'
11
+ })
12
+ @cache.migrate
13
+ @cache.clear
14
+ end
15
+ after :all do
16
+ FileUtils.rm_f File.expand_path('../reports_test.sqlite3', File.dirname(__FILE__))
17
+ end
18
+
19
+ it_should_behave_like "a read/write Moneta cache"
20
+ end
21
+ end
@@ -0,0 +1,62 @@
1
+ require 'spec_helper'
2
+
3
+ begin
4
+ require "moneta/adapters/basic_file"
5
+
6
+ describe "Moneta::Adapters::BasicFile" do
7
+ describe "without namespacing" do
8
+ before(:each) do
9
+ @cache = Moneta::Builder.build do
10
+ run Moneta::Adapters::BasicFile, :path => File.expand_path("../basic_file_cache", __FILE__)
11
+ end
12
+ @cache.clear
13
+ end
14
+
15
+ if ENV['MONETA_TEST'].nil? || ENV['MONETA_TEST'] == 'basic_file'
16
+ it_should_behave_like "a read/write Moneta cache"
17
+ end
18
+
19
+ it "should deal with '/' and '#' in a key" do
20
+ key = "hello/mom#crazycharacters"
21
+ @cache[key] = "hi"
22
+ @cache[key].should == "hi"
23
+ ::File.exists?(File.join(File.dirname(__FILE__), "basic_file_cache", "")).should == true
24
+ end
25
+ end
26
+
27
+ describe "with namespacing" do
28
+ before(:each) do
29
+ @cache = Moneta::Builder.build do
30
+ run Moneta::Adapters::BasicFile,
31
+ :path => File.expand_path("../basic_file_cache", __FILE__),
32
+ :namespace => "test_namespace"
33
+ end
34
+
35
+ @cache.clear
36
+ end
37
+
38
+ if ENV['MONETA_TEST'].nil? || ENV['MONETA_TEST'] == 'basic_file'
39
+ it_should_behave_like "a read/write Moneta cache"
40
+ end
41
+
42
+ it "should act as two stores within the same directory" do
43
+ @second = Moneta::Builder.build do
44
+ run Moneta::Adapters::BasicFile,
45
+ :path => File.expand_path("../basic_file_cache", __FILE__),
46
+ :namespace => "second_namespace"
47
+ end
48
+
49
+ @second[:key] = "hello"
50
+ @cache[:key] = "world!"
51
+ @second[:key].should == "hello"
52
+ @cache[:key].should == "world!"
53
+ end
54
+ end
55
+
56
+ after(:all) do
57
+ FileUtils.rm_rf(File.join(File.dirname(__FILE__), "basic_file_cache"))
58
+ end
59
+
60
+ end
61
+ rescue SystemExit
62
+ end
@@ -0,0 +1,17 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ begin
4
+ require 'moneta/adapters/couch'
5
+
6
+ describe "Moneta::Adapters::Couch" do
7
+ before(:each) do
8
+ @cache = Moneta::Builder.build do
9
+ run Moneta::Adapters::Couch, :db => "couch_test"
10
+ end
11
+ @cache.clear
12
+ end
13
+
14
+ it_should_behave_like "a read/write Moneta cache"
15
+ end
16
+ rescue SystemExit
17
+ end
@@ -0,0 +1,77 @@
1
+ require 'spec_helper'
2
+ require 'fileutils'
3
+
4
+ begin
5
+ require "moneta/adapters/datamapper"
6
+
7
+ DataMapper.setup(:default, :adapter => :in_memory)
8
+ path = File.expand_path("../datamapper_spec.db", __FILE__)
9
+ FileUtils.rm(path) if File.exist?(path)
10
+
11
+ describe "Moneta::DataMapper" do
12
+
13
+ before(:each) do
14
+ DataMapper.repository(:default).adapter.reset
15
+ end
16
+
17
+ describe "with the default repository" do
18
+ before(:each) do
19
+ @cache = Moneta::Adapters::DataMapper.new(:setup => "sqlite3://#{path}")
20
+ @cache.clear
21
+ end
22
+
23
+ after(:all) do
24
+ MonetaHash.auto_migrate!(:moneta)
25
+ end
26
+
27
+ it_should_behave_like "a read/write Moneta cache"
28
+ end
29
+
30
+ describe "when :repository specified" do
31
+ before(:each) do
32
+ @cache = Moneta::Adapters::DataMapper.new(:repository => :sample, :setup => "sqlite3://#{path}")
33
+ @cache.clear
34
+ end
35
+
36
+ after(:all) do
37
+ MonetaHash.auto_migrate!(:sample)
38
+ end
39
+
40
+ it_should_behave_like "a read/write Moneta cache"
41
+ end
42
+
43
+ describe "with multiple stores" do
44
+ before(:each) do
45
+ @default_cache = Moneta::Adapters::DataMapper.new(:setup => "sqlite3:moneta.db")
46
+ @default_cache.clear
47
+
48
+ @sample_cache = Moneta::Adapters::DataMapper.new(:repository => :sample, :setup => "sqlite3:sample.db")
49
+ @sample_cache.clear
50
+ end
51
+
52
+ after(:all) do
53
+ File.delete('moneta.db')
54
+ File.delete('sample.db')
55
+ end
56
+
57
+ # TODO should there be more tests than these?
58
+ it "does not cross contaminate when storing" do
59
+ @default_cache["key"] = "value"
60
+ @sample_cache["key"] = "value2"
61
+
62
+ @default_cache["key"].should == "value"
63
+ @sample_cache["key"].should == "value2"
64
+ end
65
+
66
+ it "does not cross contaminate when deleting" do
67
+ @default_cache["key"] = "value"
68
+ @sample_cache["key"] = "value2"
69
+
70
+ @default_cache.delete("key").should == "value"
71
+ @default_cache.key?("key").should be_false
72
+ @sample_cache["key"].should == "value2"
73
+ end
74
+ end
75
+ end
76
+ rescue SystemExit
77
+ end
@@ -0,0 +1,23 @@
1
+ require 'spec_helper'
2
+
3
+ begin
4
+ require "moneta/adapters/file"
5
+
6
+ describe "Moneta::Adapters::File" do
7
+ before(:each) do
8
+ @cache = Moneta::Builder.build do
9
+ run Moneta::Adapters::File, :path => File.expand_path("../file_cache", __FILE__)
10
+ end
11
+ @cache.clear
12
+ end
13
+
14
+ after(:all) do
15
+ FileUtils.rm_rf(File.join(File.dirname(__FILE__), "file_cache"))
16
+ end
17
+
18
+ if ENV['MONETA_TEST'].nil? || ENV['MONETA_TEST'] == 'file'
19
+ it_should_behave_like "a read/write Moneta cache"
20
+ end
21
+ end
22
+ rescue SystemExit
23
+ end
@@ -0,0 +1,26 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ begin
4
+ require "moneta/adapters/lmc"
5
+ require "fileutils"
6
+
7
+ # Problem: If there are multiple caches around, they start
8
+ # to block (with a system semaphore), which can be unpleasant
9
+ # so just use one cache for the entire test run.
10
+ $lmc_cache = Moneta::Builder.build do
11
+ run Moneta::Adapters::LMC, :filename => "test"
12
+ end
13
+
14
+ describe "Moneta::LMC" do
15
+ before(:all) do
16
+ @cache = $lmc_cache
17
+ end
18
+
19
+ after(:each) do
20
+ @cache.clear
21
+ end
22
+
23
+ it_should_behave_like "a read/write Moneta cache"
24
+ end
25
+ rescue SystemExit
26
+ end
@@ -0,0 +1,17 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ if defined?(MemCache)
4
+ require "moneta/adapters/memcache"
5
+
6
+ describe "Moneta::Adapters::Memcache" do
7
+ before(:each) do
8
+ @native_expires = true
9
+ @cache = Moneta::Builder.build do
10
+ run Moneta::Adapters::Memcache, :server => "localhost:11211", :namespace => "moneta_spec"
11
+ end
12
+ @cache.clear
13
+ end
14
+
15
+ it_should_behave_like "a read/write Moneta cache"
16
+ end
17
+ end
@@ -0,0 +1,18 @@
1
+ require 'spec_helper'
2
+
3
+ require "moneta/adapters/memory"
4
+
5
+ describe "Moneta::Adapters::Memory" do
6
+ class EmptyMiddleware
7
+ include Moneta::Middleware
8
+ end
9
+
10
+ before(:each) do
11
+ @cache = Moneta::Builder.build do
12
+ run Moneta::Adapters::Memory
13
+ end
14
+ @cache.clear
15
+ end
16
+
17
+ it_should_behave_like "a read/write Moneta cache"
18
+ end
@@ -0,0 +1,39 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ begin
4
+ require "moneta/adapters/mongodb"
5
+
6
+ describe "Moneta::Adapters::MongoDB" do
7
+ before(:each) do
8
+ @cache = Moneta::Adapters::MongoDB.new
9
+ @cache.clear
10
+ end
11
+
12
+ describe '#initialize' do
13
+ it 'should initialize with a URI' do
14
+ mock_mongo = mock(Object, :db => mock(Object, :collection => []))
15
+ Mongo::Connection.should_receive(:from_uri).
16
+ with('mongodb://a:b@localhost:27059/cache').
17
+ and_return mock_mongo
18
+ m = Moneta::Adapters::MongoDB.new :uri => 'mongodb://a:b@localhost:27059/cache'
19
+ end
20
+ it 'should initialize with a hash of options' do
21
+ m = Moneta::Adapters::MongoDB.new
22
+ m['example'] = 3.0
23
+ m['example'].should == 3.0
24
+ end
25
+ end
26
+
27
+ context 'initialized' do
28
+ it_should_behave_like "a read/write Moneta cache"
29
+
30
+ describe '#store' do
31
+ it 'should store marshalled data that contains "invalid" UTF-8 characters' do
32
+ expect { @cache['example'] = 17.8 }.
33
+ should_not raise_error
34
+ end
35
+ end
36
+ end
37
+ end
38
+ rescue SystemExit
39
+ end
@@ -0,0 +1,25 @@
1
+ require 'spec_helper'
2
+
3
+ begin
4
+ require "moneta/adapters/pstore"
5
+
6
+ describe Moneta::Adapters::PStore do
7
+ path = File.expand_path("../pstore_cache", __FILE__)
8
+
9
+ before(:each) do
10
+ @cache = Moneta::Builder.new do
11
+ run Moneta::Adapters::PStore, :path => path
12
+ end
13
+ @cache.clear
14
+ end
15
+
16
+ after(:all) do
17
+ FileUtils.rm_rf(path)
18
+ end
19
+
20
+ if ENV['MONETA_TEST'].nil? || ENV['MONETA_TEST'] == 'pstore'
21
+ it_should_behave_like "a read/write Moneta cache"
22
+ end
23
+ end
24
+ rescue SystemExit
25
+ end
@@ -0,0 +1,21 @@
1
+ require 'spec_helper'
2
+
3
+ begin
4
+ require 'moneta/adapters/rackspace'
5
+
6
+ describe "Moneta::Adapters::Rackspace" do
7
+ before(:each) do
8
+ #Fog.mock! unless ENV["RACKSPACE_USERNAME"]
9
+
10
+ @cache = Moneta::Adapters::Rackspace.new(
11
+ :rackspace_username => ENV["RACKSPACE_USERNAME"] || "mocked",
12
+ :rackspace_api_key => ENV["RACKSPACE_APIKEY"] || "mocked",
13
+ :namespace => "TESTING"
14
+ )
15
+ @cache.clear
16
+ end
17
+
18
+ it_should_behave_like "a read/write Moneta cache"
19
+ end
20
+ rescue SystemExit
21
+ end
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+
3
+ begin
4
+ require "moneta/adapters/redis"
5
+
6
+ describe "Moneta::Adapters::Redis" do
7
+ before(:each) do
8
+ @cache = Moneta::Adapters::Redis.new
9
+ @cache.clear
10
+ end
11
+
12
+ it_should_behave_like "a read/write Moneta cache"
13
+ end
14
+ rescue SystemExit
15
+ end
@@ -0,0 +1,21 @@
1
+ require 'spec_helper'
2
+
3
+ begin
4
+ require 'moneta/adapters/s3'
5
+
6
+ describe "Moneta::Adapters::S3" do
7
+ before(:each) do
8
+ Fog.mock! unless ENV["S3_KEY"]
9
+
10
+ @cache = Moneta::Adapters::S3.new(
11
+ :aws_access_key_id => ENV["S3_KEY"] || "mocked",
12
+ :aws_secret_access_key => ENV["S3_SECRET"] || "mocked",
13
+ :namespace => "TESTING"
14
+ )
15
+ @cache.clear
16
+ end
17
+
18
+ it_should_behave_like "a read/write Moneta cache"
19
+ end
20
+ rescue SystemExit
21
+ end
@@ -0,0 +1,23 @@
1
+ require 'spec_helper'
2
+
3
+ begin
4
+ require "moneta/adapters/sdbm"
5
+
6
+ path = File.expand_path("../sdbm_cache", __FILE__)
7
+
8
+ describe "Moneta::Adapters::SDBM" do
9
+ before(:each) do
10
+ @cache = Moneta::Adapters::SDBM.new(:file => path)
11
+ @cache.clear
12
+ end
13
+
14
+ after(:all) do
15
+ FileUtils.rm_rf(Dir["#{path}*"])
16
+ end
17
+
18
+ if ENV['MONETA_TEST'].nil? || ENV['MONETA_TEST'] == 'sdbm'
19
+ it_should_behave_like "a read/write Moneta cache"
20
+ end
21
+ end
22
+ rescue SystemExit
23
+ end
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+
3
+ begin
4
+ require "moneta/adapters/tokyo_cabinet"
5
+
6
+ describe "Moneta::Adapters::TokyoCabinet" do
7
+ before(:each) do
8
+ @cache = Moneta::Adapters::TokyoCabinet.new(:file => File.expand_path("../cache", __FILE__))
9
+ @cache.clear
10
+ end
11
+
12
+ after(:each) do
13
+ @cache.close
14
+ end
15
+
16
+ it_should_behave_like "a read/write Moneta cache"
17
+ end
18
+ rescue SystemExit
19
+ end
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+
3
+ begin
4
+ require "moneta/adapters/tyrant"
5
+
6
+ describe "Moneta::Adapters::Tyrant" do
7
+ before(:each) do
8
+ @cache = Moneta::Adapters::Tyrant.new(:host => "127.0.0.1", :port => 1978)
9
+ @cache.clear
10
+ end
11
+
12
+ it_should_behave_like "a read/write Moneta cache"
13
+ end
14
+ rescue SystemExit
15
+ end
@@ -0,0 +1,25 @@
1
+ require 'spec_helper'
2
+
3
+ begin
4
+ require "moneta/adapters/xattr"
5
+
6
+ describe "Moneta::Adapters::Xattr" do
7
+ path = File.expand_path("../file_cache/xattr_cache", __FILE__)
8
+
9
+ before(:each) do
10
+ @cache = Moneta::Builder.build do
11
+ run Moneta::Adapters::Xattr, :file => path
12
+ end
13
+ @cache.clear
14
+ end
15
+
16
+ after(:all) do
17
+ FileUtils.rm_rf(File.dirname(path))
18
+ end
19
+
20
+ if ENV['MONETA_TEST'].nil? || ENV['MONETA_TEST'] == 'xattrs'
21
+ it_should_behave_like "a read/write Moneta cache"
22
+ end
23
+ end
24
+ rescue SystemExit
25
+ end
@@ -0,0 +1,25 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ begin
4
+ require "moneta/adapters/yaml"
5
+
6
+ describe "Moneta::Adapters::YAML" do
7
+ path = File.expand_path("../yaml_cache", __FILE__)
8
+
9
+ before(:each) do
10
+ @cache = Moneta::Builder.new do
11
+ run Moneta::Adapters::YAML, :path => path
12
+ end
13
+ @cache.clear
14
+ end
15
+
16
+ after(:all) do
17
+ FileUtils.rm_rf(path)
18
+ end
19
+
20
+ if ENV['MONETA_TEST'].nil? || ENV['MONETA_TEST'] == 'yaml'
21
+ it_should_behave_like "a read/write Moneta cache"
22
+ end
23
+ end
24
+ rescue SystemExit
25
+ end