moneta 0.7.1 → 0.7.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. data/.yardopts +1 -0
  2. data/CHANGES +21 -10
  3. data/README.md +1 -1
  4. data/SPEC.md +4 -12
  5. data/lib/moneta.rb +7 -5
  6. data/lib/moneta/adapters/activerecord.rb +9 -3
  7. data/lib/moneta/adapters/cassandra.rb +9 -4
  8. data/lib/moneta/adapters/client.rb +9 -3
  9. data/lib/moneta/adapters/cookie.rb +3 -0
  10. data/lib/moneta/adapters/couch.rb +8 -3
  11. data/lib/moneta/adapters/datamapper.rb +8 -3
  12. data/lib/moneta/adapters/dbm.rb +1 -2
  13. data/lib/moneta/adapters/file.rb +9 -4
  14. data/lib/moneta/adapters/fog.rb +8 -3
  15. data/lib/moneta/adapters/gdbm.rb +1 -2
  16. data/lib/moneta/adapters/hbase.rb +10 -3
  17. data/lib/moneta/adapters/leveldb.rb +3 -2
  18. data/lib/moneta/adapters/localmemcache.rb +4 -4
  19. data/lib/moneta/adapters/lruhash.rb +8 -4
  20. data/lib/moneta/adapters/memcached/dalli.rb +10 -4
  21. data/lib/moneta/adapters/memcached/native.rb +9 -4
  22. data/lib/moneta/adapters/memory.rb +8 -3
  23. data/lib/moneta/adapters/mongo.rb +7 -3
  24. data/lib/moneta/adapters/null.rb +8 -1
  25. data/lib/moneta/adapters/pstore.rb +9 -3
  26. data/lib/moneta/adapters/redis.rb +10 -4
  27. data/lib/moneta/adapters/riak.rb +12 -7
  28. data/lib/moneta/adapters/sdbm.rb +1 -2
  29. data/lib/moneta/adapters/sequel.rb +9 -3
  30. data/lib/moneta/adapters/sqlite.rb +10 -4
  31. data/lib/moneta/adapters/tokyocabinet.rb +2 -2
  32. data/lib/moneta/builder.rb +11 -7
  33. data/lib/moneta/cache.rb +16 -6
  34. data/lib/moneta/expires.rb +12 -6
  35. data/lib/moneta/lock.rb +0 -2
  36. data/lib/moneta/logger.rb +0 -2
  37. data/lib/moneta/mixins.rb +175 -47
  38. data/lib/moneta/optionmerger.rb +2 -0
  39. data/lib/moneta/proxy.rb +14 -30
  40. data/lib/moneta/server.rb +0 -2
  41. data/lib/moneta/shared.rb +1 -3
  42. data/lib/moneta/stack.rb +20 -10
  43. data/lib/moneta/transformer.rb +84 -61
  44. data/lib/moneta/version.rb +1 -1
  45. data/lib/rack/moneta_rest.rb +56 -0
  46. data/moneta.gemspec +1 -1
  47. data/spec/active_support/cache_moneta_store_spec.rb +4 -4
  48. data/spec/generate.rb +216 -203
  49. data/spec/helper.rb +0 -6
  50. data/spec/moneta/adapter_cassandra_spec.rb +2 -2
  51. data/spec/moneta/adapter_datamapper_spec.rb +1 -1
  52. data/spec/moneta/adapter_lruhash_spec.rb +1 -1
  53. data/spec/moneta/adapter_memcached_dalli_spec.rb +2 -2
  54. data/spec/moneta/adapter_memcached_native_spec.rb +2 -2
  55. data/spec/moneta/adapter_memcached_spec.rb +2 -2
  56. data/spec/moneta/adapter_redis_spec.rb +2 -2
  57. data/spec/moneta/cache_file_memory_spec.rb +3 -3
  58. data/spec/moneta/expires_file_spec.rb +4 -4
  59. data/spec/moneta/expires_memory_spec.rb +2 -2
  60. data/spec/moneta/optionmerger_spec.rb +6 -6
  61. data/spec/moneta/shared_spec.rb +1 -1
  62. data/spec/moneta/simple_client_tcp_spec.rb +1 -1
  63. data/spec/moneta/transformer_key_marshal_spec.rb +109 -0
  64. data/spec/moneta/transformer_key_yaml_spec.rb +109 -0
  65. data/spec/moneta/transformer_marshal_spec.rb +109 -0
  66. data/spec/moneta/transformer_value_marshal_spec.rb +109 -0
  67. data/spec/moneta/transformer_value_yaml_spec.rb +109 -0
  68. data/spec/monetaspecs.rb +14460 -3956
  69. metadata +16 -6
  70. data/lib/moneta/base.rb +0 -98
  71. data/lib/moneta/net.rb +0 -22
