moneta 1.1.1 → 1.4.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (207) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/.rubocop.yml +194 -0
  4. data/.travis.yml +65 -25
  5. data/CHANGES +36 -0
  6. data/CONTRIBUTORS +4 -2
  7. data/Gemfile +94 -65
  8. data/README.md +50 -25
  9. data/feature_matrix.yaml +3 -11
  10. data/lib/action_dispatch/middleware/session/moneta_store.rb +1 -0
  11. data/lib/active_support/cache/moneta_store.rb +5 -5
  12. data/lib/moneta.rb +18 -10
  13. data/lib/moneta/adapters/activerecord.rb +35 -19
  14. data/lib/moneta/adapters/activesupportcache.rb +3 -7
  15. data/lib/moneta/adapters/cassandra.rb +24 -16
  16. data/lib/moneta/adapters/client.rb +62 -21
  17. data/lib/moneta/adapters/couch.rb +225 -80
  18. data/lib/moneta/adapters/datamapper.rb +1 -0
  19. data/lib/moneta/adapters/file.rb +9 -6
  20. data/lib/moneta/adapters/hbase.rb +1 -1
  21. data/lib/moneta/adapters/kyotocabinet.rb +8 -7
  22. data/lib/moneta/adapters/leveldb.rb +1 -1
  23. data/lib/moneta/adapters/lmdb.rb +3 -4
  24. data/lib/moneta/adapters/lruhash.rb +29 -62
  25. data/lib/moneta/adapters/memcached.rb +1 -0
  26. data/lib/moneta/adapters/memcached/dalli.rb +1 -1
  27. data/lib/moneta/adapters/memcached/native.rb +10 -8
  28. data/lib/moneta/adapters/mongo.rb +264 -6
  29. data/lib/moneta/adapters/null.rb +1 -2
  30. data/lib/moneta/adapters/pstore.rb +3 -2
  31. data/lib/moneta/adapters/redis.rb +8 -4
  32. data/lib/moneta/adapters/restclient.rb +12 -3
  33. data/lib/moneta/adapters/riak.rb +2 -2
  34. data/lib/moneta/adapters/sequel.rb +68 -494
  35. data/lib/moneta/adapters/sequel/mysql.rb +66 -0
  36. data/lib/moneta/adapters/sequel/postgres.rb +80 -0
  37. data/lib/moneta/adapters/sequel/postgres_hstore.rb +240 -0
  38. data/lib/moneta/adapters/sequel/sqlite.rb +57 -0
  39. data/lib/moneta/adapters/sqlite.rb +10 -10
  40. data/lib/moneta/adapters/tokyotyrant.rb +1 -1
  41. data/lib/moneta/builder.rb +2 -3
  42. data/lib/moneta/create_support.rb +21 -0
  43. data/lib/moneta/dbm_adapter.rb +31 -0
  44. data/lib/moneta/{mixins.rb → defaults.rb} +3 -302
  45. data/lib/moneta/each_key_support.rb +27 -0
  46. data/lib/moneta/enumerable.rb +38 -0
  47. data/lib/moneta/expires.rb +12 -12
  48. data/lib/moneta/expires_support.rb +60 -0
  49. data/lib/moneta/fallback.rb +84 -0
  50. data/lib/moneta/hash_adapter.rb +68 -0
  51. data/lib/moneta/increment_support.rb +16 -0
  52. data/lib/moneta/lock.rb +7 -2
  53. data/lib/moneta/logger.rb +2 -2
  54. data/lib/moneta/nil_values.rb +35 -0
  55. data/lib/moneta/option_support.rb +51 -0
  56. data/lib/moneta/optionmerger.rb +0 -1
  57. data/lib/moneta/pool.rb +312 -30
  58. data/lib/moneta/proxy.rb +3 -3
  59. data/lib/moneta/server.rb +216 -65
  60. data/lib/moneta/shared.rb +13 -7
  61. data/lib/moneta/stack.rb +6 -6
  62. data/lib/moneta/synchronize.rb +3 -3
  63. data/lib/moneta/transformer.rb +68 -24
  64. data/lib/moneta/transformer/config.rb +63 -43
  65. data/lib/moneta/transformer/helper.rb +3 -3
  66. data/lib/moneta/transformer/helper/bson.rb +7 -14
  67. data/lib/moneta/utils.rb +3 -9
  68. data/lib/moneta/version.rb +1 -1
  69. data/lib/moneta/weak_each_key.rb +2 -4
  70. data/lib/rack/cache/moneta.rb +13 -11
  71. data/lib/rack/moneta_rest.rb +2 -2
  72. data/lib/rack/session/moneta.rb +3 -4
  73. data/moneta.gemspec +18 -4
  74. data/script/benchmarks +61 -34
  75. data/script/contributors +11 -6
  76. data/script/start-couchdb +27 -0
  77. data/script/start-hbase +3 -2
  78. data/script/start-services +3 -11
  79. data/spec/active_support/cache_moneta_store_spec.rb +30 -30
  80. data/spec/features/concurrent_create.rb +31 -10
  81. data/spec/features/concurrent_increment.rb +26 -19
  82. data/spec/features/create_expires.rb +15 -15
  83. data/spec/features/default_expires.rb +11 -12
  84. data/spec/features/expires.rb +215 -210
  85. data/spec/features/increment.rb +41 -41
  86. data/spec/features/store.rb +3 -3
  87. data/spec/helper.rb +21 -82
  88. data/spec/moneta/adapters/activerecord/standard_activerecord_spec.rb +1 -1
  89. data/spec/moneta/adapters/activerecord/standard_activerecord_with_expires_spec.rb +1 -1
  90. data/spec/moneta/adapters/activesupportcache/adapter_activesupportcache_spec.rb +4 -1
  91. data/spec/moneta/adapters/activesupportcache/adapter_activesupportcache_with_default_expires_spec.rb +4 -1
  92. data/spec/moneta/adapters/activesupportcache/standard_activesupportcache_spec.rb +14 -0
  93. data/spec/moneta/adapters/cassandra/standard_cassandra_spec.rb +1 -1
  94. data/spec/moneta/adapters/client/adapter_client_spec.rb +6 -6
  95. data/spec/moneta/adapters/client/client_helper.rb +24 -0
  96. data/spec/moneta/adapters/client/standard_client_tcp_spec.rb +8 -8
  97. data/spec/moneta/adapters/client/standard_client_unix_spec.rb +23 -7
  98. data/spec/moneta/adapters/couch/adapter_couch_spec.rb +199 -2
  99. data/spec/moneta/adapters/couch/standard_couch_spec.rb +9 -3
  100. data/spec/moneta/adapters/couch/standard_couch_with_expires_spec.rb +8 -2
  101. data/spec/moneta/adapters/daybreak/standard_daybreak_spec.rb +1 -1
  102. data/spec/moneta/adapters/daybreak/standard_daybreak_with_expires_spec.rb +1 -1
  103. data/spec/moneta/adapters/dbm/standard_dbm_spec.rb +1 -1
  104. data/spec/moneta/adapters/dbm/standard_dbm_with_expires_spec.rb +1 -1
  105. data/spec/moneta/adapters/faraday_helper.rb +9 -0
  106. data/spec/moneta/adapters/file/standard_file_spec.rb +2 -2
  107. data/spec/moneta/adapters/file/standard_file_with_expires_spec.rb +1 -1
  108. data/spec/moneta/adapters/gdbm/standard_gdbm_spec.rb +1 -1
  109. data/spec/moneta/adapters/gdbm/standard_gdbm_with_expires_spec.rb +1 -1
  110. data/spec/moneta/adapters/kyotocabinet/adapter_kyotocabinet_spec.rb +1 -1
  111. data/spec/moneta/adapters/kyotocabinet/standard_kyotocabinet_spec.rb +2 -2
  112. data/spec/moneta/adapters/kyotocabinet/standard_kyotocabinet_with_expires_spec.rb +2 -2
  113. data/spec/moneta/adapters/leveldb/standard_leveldb_spec.rb +1 -1
  114. data/spec/moneta/adapters/leveldb/standard_leveldb_with_expires_spec.rb +1 -1
  115. data/spec/moneta/adapters/lmdb/standard_lmdb_spec.rb +1 -1
  116. data/spec/moneta/adapters/lmdb/standard_lmdb_with_expires_spec.rb +1 -1
  117. data/spec/moneta/adapters/lruhash/adapter_lruhash_spec.rb +2 -2
  118. data/spec/moneta/adapters/lruhash/standard_lruhash_spec.rb +1 -1
  119. data/spec/moneta/adapters/lruhash/standard_lruhash_with_expires_spec.rb +1 -1
  120. data/spec/moneta/adapters/memcached/adapter_memcached_spec.rb +1 -1
  121. data/spec/moneta/adapters/memcached/dalli/adapter_memcached_dalli_spec.rb +1 -1
  122. data/spec/moneta/adapters/memcached/dalli/adapter_memcached_dalli_with_default_expires_spec.rb +1 -1
  123. data/spec/moneta/adapters/memcached/dalli/standard_memcached_dalli_spec.rb +1 -1
  124. data/spec/moneta/adapters/memcached/native/adapter_memcached_native_spec.rb +1 -1
  125. data/spec/moneta/adapters/memcached/native/adapter_memcached_native_with_default_expires_spec.rb +1 -1
  126. data/spec/moneta/adapters/memcached/native/standard_memcached_native_spec.rb +1 -1
  127. data/spec/moneta/adapters/memcached/standard_memcached_spec.rb +1 -1
  128. data/spec/moneta/adapters/{memcached/helper.rb → memcached_helper.rb} +0 -0
  129. data/spec/moneta/adapters/memory/standard_memory_spec.rb +1 -1
  130. data/spec/moneta/adapters/memory/standard_memory_with_compress_spec.rb +1 -1
  131. data/spec/moneta/adapters/memory/standard_memory_with_expires_spec.rb +1 -1
  132. data/spec/moneta/adapters/memory/standard_memory_with_json_key_serializer_spec.rb +1 -1
  133. data/spec/moneta/adapters/memory/standard_memory_with_json_serializer_spec.rb +1 -1
  134. data/spec/moneta/adapters/memory/standard_memory_with_json_value_serializer_spec.rb +2 -2
  135. data/spec/moneta/adapters/memory/standard_memory_with_prefix_spec.rb +39 -2
  136. data/spec/moneta/adapters/memory/standard_memory_with_snappy_compress_spec.rb +2 -2
  137. data/spec/moneta/adapters/mongo/adapter_mongo_spec.rb +32 -2
  138. data/spec/moneta/adapters/mongo/adapter_mongo_with_default_expires_spec.rb +5 -3
  139. data/spec/moneta/adapters/mongo/standard_mongo_spec.rb +2 -2
  140. data/spec/moneta/adapters/null/null_adapter_spec.rb +1 -1
  141. data/spec/moneta/adapters/pstore/standard_pstore_spec.rb +1 -1
  142. data/spec/moneta/adapters/pstore/standard_pstore_with_expires_spec.rb +1 -1
  143. data/spec/moneta/adapters/redis/standard_redis_spec.rb +1 -1
  144. data/spec/moneta/adapters/restclient/adapter_restclient_spec.rb +7 -5
  145. data/spec/moneta/adapters/restclient/helper.rb +12 -0
  146. data/spec/moneta/adapters/restclient/standard_restclient_spec.rb +9 -6
  147. data/spec/moneta/adapters/riak/standard_riak_with_expires_spec.rb +4 -0
  148. data/spec/moneta/adapters/sdbm/standard_sdbm_spec.rb +1 -1
  149. data/spec/moneta/adapters/sdbm/standard_sdbm_with_expires_spec.rb +1 -1
  150. data/spec/moneta/adapters/sequel/adapter_sequel_spec.rb +7 -34
  151. data/spec/moneta/adapters/sequel/helper.rb +37 -0
  152. data/spec/moneta/adapters/sequel/standard_sequel_spec.rb +5 -11
  153. data/spec/moneta/adapters/sequel/standard_sequel_with_expires_spec.rb +8 -9
  154. data/spec/moneta/adapters/sqlite/standard_sqlite_spec.rb +1 -1
  155. data/spec/moneta/adapters/sqlite/standard_sqlite_with_expires_spec.rb +1 -1
  156. data/spec/moneta/adapters/tdb/standard_tdb_spec.rb +1 -1
  157. data/spec/moneta/adapters/tdb/standard_tdb_with_expires_spec.rb +1 -1
  158. data/spec/moneta/adapters/tokyocabinet/standard_tokyocabinet_spec.rb +1 -1
  159. data/spec/moneta/adapters/tokyocabinet/standard_tokyocabinet_with_expires_spec.rb +1 -1
  160. data/spec/moneta/adapters/tokyotyrant/adapter_tokyotyrant_spec.rb +6 -2
  161. data/spec/moneta/adapters/tokyotyrant/helper.rb +12 -0
  162. data/spec/moneta/adapters/tokyotyrant/standard_tokyotyrant_spec.rb +5 -2
  163. data/spec/moneta/adapters/tokyotyrant/standard_tokyotyrant_with_expires_spec.rb +5 -1
  164. data/spec/moneta/adapters/yaml/standard_yaml_spec.rb +1 -1
  165. data/spec/moneta/adapters/yaml/standard_yaml_with_expires_spec.rb +1 -1
  166. data/spec/moneta/builder_spec.rb +22 -0
  167. data/spec/moneta/proxies/enumerable/enumerable_spec.rb +26 -0
  168. data/spec/moneta/proxies/expires/expires_file_spec.rb +1 -1
  169. data/spec/moneta/proxies/fallback/fallback_spec.rb +42 -0
  170. data/spec/moneta/proxies/pool/pool_spec.rb +319 -6
  171. data/spec/moneta/proxies/shared/shared_tcp_spec.rb +14 -4
  172. data/spec/moneta/proxies/shared/shared_unix_spec.rb +14 -4
  173. data/spec/moneta/proxies/transformer/transformer_bencode_spec.rb +1 -1
  174. data/spec/moneta/proxies/transformer/transformer_bert_spec.rb +3 -3
  175. data/spec/moneta/proxies/transformer/transformer_bson_spec.rb +2 -2
  176. data/spec/moneta/proxies/transformer/transformer_json_spec.rb +1 -1
  177. data/spec/moneta/proxies/transformer/transformer_key_marshal_spec.rb +1 -1
  178. data/spec/moneta/proxies/transformer/transformer_key_yaml_spec.rb +1 -1
  179. data/spec/moneta/proxies/transformer/transformer_marshal_base64_spec.rb +1 -1
  180. data/spec/moneta/proxies/transformer/transformer_marshal_escape_spec.rb +8 -4
  181. data/spec/moneta/proxies/transformer/transformer_marshal_hex_spec.rb +1 -1
  182. data/spec/moneta/proxies/transformer/transformer_marshal_hmac_spec.rb +1 -1
  183. data/spec/moneta/proxies/transformer/transformer_marshal_prefix_base64_spec.rb +33 -0
  184. data/spec/moneta/proxies/transformer/transformer_marshal_prefix_spec.rb +1 -1
  185. data/spec/moneta/proxies/transformer/transformer_marshal_qp_spec.rb +1 -1
  186. data/spec/moneta/proxies/transformer/transformer_marshal_spec.rb +1 -1
  187. data/spec/moneta/proxies/transformer/transformer_marshal_urlsafe_base64_spec.rb +1 -1
  188. data/spec/moneta/proxies/transformer/transformer_marshal_uuencode_spec.rb +1 -1
  189. data/spec/moneta/proxies/transformer/transformer_msgpack_spec.rb +1 -1
  190. data/spec/moneta/proxies/transformer/transformer_ox_spec.rb +1 -1
  191. data/spec/moneta/proxies/transformer/transformer_php_spec.rb +1 -1
  192. data/spec/moneta/proxies/transformer/transformer_tnet_spec.rb +1 -1
  193. data/spec/moneta/proxies/transformer/transformer_yaml_spec.rb +2 -2
  194. data/spec/moneta/proxies/weak_each_key/weak_each_key_spec.rb +0 -2
  195. data/spec/restserver.rb +55 -0
  196. metadata +136 -32
  197. data/lib/moneta/adapters/mongo/base.rb +0 -103
  198. data/lib/moneta/adapters/mongo/moped.rb +0 -164
  199. data/lib/moneta/adapters/mongo/official.rb +0 -157
  200. data/script/install-kyotocabinet +0 -17
  201. data/spec/moneta/adapters/mongo/adapter_mongo_moped_spec.rb +0 -25
  202. data/spec/moneta/adapters/mongo/adapter_mongo_moped_with_default_expires_spec.rb +0 -12
  203. data/spec/moneta/adapters/mongo/adapter_mongo_official_spec.rb +0 -25
  204. data/spec/moneta/adapters/mongo/adapter_mongo_official_with_default_expires_spec.rb +0 -12
  205. data/spec/moneta/adapters/mongo/standard_mongo_moped_spec.rb +0 -7
  206. data/spec/moneta/adapters/mongo/standard_mongo_official_spec.rb +0 -7
  207. data/spec/quality_spec.rb +0 -51
