juno 0.1.1 → 0.2.0
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/.gitignore +2 -1
- data/.travis.yml +6 -0
- data/Gemfile +16 -9
- data/README.md +92 -34
- data/Rakefile +23 -5
- data/benchmarks/run.rb +19 -22
- data/juno.gemspec +0 -3
- data/lib/juno/adapters/activerecord.rb +58 -0
- data/lib/juno/adapters/cassandra.rb +47 -0
- data/lib/juno/adapters/couch.rb +43 -0
- data/lib/juno/adapters/datamapper.rb +64 -0
- data/lib/juno/adapters/dbm.rb +17 -0
- data/lib/juno/adapters/file.rb +58 -0
- data/lib/juno/adapters/fog.rb +42 -0
- data/lib/juno/adapters/gdbm.rb +17 -0
- data/lib/juno/adapters/localmemcache.rb +18 -0
- data/lib/juno/adapters/memcached.rb +11 -0
- data/lib/juno/adapters/memcached_dalli.rb +46 -0
- data/lib/juno/adapters/memcached_native.rb +47 -0
- data/lib/juno/adapters/memory.rb +30 -0
- data/lib/juno/adapters/mongo.rb +43 -0
- data/lib/juno/adapters/null.rb +28 -0
- data/lib/juno/adapters/pstore.rb +51 -0
- data/lib/juno/adapters/redis.rb +43 -0
- data/lib/juno/adapters/riak.rb +46 -0
- data/lib/juno/adapters/sdbm.rb +27 -0
- data/lib/juno/adapters/sequel.rb +50 -0
- data/lib/juno/adapters/sqlite.rb +52 -0
- data/lib/juno/adapters/tokyocabinet.rb +33 -0
- data/lib/juno/adapters/yaml.rb +13 -0
- data/lib/juno/base.rb +11 -89
- data/lib/juno/builder.rb +30 -0
- data/lib/juno/cache.rb +64 -0
- data/lib/juno/expires.rb +6 -10
- data/lib/juno/proxy.rb +62 -3
- data/lib/juno/stack.rb +27 -11
- data/lib/juno/transformer.rb +106 -0
- data/lib/juno/version.rb +1 -1
- data/lib/juno.rb +81 -29
- data/spec/adapter_activerecord_spec.rb +41 -0
- data/spec/adapter_cassandra_spec.rb +27 -0
- data/spec/adapter_couch_spec.rb +27 -0
- data/spec/adapter_datamapper_spec.rb +61 -0
- data/spec/adapter_dbm_spec.rb +27 -0
- data/spec/adapter_file_spec.rb +27 -0
- data/spec/adapter_fog_spec.rb +35 -0
- data/spec/adapter_gdbm_spec.rb +27 -0
- data/spec/adapter_localmemcache_spec.rb +27 -0
- data/spec/adapter_memcached_dalli_spec.rb +28 -0
- data/spec/adapter_memcached_native_spec.rb +28 -0
- data/spec/adapter_memcached_spec.rb +28 -0
- data/spec/adapter_memory_spec.rb +42 -0
- data/spec/adapter_mongo_spec.rb +27 -0
- data/spec/adapter_pstore_spec.rb +30 -0
- data/spec/adapter_redis_spec.rb +28 -0
- data/spec/adapter_riak_spec.rb +31 -0
- data/spec/adapter_sdbm_spec.rb +27 -0
- data/spec/adapter_sequel_spec.rb +27 -0
- data/spec/adapter_sqlite_spec.rb +27 -0
- data/spec/adapter_tokyocabinet_spec.rb +27 -0
- data/spec/adapter_yaml_spec.rb +30 -0
- data/spec/cache_file_memory_spec.rb +50 -0
- data/spec/cache_memory_null_spec.rb +39 -0
- data/spec/expires_file_spec.rb +82 -0
- data/spec/expires_memory_spec.rb +59 -0
- data/spec/generate.rb +736 -0
- data/spec/helper.rb +39 -0
- data/spec/junospecs.rb +1540 -0
- data/spec/null_adapter_spec.rb +33 -0
- data/spec/proxy_expires_memory_spec.rb +63 -0
- data/spec/proxy_redis_spec.rb +38 -0
- data/spec/simple_activerecord_spec.rb +52 -0
- data/spec/simple_cassandra_spec.rb +53 -0
- data/spec/simple_couch_spec.rb +52 -0
- data/spec/simple_datamapper_spec.rb +54 -0
- data/spec/simple_datamapper_with_repository_spec.rb +54 -0
- data/spec/simple_dbm_spec.rb +52 -0
- data/spec/simple_file_spec.rb +52 -0
- data/spec/simple_fog_spec.rb +60 -0
- data/spec/simple_gdbm_spec.rb +52 -0
- data/spec/simple_hashfile_spec.rb +52 -0
- data/spec/simple_localmemcache_spec.rb +52 -0
- data/spec/simple_memcached_dalli_spec.rb +53 -0
- data/spec/simple_memcached_native_spec.rb +53 -0
- data/spec/simple_memcached_spec.rb +53 -0
- data/spec/simple_memory_spec.rb +52 -0
- data/spec/simple_mongo_spec.rb +52 -0
- data/spec/simple_null_spec.rb +43 -0
- data/spec/simple_pstore_spec.rb +52 -0
- data/spec/simple_redis_spec.rb +53 -0
- data/spec/simple_riak_spec.rb +56 -0
- data/spec/simple_sdbm_spec.rb +52 -0
- data/spec/simple_sequel_spec.rb +52 -0
- data/spec/simple_sqlite_spec.rb +52 -0
- data/spec/simple_tokyocabinet_spec.rb +52 -0
- data/spec/simple_yaml_spec.rb +52 -0
- data/spec/stack_file_memory_spec.rb +43 -0
- data/spec/stack_memory_file_spec.rb +42 -0
- data/spec/transformer_bson_spec.rb +44 -0
- data/spec/transformer_json_spec.rb +44 -0
- data/spec/transformer_marshal_base64_spec.rb +60 -0
- data/spec/transformer_marshal_escape_spec.rb +60 -0
- data/spec/transformer_marshal_md5_spec.rb +60 -0
- data/spec/transformer_marshal_md5_spread_spec.rb +60 -0
- data/spec/transformer_msgpack_spec.rb +44 -0
- data/spec/transformer_yaml_spec.rb +59 -0
- metadata +164 -108
- data/lib/juno/activerecord.rb +0 -55
- data/lib/juno/cassandra.rb +0 -45
- data/lib/juno/couch.rb +0 -43
- data/lib/juno/datamapper.rb +0 -63
- data/lib/juno/dbm.rb +0 -15
- data/lib/juno/file.rb +0 -62
- data/lib/juno/fog.rb +0 -48
- data/lib/juno/gdbm.rb +0 -15
- data/lib/juno/hashfile.rb +0 -12
- data/lib/juno/localmemcache.rb +0 -16
- data/lib/juno/memcached.rb +0 -7
- data/lib/juno/memcached_dalli.rb +0 -55
- data/lib/juno/memcached_native.rb +0 -56
- data/lib/juno/memory.rb +0 -7
- data/lib/juno/mongodb.rb +0 -43
- data/lib/juno/null.rb +0 -23
- data/lib/juno/pstore.rb +0 -49
- data/lib/juno/redis.rb +0 -46
- data/lib/juno/riak.rb +0 -45
- data/lib/juno/sdbm.rb +0 -15
- data/lib/juno/sequel.rb +0 -48
- data/lib/juno/sqlite.rb +0 -50
- data/lib/juno/tokyocabinet.rb +0 -36
- data/lib/juno/yaml.rb +0 -9
- data/test/helper.rb +0 -212
- data/test/test_activerecord.rb +0 -33
- data/test/test_cassandra.rb +0 -13
- data/test/test_couch.rb +0 -13
- data/test/test_datamapper.rb +0 -64
- data/test/test_dbm.rb +0 -13
- data/test/test_expires.rb +0 -9
- data/test/test_file.rb +0 -9
- data/test/test_fog.rb +0 -17
- data/test/test_gdbm.rb +0 -13
- data/test/test_hashfile.rb +0 -9
- data/test/test_localmemcache.rb +0 -13
- data/test/test_memcached.rb +0 -14
- data/test/test_memcached_dalli.rb +0 -14
- data/test/test_memcached_native.rb +0 -14
- data/test/test_memory.rb +0 -9
- data/test/test_mongodb.rb +0 -13
- data/test/test_null.rb +0 -9
- data/test/test_proxy.rb +0 -9
- data/test/test_pstore.rb +0 -9
- data/test/test_redis.rb +0 -13
- data/test/test_riak.rb +0 -13
- data/test/test_sdbm.rb +0 -13
- data/test/test_sequel.rb +0 -13
- data/test/test_sqlite.rb +0 -13
- data/test/test_stack.rb +0 -10
- data/test/test_tokyocabinet.rb +0 -13
- data/test/test_yaml.rb +0 -9
- data/unsupported/test_tokyotyrant.rb +0 -13
- data/unsupported/tokyotyrant.rb +0 -29
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
require 'localmemcache'
|
|
2
|
+
|
|
3
|
+
module Juno
|
|
4
|
+
module Adapters
|
|
5
|
+
class LocalMemCache < Memory
|
|
6
|
+
def initialize(options = {})
|
|
7
|
+
raise 'No option :file specified' unless options[:file]
|
|
8
|
+
@memory = ::LocalMemCache.new(:filename => options[:file])
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def delete(key, options = {})
|
|
12
|
+
value = load(key, options)
|
|
13
|
+
@memory.delete(key)
|
|
14
|
+
value
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
require 'dalli'
|
|
2
|
+
|
|
3
|
+
module Juno
|
|
4
|
+
module Adapters
|
|
5
|
+
class MemcachedDalli < Base
|
|
6
|
+
def initialize(options = {})
|
|
7
|
+
server = options.delete(:server) || 'localhost:11211'
|
|
8
|
+
@cache = ::Dalli::Client.new(server, options)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def key?(key, options = {})
|
|
12
|
+
!!@cache.get(key)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def load(key, options = {})
|
|
16
|
+
value = @cache.get(key)
|
|
17
|
+
if value && options.include?(:expires)
|
|
18
|
+
store(key, value, options)
|
|
19
|
+
else
|
|
20
|
+
value
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def store(key, value, options = {})
|
|
25
|
+
@cache.set(key, value, options[:expires])
|
|
26
|
+
value
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def delete(key, options = {})
|
|
30
|
+
value = @cache.get(key)
|
|
31
|
+
@cache.delete(key)
|
|
32
|
+
value
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def clear(options = {})
|
|
36
|
+
@cache.flush_all
|
|
37
|
+
self
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def close
|
|
41
|
+
@cache.close
|
|
42
|
+
nil
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
require 'memcached'
|
|
2
|
+
|
|
3
|
+
module Juno
|
|
4
|
+
module Adapters
|
|
5
|
+
class MemcachedNative < Base
|
|
6
|
+
def initialize(options = {})
|
|
7
|
+
server = options.delete(:server) || 'localhost:11211'
|
|
8
|
+
options.merge!(:prefix_key => options.delete(:namespace)) if options[:namespace]
|
|
9
|
+
@cache = ::Memcached.new(server, options)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def key?(key, options = {})
|
|
13
|
+
@cache.get(key, false)
|
|
14
|
+
true
|
|
15
|
+
rescue ::Memcached::NotFound
|
|
16
|
+
false
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def load(key, options = {})
|
|
20
|
+
value = @cache.get(key, false)
|
|
21
|
+
if value && options.include?(:expires)
|
|
22
|
+
store(key, value, options)
|
|
23
|
+
else
|
|
24
|
+
value
|
|
25
|
+
end
|
|
26
|
+
rescue ::Memcached::NotFound
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def delete(key, options = {})
|
|
30
|
+
value = @cache.get(key, false)
|
|
31
|
+
@cache.delete(key)
|
|
32
|
+
value
|
|
33
|
+
rescue ::Memcached::NotFound
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def store(key, value, options = {})
|
|
37
|
+
@cache.set(key, value, options[:expires] || @cache.options[:default_ttl], false)
|
|
38
|
+
value
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def clear(options = {})
|
|
42
|
+
@cache.flush
|
|
43
|
+
self
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
module Juno
|
|
2
|
+
module Adapters
|
|
3
|
+
class Memory < Base
|
|
4
|
+
def initialize(options = {})
|
|
5
|
+
@memory = {}
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def key?(key, options = {})
|
|
9
|
+
@memory.has_key?(key)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def load(key, options = {})
|
|
13
|
+
@memory[key]
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def store(key, value, options = {})
|
|
17
|
+
@memory[key] = value
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def delete(key, options = {})
|
|
21
|
+
@memory.delete(key)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def clear(options = {})
|
|
25
|
+
@memory.clear
|
|
26
|
+
self
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
require 'mongo'
|
|
2
|
+
|
|
3
|
+
module Juno
|
|
4
|
+
module Adapters
|
|
5
|
+
class Mongo < 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
|
+
@collection = connection.db(db).collection(collection)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def key?(key, options = {})
|
|
16
|
+
!!load(key, options)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def load(key, options = {})
|
|
20
|
+
value = @collection.find_one('_id' => key)
|
|
21
|
+
value ? value['data'] : nil
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def delete(key, options = {})
|
|
25
|
+
value = load(key, options)
|
|
26
|
+
@collection.remove('_id' => key) if value
|
|
27
|
+
value
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def store(key, value, options = {})
|
|
31
|
+
@collection.update({ '_id' => key },
|
|
32
|
+
{ '_id' => key, 'data' => value },
|
|
33
|
+
{ :upsert => true })
|
|
34
|
+
value
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def clear(options = {})
|
|
38
|
+
@collection.remove
|
|
39
|
+
self
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
module Juno
|
|
2
|
+
module Adapters
|
|
3
|
+
class Null < Base
|
|
4
|
+
def initialize(options = {})
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def key?(key, options = {})
|
|
8
|
+
false
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def load(key, options = {})
|
|
12
|
+
nil
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def store(key, value, options = {})
|
|
16
|
+
value
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def delete(key, options = {})
|
|
20
|
+
nil
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def clear(options = {})
|
|
24
|
+
self
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
require 'pstore'
|
|
2
|
+
|
|
3
|
+
module Juno
|
|
4
|
+
module Adapters
|
|
5
|
+
class PStore < Base
|
|
6
|
+
def initialize(options = {})
|
|
7
|
+
raise 'No option :file specified' unless options[:file]
|
|
8
|
+
FileUtils.mkpath(::File.dirname(options[:file]))
|
|
9
|
+
@pstore = new_store(options)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def key?(key, options = {})
|
|
13
|
+
@pstore.transaction(true) { @pstore.root?(key) }
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def load(key, options = {})
|
|
17
|
+
@pstore.transaction(true) { @pstore[key] }
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def delete(key, options = {})
|
|
21
|
+
@pstore.transaction { @pstore.delete(key) }
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def store(key, value, options = {})
|
|
25
|
+
@pstore.transaction { @pstore[key] = value }
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def clear(options = {})
|
|
29
|
+
@pstore.transaction do
|
|
30
|
+
@pstore.roots.each do |key|
|
|
31
|
+
@pstore.delete(key)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
self
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
protected
|
|
38
|
+
|
|
39
|
+
if RUBY_VERSION > '1.9'
|
|
40
|
+
def new_store(options)
|
|
41
|
+
# Create a thread-safe pstore by default
|
|
42
|
+
::PStore.new(options[:file], options.include?(:thread_safe) ? options[:thread_safe] : true)
|
|
43
|
+
end
|
|
44
|
+
else
|
|
45
|
+
def new_store(options)
|
|
46
|
+
::PStore.new(options[:file])
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
require 'redis'
|
|
2
|
+
|
|
3
|
+
module Juno
|
|
4
|
+
module Adapters
|
|
5
|
+
class Redis < Base
|
|
6
|
+
def initialize(options = {})
|
|
7
|
+
@redis = ::Redis.new(options)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def key?(key, options = {})
|
|
11
|
+
@redis.exists(key)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def load(key, options = {})
|
|
15
|
+
value = @redis.get(key)
|
|
16
|
+
if value && (expires = options[:expires])
|
|
17
|
+
@redis.expire(key, expires)
|
|
18
|
+
end
|
|
19
|
+
value
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def delete(key, options = {})
|
|
23
|
+
if value = load(key, options)
|
|
24
|
+
@redis.del(key)
|
|
25
|
+
value
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def store(key, value, options = {})
|
|
30
|
+
@redis.set(key, value)
|
|
31
|
+
if expires = options[:expires]
|
|
32
|
+
@redis.expire(key, expires)
|
|
33
|
+
end
|
|
34
|
+
value
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def clear(options = {})
|
|
38
|
+
@redis.flushdb
|
|
39
|
+
self
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Copyright: 2011 TMX Credit
|
|
2
|
+
# Author: Potapov Sergey (aka Blake)
|
|
3
|
+
|
|
4
|
+
require 'riak'
|
|
5
|
+
|
|
6
|
+
module Juno
|
|
7
|
+
module Adapters
|
|
8
|
+
class Riak < Base
|
|
9
|
+
def initialize(options = {})
|
|
10
|
+
bucket = options.delete(:bucket) || 'juno'
|
|
11
|
+
@bucket = ::Riak::Client.new(options).bucket(bucket)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def key?(key, options = {})
|
|
15
|
+
@bucket.exists?(key, options)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def load(key, options = {})
|
|
19
|
+
@bucket.get(key, options).raw_data
|
|
20
|
+
rescue ::Riak::FailedRequest => ex
|
|
21
|
+
nil
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def delete(key, options = {})
|
|
25
|
+
value = load(key, options)
|
|
26
|
+
@bucket.delete(key, options)
|
|
27
|
+
value
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def store(key, value, options = {})
|
|
31
|
+
obj = ::Riak::RObject.new(@bucket, key)
|
|
32
|
+
obj.content_type = 'application/octet-stream'
|
|
33
|
+
obj.raw_data = value
|
|
34
|
+
obj.store(options)
|
|
35
|
+
value
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def clear(options = {})
|
|
39
|
+
@bucket.keys do |keys|
|
|
40
|
+
keys.each{ |key| @bucket.delete(key) }
|
|
41
|
+
end
|
|
42
|
+
self
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
require 'sdbm'
|
|
2
|
+
|
|
3
|
+
module Juno
|
|
4
|
+
module Adapters
|
|
5
|
+
class SDBM < Memory
|
|
6
|
+
def initialize(options = {})
|
|
7
|
+
raise 'No option :file specified' unless options[:file]
|
|
8
|
+
@memory = ::SDBM.new(options[:file])
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def close
|
|
12
|
+
@memory.close
|
|
13
|
+
nil
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def store(key, value, options = {})
|
|
17
|
+
super
|
|
18
|
+
value
|
|
19
|
+
rescue SDBMError
|
|
20
|
+
# SDBM is not very robust!
|
|
21
|
+
# You shouldn't put to much data into it, otherwise
|
|
22
|
+
# it might raise a SDBMError.
|
|
23
|
+
value
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
require 'sequel'
|
|
2
|
+
|
|
3
|
+
module Juno
|
|
4
|
+
module Adapters
|
|
5
|
+
class Sequel < Base
|
|
6
|
+
def initialize(options = {})
|
|
7
|
+
raise 'No option :db specified' unless db = options.delete(:db)
|
|
8
|
+
@table = options.delete(:table) || :juno
|
|
9
|
+
@db = ::Sequel.connect(db, options)
|
|
10
|
+
@db.create_table?(@table) do
|
|
11
|
+
primary_key :k
|
|
12
|
+
String :k
|
|
13
|
+
String :v
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def key?(key, options = {})
|
|
18
|
+
!!sequel_table[:k => key]
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def load(key, options = {})
|
|
22
|
+
result = sequel_table[:k => key]
|
|
23
|
+
result ? result[:v] : nil
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def store(key, value, options = {})
|
|
27
|
+
sequel_table.insert(:k => key, :v => value)
|
|
28
|
+
value
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def delete(key, options = {})
|
|
32
|
+
if value = load(key, options)
|
|
33
|
+
sequel_table.filter(:k => key).delete
|
|
34
|
+
value
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def clear(options = {})
|
|
39
|
+
sequel_table.delete
|
|
40
|
+
self
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
private
|
|
44
|
+
|
|
45
|
+
def sequel_table
|
|
46
|
+
@sequel_table ||= @db[@table]
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
require 'sqlite3'
|
|
2
|
+
|
|
3
|
+
module Juno
|
|
4
|
+
module Adapters
|
|
5
|
+
class Sqlite < Base
|
|
6
|
+
def initialize(options = {})
|
|
7
|
+
raise 'No option :file specified' unless options[:file]
|
|
8
|
+
table = options[:table] || 'juno'
|
|
9
|
+
@db = ::SQLite3::Database.new(options[:file])
|
|
10
|
+
@db.execute("create table if not exists #{table} (key string primary key, value string)")
|
|
11
|
+
@select = @db.prepare("select value from #{table} where key = ?")
|
|
12
|
+
@insert = @db.prepare("insert into #{table} values (?, ?)")
|
|
13
|
+
@delete = @db.prepare("delete from #{table} where key = ?")
|
|
14
|
+
@clear = @db.prepare("delete from #{table}")
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def key?(key, options = {})
|
|
18
|
+
!@select.execute!(key).empty?
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def load(key, options = {})
|
|
22
|
+
rows = @select.execute!(key)
|
|
23
|
+
rows.empty? ? nil : rows.first.first
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def store(key, value, options = {})
|
|
27
|
+
@insert.execute!(key, value)
|
|
28
|
+
value
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def delete(key, options = {})
|
|
32
|
+
value = load(key, options)
|
|
33
|
+
@delete.execute!(key)
|
|
34
|
+
value
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def clear(options = {})
|
|
38
|
+
@clear.execute!
|
|
39
|
+
self
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def close
|
|
43
|
+
@select.close
|
|
44
|
+
@insert.close
|
|
45
|
+
@delete.close
|
|
46
|
+
@clear.close
|
|
47
|
+
@db.close
|
|
48
|
+
nil
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
require 'tokyocabinet'
|
|
2
|
+
|
|
3
|
+
module Juno
|
|
4
|
+
module Adapters
|
|
5
|
+
class TokyoCabinet < Memory
|
|
6
|
+
def initialize(options = {})
|
|
7
|
+
file = options[:file]
|
|
8
|
+
raise 'No option :file specified' unless options[:file]
|
|
9
|
+
@memory = ::TokyoCabinet::HDB.new
|
|
10
|
+
unless @memory.open(file, ::TokyoCabinet::HDB::OWRITER | ::TokyoCabinet::HDB::OCREAT)
|
|
11
|
+
raise @memory.errmsg(@memory.ecode)
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def key?(key, options = {})
|
|
16
|
+
!!load(key, options)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def delete(key, options = {})
|
|
20
|
+
value = load(key, options)
|
|
21
|
+
if value
|
|
22
|
+
@memory.delete(key)
|
|
23
|
+
value
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def close
|
|
28
|
+
@memory.close
|
|
29
|
+
nil
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
data/lib/juno/base.rb
CHANGED
|
@@ -1,72 +1,29 @@
|
|
|
1
1
|
module Juno
|
|
2
2
|
# Simple interface to key/value stores with Hash-like interface.
|
|
3
|
-
#
|
|
4
|
-
# @abstract
|
|
5
3
|
class Base
|
|
6
|
-
#
|
|
7
|
-
#
|
|
8
|
-
# @param [Object] key
|
|
9
|
-
# @return [Boolean]
|
|
10
|
-
# @param [Hash] options
|
|
11
|
-
# @api public
|
|
12
|
-
def key?(key, options = {})
|
|
13
|
-
@store.has_key?(key_for(key))
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
def has_key?(key, options = {})
|
|
17
|
-
key?(key, options)
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
# Fetch value with key. Return nil if the key doesn't exist
|
|
21
|
-
#
|
|
22
|
-
# @param [Object] key
|
|
23
|
-
# @return [Object] value
|
|
24
|
-
# @api public
|
|
25
|
-
def [](key)
|
|
26
|
-
deserialize(@store[key_for(key)])
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
# Store value with key
|
|
30
|
-
#
|
|
31
|
-
# @param [Object] key
|
|
32
|
-
# @param [Object] value
|
|
33
|
-
# @param [Hash] options
|
|
34
|
-
# @return value
|
|
4
|
+
# Explicitly close the store
|
|
35
5
|
# @api public
|
|
36
|
-
def
|
|
37
|
-
@store[key_for(key)] = serialize(value)
|
|
38
|
-
value
|
|
6
|
+
def close
|
|
39
7
|
end
|
|
40
8
|
|
|
41
|
-
#
|
|
9
|
+
# Fetch value with key. Return default if value is nil.
|
|
42
10
|
#
|
|
43
11
|
# @param [Object] key
|
|
44
|
-
# @
|
|
45
|
-
# @param [Hash] options
|
|
46
|
-
# @api public
|
|
47
|
-
def delete(key, options = {})
|
|
48
|
-
deserialize(@store.delete(key_for(key)))
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
# Clear all keys in this store
|
|
52
|
-
#
|
|
12
|
+
# @param [Object] value Default value
|
|
53
13
|
# @param [Hash] options
|
|
54
|
-
# @return [
|
|
14
|
+
# @return [Object] value from store
|
|
55
15
|
# @api public
|
|
56
|
-
def
|
|
57
|
-
|
|
58
|
-
nil
|
|
16
|
+
def fetch(key, value = nil, options = {})
|
|
17
|
+
load(key, options) || (block_given? && yield(key)) || value
|
|
59
18
|
end
|
|
60
19
|
|
|
61
|
-
# Fetch value with key. Return
|
|
20
|
+
# Fetch value with key. Return nil if the key doesn't exist
|
|
62
21
|
#
|
|
63
22
|
# @param [Object] key
|
|
64
|
-
# @
|
|
65
|
-
# @param [Hash] options
|
|
66
|
-
# @return [Object] value from store
|
|
23
|
+
# @return [Object] value
|
|
67
24
|
# @api public
|
|
68
|
-
def
|
|
69
|
-
|
|
25
|
+
def [](key)
|
|
26
|
+
load(key)
|
|
70
27
|
end
|
|
71
28
|
|
|
72
29
|
# Store value with key
|
|
@@ -78,40 +35,5 @@ module Juno
|
|
|
78
35
|
def []=(key, value)
|
|
79
36
|
store(key, value)
|
|
80
37
|
end
|
|
81
|
-
|
|
82
|
-
# Explicitly close the store
|
|
83
|
-
# @api public
|
|
84
|
-
def close
|
|
85
|
-
nil
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
protected
|
|
89
|
-
|
|
90
|
-
# Serialize value
|
|
91
|
-
#
|
|
92
|
-
# @param [Object] value Serializable object
|
|
93
|
-
# @return [String] serialized object
|
|
94
|
-
# @api private
|
|
95
|
-
def serialize(value)
|
|
96
|
-
Marshal.dump(value)
|
|
97
|
-
end
|
|
98
|
-
|
|
99
|
-
# Deserialize value
|
|
100
|
-
#
|
|
101
|
-
# @param [String] value Serialized object
|
|
102
|
-
# @return [Object] Deserialized object
|
|
103
|
-
# @api private
|
|
104
|
-
def deserialize(value)
|
|
105
|
-
value && Marshal.load(value)
|
|
106
|
-
end
|
|
107
|
-
|
|
108
|
-
# Convert key to string
|
|
109
|
-
#
|
|
110
|
-
# @param [Object] key Key
|
|
111
|
-
# @return [String] Marshalled key
|
|
112
|
-
# @api private
|
|
113
|
-
def key_for(key)
|
|
114
|
-
String === key ? key : Marshal.dump(key)
|
|
115
|
-
end
|
|
116
38
|
end
|
|
117
39
|
end
|