moneta 1.2.0 → 1.4.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (166) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +418 -0
  3. data/.gitignore +2 -0
  4. data/.rubocop.yml +27 -9
  5. data/CHANGES +28 -0
  6. data/CONTRIBUTORS +4 -2
  7. data/Gemfile +12 -8
  8. data/README.md +20 -18
  9. data/feature_matrix.yaml +2 -11
  10. data/lib/moneta.rb +9 -9
  11. data/lib/moneta/adapters/client.rb +56 -19
  12. data/lib/moneta/adapters/couch.rb +5 -0
  13. data/lib/moneta/adapters/mongo.rb +264 -7
  14. data/lib/moneta/adapters/redis.rb +5 -1
  15. data/lib/moneta/adapters/sequel.rb +45 -464
  16. data/lib/moneta/adapters/sequel/mysql.rb +66 -0
  17. data/lib/moneta/adapters/sequel/postgres.rb +80 -0
  18. data/lib/moneta/adapters/sequel/postgres_hstore.rb +240 -0
  19. data/lib/moneta/adapters/sequel/sqlite.rb +57 -0
  20. data/lib/moneta/adapters/sqlite.rb +7 -7
  21. data/lib/moneta/builder.rb +2 -2
  22. data/lib/moneta/create_support.rb +21 -0
  23. data/lib/moneta/dbm_adapter.rb +31 -0
  24. data/lib/moneta/{mixins.rb → defaults.rb} +1 -302
  25. data/lib/moneta/each_key_support.rb +27 -0
  26. data/lib/moneta/expires_support.rb +60 -0
  27. data/lib/moneta/hash_adapter.rb +68 -0
  28. data/lib/moneta/increment_support.rb +16 -0
  29. data/lib/moneta/lock.rb +6 -1
  30. data/lib/moneta/nil_values.rb +35 -0
  31. data/lib/moneta/option_support.rb +51 -0
  32. data/lib/moneta/pool.rb +38 -6
  33. data/lib/moneta/proxy.rb +1 -1
  34. data/lib/moneta/server.rb +215 -61
  35. data/lib/moneta/shared.rb +13 -7
  36. data/lib/moneta/transformer.rb +50 -8
  37. data/lib/moneta/transformer/config.rb +59 -40
  38. data/lib/moneta/transformer/helper.rb +2 -2
  39. data/lib/moneta/transformer/helper/bson.rb +5 -15
  40. data/lib/moneta/version.rb +1 -1
  41. data/lib/rack/cache/moneta.rb +14 -15
  42. data/moneta.gemspec +14 -8
  43. data/script/benchmarks +7 -3
  44. data/script/contributors +11 -6
  45. data/script/start-couchdb +27 -0
  46. data/script/start-hbase +2 -2
  47. data/script/start-services +3 -3
  48. data/spec/active_support/cache_moneta_store_spec.rb +37 -39
  49. data/spec/features/concurrent_increment.rb +2 -3
  50. data/spec/features/create_expires.rb +15 -15
  51. data/spec/features/default_expires.rb +11 -12
  52. data/spec/features/expires.rb +215 -210
  53. data/spec/features/store.rb +3 -3
  54. data/spec/helper.rb +33 -41
  55. data/spec/moneta/adapters/activerecord/adapter_activerecord_existing_connection_spec.rb +3 -1
  56. data/spec/moneta/adapters/activerecord/adapter_activerecord_spec.rb +15 -7
  57. data/spec/moneta/adapters/activerecord/standard_activerecord_spec.rb +6 -3
  58. data/spec/moneta/adapters/activerecord/standard_activerecord_with_expires_spec.rb +6 -3
  59. data/spec/moneta/adapters/activesupportcache/adapter_activesupportcache_spec.rb +3 -3
  60. data/spec/moneta/adapters/activesupportcache/adapter_activesupportcache_with_default_expires_spec.rb +2 -2
  61. data/spec/moneta/adapters/cassandra/standard_cassandra_spec.rb +1 -1
  62. data/spec/moneta/adapters/client/adapter_client_spec.rb +6 -6
  63. data/spec/moneta/adapters/client/client_helper.rb +24 -0
  64. data/spec/moneta/adapters/client/standard_client_tcp_spec.rb +8 -8
  65. data/spec/moneta/adapters/client/standard_client_unix_spec.rb +23 -7
  66. data/spec/moneta/adapters/couch/adapter_couch_spec.rb +1 -1
  67. data/spec/moneta/adapters/couch/standard_couch_spec.rb +2 -2
  68. data/spec/moneta/adapters/couch/standard_couch_with_expires_spec.rb +2 -2
  69. data/spec/moneta/adapters/datamapper/adapter_datamapper_spec.rb +25 -8
  70. data/spec/moneta/adapters/datamapper/standard_datamapper_spec.rb +2 -2
  71. data/spec/moneta/adapters/datamapper/standard_datamapper_with_expires_spec.rb +2 -2
  72. data/spec/moneta/adapters/datamapper/standard_datamapper_with_repository_spec.rb +2 -2
  73. data/spec/moneta/adapters/daybreak/standard_daybreak_spec.rb +1 -1
  74. data/spec/moneta/adapters/daybreak/standard_daybreak_with_expires_spec.rb +1 -1
  75. data/spec/moneta/adapters/dbm/standard_dbm_spec.rb +1 -1
  76. data/spec/moneta/adapters/dbm/standard_dbm_with_expires_spec.rb +1 -1
  77. data/spec/moneta/adapters/file/standard_file_spec.rb +2 -2
  78. data/spec/moneta/adapters/file/standard_file_with_expires_spec.rb +1 -1
  79. data/spec/moneta/adapters/gdbm/standard_gdbm_spec.rb +1 -1
  80. data/spec/moneta/adapters/gdbm/standard_gdbm_with_expires_spec.rb +1 -1
  81. data/spec/moneta/adapters/kyotocabinet/adapter_kyotocabinet_spec.rb +1 -1
  82. data/spec/moneta/adapters/kyotocabinet/standard_kyotocabinet_spec.rb +2 -2
  83. data/spec/moneta/adapters/kyotocabinet/standard_kyotocabinet_with_expires_spec.rb +2 -2
  84. data/spec/moneta/adapters/leveldb/standard_leveldb_spec.rb +1 -1
  85. data/spec/moneta/adapters/leveldb/standard_leveldb_with_expires_spec.rb +1 -1
  86. data/spec/moneta/adapters/lmdb/standard_lmdb_spec.rb +1 -1
  87. data/spec/moneta/adapters/lmdb/standard_lmdb_with_expires_spec.rb +1 -1
  88. data/spec/moneta/adapters/lruhash/standard_lruhash_spec.rb +1 -1
  89. data/spec/moneta/adapters/lruhash/standard_lruhash_with_expires_spec.rb +1 -1
  90. data/spec/moneta/adapters/memcached/dalli/adapter_memcached_dalli_spec.rb +13 -3
  91. data/spec/moneta/adapters/memcached/native/adapter_memcached_native_spec.rb +13 -3
  92. data/spec/moneta/adapters/memory/standard_memory_spec.rb +1 -1
  93. data/spec/moneta/adapters/memory/standard_memory_with_compress_spec.rb +1 -1
  94. data/spec/moneta/adapters/memory/standard_memory_with_expires_spec.rb +1 -1
  95. data/spec/moneta/adapters/memory/standard_memory_with_json_key_serializer_spec.rb +1 -1
  96. data/spec/moneta/adapters/memory/standard_memory_with_json_serializer_spec.rb +1 -1
  97. data/spec/moneta/adapters/memory/standard_memory_with_json_value_serializer_spec.rb +2 -2
  98. data/spec/moneta/adapters/memory/standard_memory_with_prefix_spec.rb +39 -2
  99. data/spec/moneta/adapters/memory/standard_memory_with_snappy_compress_spec.rb +2 -2
  100. data/spec/moneta/adapters/mongo/adapter_mongo_spec.rb +32 -2
  101. data/spec/moneta/adapters/mongo/adapter_mongo_with_default_expires_spec.rb +6 -4
  102. data/spec/moneta/adapters/mongo/standard_mongo_spec.rb +2 -2
  103. data/spec/moneta/adapters/pstore/standard_pstore_spec.rb +1 -1
  104. data/spec/moneta/adapters/pstore/standard_pstore_with_expires_spec.rb +1 -1
  105. data/spec/moneta/adapters/redis/adapter_redis_spec.rb +13 -3
  106. data/spec/moneta/adapters/redis/standard_redis_spec.rb +9 -2
  107. data/spec/moneta/adapters/sdbm/standard_sdbm_spec.rb +1 -1
  108. data/spec/moneta/adapters/sdbm/standard_sdbm_with_expires_spec.rb +1 -1
  109. data/spec/moneta/adapters/sequel/adapter_sequel_spec.rb +11 -38
  110. data/spec/moneta/adapters/sequel/helper.rb +42 -0
  111. data/spec/moneta/adapters/sequel/standard_sequel_spec.rb +6 -12
  112. data/spec/moneta/adapters/sequel/standard_sequel_with_expires_spec.rb +9 -10
  113. data/spec/moneta/adapters/sqlite/adapter_sqlite_spec.rb +1 -1
  114. data/spec/moneta/adapters/sqlite/standard_sqlite_spec.rb +2 -2
  115. data/spec/moneta/adapters/sqlite/standard_sqlite_with_expires_spec.rb +2 -2
  116. data/spec/moneta/adapters/tdb/standard_tdb_spec.rb +1 -1
  117. data/spec/moneta/adapters/tdb/standard_tdb_with_expires_spec.rb +1 -1
  118. data/spec/moneta/adapters/tokyocabinet/standard_tokyocabinet_spec.rb +1 -1
  119. data/spec/moneta/adapters/tokyocabinet/standard_tokyocabinet_with_expires_spec.rb +1 -1
  120. data/spec/moneta/adapters/yaml/standard_yaml_spec.rb +1 -1
  121. data/spec/moneta/adapters/yaml/standard_yaml_with_expires_spec.rb +1 -1
  122. data/spec/moneta/builder_spec.rb +22 -0
  123. data/spec/moneta/proxies/expires/expires_file_spec.rb +1 -1
  124. data/spec/moneta/proxies/pool/pool_spec.rb +31 -3
  125. data/spec/moneta/proxies/shared/shared_tcp_spec.rb +14 -4
  126. data/spec/moneta/proxies/shared/shared_unix_spec.rb +14 -4
  127. data/spec/moneta/proxies/transformer/transformer_bencode_spec.rb +1 -1
  128. data/spec/moneta/proxies/transformer/transformer_bert_spec.rb +3 -3
  129. data/spec/moneta/proxies/transformer/transformer_bson_spec.rb +2 -2
  130. data/spec/moneta/proxies/transformer/transformer_json_spec.rb +1 -1
  131. data/spec/moneta/proxies/transformer/transformer_key_marshal_spec.rb +1 -1
  132. data/spec/moneta/proxies/transformer/transformer_key_yaml_spec.rb +1 -1
  133. data/spec/moneta/proxies/transformer/transformer_marshal_base64_spec.rb +1 -1
  134. data/spec/moneta/proxies/transformer/transformer_marshal_escape_spec.rb +8 -4
  135. data/spec/moneta/proxies/transformer/transformer_marshal_hex_spec.rb +1 -1
  136. data/spec/moneta/proxies/transformer/transformer_marshal_hmac_spec.rb +1 -1
  137. data/spec/moneta/proxies/transformer/transformer_marshal_prefix_base64_spec.rb +33 -0
  138. data/spec/moneta/proxies/transformer/transformer_marshal_prefix_spec.rb +1 -1
  139. data/spec/moneta/proxies/transformer/transformer_marshal_qp_spec.rb +1 -1
  140. data/spec/moneta/proxies/transformer/transformer_marshal_spec.rb +1 -1
  141. data/spec/moneta/proxies/transformer/transformer_marshal_urlsafe_base64_spec.rb +1 -1
  142. data/spec/moneta/proxies/transformer/transformer_marshal_uuencode_spec.rb +1 -1
  143. data/spec/moneta/proxies/transformer/transformer_msgpack_spec.rb +1 -1
  144. data/spec/moneta/proxies/transformer/transformer_ox_spec.rb +1 -1
  145. data/spec/moneta/proxies/transformer/transformer_php_spec.rb +1 -1
  146. data/spec/moneta/proxies/transformer/transformer_tnet_spec.rb +1 -1
  147. data/spec/moneta/proxies/transformer/transformer_yaml_spec.rb +2 -2
  148. data/spec/moneta/proxies/weak_each_key/weak_each_key_spec.rb +0 -2
  149. data/spec/restserver.rb +15 -0
  150. metadata +47 -66
  151. data/.travis.yml +0 -140
  152. data/lib/moneta/adapters/mongo/base.rb +0 -103
  153. data/lib/moneta/adapters/mongo/moped.rb +0 -163
  154. data/lib/moneta/adapters/mongo/official.rb +0 -156
  155. data/script/reconfigure-couchdb +0 -13
  156. data/spec/moneta/adapters/memcached/dalli/adapter_memcached_dalli_with_default_expires_spec.rb +0 -15
  157. data/spec/moneta/adapters/memcached/native/adapter_memcached_native_with_default_expires_spec.rb +0 -15
  158. data/spec/moneta/adapters/mongo/adapter_mongo_moped_spec.rb +0 -25
  159. data/spec/moneta/adapters/mongo/adapter_mongo_moped_with_default_expires_spec.rb +0 -12
  160. data/spec/moneta/adapters/mongo/adapter_mongo_official_spec.rb +0 -25
  161. data/spec/moneta/adapters/mongo/adapter_mongo_official_with_default_expires_spec.rb +0 -12
  162. data/spec/moneta/adapters/mongo/standard_mongo_moped_spec.rb +0 -7
  163. data/spec/moneta/adapters/mongo/standard_mongo_official_spec.rb +0 -7
  164. data/spec/moneta/adapters/redis/adapter_redis_with_default_expires_spec.rb +0 -10
  165. data/spec/moneta/proxies/proxy/proxy_redis_spec.rb +0 -13
  166. data/spec/quality_spec.rb +0 -51