@@ -48,7 +48,7 @@ module Moneta
48
48
  def load(key, options = {})
49
49
  value = @backend[key]
50
50
  # raise if there is an error and the error is not "no record"
51
- error if value.nil? && @backend.ecode != ENOREC
51
+ error if value == nil && @backend.ecode != ENOREC
52
52
  value && unpack(value)
53
53
  end
54
54
 
@@ -17,12 +17,12 @@ module Moneta
17
17
  adapter = @proxies.first
18
18
  if Array === adapter
19
19
  klass, options, block = adapter
20
- adapter = new_proxy(klass, options, &block)
20
+ adapter = new_proxy(klass, options.dup, &block)
21
21
  check_arity(klass, adapter, 1)
22
22
  end
23
23
  @proxies[1..-1].inject([adapter]) do |result, proxy|
24
24
  klass, options, block = proxy
25
- proxy = new_proxy(klass, result.last, options, &block)
25
+ proxy = new_proxy(klass, result.last, options.dup, &block)
26
26
  check_arity(klass, proxy, 2)
27
27
  result << proxy
28
28
  end
@@ -79,5 +79,4 @@ Please check your Moneta builder block:
79
79
  }) if args != expected
80
80
  end
81
81
  end
82
-
83
82
  end
@@ -0,0 +1,21 @@
1
+ module Moneta
2
+ # Implements simple create using key? and store.
3
+ #
4
+ # This is sufficient for non-shared stores or if atomicity is not required.
5
+ # @api private
6
+ module CreateSupport
7
+ # (see Defaults#create)
8
+ def create(key, value, options = {})
9
+ if key? key
10
+ false
11
+ else
12
+ store(key, value, options)
13
+ true
14
+ end
15
+ end
16
+
17
+ def self.included(base)
18
+ base.supports(:create) if base.respond_to?(:supports)
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,31 @@
1
+ module Moneta
2
+ # This is for adapters that conform to the DBM interface
3
+ # @api private
4
+ module DBMAdapter
5
+ include HashAdapter
6
+
7
+ # (see Proxy#close)
8
+ def close
9
+ @backend.close
10
+ nil
11
+ end
12
+
13
+ # (see Proxy#merge!)
14
+ def merge!(pairs, options = {})
15
+ hash =
16
+ if block_given?
17
+ keys = pairs.map { |k, _| k }
18
+ old_pairs = Hash[slice(*keys)]
19
+ Hash[pairs.map do |key, new_value|
20
+ new_value = yield(key, old_pairs[key], new_value) if old_pairs.key?(key)
21
+ [key, new_value]
22
+ end.to_a]
23
+ else
24
+ Hash === pairs ? pairs : Hash[pairs.to_a]
25
+ end
26
+
27
+ @backend.update(hash)
28
+ self
29
+ end
30
+ end
31
+ end
@@ -1,58 +1,8 @@
1
1
  module Moneta