@@ -6,8 +6,6 @@ module Moneta
6
6
  #
7
7
  # @api public
8
8
  class Expires < Proxy
9
- # Constructor
10
- #
11
9
  # @param [Moneta store] adapter The underlying store
12
10
  # @param [Hash] options
13
11
  # @option options [String] :expires Default expiration time
@@ -17,7 +15,11 @@ module Moneta
17
15
  end
18
16
 
19
17
  def key?(key, options = {})
18
+ # Transformer might raise exception
20
19
  load_entry(key, options) != nil
20
+ rescue Exception
21
+ options.include?(:expires) && (options = options.dup; options.delete(:expires))
22
+ super(key, options)
21
23
  end
22
24
 
23
25
  def load(key, options = {})
@@ -28,10 +30,13 @@ module Moneta
28
30
 
29
31
  def store(key, value, options = {})
30
32
  return super if options.include?(:raw)
31
- if expires = (options.delete(:expires) || @expires)
33
+ expires = options.include?(:expires) && (options = options.dup; options.delete(:expires))
34
+ if expires ||= @expires
32
35
  super(key, [value, Time.now.to_i + expires], options)
33
- else
36
+ elsif Array === value || value == nil
34
37
  super(key, [value], options)
38
+ else
39
+ super(key, value, options)
35
40
  end
36
41
  value
37
42
  end
@@ -45,8 +50,9 @@ module Moneta
45
50
  private
46
51
 
47
52
  def load_entry(key, options)
48
- new_expires = options.delete(:expires)
49
- if entry = @adapter.load(key, options)
53
+ new_expires = options.include?(:expires) && (options = options.dup; options.delete(:expires))
54
+ entry = @adapter.load(key, options)
55
+ if entry != nil
50
56
  value, expires = entry
51
57
  if expires && Time.now.to_i > expires
52
58
  delete(key)
data/lib/moneta/lock.rb CHANGED
@@ -4,8 +4,6 @@ module Moneta
4
4
  # Locks the underlying stores with a Mutex
5
5
  # @api public
6
6
  class Lock < Wrapper
7
- # Constructor
8
- #
9
7
  # @param [Moneta store] adapter The underlying store
10
8
  # @param [Hash] options
11
9
  # @option options [String] :mutex (Mutex.new) Mutex object
data/lib/moneta/logger.rb CHANGED
@@ -33,8 +33,6 @@ module Moneta
33
33
  end
34
34
  end
35
35
 
36
- # Constructor
37
- #
38
36
  # @param [Moneta store] adapter The underlying store
39
37
  # @param [Hash] options
40
38
  # @option options [Object] :logger (Moneta::Logger::Format) Callable logger object
data/lib/moneta/mixins.rb CHANGED
@@ -1,65 +1,193 @@
1
1
  module Moneta
2
2
  # @api private
3
- module Mixins
4
- module WithOptions
5
- def with(options)
6
- OptionMerger.new(self, options)
7
- end
3
+ module OptionSupport
4
+ # @api public
5
+ def with(options)
6
+ OptionMerger.new(self, options)
7
+ end
8
8
 
9
- def raw
10
- @raw_store ||=
11
- begin
12
- store = with(:raw => true, :only => [:load, :store, :delete])
13
- store.instance_variable_set(:@raw_store, store)
14
- store
15
- end
16
- end
9
+ # @api public
10
+ def raw
11
+ @raw_store ||=
12
+ begin
13
+ store = with(:raw => true, :only => [:load, :store, :delete])
14
+ store.instance_variable_set(:@raw_store, store)
15
+ store
16
+ end
17
+ end
17
18
 
