juno 0.3.1 → 0.4.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/README.md +2 -277
- data/juno.gemspec +6 -5
- data/lib/juno.rb +3 -122
- metadata +23 -307
- data/.gitignore +0 -6
- data/.travis.yml +0 -30
- data/Gemfile +0 -56
- data/LICENSE +0 -20
- data/Rakefile +0 -33
- data/SPEC.md +0 -71
- data/benchmarks/run.rb +0 -180
- data/lib/juno/adapters/activerecord.rb +0 -74
- data/lib/juno/adapters/cassandra.rb +0 -89
- data/lib/juno/adapters/cookie.rb +0 -35
- data/lib/juno/adapters/couch.rb +0 -57
- data/lib/juno/adapters/datamapper.rb +0 -76
- data/lib/juno/adapters/dbm.rb +0 -25
- data/lib/juno/adapters/file.rb +0 -60
- data/lib/juno/adapters/fog.rb +0 -51
- data/lib/juno/adapters/gdbm.rb +0 -25
- data/lib/juno/adapters/hbase.rb +0 -64
- data/lib/juno/adapters/leveldb.rb +0 -35
- data/lib/juno/adapters/localmemcache.rb +0 -26
- data/lib/juno/adapters/lruhash.rb +0 -83
- data/lib/juno/adapters/memcached.rb +0 -11
- data/lib/juno/adapters/memcached_dalli.rb +0 -51
- data/lib/juno/adapters/memcached_native.rb +0 -52
- data/lib/juno/adapters/memory.rb +0 -32
- data/lib/juno/adapters/mongo.rb +0 -50
- data/lib/juno/adapters/null.rb +0 -30
- data/lib/juno/adapters/pstore.rb +0 -58
- data/lib/juno/adapters/redis.rb +0 -56
- data/lib/juno/adapters/riak.rb +0 -57
- data/lib/juno/adapters/sdbm.rb +0 -35
- data/lib/juno/adapters/sequel.rb +0 -67
- data/lib/juno/adapters/sqlite.rb +0 -61
- data/lib/juno/adapters/tokyocabinet.rb +0 -41
- data/lib/juno/adapters/yaml.rb +0 -15
- data/lib/juno/base.rb +0 -62
- data/lib/juno/builder.rb +0 -39
- data/lib/juno/cache.rb +0 -78
- data/lib/juno/expires.rb +0 -47
- data/lib/juno/lock.rb +0 -44
- data/lib/juno/logger.rb +0 -86
- data/lib/juno/proxy.rb +0 -72
- data/lib/juno/stack.rb +0 -72
- data/lib/juno/transformer.rb +0 -176
- data/lib/juno/version.rb +0 -5
- data/lib/rack/cache/juno.rb +0 -93
- data/lib/rack/juno_cookies.rb +0 -64
- data/lib/rack/session/juno.rb +0 -63
- data/spec/generate.rb +0 -1068
- data/spec/helper.rb +0 -78
- data/spec/juno/adapter_activerecord_spec.rb +0 -27
- data/spec/juno/adapter_cassandra_spec.rb +0 -13
- data/spec/juno/adapter_cookie_spec.rb +0 -13
- data/spec/juno/adapter_couch_spec.rb +0 -13
- data/spec/juno/adapter_datamapper_spec.rb +0 -44
- data/spec/juno/adapter_dbm_spec.rb +0 -13
- data/spec/juno/adapter_file_spec.rb +0 -13
- data/spec/juno/adapter_fog_spec.rb +0 -18
- data/spec/juno/adapter_gdbm_spec.rb +0 -13
- data/spec/juno/adapter_hbase_spec.rb +0 -13
- data/spec/juno/adapter_leveldb_spec.rb +0 -13
- data/spec/juno/adapter_localmemcache_spec.rb +0 -13
- data/spec/juno/adapter_lruhash_spec.rb +0 -26
- data/spec/juno/adapter_memcached_dalli_spec.rb +0 -14
- data/spec/juno/adapter_memcached_native_spec.rb +0 -14
- data/spec/juno/adapter_memcached_spec.rb +0 -14
- data/spec/juno/adapter_memory_spec.rb +0 -34
- data/spec/juno/adapter_mongo_spec.rb +0 -13
- data/spec/juno/adapter_pstore_spec.rb +0 -16
- data/spec/juno/adapter_redis_spec.rb +0 -14
- data/spec/juno/adapter_riak_spec.rb +0 -17
- data/spec/juno/adapter_sdbm_spec.rb +0 -13
- data/spec/juno/adapter_sequel_spec.rb +0 -13
- data/spec/juno/adapter_sqlite_spec.rb +0 -13
- data/spec/juno/adapter_tokyocabinet_bdb_spec.rb +0 -13
- data/spec/juno/adapter_tokyocabinet_hdb_spec.rb +0 -13
- data/spec/juno/adapter_yaml_spec.rb +0 -16
- data/spec/juno/cache_file_memory_spec.rb +0 -29
- data/spec/juno/cache_memory_null_spec.rb +0 -18
- data/spec/juno/expires_file_spec.rb +0 -71
- data/spec/juno/expires_memory_spec.rb +0 -49
- data/spec/juno/lock_spec.rb +0 -37
- data/spec/juno/null_adapter_spec.rb +0 -22
- data/spec/juno/proxy_expires_memory_spec.rb +0 -51
- data/spec/juno/proxy_redis_spec.rb +0 -18
- data/spec/juno/simple_activerecord_spec.rb +0 -45
- data/spec/juno/simple_activerecord_with_expires_spec.rb +0 -46
- data/spec/juno/simple_cassandra_spec.rb +0 -46
- data/spec/juno/simple_couch_spec.rb +0 -45
- data/spec/juno/simple_couch_with_expires_spec.rb +0 -46
- data/spec/juno/simple_datamapper_spec.rb +0 -47
- data/spec/juno/simple_datamapper_with_expires_spec.rb +0 -48
- data/spec/juno/simple_datamapper_with_repository_spec.rb +0 -47
- data/spec/juno/simple_dbm_spec.rb +0 -45
- data/spec/juno/simple_dbm_with_expires_spec.rb +0 -46
- data/spec/juno/simple_file_spec.rb +0 -45
- data/spec/juno/simple_file_with_expires_spec.rb +0 -46
- data/spec/juno/simple_fog_spec.rb +0 -50
- data/spec/juno/simple_fog_with_expires_spec.rb +0 -52
- data/spec/juno/simple_gdbm_spec.rb +0 -45
- data/spec/juno/simple_gdbm_with_expires_spec.rb +0 -46
- data/spec/juno/simple_hashfile_spec.rb +0 -45
- data/spec/juno/simple_hashfile_with_expires_spec.rb +0 -46
- data/spec/juno/simple_hbase_spec.rb +0 -45
- data/spec/juno/simple_hbase_with_expires_spec.rb +0 -46
- data/spec/juno/simple_leveldb_spec.rb +0 -45
- data/spec/juno/simple_leveldb_with_expires_spec.rb +0 -46
- data/spec/juno/simple_localmemcache_spec.rb +0 -45
- data/spec/juno/simple_localmemcache_with_expires_spec.rb +0 -46
- data/spec/juno/simple_lruhash_spec.rb +0 -45
- data/spec/juno/simple_lruhash_with_expires_spec.rb +0 -46
- data/spec/juno/simple_memcached_dalli_spec.rb +0 -46
- data/spec/juno/simple_memcached_native_spec.rb +0 -46
- data/spec/juno/simple_memcached_spec.rb +0 -46
- data/spec/juno/simple_memory_spec.rb +0 -45
- data/spec/juno/simple_memory_with_compress_spec.rb +0 -45
- data/spec/juno/simple_memory_with_expires_spec.rb +0 -46
- data/spec/juno/simple_memory_with_json_key_serializer_spec.rb +0 -32
- data/spec/juno/simple_memory_with_json_md5_key_serializer_spec.rb +0 -32
- data/spec/juno/simple_memory_with_json_serializer_spec.rb +0 -22
- data/spec/juno/simple_memory_with_json_value_serializer_spec.rb +0 -29
- data/spec/juno/simple_memory_with_prefix_spec.rb +0 -45
- data/spec/juno/simple_memory_with_quicklz_compress_spec.rb +0 -45
- data/spec/juno/simple_mongo_spec.rb +0 -45
- data/spec/juno/simple_mongo_with_expires_spec.rb +0 -46
- data/spec/juno/simple_null_spec.rb +0 -32
- data/spec/juno/simple_pstore_spec.rb +0 -45
- data/spec/juno/simple_pstore_with_expires_spec.rb +0 -46
- data/spec/juno/simple_redis_spec.rb +0 -46
- data/spec/juno/simple_riak_spec.rb +0 -49
- data/spec/juno/simple_riak_with_expires_spec.rb +0 -50
- data/spec/juno/simple_sdbm_spec.rb +0 -45
- data/spec/juno/simple_sdbm_with_expires_spec.rb +0 -46
- data/spec/juno/simple_sequel_spec.rb +0 -45
- data/spec/juno/simple_sequel_with_expires_spec.rb +0 -46
- data/spec/juno/simple_sqlite_spec.rb +0 -45
- data/spec/juno/simple_sqlite_with_expires_spec.rb +0 -46
- data/spec/juno/simple_tokyocabinet_spec.rb +0 -45
- data/spec/juno/simple_tokyocabinet_with_expires_spec.rb +0 -46
- data/spec/juno/simple_yaml_spec.rb +0 -44
- data/spec/juno/simple_yaml_with_expires_spec.rb +0 -45
- data/spec/juno/stack_file_memory_spec.rb +0 -20
- data/spec/juno/stack_memory_file_spec.rb +0 -19
- data/spec/juno/transformer_bencode_spec.rb +0 -25
- data/spec/juno/transformer_bert_spec.rb +0 -25
- data/spec/juno/transformer_bson_spec.rb +0 -25
- data/spec/juno/transformer_bzip2_spec.rb +0 -22
- data/spec/juno/transformer_json_spec.rb +0 -25
- data/spec/juno/transformer_lzma_spec.rb +0 -22
- data/spec/juno/transformer_lzo_spec.rb +0 -22
- data/spec/juno/transformer_marshal_base64_spec.rb +0 -48
- data/spec/juno/transformer_marshal_escape_spec.rb +0 -48
- data/spec/juno/transformer_marshal_hmac_spec.rb +0 -48
- data/spec/juno/transformer_marshal_md5_spec.rb +0 -48
- data/spec/juno/transformer_marshal_md5_spread_spec.rb +0 -48
- data/spec/juno/transformer_marshal_prefix_spec.rb +0 -48
- data/spec/juno/transformer_marshal_rmd160_spec.rb +0 -48
- data/spec/juno/transformer_marshal_sha1_spec.rb +0 -48
- data/spec/juno/transformer_marshal_sha256_spec.rb +0 -48
- data/spec/juno/transformer_marshal_sha384_spec.rb +0 -48
- data/spec/juno/transformer_marshal_sha512_spec.rb +0 -48
- data/spec/juno/transformer_marshal_uuencode_spec.rb +0 -48
- data/spec/juno/transformer_msgpack_spec.rb +0 -25
- data/spec/juno/transformer_ox_spec.rb +0 -46
- data/spec/juno/transformer_quicklz_spec.rb +0 -22
- data/spec/juno/transformer_snappy_spec.rb +0 -22
- data/spec/juno/transformer_tnet_spec.rb +0 -25
- data/spec/juno/transformer_yaml_spec.rb +0 -46
- data/spec/juno/transformer_zlib_spec.rb +0 -22
- data/spec/junospecs.rb +0 -2284
- data/spec/rack/cache_juno_spec.rb +0 -355
- data/spec/rack/juno_cookies_spec.rb +0 -81
- data/spec/rack/session_juno_spec.rb +0 -305
data/lib/juno/expires.rb
DELETED
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
module Juno
|
|
2
|
-
# Adds expiration support to the underlying store
|
|
3
|
-
#
|
|
4
|
-
# #store and #load support the :expires option to set/update
|
|
5
|
-
# the expiration time.
|
|
6
|
-
#
|
|
7
|
-
# @api public
|
|
8
|
-
class Expires < Proxy
|
|
9
|
-
def key?(key, options = {})
|
|
10
|
-
load(key, options) != nil
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
def load(key, options = {})
|
|
14
|
-
value = check_expired(key, super(key, options))
|
|
15
|
-
if value && options.include?(:expires)
|
|
16
|
-
store(key, value, options)
|
|
17
|
-
else
|
|
18
|
-
value
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
def store(key, value, options = {})
|
|
23
|
-
if expires = options.delete(:expires)
|
|
24
|
-
super(key, [value, Time.now.to_i + expires].compact, options)
|
|
25
|
-
else
|
|
26
|
-
super(key, [value], options)
|
|
27
|
-
end
|
|
28
|
-
value
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
def delete(key, options = {})
|
|
32
|
-
check_expired(key, super, false)
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
protected
|
|
36
|
-
|
|
37
|
-
def check_expired(key, value, delete_expired = true)
|
|
38
|
-
value, expires = value
|
|
39
|
-
if expires && Time.now.to_i > expires
|
|
40
|
-
delete(key) if delete_expired
|
|
41
|
-
nil
|
|
42
|
-
else
|
|
43
|
-
value
|
|
44
|
-
end
|
|
45
|
-
end
|
|
46
|
-
end
|
|
47
|
-
end
|
data/lib/juno/lock.rb
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
require 'thread'
|
|
2
|
-
|
|
3
|
-
module Juno
|
|
4
|
-
# Locks the underlying stores with a Mutex
|
|
5
|
-
# @api public
|
|
6
|
-
class Lock < Proxy
|
|
7
|
-
# Constructor
|
|
8
|
-
#
|
|
9
|
-
# @param [Juno store] adapter The underlying store
|
|
10
|
-
# @param [Hash] options
|
|
11
|
-
#
|
|
12
|
-
# Options:
|
|
13
|
-
# * :mutex - Mutex object (default Mutex.new)
|
|
14
|
-
def initialize(adapter, options = {})
|
|
15
|
-
super
|
|
16
|
-
@lock = options[:mutex] || Mutex.new
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
def key?(key, options = {})
|
|
20
|
-
@lock.synchronize { super }
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
def load(key, options = {})
|
|
24
|
-
@lock.synchronize { super }
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
def store(key, value, options = {})
|
|
28
|
-
@lock.synchronize { super }
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
def delete(key, options = {})
|
|
32
|
-
@lock.synchronize { super }
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
def clear(options = {})
|
|
36
|
-
@lock.synchronize { super }
|
|
37
|
-
self
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
def close
|
|
41
|
-
@lock.synchronize { super }
|
|
42
|
-
end
|
|
43
|
-
end
|
|
44
|
-
end
|
data/lib/juno/logger.rb
DELETED
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
module Juno
|
|
2
|
-
# Logger proxy
|
|
3
|
-
# @api public
|
|
4
|
-
class Logger < Proxy
|
|
5
|
-
# Standard formatter used by the logger
|
|
6
|
-
# @api public
|
|
7
|
-
class Format
|
|
8
|
-
def initialize(options)
|
|
9
|
-
@prefix = options[:prefix] || 'Juno '
|
|
10
|
-
@out = options[:out] || STDOUT
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
def call(entry)
|
|
14
|
-
@out.write(format(entry))
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
protected
|
|
18
|
-
|
|
19
|
-
def format(entry)
|
|
20
|
-
args = entry[:args]
|
|
21
|
-
args.pop if Hash === args.last && args.last.empty?
|
|
22
|
-
args = args.map {|a| dump(a) }.join(', ')
|
|
23
|
-
if entry[:error]
|
|
24
|
-
"#{@prefix}#{entry[:method]}(#{args}) raised error: #{entry[:error].message}\n"
|
|
25
|
-
else
|
|
26
|
-
"#{@prefix}#{entry[:method]}(#{args}) -> #{dump entry[:return]}\n"
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
def dump(value)
|
|
31
|
-
value = value.inspect
|
|
32
|
-
value.size > 30 ? value[0..30] + '...' : value
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
# Constructor
|
|
37
|
-
#
|
|
38
|
-
# @param [Juno store] adapter The underlying store
|
|
39
|
-
# @param [Hash] options
|
|
40
|
-
#
|
|
41
|
-
# Options:
|
|
42
|
-
# * :logger - Callable logger object (default Juno::Logger::Format)
|
|
43
|
-
# * :logprefix - Prefix string (default 'Juno ')
|
|
44
|
-
# * :logout - Output (default STDOUT)
|
|
45
|
-
def initialize(adapter, options = {})
|
|
46
|
-
super
|
|
47
|
-
@logger = options[:logger] || Format.new(options)
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
def key?(key, options = {})
|
|
51
|
-
log(:key?, key, options) { super }
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
def load(key, options = {})
|
|
55
|
-
log(:load, key, options) { super }
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
def store(key, value, options = {})
|
|
59
|
-
log(:store, key, value, options) { super }
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
def delete(key, options = {})
|
|
63
|
-
log(:delete, key, options) { super }
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
def clear(options = {})
|
|
67
|
-
log(:clear, options) { super; nil }
|
|
68
|
-
self
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
def close
|
|
72
|
-
log(:close) { super }
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
protected
|
|
76
|
-
|
|
77
|
-
def log(method, *args)
|
|
78
|
-
ret = yield
|
|
79
|
-
@logger.call(:method => method, :args => args, :return => ret)
|
|
80
|
-
ret
|
|
81
|
-
rescue Exception => error
|
|
82
|
-
@logger.call(:method => method, :args => args, :error => error)
|
|
83
|
-
raise
|
|
84
|
-
end
|
|
85
|
-
end
|
|
86
|
-
end
|
data/lib/juno/proxy.rb
DELETED
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
module Juno
|
|
2
|
-
# Proxy base class
|
|
3
|
-
# @api public
|
|
4
|
-
class Proxy < Base
|
|
5
|
-
attr_reader :adapter
|
|
6
|
-
|
|
7
|
-
# Constructor
|
|
8
|
-
#
|
|
9
|
-
# @param [Juno store] underlying adapter
|
|
10
|
-
# @param [Hash] options
|
|
11
|
-
def initialize(adapter, options = {})
|
|
12
|
-
@adapter = adapter
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
# Exists the value with key
|
|
16
|
-
#
|
|
17
|
-
# @param [Object] key
|
|
18
|
-
# @return [Boolean]
|
|
19
|
-
# @param [Hash] options
|
|
20
|
-
# @api public
|
|
21
|
-
def key?(key, options = {})
|
|
22
|
-
@adapter.key?(key, options)
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
# Fetch value with key. Return nil if the key doesn't exist
|
|
26
|
-
#
|
|
27
|
-
# @param [Object] key
|
|
28
|
-
# @param [Hash] options
|
|
29
|
-
# @return [Object] value
|
|
30
|
-
# @api public
|
|
31
|
-
def load(key, options = {})
|
|
32
|
-
@adapter.load(key, options)
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
# Store value with key
|
|
36
|
-
#
|
|
37
|
-
# @param [Object] key
|
|
38
|
-
# @param [Object] value
|
|
39
|
-
# @param [Hash] options
|
|
40
|
-
# @return value
|
|
41
|
-
# @api public
|
|
42
|
-
def store(key, value, options = {})
|
|
43
|
-
@adapter.store(key, value, options)
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
# Delete the key from the store and return the current value
|
|
47
|
-
#
|
|
48
|
-
# @param [Object] key
|
|
49
|
-
# @return [Object] current value
|
|
50
|
-
# @param [Hash] options
|
|
51
|
-
# @api public
|
|
52
|
-
def delete(key, options = {})
|
|
53
|
-
@adapter.delete(key, options)
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
# Clear all keys in this store
|
|
57
|
-
#
|
|
58
|
-
# @param [Hash] options
|
|
59
|
-
# @return [void]
|
|
60
|
-
# @api public
|
|
61
|
-
def clear(options = {})
|
|
62
|
-
@adapter.clear(options)
|
|
63
|
-
self
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
# Close this store
|
|
67
|
-
# @api public
|
|
68
|
-
def close
|
|
69
|
-
@adapter.close
|
|
70
|
-
end
|
|
71
|
-
end
|
|
72
|
-
end
|
data/lib/juno/stack.rb
DELETED
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
module Juno
|
|
2
|
-
# Combines multiple stores. Reads return the result from the first store,
|
|
3
|
-
# writes go to all stores.
|
|
4
|
-
#
|
|
5
|
-
# @example Add stack to chain
|
|
6
|
-
# Juno.build do
|
|
7
|
-
# use(:Stack) do
|
|
8
|
-
# add { adapter :Redis }
|
|
9
|
-
# add { adapter :File, :dir => 'data' }
|
|
10
|
-
# add { adapter :File, :dir => 'replicate' }
|
|
11
|
-
# end
|
|
12
|
-
# end
|
|
13
|
-
#
|
|
14
|
-
# @api public
|
|
15
|
-
class Stack < Base
|
|
16
|
-
# @api private
|
|
17
|
-
class DSL
|
|
18
|
-
attr_reader :stack
|
|
19
|
-
|
|
20
|
-
def initialize(options, &block)
|
|
21
|
-
@stack = options[:stack].to_a
|
|
22
|
-
instance_eval(&block)
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
def add(store = nil, &block)
|
|
26
|
-
raise ArgumentError, 'Only argument or block allowed' if store && block
|
|
27
|
-
@stack << (store || Juno.build(&block))
|
|
28
|
-
nil
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
attr_reader :stack
|
|
33
|
-
|
|
34
|
-
def initialize(options = {}, &block)
|
|
35
|
-
@stack = DSL.new(options, &block).stack
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
def key?(key, options = {})
|
|
39
|
-
@stack.any? {|s| s.key?(key) }
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
def load(key, options = {})
|
|
43
|
-
@stack.each do |s|
|
|
44
|
-
value = s.load(key, options)
|
|
45
|
-
return value if value
|
|
46
|
-
end
|
|
47
|
-
nil
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
def store(key, value, options = {})
|
|
51
|
-
@stack.each {|s| s.store(key, value, options) }
|
|
52
|
-
value
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
def delete(key, options = {})
|
|
56
|
-
@stack.inject(nil) do |value, s|
|
|
57
|
-
v = s.delete(key, options)
|
|
58
|
-
value || v
|
|
59
|
-
end
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
def clear(options = {})
|
|
63
|
-
@stack.each {|s| s.clear }
|
|
64
|
-
self
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
def close
|
|
68
|
-
@stack.each {|s| s.close }
|
|
69
|
-
nil
|
|
70
|
-
end
|
|
71
|
-
end
|
|
72
|
-
end
|
data/lib/juno/transformer.rb
DELETED
|
@@ -1,176 +0,0 @@
|
|
|
1
|
-
module Juno
|
|
2
|
-
# Transforms keys and values (Marshal, YAML, JSON, Base64, MD5, ...).
|
|
3
|
-
#
|
|
4
|
-
# @example Add transformer to chain
|
|
5
|
-
# Juno.build do
|
|
6
|
-
# transformer :key => [:marshal, :escape], :value => [:marshal]
|
|
7
|
-
# adapter :File, :dir => 'data'
|
|
8
|
-
# end
|
|
9
|
-
#
|
|
10
|
-
# @api public
|
|
11
|
-
class Transformer < Proxy
|
|
12
|
-
def initialize(adapter, options = {})
|
|
13
|
-
super
|
|
14
|
-
@prefix, @secret = options[:prefix], options[:secret]
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
class << self
|
|
18
|
-
alias_method :original_new, :new
|
|
19
|
-
|
|
20
|
-
# Constructor
|
|
21
|
-
#
|
|
22
|
-
# @param [Juno store] adapter The underlying store
|
|
23
|
-
# @param [Hash] options
|
|
24
|
-
#
|
|
25
|
-
# Options:
|
|
26
|
-
# * :key - List of key transformers in the order in which they should be applied
|
|
27
|
-
# * :value - List of value transformers in the order in which they should be applied
|
|
28
|
-
# * :prefix - Prefix string for key namespacing (Used by the :prefix key transformer)
|
|
29
|
-
# * :secret - HMAC secret to verify values (Used by the :hmac value transformer)
|
|
30
|
-
def new(adapter, options = {})
|
|
31
|
-
keys = [options[:key]].flatten.compact
|
|
32
|
-
values = [options[:value]].flatten.compact
|
|
33
|
-
raise ArgumentError, 'Option :key or :value is required' if keys.empty? && values.empty?
|
|
34
|
-
raise ArgumentError, 'Option :prefix is required for :prefix key transformer' if keys.include?(:prefix) && !options[:prefix]
|
|
35
|
-
raise ArgumentError, 'Option :secret is required for :hmac value transformer' if values.include?(:hmac) && !options[:secret]
|
|
36
|
-
name = class_name(keys, values)
|
|
37
|
-
const_set(name, compile(keys, values)) unless const_defined?(name)
|
|
38
|
-
const_get(name).original_new(adapter, options)
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
private
|
|
42
|
-
|
|
43
|
-
def compile(keys, values)
|
|
44
|
-
raise ArgumentError, 'Invalid key transformer chain' if KEY_TRANSFORMER !~ keys.map(&:inspect).join
|
|
45
|
-
raise ArgumentError, 'Invalid value transformer chain' if VALUE_TRANSFORMER !~ values.map(&:inspect).join
|
|
46
|
-
|
|
47
|
-
key = compile_transformer(keys, 'key')
|
|
48
|
-
|
|
49
|
-
klass = Class.new(self)
|
|
50
|
-
if values.empty?
|
|
51
|
-
klass.class_eval <<-end_eval, __FILE__, __LINE__
|
|
52
|
-
def key?(key, options = {})
|
|
53
|
-
@adapter.key?(#{key}, options)
|
|
54
|
-
end
|
|
55
|
-
def load(key, options = {})
|
|
56
|
-
@adapter.load(#{key}, options)
|
|
57
|
-
end
|
|
58
|
-
def store(key, value, options = {})
|
|
59
|
-
@adapter.store(#{key}, value, options)
|
|
60
|
-
end
|
|
61
|
-
def delete(key, options = {})
|
|
62
|
-
@adapter.delete(#{key}, options)
|
|
63
|
-
end
|
|
64
|
-
end_eval
|
|
65
|
-
else
|
|
66
|
-
dump = compile_transformer(values, 'value')
|
|
67
|
-
load = compile_transformer(values.reverse, 'value', 1)
|
|
68
|
-
|
|
69
|
-
klass.class_eval <<-end_eval, __FILE__, __LINE__
|
|
70
|
-
def key?(key, options = {})
|
|
71
|
-
@adapter.key?(#{key}, options)
|
|
72
|
-
end
|
|
73
|
-
def load(key, options = {})
|
|
74
|
-
value = @adapter.load(#{key}, options)
|
|
75
|
-
value && #{load}
|
|
76
|
-
end
|
|
77
|
-
def store(key, value, options = {})
|
|
78
|
-
@adapter.store(#{key}, #{dump}, options)
|
|
79
|
-
value
|
|
80
|
-
end
|
|
81
|
-
def delete(key, options = {})
|
|
82
|
-
value = @adapter.delete(#{key}, options)
|
|
83
|
-
value && #{load}
|
|
84
|
-
end
|
|
85
|
-
end_eval
|
|
86
|
-
end
|
|
87
|
-
klass
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
# Compile transformer validator regular expression
|
|
91
|
-
def compile_validator(s)
|
|
92
|
-
Regexp.new(s.gsub(/\w+/) do
|
|
93
|
-
'(' + TRANSFORMER.select {|k,v| v.first.to_s == $& }.map {|v| ":#{v.first}" }.join('|') + ')'
|
|
94
|
-
end.gsub(/\s+/, '').sub(/\A/, '\A').sub(/\Z/, '\Z'))
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
# Returned compiled transformer code string
|
|
98
|
-
def compile_transformer(transformer, var, i = 2)
|
|
99
|
-
transformer.inject(var) do |value, name|
|
|
100
|
-
raise ArgumentError, "Unknown transformer #{name}" unless t = TRANSFORMER[name]
|
|
101
|
-
require t[3] if t[3]
|
|
102
|
-
code = t[i]
|
|
103
|
-
if t[0] == :serialize && var == 'key'
|
|
104
|
-
"(tmp = #{value}; String === tmp ? tmp : #{code.gsub('value', 'tmp')})"
|
|
105
|
-
else
|
|
106
|
-
code.gsub('value', value)
|
|
107
|
-
end
|
|
108
|
-
end
|
|
109
|
-
end
|
|
110
|
-
|
|
111
|
-
def class_name(keys, values)
|
|
112
|
-
(keys.empty? ? '' : keys.map(&:to_s).map(&:capitalize).join << 'Key') <<
|
|
113
|
-
(values.empty? ? '' : values.map(&:to_s).map(&:capitalize).join << 'Value')
|
|
114
|
-
end
|
|
115
|
-
end
|
|
116
|
-
|
|
117
|
-
# Available key/value transformers
|
|
118
|
-
TRANSFORMER = {
|
|
119
|
-
# Name => [ Type, Load, Dump, Library ],
|
|
120
|
-
:bencode => [ :serialize, '::BEncode.load(value)', '::BEncode.dump(value)', 'bencode' ],
|
|
121
|
-
:bert => [ :serialize, '::BERT.decode(value)', '::BERT.encode(value)', 'bert' ],
|
|
122
|
-
:bson => [ :serialize, "::BSON.deserialize(value)['v']", "::BSON.serialize('v'=>value).to_s", 'bson' ],
|
|
123
|
-
:json => [ :serialize, '::MultiJson.load(value).first', '::MultiJson.dump([value])', 'multi_json' ],
|
|
124
|
-
:marshal => [ :serialize, '::Marshal.load(value)', '::Marshal.dump(value)' ],
|
|
125
|
-
:msgpack => [ :serialize, '::MessagePack.unpack(value)', '::MessagePack.pack(value)', 'msgpack' ],
|
|
126
|
-
:ox => [ :serialize, '::Ox.parse_obj(value)', '::Ox.dump(value)', 'ox' ],
|
|
127
|
-
:tnet => [ :serialize, '::TNetstring.parse(value).first', '::TNetstring.dump(value)', 'tnetstring' ],
|
|
128
|
-
:yaml => [ :serialize, '::YAML.load(value)', '::YAML.dump(value)', 'yaml' ],
|
|
129
|
-
:bzip2 => [ :compress, '::Bzip2.uncompress(value)', '::Bzip2.compress(value)', 'bzip2' ],
|
|
130
|
-
:lzma => [ :compress, '::LZMA.decompress(value)', '::LZMA.compress(value)', 'lzma' ],
|
|
131
|
-
:lzo => [ :compress, '::LZO.decompress(value)', '::LZO.compress(value)', 'lzoruby' ],
|
|
132
|
-
:snappy => [ :compress, '::Snappy.inflate(value)', '::Snappy.deflate(value)', 'snappy' ],
|
|
133
|
-
:quicklz => [ :compress, '::QuickLZ.decompress(value)', '::QuickLZ.compress(value)', 'qlzruby' ],
|
|
134
|
-
:zlib => [ :compress, '::Zlib::Inflate.inflate(value)', '::Zlib::Deflate.deflate(value)', 'zlib' ],
|
|
135
|
-
:base64 => [ :encode, "value.unpack('m').first", "[value].pack('m').strip" ],
|
|
136
|
-
:uuencode => [ :encode, "value.unpack('u').first", "[value].pack('u').strip" ],
|
|
137
|
-
:escape => [ :encode, 'Escape.unescape(value)', 'Escape.escape(value)' ],
|
|
138
|
-
:hmac => [ :hmac, 'HMAC.verify(value, @secret)', 'HMAC.sign(value, @secret)' , 'openssl' ],
|
|
139
|
-
:md5 => [ :digest, nil, '::Digest::MD5.hexdigest(value)', 'digest/md5' ],
|
|
140
|
-
:rmd160 => [ :digest, nil, '::Digest::RMD160.hexdigest(value)', 'digest/rmd160' ],
|
|
141
|
-
:sha1 => [ :digest, nil, '::Digest::SHA1.hexdigest(value)', 'digest/sha1' ],
|
|
142
|
-
:sha256 => [ :digest, nil, '::Digest::SHA256.hexdigest(value)', 'digest/sha2' ],
|
|
143
|
-
:sha384 => [ :digest, nil, '::Digest::SHA384.hexdigest(value)', 'digest/sha2' ],
|
|
144
|
-
:sha512 => [ :digest, nil, '::Digest::SHA512.hexdigest(value)', 'digest/sha2' ],
|
|
145
|
-
:prefix => [ :prefix, nil, '@prefix+value' ],
|
|
146
|
-
:spread => [ :spread, nil, '(tmp = value; ::File.join(tmp[0..1], tmp[2..-1]))' ],
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
# Allowed value transformers (Read it like a regular expression!)
|
|
150
|
-
VALUE_TRANSFORMER = compile_validator('serialize? compress? hmac? encode?')
|
|
151
|
-
|
|
152
|
-
# Allowed key transformers (Read it like a regular expression!)
|
|
153
|
-
KEY_TRANSFORMER = compile_validator('serialize? prefix? (encode | (digest spread?))?')
|
|
154
|
-
|
|
155
|
-
module Escape
|
|
156
|
-
def self.escape(value)
|
|
157
|
-
value.gsub(/[^a-zA-Z0-9_-]+/){ '%' + $&.unpack('H2' * $&.bytesize).join('%').upcase }
|
|
158
|
-
end
|
|
159
|
-
|
|
160
|
-
def self.unescape(value)
|
|
161
|
-
value.gsub(/((?:%[0-9a-fA-F]{2})+)/){ [$1.delete('%')].pack('H*') }
|
|
162
|
-
end
|
|
163
|
-
end
|
|
164
|
-
|
|
165
|
-
module HMAC
|
|
166
|
-
def self.verify(value, secret)
|
|
167
|
-
hash, value = value[0..31], value[32..-1]
|
|
168
|
-
value if hash == OpenSSL::HMAC.digest(OpenSSL::Digest::Digest.new('sha256'), secret, value)
|
|
169
|
-
end
|
|
170
|
-
|
|
171
|
-
def self.sign(value, secret)
|
|
172
|
-
OpenSSL::HMAC.digest(OpenSSL::Digest::Digest.new('sha256'), secret, value) << value
|
|
173
|
-
end
|
|
174
|
-
end
|
|
175
|
-
end
|
|
176
|
-
end
|