2
- # @api private
3
- module OptionSupport
4
- # Return Moneta store with default options or additional proxies
5
- #
6
- # @param [Hash] options Options to merge
7
- # @return [Moneta store]
8
- #
9
- # @api public
10
- def with(options = nil, &block)
11
- adapter = self
12
- if block
13
- builder = Builder.new(&block)
14
- builder.adapter(adapter)
15
- adapter = builder.build.last
16
- end
17
- options ? OptionMerger.new(adapter, options) : adapter
18
- end
19
-
20
- # Return Moneta store with default option raw: true
21
- #
22
- # @return [OptionMerger]
23
- # @api public
24
- def raw
25
- @raw_store ||=
26
- begin
27
- store = with(raw: true, only: [:load, :store, :create, :delete])
28
- store.instance_variable_set(:@raw_store, store)
29
- store
30
- end
31
- end
32
-
33
- # Return Moneta store with default prefix option
34
- #
35
- # @param [String] prefix Key prefix
36
- # @return [OptionMerger]
37
- # @api public
38
- def prefix(prefix)
39
- with(prefix: prefix, except: :clear)
40
- end
41
-
42
- # Return Moneta store with default expiration time
43
- #
44
- # @param [Integer] expires Default expiration time
45
- # @return [OptionMerger]
46
- # @api public
47
- def expires(expires)
48
- with(expires: expires, only: [:store, :create, :increment])
49
- end
50
- end
51
-
52
2
  # Simple interface to key/value stores with Hash-like interface.
