juno 0.2.4 → 0.2.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (109) hide show
  1. data/Gemfile +7 -2
  2. data/README.md +4 -2
  3. data/lib/juno/adapters/memcached_native.rb +3 -1
  4. data/lib/juno/builder.rb +4 -5
  5. data/lib/juno/cache.rb +6 -4
  6. data/lib/juno/expires.rb +4 -0
  7. data/lib/juno/lock.rb +8 -1
  8. data/lib/juno/logger.rb +86 -0
  9. data/lib/juno/proxy.rb +4 -0
  10. data/lib/juno/stack.rb +3 -2
  11. data/lib/juno/transformer.rb +61 -61
  12. data/lib/juno/version.rb +1 -1
  13. data/lib/juno.rb +10 -8
  14. data/spec/adapter_activerecord_spec.rb +2 -2
  15. data/spec/adapter_cassandra_spec.rb +1 -1
  16. data/spec/adapter_couch_spec.rb +1 -1
  17. data/spec/adapter_datamapper_spec.rb +1 -1
  18. data/spec/adapter_dbm_spec.rb +1 -1
  19. data/spec/adapter_file_spec.rb +1 -1
  20. data/spec/adapter_fog_spec.rb +1 -1
  21. data/spec/adapter_gdbm_spec.rb +1 -1
  22. data/spec/adapter_localmemcache_spec.rb +1 -1
  23. data/spec/adapter_lruhash_spec.rb +1 -1
  24. data/spec/adapter_memcached_dalli_spec.rb +1 -1
  25. data/spec/adapter_memcached_native_spec.rb +1 -1
  26. data/spec/adapter_memcached_spec.rb +1 -1
  27. data/spec/adapter_memory_spec.rb +1 -1
  28. data/spec/adapter_mongo_spec.rb +1 -1
  29. data/spec/adapter_pstore_spec.rb +1 -1
  30. data/spec/adapter_redis_spec.rb +1 -1
  31. data/spec/adapter_riak_spec.rb +1 -1
  32. data/spec/adapter_sdbm_spec.rb +1 -1
  33. data/spec/adapter_sequel_spec.rb +1 -1
  34. data/spec/adapter_sqlite_spec.rb +1 -1
  35. data/spec/adapter_tokyocabinet_bdb_spec.rb +1 -1
  36. data/spec/adapter_tokyocabinet_hdb_spec.rb +1 -1
  37. data/spec/adapter_yaml_spec.rb +1 -1
  38. data/spec/cache_file_memory_spec.rb +1 -1
  39. data/spec/cache_memory_null_spec.rb +1 -1
  40. data/spec/expires_file_spec.rb +1 -1
  41. data/spec/expires_memory_spec.rb +1 -1
  42. data/spec/generate.rb +37 -12
  43. data/spec/junospecs.rb +1 -1
  44. data/spec/lock_spec.rb +1 -1
  45. data/spec/null_adapter_spec.rb +1 -1
  46. data/spec/proxy_expires_memory_spec.rb +1 -1
  47. data/spec/proxy_redis_spec.rb +1 -1
  48. data/spec/simple_activerecord_spec.rb +2 -2
  49. data/spec/simple_activerecord_with_expires_spec.rb +2 -2
  50. data/spec/simple_cassandra_spec.rb +2 -2
  51. data/spec/simple_couch_spec.rb +2 -2
  52. data/spec/simple_couch_with_expires_spec.rb +2 -2
  53. data/spec/simple_datamapper_spec.rb +2 -2
  54. data/spec/simple_datamapper_with_expires_spec.rb +2 -2
  55. data/spec/simple_datamapper_with_repository_spec.rb +2 -2
  56. data/spec/simple_dbm_spec.rb +2 -2
  57. data/spec/simple_dbm_with_expires_spec.rb +2 -2
  58. data/spec/simple_file_spec.rb +2 -2
  59. data/spec/simple_file_with_expires_spec.rb +2 -2
  60. data/spec/simple_fog_spec.rb +2 -2
  61. data/spec/simple_fog_with_expires_spec.rb +2 -2
  62. data/spec/simple_gdbm_spec.rb +2 -2
  63. data/spec/simple_gdbm_with_expires_spec.rb +2 -2
  64. data/spec/simple_hashfile_spec.rb +2 -2
  65. data/spec/simple_hashfile_with_expires_spec.rb +2 -2
  66. data/spec/simple_localmemcache_spec.rb +2 -2
  67. data/spec/simple_localmemcache_with_expires_spec.rb +2 -2
  68. data/spec/simple_lruhash_spec.rb +2 -2
  69. data/spec/simple_lruhash_with_expires_spec.rb +2 -2
  70. data/spec/simple_memcached_dalli_spec.rb +2 -2
  71. data/spec/simple_memcached_native_spec.rb +2 -2
  72. data/spec/simple_memcached_spec.rb +2 -2
  73. data/spec/simple_memory_spec.rb +2 -2
  74. data/spec/simple_memory_with_expires_spec.rb +2 -2
  75. data/spec/simple_mongo_spec.rb +2 -2
  76. data/spec/simple_mongo_with_expires_spec.rb +2 -2
  77. data/spec/simple_null_spec.rb +2 -2
  78. data/spec/simple_pstore_spec.rb +2 -2
  79. data/spec/simple_pstore_with_expires_spec.rb +2 -2
  80. data/spec/simple_redis_spec.rb +2 -2
  81. data/spec/simple_riak_spec.rb +2 -2
  82. data/spec/simple_riak_with_expires_spec.rb +2 -2
  83. data/spec/simple_sdbm_spec.rb +2 -2
  84. data/spec/simple_sdbm_with_expires_spec.rb +2 -2
  85. data/spec/simple_sequel_spec.rb +2 -2
  86. data/spec/simple_sequel_with_expires_spec.rb +2 -2
  87. data/spec/simple_sqlite_spec.rb +2 -2
  88. data/spec/simple_sqlite_with_expires_spec.rb +2 -2
  89. data/spec/simple_tokyocabinet_spec.rb +2 -2
  90. data/spec/simple_tokyocabinet_with_expires_spec.rb +2 -2
  91. data/spec/simple_yaml_spec.rb +2 -2
  92. data/spec/simple_yaml_with_expires_spec.rb +2 -2
  93. data/spec/stack_file_memory_spec.rb +1 -1
  94. data/spec/stack_memory_file_spec.rb +1 -1
  95. data/spec/transformer_bencode_spec.rb +25 -0
  96. data/spec/transformer_bert_spec.rb +25 -0
  97. data/spec/transformer_bson_spec.rb +1 -1
  98. data/spec/transformer_compress_spec.rb +1 -1
  99. data/spec/transformer_json_spec.rb +1 -1
  100. data/spec/transformer_marshal_base64_spec.rb +1 -1
  101. data/spec/transformer_marshal_escape_spec.rb +1 -1
  102. data/spec/transformer_marshal_md5_spec.rb +1 -1
  103. data/spec/transformer_marshal_md5_spread_spec.rb +1 -1
  104. data/spec/transformer_marshal_uuencode_spec.rb +41 -0
  105. data/spec/transformer_msgpack_spec.rb +1 -1
  106. data/spec/transformer_ox_spec.rb +1 -1
  107. data/spec/transformer_tnet_spec.rb +25 -0
  108. data/spec/transformer_yaml_spec.rb +1 -1
  109. metadata +11 -2