@@ -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
@@ -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 ||=
26
- begin
27
- store = with(raw: true, only: [:load, :store, :create, :delete])
28
- store.instance_variable_set(:@raw, 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
@@ -367,255 +317,4 @@ module Moneta
367
317
  features.include?(feature)
368
318
  end
369
319
  end
370
-
371
- # This contains overrides of methods in Defaults where additional nil
372
- # checks are required, because nil values are possible in the store.
373
- # @api private
374
- module NilValues
375
- def fetch_values(*keys, **options)
376
- values = values_at(*keys, **options)
377
- return values unless block_given?
378
- keys.zip(values).map do |key, value|
379
- if value == nil && !key?(key)
380
- yield key
381
- else
382
- value
383
- end
384
- end
385
- end
386
-
387
- def slice(*keys, **options)
388
- keys.zip(values_at(*keys, **options)).reject do |key, value|
389
- value == nil && !key?(key)
390
- end
391
- end
392
-
393
- def merge!(pairs, options = {})
394
- pairs.each do |key, value|
395
- if block_given? && key?(key, options)
396
- existing = load(key, options)
397
- value = yield(key, existing, value)
398
- end
399
- store(key, value, options)
400
- end
401
- self
402
- end
403
- end
404
-
405
- # @api private
406
- module IncrementSupport
407
- # (see Defaults#increment)
408
- def increment(key, amount = 1, options = {})
409
- existing = load(key, options)
410
- value = (existing == nil ? 0 : Integer(existing)) + 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
- class << self
616
- def included(base)
617
- base.supports(:expires) if base.respond_to?(:supports)
618
- end
619
- end
620
- end
621
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,60 @@
1
+ module Moneta
2
+ # This mixin handles the calculation of expiration times.
3
+ #
4
+ #
5
+ module ExpiresSupport
6
+ attr_accessor :default_expires
7
+
8
+ protected
9
+
10
+ # Calculates the time when something will expire.
11
+ #
12
+ # This method considers false and 0 as "no-expire" and every positive
13
+ # number as a time to live in seconds.
14
+ #
15
+ # @param [Hash] options Options hash
16
+ # @option options [0,false,nil,Numeric] :expires expires value given by user
17
+ # @param [0,false,nil,Numeric] default default expiration time
18
+ #
19
+ # @return [false] if it should not expire
20
+ # @return [Time] the time when something should expire
21
+ # @return [nil] if it is not known
22
+ def expires_at(options, default = @default_expires)
23
+ value = expires_value(options, default)
24
+ Numeric === value ? Time.now + value : value
25
+ end
26
+
27
+ # Calculates the number of seconds something should last.
28
+ #
29
+ # This method considers false and 0 as "no-expire" and every positive
30
+ # number as a time to live in seconds.
31
+ #
32
+ # @param [Hash] options Options hash
33
+ # @option options [0,false,nil,Numeric] :expires expires value given by user
34
+ # @param [0,false,nil,Numeric] default default expiration time
35
+ #
36
+ # @return [false] if it should not expire
37
+ # @return [Numeric] seconds until expiration
38
+ # @return [nil] if it is not known
39
+ def expires_value(options, default = @default_expires)
40
+ case value = options[:expires]
41
+ when 0, false
42
+ false
43
+ when nil
44
+ default ? default.to_r : nil
45
+ when Numeric
46
+ value = value.to_r
47
+ raise ArgumentError, ":expires must be a positive value, got #{value}" if value < 0
48
+ value
49
+ else
50
+ raise ArgumentError, ":expires must be Numeric or false, got #{value.inspect}"
51
+ end
52
+ end
53
+
54
+ class << self
55
+ def included(base)
56
+ base.supports(:expires) if base.respond_to?(:supports)
57
+ end
58
+ end
59
+ end
60
+ end