53
3
  # @api public
54
4
  module Defaults
55
- include OptionSupport
5
+ include ::Moneta::OptionSupport
56
6
 
57
7
  # @api private
58
8
  module ClassMethods
@@ -151,8 +101,7 @@ module Moneta
151
101
  # Explicitly close the store
152
102
  # @return nil
153
103
  # @api public
154
- def close
155
- end
104
+ def close; end
156
105
 
157
106
  # Fetch a value with a key
158
107
  #
@@ -338,7 +287,7 @@ module Moneta
338
287
  # @yieldreturn [Object] The value to use for overwriting
339
288
  # @return [self]
340
289
  # @api public
341
- def merge!(pairs, options={})
290
+ def merge!(pairs, options = {})
342
291
  pairs.each do |key, value|
343
292
  if block_given?
344
293
  existing = load(key, options)
@@ -368,252 +317,4 @@ module Moneta
368
317
  features.include?(feature)
369
318
  end
370
319
  end
371
-
372
- # This contains overrides of methods in Defaults where additional nil
373
- # checks are required, because nil values are possible in the store.
374
- # @api private
375
- module NilValues
376
- def fetch_values(*keys, **options)
377
- values = values_at(*keys, **options)
378
- return values unless block_given?
379
- keys.zip(values).map do |key, value|
380
- if value == nil && !key?(key)
381
- yield key
382
- else
383
- value
384
- end
385
- end
386
- end
387
-
388
- def slice(*keys, **options)
389
- keys.zip(values_at(*keys, **options)).reject do |key, value|
390
- value == nil && !key?(key)
391
- end
392
- end
393
-
394
- def merge!(pairs, options={})
395
- pairs.each do |key, value|
396
- if block_given? && key?(key, options)
397
- existing = load(key, options)
398
- value = yield(key, existing, value)
399
- end
400
- store(key, value, options)
401
- end
402
- self
403
- end
404
- end
405
-
406
- # @api private
407
- module IncrementSupport
408
- # (see Defaults#increment)
409
- def increment(key, amount = 1, options = {})
410
- value = Utils.to_int(load(key, options)) + amount
411
- store(key, value.to_s, options)
412
- value
413
- end
414
-
415
- def self.included(base)
416
- base.supports(:increment) if base.respond_to?(:supports)
417
- end
418
- end
419
-
420
- # This provides an each_key implementation that works in most cases.
421
- # @api private
422
- module EachKeySupport
423
- def each_key
424
- return enum_for(:each_key) unless block_given?
425
-
426
- if @backend.respond_to?(:each_key)
427
- @backend.each_key { |key| yield key }
428
- elsif @backend.respond_to?(:keys)
429
- if keys = @backend.keys
430
- keys.each { |key| yield key }
431
- end
432
- elsif @backend.respond_to?(:each)
433
- @backend.each { |key, _| yield key }
434
- else
435
- raise ::NotImplementedError, "No enumerable found on backend"
436
- end
437
-
438
- self
439
- end
440
-
441
- def self.included(base)
442
- base.supports(:each_key) if base.respond_to?(:supports)
443
- end
444
- end
445
-
446
- # Implements simple create using key? and store.
447
- #
448
- # This is sufficient for non-shared stores or if atomicity is not required.
449
- # @api private
450
- module CreateSupport
451
- # (see Defaults#create)
452
- def create(key, value, options = {})
453
- if key? key
454
- false
455
- else
456
- store(key, value, options)
457
- true
458
- end
459
- end
460
-
461
- def self.included(base)
462
- base.supports(:create) if base.respond_to?(:supports)
463
- end
464
- end
465
-
466
- # @api private
467
- module HashAdapter
468
- attr_reader :backend
469
-
470
- # (see Proxy#key?)
471
- def key?(key, options = {})
472
- @backend.has_key?(key)
473
- end
474
-
475
- # (see Proxy#load)
476
- def load(key, options = {})
477
- @backend[key]
478
- end
479
-
480
- # (see Proxy#store)
481
- def store(key, value, options = {})
482
- @backend[key] = value
483
- end
484
-
485
- # (see Proxy#delete)
486
- def delete(key, options = {})
487
- @backend.delete(key)
488
- end
489
-
490
- # (see Proxy#clear)
491
- def clear(options = {})
492
- @backend.clear
493
- self
494
- end
495
-
496
- # (see Defaults#values_at)
497
- def values_at(*keys, **options)
498
- return super unless @backend.respond_to? :values_at
499
- @backend.values_at(*keys)
500
- end
501
-
502
- # (see Defaults#fetch_values)
503
- def fetch_values(*keys, **options, &defaults)
504
- return super unless @backend.respond_to? :fetch_values
505
- defaults ||= {} # prevents KeyError
506
- @backend.fetch_values(*keys, &defaults)
507
- end
508
-
509
- # (see Defaults#slice)
510
- def slice(*keys, **options)
511
- return super unless @backend.respond_to? :slice
512
- @backend.slice(*keys)
513
- end
514
-
515
- # (see Defaults#merge!)
516
- def merge!(pairs, options={}, &block)
517
- return super unless method = [:merge!, :update].find do |method|
518
- @backend.respond_to? method
519
- end
520
-
521
- hash = Hash === pairs ? pairs : Hash[pairs.to_a]
522
- case method
523
- when :merge!
524
- @backend.merge!(hash, &block)
525
- when :update
526
- @backend.update(hash, &block)
527
- end
528
-
529
- self
530
- end
531
- end
532
-
533
- # This is for adapters that conform to the DBM interface
534
- # @api private
535
- module DBMAdapter
536
- include HashAdapter
537
-
538
- # (see Proxy#close)
539
- def close
540
- @backend.close
541
- nil
542
- end
543
-
544
- # (see Proxy#merge!)
545
- def merge!(pairs, options = {})
546
- hash =
547
- if block_given?
548
- keys = pairs.map { |k, _| k }
549
- old_pairs = Hash[slice(*keys)]
550
- Hash[pairs.map do |key, new_value|
551
- new_value = yield(key, old_pairs[key], new_value) if old_pairs.key?(key)
552
- [key, new_value]
553
- end.to_a]
554
- else
555
- Hash === pairs ? pairs : Hash[pairs.to_a]
556
- end
557
-
558
- @backend.update(hash)
559
- self
560
- end
561
- end
562
-
563
- # This mixin handles the calculation of expiration times.
564
- #
565
- #
566
- module ExpiresSupport
567
- attr_accessor :default_expires
568
-
569
- protected
570
-
571
- # Calculates the time when something will expire.
572
- #
573
- # This method considers false and 0 as "no-expire" and every positive
574
- # number as a time to live in seconds.
575
- #
576
- # @param [Hash] options Options hash
577
- # @option options [0,false,nil,Numeric] :expires expires value given by user
578
- # @param [0,false,nil,Numeric] default default expiration time
579
- #
580
- # @return [false] if it should not expire
581
- # @return [Time] the time when something should expire
582
- # @return [nil] if it is not known
583
- def expires_at(options, default = @default_expires)
584
- value = expires_value(options, default)
585
- Numeric === value ? Time.now + value : value
586
- end
587
-
588
- # Calculates the number of seconds something should last.
589
- #
590
- # This method considers false and 0 as "no-expire" and every positive
591
- # number as a time to live in seconds.
592
- #
593
- # @param [Hash] options Options hash
594
- # @option options [0,false,nil,Numeric] :expires expires value given by user
595
- # @param [0,false,nil,Numeric] default default expiration time
596
- #
597
- # @return [false] if it should not expire
598
- # @return [Numeric] seconds until expiration
599
- # @return [nil] if it is not known
600
- def expires_value(options, default = @default_expires)
601
- case value = options[:expires]
602
- when 0, false
603
- false
604
- when nil
605
- default ? default.to_r : nil
606
- when Numeric
607
- value = value.to_r
608
- raise ArgumentError, ":expires must be a positive value, got #{value}" if value < 0
609
- value
610
- else
611
- raise ArgumentError, ":expires must be Numeric or false, got #{value.inspect}"
612
- end
613
- end
614
-
615
- def self.included(base)
616
- base.supports(:expires) if base.respond_to?(:supports)
617
- end
618
- end
619
320
  end