data/Gemfile CHANGED
@@ -7,10 +7,11 @@ gem 'rspec'
7
7
  gem 'parallel_tests'
8
8
 
9
9
  # Serializer
10
- #gem 'tnetstring'
10
+ gem 'tnetstring'
11
+ gem 'bert'
12
+ gem 'bencode'
11
13
  gem 'bson'
12
14
  gem 'multi_json'
13
- gem 'json' # Ripple/Riak needs json
14
15
 
15
16
  # Backends
16
17
  gem 'dm-core'
@@ -27,9 +28,13 @@ gem 'riak-client'
27
28
  gem 'hashery'
28
29
 
29
30
  if defined?(JRUBY_VERSION)
31
+ gem 'msgpack-jruby'
30
32
  gem 'jdbc-sqlite3'
31
33
  gem 'activerecord-jdbc-adapter'
32
34
  gem 'activerecord-jdbcsqlite3-adapter'
35
+ gem 'jruby-memcached'
36
+ gem 'ffi' # gdbm for jruby needs ffi
37
+ gem 'gdbm'
33
38
  else
34
39
  gem 'msgpack'
35
40
  gem 'tokyocabinet'
data/README.md CHANGED
@@ -10,7 +10,7 @@ fork was that Moneta was unmaintained for a long time.
10
10
  Juno is very feature rich:
