moneta 0.7.1 → 0.7.2

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.
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