moneta 0.7.3 → 0.7.4
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +17 -51
- data/CHANGES +13 -0
- data/Gemfile +4 -4
- data/README.md +79 -40
- data/Rakefile +40 -25
- data/benchmarks/run.rb +35 -5
- data/lib/moneta.rb +5 -5
- data/lib/moneta/adapters/activerecord.rb +4 -6
- data/lib/moneta/adapters/cassandra.rb +8 -11
- data/lib/moneta/adapters/couch.rb +3 -1
- data/lib/moneta/adapters/daybreak.rb +28 -0
- data/lib/moneta/adapters/fog.rb +3 -3
- data/lib/moneta/adapters/hbase.rb +2 -4
- data/lib/moneta/adapters/memcached/dalli.rb +8 -7
- data/lib/moneta/adapters/memcached/native.rb +8 -9
- data/lib/moneta/adapters/mongo.rb +42 -11
- data/lib/moneta/adapters/pstore.rb +4 -6
- data/lib/moneta/adapters/redis.rb +17 -10
- data/lib/moneta/adapters/restclient.rb +19 -10
- data/lib/moneta/adapters/sequel.rb +4 -6
- data/lib/moneta/adapters/tdb.rb +22 -0
- data/lib/moneta/expires.rb +28 -12
- data/lib/moneta/mixins.rb +64 -3
- data/lib/moneta/pool.rb +37 -0
- data/lib/moneta/proxy.rb +18 -7
- data/lib/moneta/server.rb +1 -1
- data/lib/moneta/shared.rb +2 -2
- data/lib/moneta/transformer/helper.rb +1 -1
- data/lib/moneta/version.rb +1 -1
- data/{spec/generate.rb → script/generate-specs.rb} +195 -91
- data/script/install-bundle.rb +35 -0
- data/spec/helper.rb +6 -0
- data/spec/moneta/adapter_activerecord_spec.rb +1 -1
- data/spec/moneta/adapter_cassandra_spec.rb +1 -12
- data/spec/moneta/adapter_cassandra_with_default_expires_spec.rb +21 -0
- data/spec/moneta/adapter_client_spec.rb +1 -1
- data/spec/moneta/adapter_cookie_spec.rb +1 -1
- data/spec/moneta/adapter_couch_spec.rb +1 -1
- data/spec/moneta/adapter_datamapper_spec.rb +1 -1
- data/spec/moneta/adapter_daybreak_spec.rb +19 -0
- data/spec/moneta/adapter_dbm_spec.rb +1 -1
- data/spec/moneta/adapter_file_spec.rb +1 -1
- data/spec/moneta/adapter_fog_spec.rb +1 -1
- data/spec/moneta/adapter_gdbm_spec.rb +1 -1
- data/spec/moneta/adapter_hbase_spec.rb +1 -1
- data/spec/moneta/adapter_leveldb_spec.rb +1 -1
- data/spec/moneta/adapter_localmemcache_spec.rb +1 -1
- data/spec/moneta/adapter_lruhash_spec.rb +1 -1
- data/spec/moneta/adapter_memcached_dalli_spec.rb +1 -12
- data/spec/moneta/adapter_memcached_dalli_with_default_expires_spec.rb +21 -0
- data/spec/moneta/adapter_memcached_native_spec.rb +1 -13
- data/spec/moneta/adapter_memcached_native_with_default_expires_spec.rb +21 -0
- data/spec/moneta/adapter_memcached_spec.rb +1 -12
- data/spec/moneta/adapter_memcached_with_default_expires_spec.rb +21 -0
- data/spec/moneta/adapter_memory_spec.rb +1 -1
- data/spec/moneta/adapter_mongo_spec.rb +9 -2
- data/spec/moneta/adapter_mongo_with_default_expires_spec.rb +21 -0
- data/spec/moneta/adapter_pstore_spec.rb +1 -1
- data/spec/moneta/adapter_redis_spec.rb +1 -12
- data/spec/moneta/adapter_redis_with_default_expires_spec.rb +21 -0
- data/spec/moneta/adapter_restclient_spec.rb +1 -1
- data/spec/moneta/adapter_riak_spec.rb +1 -1
- data/spec/moneta/adapter_sdbm_spec.rb +1 -1
- data/spec/moneta/adapter_sequel_spec.rb +1 -1
- data/spec/moneta/adapter_sqlite_spec.rb +1 -1
- data/spec/moneta/adapter_tdb_spec.rb +19 -0
- data/spec/moneta/adapter_tokyocabinet_bdb_spec.rb +1 -1
- data/spec/moneta/adapter_tokyocabinet_hdb_spec.rb +1 -1
- data/spec/moneta/adapter_yaml_spec.rb +1 -1
- data/spec/moneta/cache_file_memory_spec.rb +1 -1
- data/spec/moneta/cache_memory_null_spec.rb +1 -1
- data/spec/moneta/expires_file_spec.rb +1 -1
- data/spec/moneta/expires_memory_spec.rb +1 -12
- data/spec/moneta/expires_memory_with_default_expires_spec.rb +111 -0
- data/spec/moneta/lock_spec.rb +1 -1
- data/spec/moneta/null_adapter_spec.rb +1 -1
- data/spec/moneta/optionmerger_spec.rb +1 -1
- data/spec/moneta/pool_spec.rb +23 -0
- data/spec/moneta/proxy_expires_memory_spec.rb +1 -1
- data/spec/moneta/proxy_redis_spec.rb +1 -1
- data/spec/moneta/shared_spec.rb +1 -1
- data/spec/moneta/simple_activerecord_spec.rb +1 -1
- data/spec/moneta/simple_activerecord_with_expires_spec.rb +1 -1
- data/spec/moneta/simple_cassandra_spec.rb +1 -1
- data/spec/moneta/simple_client_tcp_spec.rb +1 -1
- data/spec/moneta/simple_client_unix_spec.rb +1 -1
- data/spec/moneta/simple_couch_spec.rb +1 -1
- data/spec/moneta/simple_couch_with_expires_spec.rb +1 -1
- data/spec/moneta/simple_datamapper_spec.rb +1 -1
- data/spec/moneta/simple_datamapper_with_expires_spec.rb +1 -1
- data/spec/moneta/simple_datamapper_with_repository_spec.rb +1 -1
- data/spec/moneta/simple_daybreak_spec.rb +144 -0
- data/spec/moneta/simple_daybreak_with_expires_spec.rb +145 -0
- data/spec/moneta/simple_dbm_spec.rb +1 -1
- data/spec/moneta/simple_dbm_with_expires_spec.rb +1 -1
- data/spec/moneta/simple_file_spec.rb +1 -1
- data/spec/moneta/simple_file_with_expires_spec.rb +1 -1
- data/spec/moneta/simple_fog_spec.rb +1 -1
- data/spec/moneta/simple_fog_with_expires_spec.rb +1 -1
- data/spec/moneta/simple_gdbm_spec.rb +1 -1
- data/spec/moneta/simple_gdbm_with_expires_spec.rb +1 -1
- data/spec/moneta/simple_hashfile_spec.rb +1 -1
- data/spec/moneta/simple_hashfile_with_expires_spec.rb +1 -1
- data/spec/moneta/simple_hbase_spec.rb +1 -1
- data/spec/moneta/simple_hbase_with_expires_spec.rb +1 -1
- data/spec/moneta/simple_leveldb_spec.rb +1 -1
- data/spec/moneta/simple_leveldb_with_expires_spec.rb +1 -1
- data/spec/moneta/simple_localmemcache_spec.rb +1 -1
- data/spec/moneta/simple_localmemcache_with_expires_spec.rb +1 -1
- data/spec/moneta/simple_lruhash_spec.rb +1 -1
- data/spec/moneta/simple_lruhash_with_expires_spec.rb +1 -1
- data/spec/moneta/simple_memcached_dalli_spec.rb +1 -1
- data/spec/moneta/simple_memcached_native_spec.rb +1 -1
- data/spec/moneta/simple_memcached_spec.rb +1 -1
- data/spec/moneta/simple_memory_spec.rb +1 -1
- data/spec/moneta/simple_memory_with_compress_spec.rb +1 -1
- data/spec/moneta/simple_memory_with_expires_spec.rb +1 -1
- data/spec/moneta/simple_memory_with_json_key_serializer_spec.rb +1 -1
- data/spec/moneta/simple_memory_with_json_serializer_spec.rb +1 -1
- data/spec/moneta/simple_memory_with_json_value_serializer_spec.rb +1 -1
- data/spec/moneta/simple_memory_with_prefix_spec.rb +1 -1
- data/spec/moneta/simple_memory_with_snappy_compress_spec.rb +1 -1
- data/spec/moneta/simple_mongo_spec.rb +3 -2
- data/spec/moneta/simple_null_spec.rb +1 -1
- data/spec/moneta/simple_pstore_spec.rb +1 -1
- data/spec/moneta/simple_pstore_with_expires_spec.rb +1 -1
- data/spec/moneta/simple_redis_spec.rb +1 -1
- data/spec/moneta/simple_restclient_spec.rb +1 -1
- data/spec/moneta/simple_riak_spec.rb +1 -1
- data/spec/moneta/simple_riak_with_expires_spec.rb +1 -1
- data/spec/moneta/simple_sdbm_spec.rb +1 -1
- data/spec/moneta/simple_sdbm_with_expires_spec.rb +1 -1
- data/spec/moneta/simple_sequel_spec.rb +1 -1
- data/spec/moneta/simple_sequel_with_expires_spec.rb +1 -1
- data/spec/moneta/simple_sqlite_spec.rb +1 -1
- data/spec/moneta/simple_sqlite_with_expires_spec.rb +1 -1
- data/spec/moneta/simple_tdb_spec.rb +144 -0
- data/spec/moneta/{simple_mongo_with_expires_spec.rb → simple_tdb_with_expires_spec.rb} +4 -4
- data/spec/moneta/simple_tokyocabinet_spec.rb +1 -1
- data/spec/moneta/simple_tokyocabinet_with_expires_spec.rb +1 -1
- data/spec/moneta/simple_yaml_spec.rb +1 -1
- data/spec/moneta/simple_yaml_with_expires_spec.rb +1 -1
- data/spec/moneta/stack_file_memory_spec.rb +1 -1
- data/spec/moneta/stack_memory_file_spec.rb +1 -1
- data/spec/moneta/transformer_bencode_spec.rb +1 -1
- data/spec/moneta/transformer_bert_spec.rb +1 -1
- data/spec/moneta/transformer_bson_spec.rb +1 -1
- data/spec/moneta/transformer_bzip2_spec.rb +1 -1
- data/spec/moneta/transformer_json_spec.rb +1 -1
- data/spec/moneta/transformer_key_marshal_spec.rb +1 -1
- data/spec/moneta/transformer_key_yaml_spec.rb +1 -1
- data/spec/moneta/transformer_lzma_spec.rb +1 -1
- data/spec/moneta/transformer_lzo_spec.rb +1 -1
- data/spec/moneta/transformer_marshal_base64_spec.rb +1 -1
- data/spec/moneta/transformer_marshal_escape_spec.rb +1 -1
- data/spec/moneta/transformer_marshal_hmac_spec.rb +1 -1
- data/spec/moneta/transformer_marshal_md5_spec.rb +1 -1
- data/spec/moneta/transformer_marshal_md5_spread_spec.rb +1 -1
- data/spec/moneta/transformer_marshal_prefix_spec.rb +1 -1
- data/spec/moneta/transformer_marshal_rmd160_spec.rb +1 -1
- data/spec/moneta/transformer_marshal_sha1_spec.rb +1 -1
- data/spec/moneta/transformer_marshal_sha256_spec.rb +1 -1
- data/spec/moneta/transformer_marshal_sha384_spec.rb +1 -1
- data/spec/moneta/transformer_marshal_sha512_spec.rb +1 -1
- data/spec/moneta/transformer_marshal_spec.rb +1 -1
- data/spec/moneta/transformer_marshal_truncate_spec.rb +1 -1
- data/spec/moneta/transformer_marshal_uuencode_spec.rb +1 -1
- data/spec/moneta/transformer_msgpack_spec.rb +1 -1
- data/spec/moneta/transformer_ox_spec.rb +1 -1
- data/spec/moneta/transformer_quicklz_spec.rb +1 -1
- data/spec/moneta/transformer_snappy_spec.rb +1 -1
- data/spec/moneta/transformer_tnet_spec.rb +1 -1
- data/spec/moneta/transformer_value_marshal_spec.rb +1 -1
- data/spec/moneta/transformer_value_yaml_spec.rb +1 -1
- data/spec/moneta/transformer_yaml_spec.rb +1 -1
- data/spec/moneta/transformer_zlib_spec.rb +1 -1
- data/spec/monetaspecs.rb +105 -3
- metadata +35 -6
data/lib/moneta.rb
CHANGED
@@ -2,6 +2,7 @@ module Moneta
|
|
2
2
|
autoload :Builder, 'moneta/builder'
|
3
3
|
autoload :Cache, 'moneta/cache'
|
4
4
|
autoload :Defaults, 'moneta/mixins'
|
5
|
+
autoload :ExpiresSupport, 'moneta/mixins'
|
5
6
|
autoload :Expires, 'moneta/expires'
|
6
7
|
autoload :HashAdapter, 'moneta/mixins'
|
7
8
|
autoload :IncrementSupport, 'moneta/mixins'
|
@@ -10,6 +11,7 @@ module Moneta
|
|
10
11
|
autoload :Net, 'moneta/mixins'
|
11
12
|
autoload :OptionMerger, 'moneta/optionmerger'
|
12
13
|
autoload :OptionSupport, 'moneta/mixins'
|
14
|
+
autoload :Pool, 'moneta/pool'
|
13
15
|
autoload :Proxy, 'moneta/proxy'
|
14
16
|
autoload :Server, 'moneta/server'
|
15
17
|
autoload :Shared, 'moneta/shared'
|
@@ -23,6 +25,7 @@ module Moneta
|
|
23
25
|
autoload :Client, 'moneta/adapters/client'
|
24
26
|
autoload :Cookie, 'moneta/adapters/cookie'
|
25
27
|
autoload :Couch, 'moneta/adapters/couch'
|
28
|
+
autoload :Daybreak, 'moneta/adapters/daybreak'
|
26
29
|
autoload :DBM, 'moneta/adapters/dbm'
|
27
30
|
autoload :DataMapper, 'moneta/adapters/datamapper'
|
28
31
|
autoload :File, 'moneta/adapters/file'
|
@@ -45,6 +48,7 @@ module Moneta
|
|
45
48
|
autoload :SDBM, 'moneta/adapters/sdbm'
|
46
49
|
autoload :Sequel, 'moneta/adapters/sequel'
|
47
50
|
autoload :Sqlite, 'moneta/adapters/sqlite'
|
51
|
+
autoload :TDB, 'moneta/adapters/tdb'
|
48
52
|
autoload :TokyoCabinet, 'moneta/adapters/tokyocabinet'
|
49
53
|
autoload :YAML, 'moneta/adapters/yaml'
|
50
54
|
end
|
@@ -98,10 +102,6 @@ module Moneta
|
|
98
102
|
# Riak accepts only utf-8 keys over the http interface
|
99
103
|
# We use base64 encoding therefore.
|
100
104
|
transformer[:key] << :base64
|
101
|
-
when :Memcached, :MemcachedDalli, :MemcachedNative
|
102
|
-
# Memcached supports expires already
|
103
|
-
options[:expires] = expires if Integer === expires
|
104
|
-
expires = false
|
105
105
|
when :PStore, :YAML, :Null
|
106
106
|
# For PStore and YAML only the key has to be a string
|
107
107
|
transformer.delete(:value) if transformer[:value] == [:marshal]
|
@@ -112,7 +112,7 @@ module Moneta
|
|
112
112
|
when :File
|
113
113
|
# Use escaping
|
114
114
|
transformer[:key] << :escape
|
115
|
-
when :Cassandra, :Redis
|
115
|
+
when :Cassandra, :Redis, :Mongo, :Memcached, :MemcachedDalli, :MemcachedNative
|
116
116
|
# Expires already supported
|
117
117
|
options[:expires] = expires if Integer === expires
|
118
118
|
expires = false
|
@@ -6,6 +6,7 @@ module Moneta
|
|
6
6
|
# @api public
|
7
7
|
class ActiveRecord
|
8
8
|
include Defaults
|
9
|
+
include IncrementSupport
|
9
10
|
|
10
11
|
def self.tables
|
11
12
|
@tables ||= {}
|
@@ -66,13 +67,10 @@ module Moneta
|
|
66
67
|
# (see Proxy#increment)
|
67
68
|
def increment(key, amount = 1, options = {})
|
68
69
|
record = @table.where(:k => key).lock.first_or_initialize
|
69
|
-
value = record.v
|
70
|
-
|
71
|
-
raise 'Tried to increment non integer value' unless value == nil || intvalue.to_s == value.to_s
|
72
|
-
intvalue += amount
|
73
|
-
record.v = intvalue.to_s
|
70
|
+
value = convert_for_increment(record.v) + amount
|
71
|
+
record.v = value.to_s
|
74
72
|
record.save
|
75
|
-
|
73
|
+
value
|
76
74
|
end
|
77
75
|
|
78
76
|
# (see Proxy#clear)
|
@@ -9,6 +9,7 @@ module Moneta
|
|
9
9
|
# @api public
|
10
10
|
class Cassandra
|
11
11
|
include Defaults
|
12
|
+
include ExpiresSupport
|
12
13
|
|
13
14
|
# @param [Hash] options
|
14
15
|
# @option options [String] :keyspace ('moneta') Cassandra keyspace
|
@@ -19,7 +20,7 @@ module Moneta
|
|
19
20
|
def initialize(options = {})
|
20
21
|
options[:host] ||= '127.0.0.1'
|
21
22
|
options[:port] ||= 9160
|
22
|
-
|
23
|
+
self.default_expires = options[:expires]
|
23
24
|
keyspace = (options[:keyspace] ||= 'moneta')
|
24
25
|
@cf = (options[:column_family] || 'moneta').to_sym
|
25
26
|
@client = ::Cassandra.new('system', "#{options[:host]}:#{options[:port]}")
|
@@ -35,7 +36,7 @@ module Moneta
|
|
35
36
|
begin
|
36
37
|
@client.add_keyspace(ks_def)
|
37
38
|
rescue Exception => ex
|
38
|
-
|
39
|
+
warn "Cassandra: #{ex.message}"
|
39
40
|
end
|
40
41
|
break if @client.keyspaces.include?(keyspace)
|
41
42
|
sleep 0.1
|
@@ -47,9 +48,7 @@ module Moneta
|
|
47
48
|
# (see Proxy#key?)
|
48
49
|
def key?(key, options = {})
|
49
50
|
if @client.exists?(@cf, key)
|
50
|
-
if options.include?(:expires)
|
51
|
-
store(key, value, options)
|
52
|
-
end
|
51
|
+
load(key, options) if options.include?(:expires)
|
53
52
|
true
|
54
53
|
else
|
55
54
|
false
|
@@ -60,17 +59,15 @@ module Moneta
|
|
60
59
|
def load(key, options = {})
|
61
60
|
value = @client.get(@cf, key)
|
62
61
|
if value
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
value['value']
|
67
|
-
end
|
62
|
+
expires = expires_value(options, nil)
|
63
|
+
@client.insert(@cf, key, {'value' => value['value'] }, :ttl => expires || nil) if expires != nil
|
64
|
+
value['value']
|
68
65
|
end
|
69
66
|
end
|
70
67
|
|
71
68
|
# (see Proxy#store)
|
72
69
|
def store(key, value, options = {})
|
73
|
-
@client.insert(@cf, key, {'value' => value}, :ttl => (options
|
70
|
+
@client.insert(@cf, key, {'value' => value}, :ttl => expires_value(options) || nil)
|
74
71
|
value
|
75
72
|
end
|
76
73
|
|
@@ -8,10 +8,12 @@ module Moneta
|
|
8
8
|
include Defaults
|
9
9
|
|
10
10
|
# @param [Hash] options
|
11
|
+
# @option options [String] :host ('http://127.0.0.1:5984') Couch host
|
11
12
|
# @option options [String] :db ('moneta') Couch database
|
12
13
|
def initialize(options = {})
|
13
14
|
options[:db] ||= 'moneta'
|
14
|
-
|
15
|
+
options[:host] ||= '127.0.0.1:5984'
|
16
|
+
@db = CouchRest.new(options[:host]).database!(options[:db])
|
15
17
|
end
|
16
18
|
|
17
19
|
# (see Proxy#key?)
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'daybreak'
|
2
|
+
|
3
|
+
module Moneta
|
4
|
+
module Adapters
|
5
|
+
# Daybreak backend
|
6
|
+
# @api public
|
7
|
+
class Daybreak < Memory
|
8
|
+
# Disable serialization, we have `Moneta::Transformer` for that
|
9
|
+
class DB < ::Daybreak::DB
|
10
|
+
def serialize(value) value; end
|
11
|
+
def parse(value) value; end
|
12
|
+
end
|
13
|
+
|
14
|
+
# @param [Hash] options
|
15
|
+
# @option options [String] :file Database file
|
16
|
+
def initialize(options = {})
|
17
|
+
raise ArgumentError, 'Option :file is required' unless options[:file]
|
18
|
+
@hash = DB.new(options[:file])
|
19
|
+
end
|
20
|
+
|
21
|
+
# (see Proxy#close)
|
22
|
+
def close
|
23
|
+
@hash.close!
|
24
|
+
nil
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/lib/moneta/adapters/fog.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require 'fog'
|
1
|
+
require 'fog/storage'
|
2
2
|
|
3
3
|
module Moneta
|
4
4
|
module Adapters
|
@@ -13,7 +13,7 @@ module Moneta
|
|
13
13
|
def initialize(options = {})
|
14
14
|
raise ArgumentError, 'Option :dir is required' unless dir = options.delete(:dir)
|
15
15
|
storage = ::Fog::Storage.new(options)
|
16
|
-
@directory = storage.directories.create(:key => dir)
|
16
|
+
@directory = storage.directories.get(dir) || storage.directories.create(:key => dir)
|
17
17
|
end
|
18
18
|
|
19
19
|
# (see Proxy#key?)
|
@@ -38,7 +38,7 @@ module Moneta
|
|
38
38
|
|
39
39
|
# (see Proxy#store)
|
40
40
|
def store(key, value, options = {})
|
41
|
-
@directory.files.create(:key => key, :body => value)
|
41
|
+
@directory.files.create(options.merge(:key => key, :body => value))
|
42
42
|
value
|
43
43
|
end
|
44
44
|
|
@@ -6,6 +6,7 @@ module Moneta
|
|
6
6
|
# @api public
|
7
7
|
class HBase
|
8
8
|
include Defaults
|
9
|
+
include IncrementSupport
|
9
10
|
|
10
11
|
# @param [Hash] options
|
11
12
|
# @option options [String] :host ('127.0.0.1') Server host name
|
@@ -46,10 +47,7 @@ module Moneta
|
|
46
47
|
def increment(key, amount = 1, options = {})
|
47
48
|
result = @table.atomic_increment(key, @column, amount)
|
48
49
|
# HACK: Throw error if applied to invalid value
|
49
|
-
if result == 0
|
50
|
-
value = load(key)
|
51
|
-
raise 'Tried to increment non integer value' unless value.to_s == value.to_i.to_s
|
52
|
-
end
|
50
|
+
convert_for_increment(load(key)) if result == 0
|
53
51
|
result
|
54
52
|
end
|
55
53
|
|
@@ -6,13 +6,14 @@ module Moneta
|
|
6
6
|
# @api public
|
7
7
|
class MemcachedDalli
|
8
8
|
include Defaults
|
9
|
+
include ExpiresSupport
|
9
10
|
|
10
11
|
# @param [Hash] options
|
11
12
|
# @option options [String] :server ('127.0.0.1:11211') Memcached server
|
12
13
|
# @option options [Integer] :expires Default expiration time
|
13
14
|
# @option options Other options passed to `Dalli::Client#new`
|
14
15
|
def initialize(options = {})
|
15
|
-
|
16
|
+
self.default_expires = options.delete(:expires)
|
16
17
|
server = options.delete(:server) || '127.0.0.1:11211'
|
17
18
|
@cache = ::Dalli::Client.new(server, options)
|
18
19
|
end
|
@@ -20,16 +21,16 @@ module Moneta
|
|
20
21
|
# (see Proxy#load)
|
21
22
|
def load(key, options = {})
|
22
23
|
value = @cache.get(key)
|
23
|
-
if value
|
24
|
-
|
25
|
-
|
24
|
+
if value
|
25
|
+
expires = expires_value(options, nil)
|
26
|
+
@cache.set(key, value, expires || nil, :raw => true) if expires != nil
|
26
27
|
value
|
27
28
|
end
|
28
29
|
end
|
29
30
|
|
30
31
|
# (see Proxy#store)
|
31
32
|
def store(key, value, options = {})
|
32
|
-
@cache.set(key, value, options
|
33
|
+
@cache.set(key, value, expires_value(options) || nil, :raw => true)
|
33
34
|
value
|
34
35
|
end
|
35
36
|
|
@@ -45,9 +46,9 @@ module Moneta
|
|
45
46
|
# FIXME: There is a Dalli bug, load(key) returns a wrong value after increment
|
46
47
|
# therefore we set default = nil and create the counter manually
|
47
48
|
result = if amount >= 0
|
48
|
-
@cache.incr(key, amount, options
|
49
|
+
@cache.incr(key, amount, expires_value(options) || nil, nil)
|
49
50
|
else
|
50
|
-
@cache.decr(key, -amount, options
|
51
|
+
@cache.decr(key, -amount, expires_value(options) || nil, nil)
|
51
52
|
end
|
52
53
|
if result
|
53
54
|
result
|
@@ -6,6 +6,8 @@ module Moneta
|
|
6
6
|
# @api public
|
7
7
|
class MemcachedNative
|
8
8
|
include Defaults
|
9
|
+
include IncrementSupport
|
10
|
+
include ExpiresSupport
|
9
11
|
|
10
12
|
# @param [Hash] options
|
11
13
|
# @option options [String] :server ('127.0.0.1:11211') Memcached server
|
@@ -14,7 +16,7 @@ module Moneta
|
|
14
16
|
# @option options Other options passed to `Memcached#new`
|
15
17
|
def initialize(options = {})
|
16
18
|
server = options.delete(:server) || '127.0.0.1:11211'
|
17
|
-
|
19
|
+
self.default_expires = options.delete(:expires)
|
18
20
|
options.merge!(:prefix_key => options.delete(:namespace)) if options[:namespace]
|
19
21
|
# We don't want a limitation on the key charset. Therefore we use the binary protocol.
|
20
22
|
# It is also faster.
|
@@ -25,9 +27,9 @@ module Moneta
|
|
25
27
|
# (see Proxy#load)
|
26
28
|
def load(key, options = {})
|
27
29
|
value = @cache.get(key, false)
|
28
|
-
if value
|
29
|
-
|
30
|
-
|
30
|
+
if value
|
31
|
+
expires = expires_value(options, nil)
|
32
|
+
@cache.set(key, value, expires || 0, false) if expires != nil
|
31
33
|
value
|
32
34
|
end
|
33
35
|
rescue ::Memcached::NotFound
|
@@ -36,7 +38,7 @@ module Moneta
|
|
36
38
|
# (see Proxy#store)
|
37
39
|
def store(key, value, options = {})
|
38
40
|
# TTL must be Fixnum
|
39
|
-
@cache.set(key, value, options
|
41
|
+
@cache.set(key, value, expires_value(options) || 0, false)
|
40
42
|
value
|
41
43
|
end
|
42
44
|
|
@@ -56,10 +58,7 @@ module Moneta
|
|
56
58
|
@cache.decrement(key, -amount)
|
57
59
|
end
|
58
60
|
# HACK: Throw error if applied to invalid value
|
59
|
-
if result == 0
|
60
|
-
value = @cache.get(key, false) rescue nil
|
61
|
-
raise 'Tried to increment non integer value' unless value.to_s == value.to_i.to_s
|
62
|
-
end
|
61
|
+
convert_for_increment((@cache.get(key, false) rescue nil)) if result == 0
|
63
62
|
result
|
64
63
|
rescue ::Memcached::NotFound => ex
|
65
64
|
store(key, amount.to_s, options)
|
@@ -3,28 +3,60 @@ require 'mongo'
|
|
3
3
|
module Moneta
|
4
4
|
module Adapters
|
5
5
|
# MongoDB backend
|
6
|
+
#
|
7
|
+
# Supports expiration, documents will be automatically removed starting
|
8
|
+
# with mongodb >= 2.2 (see http://docs.mongodb.org/manual/tutorial/expire-data/).
|
9
|
+
#
|
6
10
|
# @api public
|
7
11
|
class Mongo
|
8
12
|
include Defaults
|
13
|
+
include ExpiresSupport
|
9
14
|
|
10
15
|
# @param [Hash] options
|
11
16
|
# @option options [String] :collection ('moneta') MongoDB collection name
|
12
17
|
# @option options [String] :host ('127.0.0.1') MongoDB server host
|
13
18
|
# @option options [Integer] :port (MongoDB default port) MongoDB server port
|
14
19
|
# @option options [String] :db ('moneta') MongoDB database
|
20
|
+
# @option options [Integer] :expires Default expiration time
|
15
21
|
def initialize(options = {})
|
22
|
+
self.default_expires = options.delete(:expires)
|
16
23
|
collection = options.delete(:collection) || 'moneta'
|
17
24
|
host = options.delete(:host) || '127.0.0.1'
|
18
|
-
port = options.delete(:port) || ::Mongo::
|
25
|
+
port = options.delete(:port) || ::Mongo::MongoClient::DEFAULT_PORT
|
19
26
|
db = options.delete(:db) || 'moneta'
|
20
|
-
connection = ::Mongo::
|
27
|
+
connection = ::Mongo::MongoClient.new(host, port, options)
|
21
28
|
@collection = connection.db(db).collection(collection)
|
29
|
+
if connection.server_version >= '2.2'
|
30
|
+
@collection.ensure_index([['expiresAt', ::Mongo::ASCENDING]], :expireAfterSeconds => 0)
|
31
|
+
else
|
32
|
+
warn 'You are using MongoDB version < 2.2, expired documents will not be deleted'
|
33
|
+
end
|
22
34
|
end
|
23
35
|
|
24
36
|
# (see Proxy#load)
|
25
37
|
def load(key, options = {})
|
26
|
-
|
27
|
-
|
38
|
+
key = ::BSON::Binary.new(key)
|
39
|
+
doc = @collection.find_one('_id' => key)
|
40
|
+
if doc && (!doc['expiresAt'] || doc['expiresAt'] >= Time.now)
|
41
|
+
expires = expires_at(options, nil)
|
42
|
+
@collection.update({ '_id' => key },
|
43
|
+
# expiresAt must be a Time object (BSON date datatype)
|
44
|
+
{ '$set' => { 'expiresAt' => expires || nil } }) if expires != nil
|
45
|
+
doc['value'].to_s
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# (see Proxy#store)
|
50
|
+
def store(key, value, options = {})
|
51
|
+
key = ::BSON::Binary.new(key)
|
52
|
+
intvalue = value.to_i
|
53
|
+
@collection.update({ '_id' => key },
|
54
|
+
{ '_id' => key,
|
55
|
+
'value' => intvalue.to_s == value ? intvalue : ::BSON::Binary.new(value),
|
56
|
+
# expiresAt must be a Time object (BSON date datatype)
|
57
|
+
'expiresAt' => expires_at(options) || nil },
|
58
|
+
{ :upsert => true })
|
59
|
+
value
|
28
60
|
end
|
29
61
|
|
30
62
|
# (see Proxy#delete)
|
@@ -34,13 +66,12 @@ module Moneta
|
|
34
66
|
value
|
35
67
|
end
|
36
68
|
|
37
|
-
# (see Proxy#
|
38
|
-
def
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
value
|
69
|
+
# (see Proxy#increment)
|
70
|
+
def increment(key, amount = 1, options = {})
|
71
|
+
@collection.find_and_modify(:query => { '_id' => ::BSON::Binary.new(key) },
|
72
|
+
:update => { '$inc' => { 'value' => amount } },
|
73
|
+
:new => true,
|
74
|
+
:upsert => true)['value']
|
44
75
|
end
|
45
76
|
|
46
77
|
# (see Proxy#clear)
|
@@ -6,6 +6,7 @@ module Moneta
|
|
6
6
|
# @api public
|
7
7
|
class PStore
|
8
8
|
include Defaults
|
9
|
+
include IncrementSupport
|
9
10
|
|
10
11
|
# @param [Hash] options
|
11
12
|
# @option options [String] :file PStore file
|
@@ -38,12 +39,9 @@ module Moneta
|
|
38
39
|
# (see Proxy#increment)
|
39
40
|
def increment(key, amount = 1, options = {})
|
40
41
|
@pstore.transaction do
|
41
|
-
value = @pstore[key]
|
42
|
-
|
43
|
-
|
44
|
-
intvalue += amount
|
45
|
-
@pstore[key] = intvalue.to_s
|
46
|
-
intvalue
|
42
|
+
value = convert_for_increment(@pstore[key]) + amount
|
43
|
+
@pstore[key] = value.to_s
|
44
|
+
value
|
47
45
|
end
|
48
46
|
end
|
49
47
|
|
@@ -6,21 +6,20 @@ module Moneta
|
|
6
6
|
# @api public
|
7
7
|
class Redis
|
8
8
|
include Defaults
|
9
|
+
include ExpiresSupport
|
9
10
|
|
10
11
|
# @param [Hash] options
|
11
12
|
# @option options [Integer] :expires Default expiration time
|
12
13
|
# @option options Other options passed to `Redis#new`
|
13
14
|
def initialize(options = {})
|
14
|
-
|
15
|
+
self.default_expires = options.delete(:expires)
|
15
16
|
@redis = ::Redis.new(options)
|
16
17
|
end
|
17
18
|
|
18
19
|
# (see Proxy#key?)
|
19
20
|
def key?(key, options = {})
|
20
21
|
if @redis.exists(key)
|
21
|
-
|
22
|
-
@redis.expire(key, expires)
|
23
|
-
end
|
22
|
+
update_expires(key, options, nil)
|
24
23
|
true
|
25
24
|
else
|
26
25
|
false
|
@@ -30,15 +29,13 @@ module Moneta
|
|
30
29
|
# (see Proxy#load)
|
31
30
|
def load(key, options = {})
|
32
31
|
value = @redis.get(key)
|
33
|
-
|
34
|
-
@redis.expire(key, expires)
|
35
|
-
end
|
32
|
+
update_expires(key, options, nil)
|
36
33
|
value
|
37
34
|
end
|
38
35
|
|
39
36
|
# (see Proxy#store)
|
40
37
|
def store(key, value, options = {})
|
41
|
-
if expires = (options
|
38
|
+
if expires = expires_value(options)
|
42
39
|
@redis.setex(key, expires, value)
|
43
40
|
else
|
44
41
|
@redis.set(key, value)
|
@@ -57,8 +54,7 @@ module Moneta
|
|
57
54
|
# (see Proxy#increment)
|
58
55
|
def increment(key, amount = 1, options = {})
|
59
56
|
value = @redis.incrby(key, amount)
|
60
|
-
|
61
|
-
@redis.expire(key, expires) if expires
|
57
|
+
update_expires(key, options)
|
62
58
|
value
|
63
59
|
end
|
64
60
|
|
@@ -67,6 +63,17 @@ module Moneta
|
|
67
63
|
@redis.flushdb
|
68
64
|
self
|
69
65
|
end
|
66
|
+
|
67
|
+
protected
|
68
|
+
|
69
|
+
def update_expires(key, options, default = @default_expires)
|
70
|
+
case expires = expires_value(options, default)
|
71
|
+
when false
|
72
|
+
@redis.persist(key)
|
73
|
+
when Numeric
|
74
|
+
@redis.expire(key, expires)
|
75
|
+
end
|
76
|
+
end
|
70
77
|
end
|
71
78
|
end
|
72
79
|
end
|