18
- def prefix(prefix)
19
- with(:prefix => prefix, :except => :clear)
20
- end
19
+ # @api public
20
+ def prefix(prefix)
21
+ with(:prefix => prefix, :except => :clear)
22
+ end
21
23
 
22
- def expires(expires)
23
- with(:expires => expires, :only => [:store, :increment])
24
- end
24
+ # @api public
25
+ def expires(expires)
26
+ with(:expires => expires, :only => [:store, :increment])
25
27
  end
28
+ end
26
29
 
27
- module IncrementSupport
28
- def increment(key, amount = 1, options = {})
29
- value = load(key, options)
30
- intvalue = value.to_i
31
- raise 'Tried to increment non integer value' unless value == nil || intvalue.to_s == value.to_s
32
- intvalue += amount
33
- store(key, intvalue.to_s, options)
34
- intvalue
35
- end
30
+ # Simple interface to key/value stores with Hash-like interface.
31
+ # @api public
32
+ module Defaults
33
+ include OptionSupport
34
+
35
+ # Exists the value with key
36
+ #
37
+ # @param [Object] key
38
+ # @return [Boolean]
39
+ # @param [Hash] options
40
+ # @api public
41
+ def key?(key, options = {})
42
+ load(key, options) != nil
36
43
  end
37
44
 
38
- module HashAdapter
39
- def initialize(options = {})
40
- @hash = {}
41
- end
45
+ # Atomically increment integer value with key
46
+ #
47
+ # Not every Moneta store implements this method,
48
+ # a NotImplementedError if it is not supported.
49
+ #
50
+ # This method also accepts negative amounts.
51
+ #
52
+ # @param [Object] key
53
+ # @param [Integer] amount
54
+ # @param [Hash] options
55
+ # @return [Object] value from store
56
+ # @api public
57
+ def increment(key, amount = 1, options = {})
58
+ raise NotImplementedError, 'increment is not supported'
59
+ end
42
60
 
43
- def key?(key, options = {})
44
- @hash.has_key?(key)
45
- end
61
+ # Atomically decrement integer value with key
62
+ #
63
+ # This is just syntactic sugar for calling #increment with a negative value.
64
+ #
65
+ # This method also accepts negative amounts.
66
+ #
67
+ # @param [Object] key
68
+ # @param [Integer] amount
69
+ # @param [Hash] options
70
+ # @return [Object] value from store
71
+ # @api public
72
+ def decrement(key, amount = 1, options = {})
73
+ increment(key, -amount, options)
74
+ end
46
75
 
47
- def load(key, options = {})
48
- @hash[key]
49
- end
76
+ # Explicitly close the store
77
+ # @return nil
78
+ # @api public
79
+ def close
80
+ end
50
81
 
51
- def store(key, value, options = {})
52
- @hash[key] = value
82
+ # Fetch a value with a key
83
+ #
84
+ # @overload fetch(key, options = {}, &block)
85
+ # retrieve a key. if the key is not available, execute the
86
+ # block and return its return value.
87
+ # @param [Object] key
88
+ # @param [Hash] options
89
+ # @return [Object] value from store
90
+ #
91
+ # @overload fetch(key, default, options = {})
92
+ # retrieve a key. if the key is not available, return the default value.
93
+ # @param [Object] key
94
+ # @param [Object] default Default value
95
+ # @param [Hash] options
96
+ # @return [Object] value from store
97
+ #
98
+ # @api public
99
+ def fetch(key, default = nil, options = nil)
100
+ if block_given?
101
+ raise ArgumentError, 'Only one argument accepted if block is given' if options
102
+ result = load(key, default || {})
103
+ result == nil ? yield(key) : result
104
+ else
105
+ result = load(key, options || {})
106
+ result == nil ? default : result
53
107
  end
108
+ end
54
109
 
55
- def delete(key, options = {})
56
- @hash.delete(key)
57
- end
110
+ # Fetch value with key. Return nil if the key doesn't exist
111
+ #
112
+ # @param [Object] key
113
+ # @return [Object] value
114
+ # @api public
115
+ def [](key)
116
+ load(key)
117
+ end
58
118
 