11
11
 
12
12
  * Supports for a lot of backends (See below)
13
- * Supports proxies (Similar to [Rack middlewares](http://rack.rubyforge.org/))
13
+ * Supports proxies (Similar to [Rack middlewares](http://rack.github.com/))
14
14
  * Custom serialization via `Juno::Transformer` proxy (Marshal/JSON/YAML and many more)
15
15
  * Custom key transformation via `Juno::Transformer` proxy
16
16
  * Expiration for all stores (Added via proxy if not supported natively)
@@ -58,11 +58,12 @@ Supported serializers:
58
58
  * MessagePack
59
59
  * BSON
60
60
  * Ox
61
+ * BERT
61
62
 
62
63
  Proxies
63
64
  -------
64
65
 
65
- In addition it supports proxies (Similar to [Rack middlewares](http://rack.rubyforge.org/)) which
66
+ In addition it supports proxies (Similar to [Rack middlewares](http://rack.github.com/)) which
66
67
  add additional features to storage backends:
67
68
 
68
69
  * `Juno::Proxy` proxy base class
@@ -71,6 +72,7 @@ add additional features to storage backends:
71
72
  * `Juno::Transformer` transforms keys and values (Marshal, YAML, JSON, Base64, MD5, ...)
72
73
  * `Juno::Cache` combine two stores, one as backend and one as cache (e.g. Juno::Adapters::File + Juno::Adapters::Memory)
73
74
  * `Juno::Lock` to make store thread safe
75
+ * `Juno::Logger` to log database accesses
74
76
 
75
77
  The Juno API is purposely extremely similar to the Hash API. In order so support an
76
78
  identical API across stores, it does not support iteration or partial matches.
@@ -16,6 +16,7 @@ module Juno
16
16
  def initialize(options = {})
17
17
  server = options.delete(:server) || 'localhost:11211'
18
18
  options.merge!(:prefix_key => options.delete(:namespace)) if options[:namespace]
19
+ @default_ttl = options[:default_ttl] || 604800
19
20
  @cache = ::Memcached.new(server, options)
20
21
  end
21
22
 
@@ -44,7 +45,8 @@ module Juno
44
45
  end
45
46
 
46
47
  def store(key, value, options = {})
47
- @cache.set(key, value, options[:expires] || @cache.options[:default_ttl], false)
48
+ # TTL must be Fixnum
49
+ @cache.set(key, value, options[:expires] || @default_ttl, false)
48
50
  value
49
51
  end
50
52
 
data/lib/juno/builder.rb CHANGED
@@ -4,24 +4,23 @@ module Juno
4
4
  class Builder
5
5
  def build
6
6
  klass, options, block = @proxies.first
7
- store = klass.new(@options.merge(options), &block)
7
+ store = klass.new(options, &block)
8
8
  @proxies[1..-1].each do |proxy|
9
9
  klass, options, block = proxy
10
- store = klass.new(store, @options.merge(options), &block)
10
+ store = klass.new(store, options, &block)
11
11
  end
12
12
  store
13
13
  end
14
14
 
15
- def initialize(options = {}, &block)
15
+ def initialize(&block)
16
16
  raise 'No block given' unless block_given?
17
- raise 'Options must be Hash' unless Hash === options
18
- @options = options
19
17
  @proxies = []
20
18
  instance_eval(&block)
21
19
  end
22
20
 
23
21
  def use(proxy, options = {}, &block)
24
22
  proxy = Juno.const_get(proxy) if Symbol === proxy
23
+ raise 'You must give a Class or a Symbol' unless Class === proxy
25
24
  @proxies.unshift [proxy, options, block]
26
25
  end
27
26
 
data/lib/juno/cache.rb CHANGED
@@ -18,14 +18,16 @@ module Juno
18
18
  instance_eval(&block)
19
19
  end
20
20
 
21
- def backend(options = {}, &block)
21
+ def backend(store = nil, &block)
22
22
  raise 'Backend already set' if @backend
23
- @backend = Hash === options ? Juno.build(options, &block) : options
23
+ raise 'Only argument or block allowed' if store && block
24
+ @backend = store || Juno.build(&block)
24
25
  end
25
26
 
26
- def cache(options = {}, &block)
27
+ def cache(store = nil, &block)
27
28
  raise 'Cache already set' if @cache
28
- @cache = Hash === options ? Juno.build(options, &block) : options
29
+ raise 'Only argument or block allowed' if store && block
30
+ @cache = store || Juno.build(&block)
29
31
  end
30
32
 
31
33
  def result
data/lib/juno/expires.rb CHANGED
@@ -1,5 +1,9 @@
1
1
  module Juno
2
2
  # Adds expiration support to the underlying store
3
+ #
4
+ # #store and #load support the :expires options to set/update
5
+ # the expiration time.
6
+ #
3
7
  # @api public
4
8
  class Expires < Proxy
5
9
  def key?(key, options = {})
data/lib/juno/lock.rb CHANGED
@@ -4,9 +4,16 @@ module Juno
4
4
  # Locks the underlying stores with a Mutex
5
5
  # @api public
6
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)
7
14
  def initialize(adapter, options = {})
8
15
  super
9
- @lock = Mutex.new
16
+ @lock = options[:mutex] || Mutex.new
10
17
  end
11
18
 
12
19
  def key?(key, options = {})
@@ -0,0 +1,86 @@
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 CHANGED
@@ -4,6 +4,10 @@ module Juno
4
4
  class Proxy < Base
5
5
  attr_reader :adapter
6
6
 
7
+ # Constructor
8
+ #
9
+ # @param [Juno store] underlying adapter
10
+ # @param [Hash] options
7
11
  def initialize(adapter, options = {})
8
12
  @adapter = adapter
9
13
  end
data/lib/juno/stack.rb CHANGED
@@ -22,8 +22,9 @@ module Juno
22
22
  instance_eval(&block)
23
23
  end
24
24
 
25
- def add(options = {}, &block)
26
- @stack << (Hash === options ? Juno.build(options, &block) : options)
25
+ def add(store = nil, &block)
26
+ raise 'Only argument or block allowed' if store && block
27
+ @stack << (store || Juno.build(&block))
27
28
  nil
28
29
  end
29
30
  end
@@ -11,29 +11,35 @@ module Juno
11
11
  # @api public
12
12
  class Transformer < Proxy
13
13
  VALUE_TRANSFORMER = {
14
- :marshal => { :load => '::Marshal.load(VALUE)', :dump => '::Marshal.dump(VALUE)' },
15
- :ox => { :load => '::Ox.parse_obj(VALUE)', :dump => '::Ox.dump(VALUE)', :require => 'ox' },
16
- :base64 => { :load => "VALUE.unpack('m').first", :dump => "[VALUE].pack('m').strip" },
17
- :json => { :load => '::MultiJson.load(VALUE).first', :dump => '::MultiJson.dump([VALUE])', :require => 'multi_json' },
18
- :yaml => { :load => '::YAML.load(VALUE)', :dump => '::YAML.dump(VALUE)', :require => 'yaml' },
19
- #:tnet => { :load => '::TNetstring.parse(VALUE)', :dump => '::TNetstring.dump(VALUE)', :require => 'tnetstring' },
20
- :msgpack => { :load => '::MessagePack.unpack(VALUE)', :dump => '::MessagePack.pack(VALUE)', :require => 'msgpack' },
21
- :bson => { :load => '::BSON.deserialize(VALUE)["v"]', :dump => '::BSON.serialize({"v"=>VALUE})', :require => 'bson' },
22
- :compress => { :load => '::Zlib::Inflate.inflate(VALUE)', :dump => '::Zlib::Deflate.deflate(VALUE)', :require => 'zlib' },
14
+ :base64 => { :load => "value.unpack('m').first", :dump => "[value].pack('m').strip" },
15
+ :bencode => { :load => '::BEncode.load(value)', :dump => '::BEncode.dump(value)', :require => 'bencode' },
16
+ :bert => { :load => '::BERT.decode(value)', :dump => '::BERT.encode(value)', :require => 'bert' },
17
+ :bson => { :load => "::BSON.deserialize(value)['v']", :dump => "::BSON.serialize('v'=>value)", :require => 'bson' },
18
+ :compress => { :load => '::Zlib::Inflate.inflate(value)', :dump => '::Zlib::Deflate.deflate(value)', :require => 'zlib' },
19
+ :json => { :load => '::MultiJson.load(value).first', :dump => '::MultiJson.dump([value])', :require => 'multi_json' },
20
+ :marshal => { :load => '::Marshal.load(value)', :dump => '::Marshal.dump(value)' },
21
+ :msgpack => { :load => '::MessagePack.unpack(value)', :dump => '::MessagePack.pack(value)', :require => 'msgpack' },
22
+ :ox => { :load => '::Ox.parse_obj(value)', :dump => '::Ox.dump(value)', :require => 'ox' },
23
+ :tnet => { :load => '::TNetstring.parse(value).first', :dump => '::TNetstring.dump(value)', :require => 'tnetstring' },
24
+ :uuencode => { :load => "value.unpack('u').first", :dump => "[value].pack('u').strip" },
25
+ :yaml => { :load => '::YAML.load(value)', :dump => '::YAML.dump(value)', :require => 'yaml' }
23
26
  }
24
27
 
25
28
  KEY_TRANSFORMER = {
26
- :base64 => { :transform => "[KEY].pack('m').strip" },
27
- :spread => { :transform => '(TMP = KEY; ::File.join(TMP[0..1], TMP[2..-1]))' },
28
- :escape => { :transform => "KEY.gsub(/[^a-zA-Z0-9_-]+/) { '%%' + $&.unpack('H2' * $&.bytesize).join('%%').upcase }" },
29
- :md5 => { :transform => '::Digest::MD5.hexdigest(KEY)', :require => 'digest/md5' },
30
- :json => { :transform => '(TMP = KEY; String === TMP ? TMP : ::MultiJson.dump(TMP))', :require => 'multi_json' },
31
- :bson => { :transform => '(TMP = KEY; String === TMP ? TMP : ::BSON.serialize({"k"=>TMP}).to_s)', :require => 'bson' },
32
- :yaml => { :transform => '(TMP = KEY; String === TMP ? TMP : ::YAML.dump(TMP))', :require => 'yaml' },
33
- :marshal => { :transform => '(TMP = KEY; String === TMP ? TMP : ::Marshal.dump(TMP))' },
34
- :ox => { :transform => '(TMP = KEY; String === TMP ? TMP : ::Ox.dump(TMP))' },
35
- #:tnet => { :transform => '(TMP = KEY; String === TMP ? TMP : ::TNetstring.dump(TMP))', :require => 'tnetstring' },
36
- :msgpack => { :transform => '(TMP = KEY; String === TMP ? TMP : ::MessagePack.pack(TMP))', :require => 'msgpack' },
29
+ :base64 => { :transform => "[key].pack('m').strip" },
30
+ :bencode => { :transform => '::BEncode.dump(key)', :require => 'bencode' },
31
+ :bert => { :transform => '::BERT.encode(key)', :require => 'bert' },
32
+ :bson => { :transform => "(tmp = key; String === tmp ? tmp : ::BSON.serialize('k'=>tmp).to_s)", :require => 'bson' },
33
+ :escape => { :transform => "key.gsub(/[^a-zA-Z0-9_-]+/) { '%%' + $&.unpack('H2' * $&.bytesize).join('%%').upcase }" },
34
+ :json => { :transform => '(tmp = key; String === tmp ? tmp : ::MultiJson.dump(tmp))', :require => 'multi_json' },
35
+ :marshal => { :transform => '(tmp = key; String === tmp ? tmp : ::Marshal.dump(tmp))' },
36
+ :md5 => { :transform => '::Digest::MD5.hexdigest(key)', :require => 'digest/md5' },
37
+ :msgpack => { :transform => '(tmp = key; String === tmp ? tmp : ::MessagePack.pack(tmp))', :require => 'msgpack' },
38
+ :ox => { :transform => '(tmp = key; String === tmp ? tmp : ::Ox.dump(tmp))' },
39
+ :spread => { :transform => '(tmp = key; ::File.join(tmp[0..1], tmp[2..-1]))' },
40
+ :tnet => { :transform => '(tmp = key; String === tmp ? tmp : ::TNetstring.dump(tmp))', :require => 'tnetstring' },
41
+ :uuencode => { :transform => "[key].pack('u').strip" },
42
+ :yaml => { :transform => '(tmp = key; String === tmp ? tmp : ::YAML.dump(tmp))', :require => 'yaml' },
37
43
  }
38
44
 
39
45
  @classes = {}
@@ -46,76 +52,70 @@ module Juno
46
52
  keys.each do |tn|
47
53
  raise "Unknown key transformer #{tn}" unless t = KEY_TRANSFORMER[tn]
48
54
  require t[:require] if t[:require]
49
- key = t[:transform].gsub('KEY', key).gsub('TMP', "x#{tmp}")
55
+ key = t[:transform].gsub('key', key).gsub('tmp', "x#{tmp}")
50
56
  tmp += 1
51
57
  end
52
58
 
53
59
  klass = Class.new(Transformer)
54
60
  if values.empty?
55
61
  klass.class_eval <<-end_eval, __FILE__, __LINE__
56
- def key?(key, options = {})
57
- @adapter.key?(#{key}, options)
58
- end
59
-
60
- def load(key, options = {})
61
- @adapter.load(#{key}, options)
62
- end
63
-
64
- def store(key, value, options = {})
65
- @adapter.store(#{key}, value, options)
66
- end
67
-
68
- def delete(key, options = {})
69
- @adapter.delete(#{key}, options)
70
- end
71
- end_eval
62
+ def key?(key, options = {})
63
+ @adapter.key?(#{key}, options)
64
+ end
65
+ def load(key, options = {})
66
+ @adapter.load(#{key}, options)
67
+ end
68
+ def store(key, value, options = {})
69
+ @adapter.store(#{key}, value, options)
70
+ end
71
+ def delete(key, options = {})
72
+ @adapter.delete(#{key}, options)
73
+ end
74
+ end_eval
72
75
  else
73
76
  dumper, loader = 'value', 'value'
74
77
  values.each_index do |i|
75
78
  raise "Unknown value transformer #{values[i]}" unless t = VALUE_TRANSFORMER[values[i]]
76
79
  require t[:require] if t[:require]
77
- dumper = t[:dump].gsub('VALUE', dumper)
78
- loader = VALUE_TRANSFORMER[values[-i-1]][:load].gsub('VALUE', loader)
80
+ dumper = t[:dump].gsub('value', dumper)
81
+ loader = VALUE_TRANSFORMER[values[-i-1]][:load].gsub('value', loader)
79
82
  end
80
83
 
81
84
  klass.class_eval <<-end_eval, __FILE__, __LINE__
82
- def key?(key, options = {})
83
- @adapter.key?(#{key}, options)
84
- end
85
-
86
- def load(key, options = {})
87
- value = @adapter.load(#{key}, options)
88
- value && #{loader}
89
- end
90
-
91
- def store(key, value, options = {})
92
- @adapter.store(#{key}, #{dumper}, options)
93
- value
94
- end
95
-
96
- def delete(key, options = {})
97
- value = @adapter.delete(#{key}, options)
98
- value && #{loader}
99
- end
100
- end_eval
85
+ def key?(key, options = {})
86
+ @adapter.key?(#{key}, options)
87
+ end
88
+ def load(key, options = {})
89
+ value = @adapter.load(#{key}, options)
90
+ value && #{loader}
91
+ end
92
+ def store(key, value, options = {})
93
+ @adapter.store(#{key}, #{dumper}, options)
94
+ value
95
+ end
96
+ def delete(key, options = {})
97
+ value = @adapter.delete(#{key}, options)
98
+ value && #{loader}
99
+ end
100
+ end_eval
101
101
  end
102
102
  klass
103
103
  end
104
104
 
105
105
  # Constructor
106
106
  #
107
- # @param [Juno store] store The underlying store
107
+ # @param [Juno store] adapter The underlying store
108
108
  # @param [Hash] options
109
109
  #
110
110
  # Options:
111
111
  # * :key - List of key transformers in the order in which they should be applied
112
112
  # * :value - List of value transformers in the order in which they should be applied
113
- def new(store, options = {})
113
+ def new(adapter, options = {})
114
114
  keys = [options[:key]].flatten.compact
115
115
  values = [options[:value]].flatten.compact
116
116
  raise 'No option :key or :value specified' if keys.empty? && values.empty?
117
117
  klass = @classes["#{keys.join('-')}+#{values.join('-')}"] ||= compile(keys, values)
118
- klass.original_new(store, options)
118
+ klass.original_new(adapter, options)
119
119
  end
120
120
  end
121
121
  end
data/lib/juno/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  module Juno
2
2
  # Juno version number
3
3
  # @api public
4
- VERSION = '0.2.4'
4
+ VERSION = '0.2.5'
5
5
  end
data/lib/juno.rb CHANGED
@@ -4,6 +4,7 @@ module Juno
4
4
  autoload :Cache, 'juno/cache'
5
5
  autoload :Expires, 'juno/expires'
6
6
  autoload :Lock, 'juno/lock'
7
+ autoload :Logger, 'juno/logger'
7
8
  autoload :Proxy, 'juno/proxy'
8
9
  autoload :Stack, 'juno/stack'
9
10
  autoload :Transformer, 'juno/transformer'
@@ -44,9 +45,10 @@ module Juno
44
45
  # @param [Hash] options
45
46
  #
46
47
  # Options:
47
- # * :expires - Ensure that store supports expiration by inserting
48
+ # * :expires - If options is true, ensure that store supports expiration by inserting
48
49
  # Juno::Expires if the underlying adapter doesn't support it natively
49
- # * :threadsafe - Ensure that the store is thread safe by inserting Juno::Lock
50
+ # * :threadsafe - If options is true, ensure that the store is thread safe by inserting Juno::Lock
51
+ # * :logger - If options is a true or Hash, add logger to chain (Hash is passed to logger as options)
50
52
  # * All other options passed to the adapter
51
53
  #
52
54
  # Supported adapters:
@@ -56,6 +58,7 @@ module Juno
56
58
  # * ... (All other adapters from Juno::Adapters)
57
59
  def self.new(name, options = {})
58
60
  expires = options.delete(:expires)
61
+ logger = options.delete(:logger)
59
62
  threadsafe = options.delete(:threadsafe)
60
63
  transformer = {:key => :marshal, :value => :marshal}
61
64
  raise 'Name must be Symbol' unless Symbol === name
@@ -82,25 +85,24 @@ module Juno
82
85
  # Expires already supported
83
86
  expires = false
84
87
  end
85
- build(options) do
88
+ build do
89
+ use :Logger, Hash === logger ? logger : {} if logger
86
90
  use :Expires if expires
87
91
  use :Transformer, transformer
88
92
  use :Lock if threadsafe
89
- adapter name
93
+ adapter name, options
90
94
  end
91
95
  end
92
96
 
93
97
  # Build your own store chain!
94
98
  #
95
- # @params [Hash] options Options passed to the proxies and adapter
96
- #
97
99
  # Example:
98
100
  #
99
101
  # Juno.build do
100
102
  # use :Expires
101
103
  # adapter :Memory
102
104
  # end
103
- def self.build(options = {}, &block)
104
- Builder.new(options, &block).build
105
+ def self.build(&block)
106
+ Builder.new(&block).build
105
107
  end
106
108
  end
@@ -1,4 +1,4 @@
1
- # Generated by generate.rb at 2012-12-02 18:03:24 +0100, heads/master-0-g9a90bb4
1
+ # Generated by generate.rb
2
2
  require 'helper'
3
3
 
4
4
  describe_juno "adapter_activerecord" do
@@ -21,7 +21,7 @@ describe_juno "adapter_activerecord" do
21
21
  ActiveRecord::Base.establish_connection :adapter => (defined?(JRUBY_VERSION) ? 'jdbcsqlite3' : 'sqlite3'), :database => File.join(make_tempdir, 'activerecord-existing')
22
22
 
23
23
  store = Juno::Adapters::ActiveRecord.new
24
- store.table.table_exists?.should == true
24
+ store.table.should be_table_exists
25
25
  end
26
26
 
27
27
  end
@@ -1,4 +1,4 @@
1
- # Generated by generate.rb at 2012-12-02 18:03:24 +0100, heads/master-0-g9a90bb4
1
+ # Generated by generate.rb
2
2
  require 'helper'
3
3
 
4
4
  describe_juno "adapter_cassandra" do
@@ -1,4 +1,4 @@
1
- # Generated by generate.rb at 2012-12-02 18:03:24 +0100, heads/master-0-g9a90bb4
1
+ # Generated by generate.rb
2
2
  require 'helper'
3
3
 
4
4
  describe_juno "adapter_couch" do
@@ -1,4 +1,4 @@
1
- # Generated by generate.rb at 2012-12-02 18:03:24 +0100, heads/master-0-g9a90bb4
1
+ # Generated by generate.rb
2
2
  require 'helper'
3
3
 
4
4
  describe_juno "adapter_datamapper" do
@@ -1,4 +1,4 @@
1
- # Generated by generate.rb at 2012-12-02 18:03:24 +0100, heads/master-0-g9a90bb4
1
+ # Generated by generate.rb
2
2
  require 'helper'
3
3
 
4
4
  describe_juno "adapter_dbm" do
@@ -1,4 +1,4 @@
1
- # Generated by generate.rb at 2012-12-02 18:03:24 +0100, heads/master-0-g9a90bb4
1
+ # Generated by generate.rb
2
2
  require 'helper'
3
3
 
4
4
  describe_juno "adapter_file" do
@@ -1,4 +1,4 @@
1
- # Generated by generate.rb at 2012-12-02 18:03:24 +0100, heads/master-0-g9a90bb4
1
+ # Generated by generate.rb
2
2
  require 'helper'
3
3
 
4
4
  describe_juno "adapter_fog" do
@@ -1,4 +1,4 @@
1
- # Generated by generate.rb at 2012-12-02 18:03:24 +0100, heads/master-0-g9a90bb4
1
+ # Generated by generate.rb
2
2
  require 'helper'
3
3
 
4
4
  describe_juno "adapter_gdbm" do
@@ -1,4 +1,4 @@
1
- # Generated by generate.rb at 2012-12-02 18:03:24 +0100, heads/master-0-g9a90bb4
1
+ # Generated by generate.rb
2
2
  require 'helper'
3
3
 
4
4
  describe_juno "adapter_localmemcache" do
@@ -1,4 +1,4 @@
1
- # Generated by generate.rb at 2012-12-02 18:03:24 +0100, heads/master-0-g9a90bb4
1
+ # Generated by generate.rb
2
2
  require 'helper'
3
3
 
4
4
  describe_juno "adapter_lruhash" do
@@ -1,4 +1,4 @@
1
- # Generated by generate.rb at 2012-12-02 18:03:24 +0100, heads/master-0-g9a90bb4
1
+ # Generated by generate.rb
2
2
  require 'helper'
3
3
 
4
4
  describe_juno "adapter_memcached_dalli" do
@@ -1,4 +1,4 @@
1
- # Generated by generate.rb at 2012-12-02 18:03:24 +0100, heads/master-0-g9a90bb4
1
+ # Generated by generate.rb
2
2
  require 'helper'
3
3
 
4
4
  describe_juno "adapter_memcached_native" do
@@ -1,4 +1,4 @@
1
- # Generated by generate.rb at 2012-12-02 18:03:24 +0100, heads/master-0-g9a90bb4
1
+ # Generated by generate.rb
2
2
  require 'helper'
3
3
 
4
4
  describe_juno "adapter_memcached" do
@@ -1,4 +1,4 @@
1
- # Generated by generate.rb at 2012-12-02 18:03:24 +0100, heads/master-0-g9a90bb4
1
+ # Generated by generate.rb
2
2
  require 'helper'
3
3
 
4
4
  describe_juno "adapter_memory" do
@@ -1,4 +1,4 @@
1
- # Generated by generate.rb at 2012-12-02 18:03:24 +0100, heads/master-0-g9a90bb4
1
+ # Generated by generate.rb
2
2
  require 'helper'
3
3
 
4
4
  describe_juno "adapter_mongo" do
@@ -1,4 +1,4 @@
1
- # Generated by generate.rb at 2012-12-02 18:03:24 +0100, heads/master-0-g9a90bb4
1
+ # Generated by generate.rb
2
2
  require 'helper'
3
3
 
4
4
  describe_juno "adapter_pstore" do
@@ -1,4 +1,4 @@
1
- # Generated by generate.rb at 2012-12-02 18:03:24 +0100, heads/master-0-g9a90bb4
1
+ # Generated by generate.rb
2
2
  require 'helper'
3
3
 
4
4
  describe_juno "adapter_redis" do