@@ -0,0 +1,27 @@
1
+ module Moneta
2
+ # This provides an each_key implementation that works in most cases.
3
+ # @api private
4
+ module EachKeySupport
5
+ def each_key
6
+ return enum_for(:each_key) unless block_given?
7
+
8
+ if @backend.respond_to?(:each_key)
9
+ @backend.each_key { |key| yield key }
10
+ elsif @backend.respond_to?(:keys)
11
+ if keys = @backend.keys
12
+ keys.each { |key| yield key }
13
+ end
14
+ elsif @backend.respond_to?(:each)
15
+ @backend.each { |key, _| yield key }
16
+ else
17
+ raise ::NotImplementedError, "No enumerable found on backend"
18
+ end
19
+
20
+ self
21
+ end
22
+
23
+ def self.included(base)
24
+ base.supports(:each_key) if base.respond_to?(:supports)
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,38 @@
1
+ module Moneta
2
+ # Adds the Ruby {Enumerable} API to the store. The underlying store must
3
+ # support `:each_key`.
4
+ #
5
+ # @example Adding to a builder
6
+ # Moneta.build do
7
+ # # It should be the top middleware
8
+ # use :Enumerable
9
+ # adapter :DBM
10
+ # end
11
+ #
12
+ # @api public
13
+ class Enumerable < Proxy
14
+ include ::Enumerable
15
+
16
+ def initialize(adapter, options = {})
17
+ raise "Adapter must support :each_key" unless adapter.supports? :each_key
18
+ super
19
+ end
20
+
21
+ # Enumerate over all pairs in the store
22
+ #
23
+ # @overload each
24
+ # @return [Enumerator]
25
+ #
26
+ # @overload each
27
+ # @yieldparam pair [Array<(Object, Object)>] Each pair is yielded
28
+ # @return [self]
29
+ #
30
+ def each
31
+ return enum_for(:each) unless block_given?
32
+ each_key { |key| yield key, load(key) }
33
+ self
34
+ end
35
+
36
+ alias each_pair each
37
+ end
38
+ end