juno 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -0
- data/.travis.yml +25 -0
- data/Gemfile +19 -0
- data/LICENSE +20 -0
- data/README.md +83 -0
- data/Rakefile +15 -0
- data/SPEC.md +95 -0
- data/juno.gemspec +22 -0
- data/lib/juno.rb +31 -0
- data/lib/juno/activerecord.rb +58 -0
- data/lib/juno/base.rb +113 -0
- data/lib/juno/couch.rb +43 -0
- data/lib/juno/datamapper.rb +63 -0
- data/lib/juno/dbm.rb +15 -0
- data/lib/juno/expires.rb +45 -0
- data/lib/juno/file.rb +62 -0
- data/lib/juno/gdbm.rb +15 -0
- data/lib/juno/hashfile.rb +12 -0
- data/lib/juno/localmemcache.rb +16 -0
- data/lib/juno/memcached.rb +7 -0
- data/lib/juno/memcached_dalli.rb +55 -0
- data/lib/juno/memcached_native.rb +56 -0
- data/lib/juno/memory.rb +7 -0
- data/lib/juno/mongodb.rb +43 -0
- data/lib/juno/proxy.rb +5 -0
- data/lib/juno/pstore.rb +49 -0
- data/lib/juno/redis.rb +34 -0
- data/lib/juno/riak.rb +45 -0
- data/lib/juno/sdbm.rb +15 -0
- data/lib/juno/sequel.rb +51 -0
- data/lib/juno/sqlite.rb +50 -0
- data/lib/juno/tokyocabinet.rb +36 -0
- data/lib/juno/version.rb +3 -0
- data/lib/juno/yaml.rb +9 -0
- data/test/helper.rb +182 -0
- data/test/test_active_record.rb +36 -0
- data/test/test_couch.rb +13 -0
- data/test/test_datamapper.rb +64 -0
- data/test/test_dbm.rb +13 -0
- data/test/test_expires.rb +10 -0
- data/test/test_file.rb +9 -0
- data/test/test_gdbm.rb +13 -0
- data/test/test_hashfile.rb +9 -0
- data/test/test_localmemcache.rb +13 -0
- data/test/test_memcached.rb +15 -0
- data/test/test_memcached_dalli.rb +15 -0
- data/test/test_memcached_native.rb +15 -0
- data/test/test_memory.rb +9 -0
- data/test/test_mongodb.rb +13 -0
- data/test/test_proxy.rb +9 -0
- data/test/test_pstore.rb +9 -0
- data/test/test_redis.rb +13 -0
- data/test/test_riak.rb +13 -0
- data/test/test_sdbm.rb +13 -0
- data/test/test_sequel.rb +13 -0
- data/test/test_sqlite.rb +13 -0
- data/test/test_tokyocabinet.rb +13 -0
- data/test/test_yaml.rb +9 -0
- data/unsupported/benchmarks.rb +234 -0
- data/unsupported/cassandra.rb +45 -0
- data/unsupported/fog.rb +60 -0
- data/unsupported/test_cassandra.rb +13 -0
- data/unsupported/test_rackspace.rb +15 -0
- data/unsupported/test_s3.rb +15 -0
- data/unsupported/test_tokyotyrant.rb +13 -0
- data/unsupported/tokyotyrant.rb +29 -0
- metadata +165 -0
data/lib/juno/couch.rb
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'couchrest'
|
2
|
+
|
3
|
+
module Juno
|
4
|
+
class Couch < Base
|
5
|
+
def initialize(options = {})
|
6
|
+
@db = ::CouchRest.database!(options[:db])
|
7
|
+
end
|
8
|
+
|
9
|
+
def key?(key, options = {})
|
10
|
+
!!self[key_for(key)]
|
11
|
+
rescue RestClient::ResourceNotFound
|
12
|
+
false
|
13
|
+
end
|
14
|
+
|
15
|
+
def [](key)
|
16
|
+
deserialize(@db.get(key_for(key))['data'])
|
17
|
+
rescue RestClient::ResourceNotFound
|
18
|
+
nil
|
19
|
+
end
|
20
|
+
|
21
|
+
def store(key, value, options = {})
|
22
|
+
@db.save_doc('_id' => key_for(key), :data => serialize(value))
|
23
|
+
value
|
24
|
+
rescue RestClient::RequestFailed
|
25
|
+
value
|
26
|
+
end
|
27
|
+
|
28
|
+
def delete(key, options = {})
|
29
|
+
value = @db.get(key_for(key))
|
30
|
+
if value
|
31
|
+
@db.delete_doc({'_id' => value['_id'], '_rev' => value['_rev']}) if value
|
32
|
+
deserialize(value['data'])
|
33
|
+
end
|
34
|
+
rescue RestClient::ResourceNotFound
|
35
|
+
nil
|
36
|
+
end
|
37
|
+
|
38
|
+
def clear(options = {})
|
39
|
+
@db.recreate!
|
40
|
+
nil
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'dm-core'
|
2
|
+
require 'dm-migrations'
|
3
|
+
|
4
|
+
module Juno
|
5
|
+
class DataMapper < Base
|
6
|
+
class Store
|
7
|
+
include ::DataMapper::Resource
|
8
|
+
property :k, String, :key => true
|
9
|
+
property :v, Object, :lazy => false
|
10
|
+
end
|
11
|
+
|
12
|
+
def initialize(options = {})
|
13
|
+
raise 'No option :setup specified' unless options[:setup]
|
14
|
+
@repository = options.delete(:repository) || :juno
|
15
|
+
Store.storage_names[@repository] = options.delete(:table) || :juno
|
16
|
+
::DataMapper.setup(@repository, options[:setup])
|
17
|
+
context { Store.auto_upgrade! }
|
18
|
+
end
|
19
|
+
|
20
|
+
def key?(key, options = {})
|
21
|
+
context { !!Store.get(key_for(key)) }
|
22
|
+
end
|
23
|
+
|
24
|
+
def [](key)
|
25
|
+
context do
|
26
|
+
record = Store.get(key_for(key))
|
27
|
+
record ? record.v : nil
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def store(key, value, options = {})
|
32
|
+
key = key_for(key)
|
33
|
+
context do
|
34
|
+
record = Store.get(key)
|
35
|
+
if record
|
36
|
+
record.update(key, value)
|
37
|
+
else
|
38
|
+
Store.create(:k => key, :v => value)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
value
|
42
|
+
end
|
43
|
+
|
44
|
+
def delete(key, options = {})
|
45
|
+
context do
|
46
|
+
value = self[key]
|
47
|
+
Store.all(:k => key_for(key)).destroy!
|
48
|
+
value
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def clear(options = {})
|
53
|
+
context { Store.all.destroy! }
|
54
|
+
nil
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
def context
|
60
|
+
::DataMapper.repository(@repository) { yield }
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
data/lib/juno/dbm.rb
ADDED
data/lib/juno/expires.rb
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
module Juno
|
2
|
+
class Expires < Proxy
|
3
|
+
def key?(key, options = {})
|
4
|
+
!!self[key]
|
5
|
+
end
|
6
|
+
|
7
|
+
def fetch(key, value = nil, options = {}, &block)
|
8
|
+
result = check_expired(key, super(key, value, options, &block))
|
9
|
+
if result && options.include?(:expires)
|
10
|
+
store(key, result, options)
|
11
|
+
else
|
12
|
+
result
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def [](key)
|
17
|
+
check_expired(key, super(key))
|
18
|
+
end
|
19
|
+
|
20
|
+
def store(key, value, options = {})
|
21
|
+
if expires = options.delete(:expires)
|
22
|
+
super(key, [value, Time.now.to_i + expires].compact, options)
|
23
|
+
else
|
24
|
+
super(key, [value], options)
|
25
|
+
end
|
26
|
+
value
|
27
|
+
end
|
28
|
+
|
29
|
+
def delete(key, options = {})
|
30
|
+
check_expired(key, super, false)
|
31
|
+
end
|
32
|
+
|
33
|
+
protected
|
34
|
+
|
35
|
+
def check_expired(key, value, delete_expired = true)
|
36
|
+
value, expires = value
|
37
|
+
if expires && Time.now.to_i > expires
|
38
|
+
delete(key) if delete_expired
|
39
|
+
nil
|
40
|
+
else
|
41
|
+
value
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/lib/juno/file.rb
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
|
3
|
+
module Juno
|
4
|
+
class File < Base
|
5
|
+
def initialize(options = {})
|
6
|
+
raise 'No option :dir specified' unless @dir = options[:dir]
|
7
|
+
FileUtils.mkpath(@dir)
|
8
|
+
raise "#{@dir} is not a dir" unless ::File.directory?(@dir)
|
9
|
+
end
|
10
|
+
|
11
|
+
def key?(key, options = {})
|
12
|
+
::File.exist?(store_path(key))
|
13
|
+
end
|
14
|
+
|
15
|
+
def [](key)
|
16
|
+
deserialize(::File.read(store_path(key)))
|
17
|
+
rescue Errno::ENOENT
|
18
|
+
end
|
19
|
+
|
20
|
+
def store(key, value, options = {})
|
21
|
+
path = store_path(key)
|
22
|
+
temp_file = ::File.join(@dir, "value-#{$$}-#{Thread.current.object_id}")
|
23
|
+
FileUtils.mkpath(::File.dirname(path))
|
24
|
+
::File.open(temp_file, 'wb') {|file| file.write(serialize(value)) }
|
25
|
+
::File.unlink(path) if ::File.exist?(path)
|
26
|
+
::File.rename(temp_file, path)
|
27
|
+
value
|
28
|
+
rescue Errno::ENOENT
|
29
|
+
::File.unlink(temp_file) rescue nil
|
30
|
+
value
|
31
|
+
end
|
32
|
+
|
33
|
+
def delete(key, options = {})
|
34
|
+
value = self[key]
|
35
|
+
::File.unlink(store_path(key))
|
36
|
+
value
|
37
|
+
rescue Errno::ENOENT
|
38
|
+
end
|
39
|
+
|
40
|
+
def clear(options = {})
|
41
|
+
temp_dir = "#{@dir}-#{$$}-#{Thread.current.object_id}"
|
42
|
+
::File.rename(@dir, temp_dir)
|
43
|
+
FileUtils.mkpath(@dir)
|
44
|
+
FileUtils.rm_rf(temp_dir)
|
45
|
+
nil
|
46
|
+
rescue Errno::ENOENT
|
47
|
+
nil
|
48
|
+
end
|
49
|
+
|
50
|
+
protected
|
51
|
+
|
52
|
+
def escape(s)
|
53
|
+
s.gsub(/[^a-zA-Z0-9_-]+/) do
|
54
|
+
'%' + $&.unpack('H2' * $&.bytesize).join('%').upcase
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def store_path(key)
|
59
|
+
::File.join(@dir, escape(key_for(key)))
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
data/lib/juno/gdbm.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'localmemcache'
|
2
|
+
|
3
|
+
module Juno
|
4
|
+
class LocalMemCache < Base
|
5
|
+
def initialize(options = {})
|
6
|
+
raise 'No option :file specified' unless options[:file]
|
7
|
+
@store = ::LocalMemCache.new(:filename => options[:file])
|
8
|
+
end
|
9
|
+
|
10
|
+
def delete(key, options = {})
|
11
|
+
value = self[key]
|
12
|
+
@store.delete(key_for(key))
|
13
|
+
value
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'dalli'
|
2
|
+
|
3
|
+
module Juno
|
4
|
+
class MemcachedDalli < Base
|
5
|
+
def initialize(options = {})
|
6
|
+
server = options.delete(:server) || 'localhost:11211'
|
7
|
+
@cache = ::Dalli::Client.new(server, options)
|
8
|
+
end
|
9
|
+
|
10
|
+
def key?(key, options = {})
|
11
|
+
!!@cache.get(key_for(key))
|
12
|
+
end
|
13
|
+
|
14
|
+
def fetch(key, value = nil, options = {})
|
15
|
+
result = super
|
16
|
+
if result && options.include?(:expires)
|
17
|
+
store(key, result, options)
|
18
|
+
else
|
19
|
+
result
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def [](key)
|
24
|
+
deserialize(@cache.get(key_for(key)))
|
25
|
+
end
|
26
|
+
|
27
|
+
def store(key, value, options = {})
|
28
|
+
@cache.set(key_for(key), serialize(value), options[:expires])
|
29
|
+
value
|
30
|
+
end
|
31
|
+
|
32
|
+
def delete(key, options = {})
|
33
|
+
key = key_for(key)
|
34
|
+
value = deserialize(@cache.get(key))
|
35
|
+
@cache.delete(key)
|
36
|
+
value
|
37
|
+
end
|
38
|
+
|
39
|
+
def clear(options = {})
|
40
|
+
@cache.flush_all
|
41
|
+
nil
|
42
|
+
end
|
43
|
+
|
44
|
+
def close
|
45
|
+
@cache.close
|
46
|
+
nil
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def key_for(key)
|
52
|
+
[super].pack('m').strip
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'memcached'
|
2
|
+
|
3
|
+
module Juno
|
4
|
+
class MemcachedNative < Base
|
5
|
+
def initialize(options = {})
|
6
|
+
server = options.delete(:server) || 'localhost:11211'
|
7
|
+
@cache = ::Memcached.new(server, options)
|
8
|
+
end
|
9
|
+
|
10
|
+
def key?(key, options = {})
|
11
|
+
@cache.get(key_for(key), false)
|
12
|
+
true
|
13
|
+
rescue ::Memcached::NotFound
|
14
|
+
false
|
15
|
+
end
|
16
|
+
|
17
|
+
def fetch(key, value = nil, options = {})
|
18
|
+
result = super
|
19
|
+
if result && options.include?(:expires)
|
20
|
+
store(key, result, options)
|
21
|
+
else
|
22
|
+
result
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def [](key)
|
27
|
+
deserialize(@cache.get(key_for(key), false))
|
28
|
+
rescue ::Memcached::NotFound
|
29
|
+
end
|
30
|
+
|
31
|
+
def delete(key, options = {})
|
32
|
+
key = key_for(key)
|
33
|
+
value = deserialize(@cache.get(key, false))
|
34
|
+
@cache.delete(key)
|
35
|
+
value
|
36
|
+
rescue ::Memcached::NotFound
|
37
|
+
end
|
38
|
+
|
39
|
+
def store(key, value, options = {})
|
40
|
+
ttl = options[:expires] || ::Memcached::DEFAULTS[:default_ttl]
|
41
|
+
@cache.set(key_for(key), serialize(value), ttl, false)
|
42
|
+
value
|
43
|
+
end
|
44
|
+
|
45
|
+
def clear(options = {})
|
46
|
+
@cache.flush
|
47
|
+
nil
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def key_for(key)
|
53
|
+
[super].pack('m').strip
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
data/lib/juno/memory.rb
ADDED
data/lib/juno/mongodb.rb
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'mongo'
|
2
|
+
require 'uri'
|
3
|
+
|
4
|
+
module Juno
|
5
|
+
class MongoDB < Base
|
6
|
+
def initialize(options = {})
|
7
|
+
collection = options.delete(:collection) || 'juno'
|
8
|
+
host = options.delete(:host) || 'localhost'
|
9
|
+
port = options.delete(:port) || Mongo::Connection::DEFAULT_PORT
|
10
|
+
db = options.delete(:db) || 'juno'
|
11
|
+
connection = Mongo::Connection.new(host, port, options)
|
12
|
+
@store = connection.db(db).collection(collection)
|
13
|
+
end
|
14
|
+
|
15
|
+
def key?(key, options = {})
|
16
|
+
!!self[key]
|
17
|
+
end
|
18
|
+
|
19
|
+
def [](key)
|
20
|
+
value = @store.find_one('_id' => key_for(key))
|
21
|
+
value ? deserialize(value['data']) : nil
|
22
|
+
end
|
23
|
+
|
24
|
+
def delete(key, options = {})
|
25
|
+
value = self[key]
|
26
|
+
@store.remove('_id' => key_for(key)) if value
|
27
|
+
value
|
28
|
+
end
|
29
|
+
|
30
|
+
def store(key, value, options = {})
|
31
|
+
key = key_for(key)
|
32
|
+
@store.update({ '_id' => key },
|
33
|
+
{ '_id' => key, 'data' => serialize(value) },
|
34
|
+
{ :upsert => true })
|
35
|
+
value
|
36
|
+
end
|
37
|
+
|
38
|
+
def clear(options = {})
|
39
|
+
@store.remove
|
40
|
+
nil
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|