59
- def clear(options = {})
60
- @hash.clear
61
- self
62
- end
119
+ # Store value with key
120
+ #
121
+ # @param [Object] key
122
+ # @param [Object] value
123
+ # @return value
124
+ # @api public
125
+ def []=(key, value)
126
+ store(key, value)
127
+ end
128
+ end
129
+
130
+ # @api private
131
+ module IncrementSupport
132
+ # (see Defaults#increment)
133
+ # @api public
134
+ def increment(key, amount = 1, options = {})
135
+ value = load(key, options)
136
+ intvalue = value.to_i
137
+ raise 'Tried to increment non integer value' unless value == nil || intvalue.to_s == value.to_s
138
+ intvalue += amount
139
+ store(key, intvalue.to_s, options)
140
+ intvalue
141
+ end
142
+ end
143
+
144
+ # @api private
145
+ module HashAdapter
146
+ # (see Proxy#key?)
147
+ def key?(key, options = {})
148
+ @hash.has_key?(key)
149
+ end
150
+
151
+ # (see Proxy#load)
152
+ def load(key, options = {})
153
+ @hash[key]
154
+ end
155
+
156
+ # (see Proxy#store)
157
+ def store(key, value, options = {})
158
+ @hash[key] = value
159
+ end
160
+
161
+ # (see Proxy#delete)
162
+ def delete(key, options = {})
163
+ @hash.delete(key)
164
+ end
165
+
166
+ # (see Proxy#clear)
167
+ def clear(options = {})
168
+ @hash.clear
169
+ self
170
+ end
171
+ end
172
+
173
+ # @api private
174
+ module Net
175
+ DEFAULT_PORT = 9000
176
+
177
+ class Error < RuntimeError; end
178
+
179
+ def pack(o)
180
+ s = Marshal.dump(o)
181
+ [s.bytesize].pack('N') << s
182
+ end
183
+
184
+ def read(io)
185
+ size = io.read(4).unpack('N').first
186
+ Marshal.load(io.read(size))
187
+ end
188
+
189
+ def write(io, o)
190
+ io.write(pack(o))
63
191
  end
64
192
  end
65
193
  end
@@ -29,6 +29,8 @@ module Moneta
29
29
  end
30
30
  end
31
31
 
32
+ protected
33
+
32
34
  def wrap(method, *args)
33
35
  options = args.last
34
36
  options.merge!(@default_options[method]) if Hash === options && @default_options.include?(method)
data/lib/moneta/proxy.rb CHANGED
@@ -1,27 +1,32 @@
1
1
  module Moneta
2
2
  # Proxy base class
3
3
  # @api public
4
- class Proxy < Base
4
+ class Proxy
5
+ include Defaults
6
+
5
7
  attr_reader :adapter
6
8
 
7
- # Constructor
8
- #
9
9
  # @param [Moneta store] adapter underlying adapter
10
10
  # @param [Hash] options
11
11
  def initialize(adapter, options = {})
12
12
  @adapter = adapter
13
13
  end
14
14
 
15
- # Exists the value with key
16
- #
17
- # @param [Object] key
18
- # @return [Boolean]
19
- # @param [Hash] options
20
- # @api public
15
+ # (see Defaults#key?)
21
16
  def key?(key, options = {})
22
17
  @adapter.key?(key, options)
23
18
  end
24
19
 
20
+ # (see Defaults#increment)
21
+ def increment(key, amount = 1, options = {})
22
+ @adapter.increment(key, amount, options)
23
+ end
24
+
25
+ # (see Defaults#close)
26
+ def close
27
+ @adapter.close
28
+ end
29
+
25
30
  # Fetch value with key. Return nil if the key doesn't exist
26
31
  #
27
32
  # @param [Object] key
@@ -53,20 +58,6 @@ module Moneta
53
58
  @adapter.delete(key, options)
54
59
  end
55
60
 
56
- # Atomically increment integer value with key
57
- #
58
- # Not every Moneta store implements this method,
59
- # a NotImplementedError if it is not supported.
60
- #
61
- # @param [Object] key
62
- # @param [Integer] amount
63
- # @param [Hash] options
64
- # @return [Object] value from store
65
- # @api public
66
- def increment(key, amount = 1, options = {})
67
- @adapter.increment(key, amount, options)
68
- end
69
-
70
61
  # Clear all keys in this store
71
62
  #
72
63
  # @param [Hash] options
@@ -76,12 +67,5 @@ module Moneta
76
67
  @adapter.clear(options)
77
68
  self
78
69
  end
79
-
80
- # Close this store
81
- # @return nil
82
- # @api public
83
- def close
84
- @adapter.close
85
- end
86
70
  end
87
71
  end
data/lib/moneta/server.rb CHANGED
@@ -4,8 +4,6 @@ module Moneta
4
4
  # Moneta server
5
5
  # @api public
6
6
  class Server
7
- # Constructor
8
- #
9
7
  # @param [Hash] options
10
8
  # @option options [Integer] :port (9000) TCP port
11
9
  # @option options [String] :file Alternative Unix socket file name
data/lib/moneta/shared.rb CHANGED
@@ -11,8 +11,6 @@ module Moneta
11
11
  #
12
12
  # @api public
13
13
  class Shared < Wrapper
14
- # Constructor
15
- #
16
14
  # @param [Hash] options
17
15
  # @option options [Integer] :port (9000) TCP port
18
16
  # @option options [String] :host Server hostname
@@ -34,7 +32,7 @@ module Moneta
34
32
  end
35
33
  end
36
34
 
37
- private
35
+ protected
38
36
 
39
37
  def wrap(*args)
40
38
  @adapter ||= Adapters::Client.new(@options)
data/lib/moneta/stack.rb CHANGED
@@ -12,7 +12,9 @@ module Moneta
12
12
  # end
13
13
  #
14
14
  # @api public
15
- class Stack < Base
15
+ class Stack
16
+ include Defaults
17
+
16
18
  # @api private
17
19
  class DSL
18
20
  attr_reader :stack
@@ -22,6 +24,7 @@ module Moneta
22
24
  instance_eval(&block)
23
25
  end
24
26
 
27
+ # @api public
25
28
  def add(store = nil, &block)
26
29
  raise ArgumentError, 'Only argument or block allowed' if store && block
27
30
  @stack << (store || Moneta.build(&block))
@@ -35,23 +38,34 @@ module Moneta
35
38
  @stack = DSL.new(options, &block).stack
36
39
  end
37
40
 
41
+ # (see Proxy#key?)
38
42
  def key?(key, options = {})
39
- @stack.any? {|s| s.key?(key) }
43
+ @stack.any? {|s| s.key?(key, options) }
40
44
  end
41
45
 
46
+ # (see Proxy#load)
42
47
  def load(key, options = {})
43
48
  @stack.each do |s|
44
49
  value = s.load(key, options)
45
- return value if value
50
+ return value if value != nil
46
51
  end
47
52
  nil
48
53
  end
49
54
 
55
+ # (see Proxy#store)
50
56
  def store(key, value, options = {})
51
57
  @stack.each {|s| s.store(key, value, options) }
52
58
  value
53
59
  end
54
60
 
61
+ # (see Proxy#increment)
62
+ def increment(key, amount = 1, options = {})
63
+ last = nil
64
+ @stack.each {|s| last = s.increment(key, amount, options) }
65
+ last
66
+ end
67
+
68
+ # (see Proxy#delete)
55
69
  def delete(key, options = {})
56
70
  @stack.inject(nil) do |value, s|
57
71
  v = s.delete(key, options)
@@ -59,17 +73,13 @@ module Moneta
59
73
  end
60
74
  end
61
75
 
62
- def increment(key, amount = 1, options = {})
63
- last = nil
64
- @stack.each {|s| last = s.increment(key, amount, options) }
65
- last
66
- end
67
-
76
+ # (see Proxy#clear)
68
77
  def clear(options = {})
69
- @stack.each {|s| s.clear }
78
+ @stack.each {|s| s.clear(options) }
70
79
  self
71
80
  end
72
81
 
82
+ # (see Proxy#close)
73
83
  def close
74
84
  @stack.each {|s| s.close }
75
85
  nil