moneta 0.7.6 → 0.7.8
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.
- data/CHANGES +15 -0
- data/README.md +160 -50
- data/Rakefile +11 -2
- data/SPEC.md +7 -2
- data/lib/moneta.rb +7 -1
- data/lib/moneta/adapters/activerecord.rb +27 -3
- data/lib/moneta/adapters/cassandra.rb +1 -1
- data/lib/moneta/adapters/client.rb +8 -2
- data/lib/moneta/adapters/cookie.rb +1 -1
- data/lib/moneta/adapters/couch.rb +2 -1
- data/lib/moneta/adapters/datamapper.rb +16 -0
- data/lib/moneta/adapters/daybreak.rb +19 -1
- data/lib/moneta/adapters/file.rb +12 -0
- data/lib/moneta/adapters/hbase.rb +1 -2
- data/lib/moneta/adapters/lruhash.rb +4 -1
- data/lib/moneta/adapters/memcached.rb +7 -3
- data/lib/moneta/adapters/memcached/dalli.rb +8 -2
- data/lib/moneta/adapters/memcached/native.rb +10 -3
- data/lib/moneta/adapters/memory.rb +1 -0
- data/lib/moneta/adapters/mongo.rb +32 -5
- data/lib/moneta/adapters/pstore.rb +13 -2
- data/lib/moneta/adapters/redis.rb +19 -0
- data/lib/moneta/adapters/restclient.rb +1 -1
- data/lib/moneta/adapters/sequel.rb +20 -6
- data/lib/moneta/adapters/sqlite.rb +13 -1
- data/lib/moneta/adapters/tokyocabinet.rb +5 -0
- data/lib/moneta/cache.rb +10 -0
- data/lib/moneta/expires.rb +19 -22
- data/lib/moneta/lock.rb +2 -2
- data/lib/moneta/mixins.rb +33 -11
- data/lib/moneta/optionmerger.rb +1 -1
- data/lib/moneta/proxy.rb +13 -8
- data/lib/moneta/server.rb +13 -6
- data/lib/moneta/shared.rb +6 -10
- data/lib/moneta/synchronize.rb +125 -0
- data/lib/moneta/transformer.rb +50 -42
- data/lib/moneta/transformer/config.rb +34 -32
- data/lib/moneta/utils.rb +20 -0
- data/lib/moneta/version.rb +1 -1
- data/lib/moneta/weak.rb +17 -0
- data/lib/moneta/wrapper.rb +5 -0
- data/lib/rack/moneta_cookies.rb +2 -2
- data/lib/rack/moneta_store.rb +4 -4
- data/script/benchmarks +3 -9
- data/script/generate-specs +278 -41
- data/script/install-bundle +2 -2
- data/spec/moneta/adapter_activerecord_spec.rb +1 -0
- data/spec/moneta/adapter_cassandra_spec.rb +1 -0
- data/spec/moneta/adapter_cassandra_with_default_expires_spec.rb +1 -0
- data/spec/moneta/adapter_client_spec.rb +1 -0
- data/spec/moneta/adapter_cookie_spec.rb +1 -0
- data/spec/moneta/adapter_couch_spec.rb +1 -0
- data/spec/moneta/adapter_datamapper_spec.rb +1 -0
- data/spec/moneta/adapter_daybreak_spec.rb +1 -0
- data/spec/moneta/adapter_dbm_spec.rb +1 -0
- data/spec/moneta/adapter_file_spec.rb +1 -0
- data/spec/moneta/adapter_fog_spec.rb +1 -0
- data/spec/moneta/adapter_gdbm_spec.rb +1 -1
- data/spec/moneta/adapter_hbase_spec.rb +1 -0
- data/spec/moneta/adapter_leveldb_spec.rb +1 -0
- data/spec/moneta/adapter_localmemcache_spec.rb +1 -0
- data/spec/moneta/adapter_lruhash_spec.rb +1 -0
- data/spec/moneta/adapter_memcached_dalli_spec.rb +2 -0
- data/spec/moneta/adapter_memcached_dalli_with_default_expires_spec.rb +2 -0
- data/spec/moneta/adapter_memcached_native_spec.rb +2 -0
- data/spec/moneta/adapter_memcached_native_with_default_expires_spec.rb +2 -0
- data/spec/moneta/adapter_memcached_spec.rb +2 -0
- data/spec/moneta/adapter_memcached_with_default_expires_spec.rb +2 -0
- data/spec/moneta/adapter_memory_spec.rb +1 -0
- data/spec/moneta/adapter_mongo_spec.rb +2 -0
- data/spec/moneta/adapter_mongo_with_default_expires_spec.rb +2 -0
- data/spec/moneta/adapter_pstore_spec.rb +1 -0
- data/spec/moneta/adapter_redis_spec.rb +2 -0
- data/spec/moneta/adapter_redis_with_default_expires_spec.rb +2 -0
- data/spec/moneta/adapter_restclient_spec.rb +1 -0
- data/spec/moneta/adapter_riak_spec.rb +1 -0
- data/spec/moneta/adapter_sdbm_spec.rb +1 -0
- data/spec/moneta/adapter_sequel_spec.rb +1 -0
- data/spec/moneta/adapter_sqlite_spec.rb +1 -0
- data/spec/moneta/adapter_tdb_spec.rb +1 -0
- data/spec/moneta/adapter_tokyocabinet_bdb_spec.rb +1 -0
- data/spec/moneta/adapter_tokyocabinet_hdb_spec.rb +1 -0
- data/spec/moneta/adapter_yaml_spec.rb +1 -0
- data/spec/moneta/cache_file_memory_spec.rb +1 -0
- data/spec/moneta/cache_memory_null_spec.rb +1 -0
- data/spec/moneta/expires_file_spec.rb +3 -1
- data/spec/moneta/expires_memory_spec.rb +2 -0
- data/spec/moneta/expires_memory_with_default_expires_spec.rb +2 -0
- data/spec/moneta/lock_spec.rb +1 -0
- data/spec/moneta/mutex_spec.rb +71 -0
- data/spec/moneta/null_adapter_spec.rb +1 -0
- data/spec/moneta/optionmerger_spec.rb +5 -7
- data/spec/moneta/pool_spec.rb +1 -0
- data/spec/moneta/proxy_expires_memory_spec.rb +2 -0
- data/spec/moneta/proxy_redis_spec.rb +2 -0
- data/spec/moneta/semaphore_spec.rb +84 -0
- data/spec/moneta/{shared_spec.rb → shared_tcp_spec.rb} +4 -3
- data/spec/moneta/shared_unix_spec.rb +37 -0
- data/spec/moneta/simple_activerecord_spec.rb +1 -0
- data/spec/moneta/simple_activerecord_with_expires_spec.rb +3 -1
- data/spec/moneta/simple_cassandra_spec.rb +1 -0
- data/spec/moneta/simple_client_tcp_spec.rb +1 -0
- data/spec/moneta/simple_client_unix_spec.rb +3 -2
- data/spec/moneta/simple_couch_spec.rb +1 -0
- data/spec/moneta/simple_couch_with_expires_spec.rb +2 -1
- data/spec/moneta/simple_datamapper_spec.rb +1 -0
- data/spec/moneta/simple_datamapper_with_expires_spec.rb +3 -1
- data/spec/moneta/simple_datamapper_with_repository_spec.rb +1 -0
- data/spec/moneta/simple_daybreak_spec.rb +1 -0
- data/spec/moneta/simple_daybreak_with_expires_spec.rb +3 -1
- data/spec/moneta/simple_dbm_spec.rb +1 -0
- data/spec/moneta/simple_dbm_with_expires_spec.rb +3 -1
- data/spec/moneta/simple_file_spec.rb +1 -0
- data/spec/moneta/simple_file_with_expires_spec.rb +3 -1
- data/spec/moneta/simple_fog_spec.rb +1 -0
- data/spec/moneta/simple_fog_with_expires_spec.rb +2 -1
- data/spec/moneta/simple_gdbm_spec.rb +1 -0
- data/spec/moneta/simple_gdbm_with_expires_spec.rb +3 -1
- data/spec/moneta/simple_hashfile_spec.rb +1 -0
- data/spec/moneta/simple_hashfile_with_expires_spec.rb +3 -1
- data/spec/moneta/simple_hbase_spec.rb +1 -0
- data/spec/moneta/simple_hbase_with_expires_spec.rb +3 -1
- data/spec/moneta/simple_leveldb_spec.rb +1 -0
- data/spec/moneta/simple_leveldb_with_expires_spec.rb +3 -1
- data/spec/moneta/simple_localmemcache_spec.rb +1 -0
- data/spec/moneta/simple_localmemcache_with_expires_spec.rb +2 -1
- data/spec/moneta/simple_lruhash_spec.rb +1 -0
- data/spec/moneta/simple_lruhash_with_expires_spec.rb +3 -1
- data/spec/moneta/simple_memcached_dalli_spec.rb +2 -0
- data/spec/moneta/simple_memcached_native_spec.rb +2 -0
- data/spec/moneta/simple_memcached_spec.rb +2 -0
- data/spec/moneta/simple_memory_spec.rb +1 -0
- data/spec/moneta/simple_memory_with_compress_spec.rb +1 -0
- data/spec/moneta/simple_memory_with_expires_spec.rb +3 -1
- data/spec/moneta/simple_memory_with_json_key_serializer_spec.rb +1 -0
- data/spec/moneta/simple_memory_with_json_serializer_spec.rb +1 -0
- data/spec/moneta/simple_memory_with_json_value_serializer_spec.rb +1 -0
- data/spec/moneta/simple_memory_with_prefix_spec.rb +1 -0
- data/spec/moneta/simple_memory_with_snappy_compress_spec.rb +1 -0
- data/spec/moneta/simple_mongo_spec.rb +2 -0
- data/spec/moneta/simple_null_spec.rb +1 -0
- data/spec/moneta/simple_pstore_spec.rb +1 -0
- data/spec/moneta/simple_pstore_with_expires_spec.rb +3 -1
- data/spec/moneta/simple_redis_spec.rb +2 -0
- data/spec/moneta/simple_restclient_spec.rb +1 -0
- data/spec/moneta/simple_riak_spec.rb +1 -0
- data/spec/moneta/simple_riak_with_expires_spec.rb +2 -1
- data/spec/moneta/simple_sdbm_spec.rb +1 -0
- data/spec/moneta/simple_sdbm_with_expires_spec.rb +3 -1
- data/spec/moneta/simple_sequel_spec.rb +1 -0
- data/spec/moneta/simple_sequel_with_expires_spec.rb +3 -1
- data/spec/moneta/simple_sqlite_spec.rb +1 -0
- data/spec/moneta/simple_sqlite_with_expires_spec.rb +3 -1
- data/spec/moneta/simple_tdb_spec.rb +1 -0
- data/spec/moneta/simple_tdb_with_expires_spec.rb +3 -1
- data/spec/moneta/simple_tokyocabinet_spec.rb +1 -0
- data/spec/moneta/simple_tokyocabinet_with_expires_spec.rb +3 -1
- data/spec/moneta/simple_yaml_spec.rb +1 -0
- data/spec/moneta/simple_yaml_with_expires_spec.rb +3 -1
- data/spec/moneta/stack_file_memory_spec.rb +1 -0
- data/spec/moneta/stack_memory_file_spec.rb +1 -0
- data/spec/moneta/transformer_bencode_spec.rb +1 -0
- data/spec/moneta/transformer_bert_spec.rb +1 -0
- data/spec/moneta/transformer_bson_spec.rb +1 -0
- data/spec/moneta/transformer_bzip2_spec.rb +1 -0
- data/spec/moneta/transformer_json_spec.rb +1 -0
- data/spec/moneta/transformer_key_inspect_spec.rb +73 -0
- data/spec/moneta/transformer_key_marshal_spec.rb +1 -0
- data/spec/moneta/transformer_key_to_s_spec.rb +1 -0
- data/spec/moneta/transformer_key_yaml_spec.rb +1 -0
- data/spec/moneta/transformer_lzma_spec.rb +1 -0
- data/spec/moneta/transformer_lzo_spec.rb +1 -0
- data/spec/moneta/transformer_marshal_base64_spec.rb +1 -0
- data/spec/moneta/transformer_marshal_escape_spec.rb +1 -0
- data/spec/moneta/transformer_marshal_hmac_spec.rb +1 -0
- data/spec/moneta/transformer_marshal_md5_spec.rb +1 -0
- data/spec/moneta/transformer_marshal_md5_spread_spec.rb +1 -0
- data/spec/moneta/transformer_marshal_prefix_spec.rb +1 -0
- data/spec/moneta/transformer_marshal_rmd160_spec.rb +1 -0
- data/spec/moneta/transformer_marshal_sha1_spec.rb +1 -0
- data/spec/moneta/transformer_marshal_sha256_spec.rb +1 -0
- data/spec/moneta/transformer_marshal_sha384_spec.rb +1 -0
- data/spec/moneta/transformer_marshal_sha512_spec.rb +1 -0
- data/spec/moneta/transformer_marshal_spec.rb +1 -0
- data/spec/moneta/transformer_marshal_truncate_spec.rb +1 -0
- data/spec/moneta/transformer_marshal_uuencode_spec.rb +1 -0
- data/spec/moneta/transformer_msgpack_spec.rb +1 -0
- data/spec/moneta/transformer_ox_spec.rb +1 -0
- data/spec/moneta/transformer_quicklz_spec.rb +1 -0
- data/spec/moneta/transformer_snappy_spec.rb +1 -0
- data/spec/moneta/transformer_tnet_spec.rb +1 -0
- data/spec/moneta/transformer_value_marshal_spec.rb +1 -0
- data/spec/moneta/transformer_value_yaml_spec.rb +1 -0
- data/spec/moneta/transformer_yaml_spec.rb +1 -0
- data/spec/moneta/transformer_zlib_spec.rb +1 -0
- data/spec/moneta/weak_create_spec.rb +114 -0
- data/spec/moneta/weak_increment_spec.rb +114 -0
- data/spec/monetaspecs.rb +75 -2
- data/spec/rack/moneta_cookies_spec.rb +1 -1
- metadata +20 -4
data/lib/moneta/transformer.rb
CHANGED
|
@@ -57,86 +57,91 @@ module Moneta
|
|
|
57
57
|
end
|
|
58
58
|
end_eval
|
|
59
59
|
|
|
60
|
-
key = compile_transformer(keys, 'key')
|
|
61
|
-
dump = compile_transformer(values, 'value')
|
|
62
|
-
load = compile_transformer(values.reverse, 'value', 1)
|
|
60
|
+
key, key_opts = compile_transformer(keys, 'key')
|
|
61
|
+
dump, dump_opts = compile_transformer(values, 'value')
|
|
62
|
+
load, load_opts = compile_transformer(values.reverse, 'value', 1)
|
|
63
63
|
|
|
64
64
|
if values.empty?
|
|
65
|
-
compile_key_transformer(klass, key)
|
|
65
|
+
compile_key_transformer(klass, key, key_opts)
|
|
66
66
|
elsif keys.empty?
|
|
67
|
-
compile_value_transformer(klass, load, dump)
|
|
67
|
+
compile_value_transformer(klass, load, load_opts, dump, dump_opts)
|
|
68
68
|
else
|
|
69
|
-
compile_key_value_transformer(klass, key, load, dump)
|
|
69
|
+
compile_key_value_transformer(klass, key, key_opts, load, load_opts, dump, dump_opts)
|
|
70
70
|
end
|
|
71
71
|
|
|
72
72
|
klass
|
|
73
73
|
end
|
|
74
74
|
|
|
75
|
-
def
|
|
75
|
+
def without(*options)
|
|
76
|
+
options = options.flatten.uniq
|
|
77
|
+
options.empty? ? 'options' : "Utils.without(options, #{options.map(&:to_sym).map(&:inspect).join(', ')})"
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def compile_key_transformer(klass, key, key_opts)
|
|
76
81
|
klass.class_eval <<-end_eval, __FILE__, __LINE__
|
|
77
82
|
def key?(key, options = {})
|
|
78
|
-
@adapter.key?(#{key},
|
|
83
|
+
@adapter.key?(#{key}, #{without key_opts})
|
|
79
84
|
end
|
|
80
85
|
def increment(key, amount = 1, options = {})
|
|
81
|
-
@adapter.increment(#{key}, amount,
|
|
86
|
+
@adapter.increment(#{key}, amount, #{without key_opts})
|
|
82
87
|
end
|
|
83
88
|
def load(key, options = {})
|
|
84
|
-
|
|
85
|
-
@adapter.load(#{key}, options)
|
|
89
|
+
@adapter.load(#{key}, #{without :raw, key_opts})
|
|
86
90
|
end
|
|
87
91
|
def store(key, value, options = {})
|
|
88
|
-
|
|
89
|
-
@adapter.store(#{key}, value, options)
|
|
92
|
+
@adapter.store(#{key}, value, #{without :raw, key_opts})
|
|
90
93
|
end
|
|
91
94
|
def delete(key, options = {})
|
|
92
|
-
|
|
93
|
-
|
|
95
|
+
@adapter.delete(#{key}, #{without :raw, key_opts})
|
|
96
|
+
end
|
|
97
|
+
def create(key, value, options = {})
|
|
98
|
+
@adapter.create(#{key}, value, #{without :raw, key_opts})
|
|
94
99
|
end
|
|
95
100
|
end_eval
|
|
96
101
|
end
|
|
97
102
|
|
|
98
|
-
def compile_value_transformer(klass, load, dump)
|
|
103
|
+
def compile_value_transformer(klass, load, load_opts, dump, dump_opts)
|
|
99
104
|
klass.class_eval <<-end_eval, __FILE__, __LINE__
|
|
100
105
|
def load(key, options = {})
|
|
101
|
-
|
|
102
|
-
value
|
|
103
|
-
value && !raw ? #{load} : value
|
|
106
|
+
value = @adapter.load(key, #{without :raw, load_opts})
|
|
107
|
+
value && !options[:raw] ? #{load} : value
|
|
104
108
|
end
|
|
105
109
|
def store(key, value, options = {})
|
|
106
|
-
|
|
107
|
-
@adapter.store(key, raw ? value : #{dump}, options)
|
|
110
|
+
@adapter.store(key, options[:raw] ? value : #{dump}, #{without :raw, dump_opts})
|
|
108
111
|
value
|
|
109
112
|
end
|
|
110
113
|
def delete(key, options = {})
|
|
111
|
-
|
|
112
|
-
value
|
|
113
|
-
|
|
114
|
+
value = @adapter.delete(key, #{without :raw, load_opts})
|
|
115
|
+
value && !options[:raw] ? #{load} : value
|
|
116
|
+
end
|
|
117
|
+
def create(key, value, options = {})
|
|
118
|
+
@adapter.create(key, options[:raw] ? value : #{dump}, #{without :raw, dump_opts})
|
|
114
119
|
end
|
|
115
120
|
end_eval
|
|
116
121
|
end
|
|
117
122
|
|
|
118
|
-
def compile_key_value_transformer(klass, key, load, dump)
|
|
123
|
+
def compile_key_value_transformer(klass, key, key_opts, load, load_opts, dump, dump_opts)
|
|
119
124
|
klass.class_eval <<-end_eval, __FILE__, __LINE__
|
|
120
125
|
def key?(key, options = {})
|
|
121
|
-
@adapter.key?(#{key},
|
|
126
|
+
@adapter.key?(#{key}, #{without key_opts})
|
|
122
127
|
end
|
|
123
128
|
def increment(key, amount = 1, options = {})
|
|
124
|
-
@adapter.increment(#{key}, amount,
|
|
129
|
+
@adapter.increment(#{key}, amount, #{without key_opts})
|
|
125
130
|
end
|
|
126
131
|
def load(key, options = {})
|
|
127
|
-
|
|
128
|
-
value
|
|
129
|
-
value && !raw ? #{load} : value
|
|
132
|
+
value = @adapter.load(#{key}, #{without :raw, key_opts, load_opts})
|
|
133
|
+
value && !options[:raw] ? #{load} : value
|
|
130
134
|
end
|
|
131
135
|
def store(key, value, options = {})
|
|
132
|
-
|
|
133
|
-
@adapter.store(#{key}, raw ? value : #{dump}, options)
|
|
136
|
+
@adapter.store(#{key}, options[:raw] ? value : #{dump}, #{without :raw, key_opts, dump_opts})
|
|
134
137
|
value
|
|
135
138
|
end
|
|
136
139
|
def delete(key, options = {})
|
|
137
|
-
|
|
138
|
-
value
|
|
139
|
-
|
|
140
|
+
value = @adapter.delete(#{key}, #{without :raw, key_opts, load_opts})
|
|
141
|
+
value && !options[:raw] ? #{load} : value
|
|
142
|
+
end
|
|
143
|
+
def create(key, value, options = {})
|
|
144
|
+
@adapter.create(#{key}, options[:raw] ? value : #{dump}, #{without :raw, key_opts, dump_opts})
|
|
140
145
|
end
|
|
141
146
|
end_eval
|
|
142
147
|
end
|
|
@@ -151,7 +156,6 @@ module Moneta
|
|
|
151
156
|
end.join("\n")
|
|
152
157
|
end
|
|
153
158
|
|
|
154
|
-
# Compile transformer validator regular expression
|
|
155
159
|
def compile_validator(s)
|
|
156
160
|
Regexp.new('\A' + s.gsub(/\w+/) do
|
|
157
161
|
'(' + TRANSFORMER.select {|k,v| v.first.to_s == $& }.map {|v| ":#{v.first}" }.join('|') + ')'
|
|
@@ -160,16 +164,20 @@ module Moneta
|
|
|
160
164
|
|
|
161
165
|
# Returned compiled transformer code string
|
|
162
166
|
def compile_transformer(transformer, var, i = 2)
|
|
163
|
-
|
|
167
|
+
value, options = var, []
|
|
168
|
+
transformer.each do |name|
|
|
164
169
|
raise ArgumentError, "Unknown transformer #{name}" unless t = TRANSFORMER[name]
|
|
165
170
|
require t[3] if t[3]
|
|
166
171
|
code = t[i]
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
+
options += code.scan(/options\[:(\w+)\]/).flatten
|
|
173
|
+
value =
|
|
174
|
+
if t[0] == :serialize && var == 'key'
|
|
175
|
+
"(tmp = #{value}; String === tmp ? tmp : #{code % 'tmp'})"
|
|
176
|
+
else
|
|
177
|
+
code % value
|
|
178
|
+
end
|
|
172
179
|
end
|
|
180
|
+
return value, options
|
|
173
181
|
end
|
|
174
182
|
|
|
175
183
|
def class_name(keys, values)
|
|
@@ -2,44 +2,46 @@ module Moneta
|
|
|
2
2
|
class Transformer
|
|
3
3
|
# Available key/value transformers
|
|
4
4
|
TRANSFORMER = {
|
|
5
|
-
# Name => [ Type, Load,
|
|
6
|
-
:bencode => [ :serialize, '::BEncode.load(%s)',
|
|
7
|
-
:bert => [ :serialize, '::BERT.decode(%s)',
|
|
8
|
-
:bson => [ :serialize, "::BSON.deserialize(%s)['v']",
|
|
9
|
-
:json => [ :serialize, '::MultiJson.load(%s).first',
|
|
10
|
-
:marshal => [ :serialize, '::Marshal.load(%s)',
|
|
11
|
-
:msgpack => [ :serialize, '::MessagePack.unpack(%s)',
|
|
12
|
-
:ox => [ :serialize, '::Ox.parse_obj(%s)',
|
|
13
|
-
:tnet => [ :serialize, '::TNetstring.parse(%s).first',
|
|
14
|
-
:yaml => [ :serialize, '::YAML.load(%s)',
|
|
15
|
-
:bzip2 => [ :compress, '::Bzip2.uncompress(%s)',
|
|
16
|
-
:lzma => [ :compress, '::LZMA.decompress(%s)',
|
|
17
|
-
:lzo => [ :compress, '::LZO.decompress(%s)',
|
|
18
|
-
:snappy => [ :compress, '::Snappy.inflate(%s)',
|
|
19
|
-
:quicklz => [ :compress, '::QuickLZ.decompress(%s)',
|
|
20
|
-
:zlib => [ :compress, '::Zlib::Inflate.inflate(%s)',
|
|
21
|
-
:uuencode => [ :encode, "%s.unpack('u').first",
|
|
5
|
+
# Name => [ Type, Load, Dump, Library ],
|
|
6
|
+
:bencode => [ :serialize, '::BEncode.load(%s)', '::BEncode.dump(%s)', 'bencode' ],
|
|
7
|
+
:bert => [ :serialize, '::BERT.decode(%s)', '::BERT.encode(%s)', 'bert' ],
|
|
8
|
+
:bson => [ :serialize, "::BSON.deserialize(%s)['v']", "::BSON.serialize('v'=>%s).to_s", 'bson' ],
|
|
9
|
+
:json => [ :serialize, '::MultiJson.load(%s).first', '::MultiJson.dump([%s])', 'multi_json' ],
|
|
10
|
+
:marshal => [ :serialize, '::Marshal.load(%s)', '::Marshal.dump(%s)' ],
|
|
11
|
+
:msgpack => [ :serialize, '::MessagePack.unpack(%s)', '::MessagePack.pack(%s)', 'msgpack' ],
|
|
12
|
+
:ox => [ :serialize, '::Ox.parse_obj(%s)', '::Ox.dump(%s)', 'ox' ],
|
|
13
|
+
:tnet => [ :serialize, '::TNetstring.parse(%s).first', '::TNetstring.dump(%s)', 'tnetstring' ],
|
|
14
|
+
:yaml => [ :serialize, '::YAML.load(%s)', '::YAML.dump(%s)', 'yaml' ],
|
|
15
|
+
:bzip2 => [ :compress, '::Bzip2.uncompress(%s)', '::Bzip2.compress(%s)', 'bzip2' ],
|
|
16
|
+
:lzma => [ :compress, '::LZMA.decompress(%s)', '::LZMA.compress(%s)', 'lzma' ],
|
|
17
|
+
:lzo => [ :compress, '::LZO.decompress(%s)', '::LZO.compress(%s)', 'lzoruby' ],
|
|
18
|
+
:snappy => [ :compress, '::Snappy.inflate(%s)', '::Snappy.deflate(%s)', 'snappy' ],
|
|
19
|
+
:quicklz => [ :compress, '::QuickLZ.decompress(%s)', '::QuickLZ.compress(%s)', 'qlzruby' ],
|
|
20
|
+
:zlib => [ :compress, '::Zlib::Inflate.inflate(%s)', '::Zlib::Deflate.deflate(%s)', 'zlib' ],
|
|
21
|
+
:uuencode => [ :encode, "%s.unpack('u').first", "[%s].pack('u').strip" ],
|
|
22
22
|
:base64 => RUBY_VERSION > '1.9' ?
|
|
23
|
-
[ :encode, "%s.unpack('m0').first",
|
|
24
|
-
[ :encode, "%s.unpack('m').first",
|
|
25
|
-
:escape => [ :encode, 'Helper.unescape(%s)',
|
|
26
|
-
:hmac => [ :hmac, 'Helper.hmacverify(%s,
|
|
27
|
-
|
|
28
|
-
:
|
|
29
|
-
:
|
|
30
|
-
:
|
|
31
|
-
:
|
|
32
|
-
:
|
|
33
|
-
:
|
|
34
|
-
:
|
|
35
|
-
:
|
|
36
|
-
:
|
|
23
|
+
[ :encode, "%s.unpack('m0').first", "[%s].pack('m0')" ] :
|
|
24
|
+
[ :encode, "%s.unpack('m').first", "[%s].pack('m').gsub(\"\n\", '')" ],
|
|
25
|
+
:escape => [ :encode, 'Helper.unescape(%s)', 'Helper.escape(%s)' ],
|
|
26
|
+
:hmac => [ :hmac, 'Helper.hmacverify(%s, options[:secret] || @secret)',
|
|
27
|
+
'Helper.hmacsign(%s, options[:secret] || @secret)', 'openssl' ],
|
|
28
|
+
:truncate => [ :truncate, nil, 'Helper.truncate(%s, @maxlen)', 'digest/md5' ],
|
|
29
|
+
:md5 => [ :digest, nil, '::Digest::MD5.hexdigest(%s)', 'digest/md5' ],
|
|
30
|
+
:rmd160 => [ :digest, nil, '::Digest::RMD160.hexdigest(%s)', 'digest/rmd160' ],
|
|
31
|
+
:sha1 => [ :digest, nil, '::Digest::SHA1.hexdigest(%s)', 'digest/sha1' ],
|
|
32
|
+
:sha256 => [ :digest, nil, '::Digest::SHA256.hexdigest(%s)', 'digest/sha2' ],
|
|
33
|
+
:sha384 => [ :digest, nil, '::Digest::SHA384.hexdigest(%s)', 'digest/sha2' ],
|
|
34
|
+
:sha512 => [ :digest, nil, '::Digest::SHA512.hexdigest(%s)', 'digest/sha2' ],
|
|
35
|
+
:prefix => [ :prefix, nil, '(options[:prefix] || @prefix)+%s' ],
|
|
36
|
+
:spread => [ :spread, nil, 'Helper.spread(%s)' ],
|
|
37
|
+
:to_s => [ :string, nil, '%s.to_s' ],
|
|
38
|
+
:inspect => [ :string, nil, '%s.inspect' ],
|
|
37
39
|
}
|
|
38
40
|
|
|
39
41
|
# Allowed value transformers (Read it like a regular expression!)
|
|
40
42
|
VALUE_TRANSFORMER = 'serialize? compress? hmac? encode?'
|
|
41
43
|
|
|
42
44
|
# Allowed key transformers (Read it like a regular expression!)
|
|
43
|
-
KEY_TRANSFORMER = '(serialize |
|
|
45
|
+
KEY_TRANSFORMER = '(serialize | string)? prefix? ((encode? truncate?) | (digest spread?))?'
|
|
44
46
|
end
|
|
45
47
|
end
|
data/lib/moneta/utils.rb
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
module Moneta
|
|
2
|
+
# @api private
|
|
3
|
+
module Utils
|
|
4
|
+
extend self
|
|
5
|
+
|
|
6
|
+
def without(hash, *keys)
|
|
7
|
+
if keys.any? {|k| hash.include?(k) }
|
|
8
|
+
hash = hash.dup
|
|
9
|
+
keys.each {|k| hash.delete(k) }
|
|
10
|
+
end
|
|
11
|
+
hash
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def to_int(value)
|
|
15
|
+
intvalue = value.to_i
|
|
16
|
+
raise "#{value.inspect} is not an integer value" unless value == nil || intvalue.to_s == value.to_s
|
|
17
|
+
intvalue
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
data/lib/moneta/version.rb
CHANGED
data/lib/moneta/weak.rb
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module Moneta
|
|
2
|
+
# Adds weak create support to the underlying store
|
|
3
|
+
#
|
|
4
|
+
# @note The increment method will not be thread or multi-process safe (this is meant by weak)
|
|
5
|
+
# @api public
|
|
6
|
+
class WeakCreate < Proxy
|
|
7
|
+
include CreateSupport
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
# Adds weak increment support to the underlying store
|
|
11
|
+
#
|
|
12
|
+
# @note The increment method will not be thread or multi-process safe (this is meant by weak)
|
|
13
|
+
# @api public
|
|
14
|
+
class WeakIncrement < Proxy
|
|
15
|
+
include IncrementSupport
|
|
16
|
+
end
|
|
17
|
+
end
|
data/lib/moneta/wrapper.rb
CHANGED
|
@@ -27,6 +27,11 @@ module Moneta
|
|
|
27
27
|
wrap(:increment, key, amount, options) { super }
|
|
28
28
|
end
|
|
29
29
|
|
|
30
|
+
# (see Proxy#create)
|
|
31
|
+
def create(key, value, options = {})
|
|
32
|
+
wrap(:create, key, value, options) { super }
|
|
33
|
+
end
|
|
34
|
+
|
|
30
35
|
# (see Proxy#clear)
|
|
31
36
|
def clear(options = {})
|
|
32
37
|
wrap(:clear, options) { super }
|
data/lib/rack/moneta_cookies.rb
CHANGED
|
@@ -23,7 +23,7 @@ module Rack
|
|
|
23
23
|
# adapter :Cookie
|
|
24
24
|
# end
|
|
25
25
|
#
|
|
26
|
-
# run lambda
|
|
26
|
+
# run lambda { |env|
|
|
27
27
|
# req = Rack::Request.new(env)
|
|
28
28
|
# req.cookies #=> is now a Moneta store!
|
|
29
29
|
# env['rack.request.cookie_hash'] #=> is now a Moneta store!
|
|
@@ -31,7 +31,7 @@ module Rack
|
|
|
31
31
|
# req.cookies['key'] = 'value' #=> sets 'moneta.key'
|
|
32
32
|
# req.cookies.delete('key') #=> removes 'moneta.key'
|
|
33
33
|
# [200, {}, []]
|
|
34
|
-
#
|
|
34
|
+
# }
|
|
35
35
|
#
|
|
36
36
|
# @api public
|
|
37
37
|
class MonetaCookies
|
data/lib/rack/moneta_store.rb
CHANGED
|
@@ -8,9 +8,9 @@ module Rack
|
|
|
8
8
|
# # Add Rack::MonetaStore somewhere in your rack stack
|
|
9
9
|
# use Rack::MonetaStore, :Memory, :cache => true
|
|
10
10
|
#
|
|
11
|
-
# run lambda
|
|
11
|
+
# run lambda { |env|
|
|
12
12
|
# env['rack.moneta_store'] # is a Moneta store with per-request caching
|
|
13
|
-
#
|
|
13
|
+
# }
|
|
14
14
|
#
|
|
15
15
|
# @example config.ru
|
|
16
16
|
# # Pass it a block like the one passed to Moneta.build
|
|
@@ -19,9 +19,9 @@ module Rack
|
|
|
19
19
|
# adapter :Cookie
|
|
20
20
|
# end
|
|
21
21
|
#
|
|
22
|
-
# run lambda
|
|
22
|
+
# run lambda { |env|
|
|
23
23
|
# env['rack.moneta_store'] # is a Moneta store without caching
|
|
24
|
-
#
|
|
24
|
+
# }
|
|
25
25
|
#
|
|
26
26
|
# @api public
|
|
27
27
|
class MonetaStore
|
data/script/benchmarks
CHANGED
|
@@ -24,12 +24,6 @@ class Array
|
|
|
24
24
|
m = mean
|
|
25
25
|
Math.sqrt(map {|s| (s - m) ** 2 }.mean)
|
|
26
26
|
end
|
|
27
|
-
|
|
28
|
-
def randomize
|
|
29
|
-
rest, result = dup, []
|
|
30
|
-
result << rest.slice!(rand(rest.size)) until result.size == size
|
|
31
|
-
result
|
|
32
|
-
end
|
|
33
27
|
end
|
|
34
28
|
|
|
35
29
|
class MonetaBenchmarks
|
|
@@ -242,7 +236,7 @@ class MonetaBenchmarks
|
|
|
242
236
|
puts "\e[31m#{name} not benchmarked - #{ex.message}\e[0m"
|
|
243
237
|
STORES.delete(name)
|
|
244
238
|
ensure
|
|
245
|
-
cache.close if cache
|
|
239
|
+
(cache.close rescue nil) if cache
|
|
246
240
|
end
|
|
247
241
|
end
|
|
248
242
|
end
|
|
@@ -312,14 +306,14 @@ class MonetaBenchmarks
|
|
|
312
306
|
store.clear
|
|
313
307
|
print "%s[%-#{2 * @config[:runs]}s] " % ["\b" * (2 * @config[:runs] + 3), state << 'W']
|
|
314
308
|
|
|
315
|
-
@data
|
|
309
|
+
@data.shuffle!
|
|
316
310
|
m1 = Benchmark.measure do
|
|
317
311
|
@data.each {|k,v| store[k] = v }
|
|
318
312
|
end
|
|
319
313
|
|
|
320
314
|
print "%s[%-#{2 * @config[:runs]}s] " % ["\b" * (2 * @config[:runs] + 3), state << 'R']
|
|
321
315
|
|
|
322
|
-
@data
|
|
316
|
+
@data.shuffle!
|
|
323
317
|
error = 0
|
|
324
318
|
m2 = Benchmark.measure do
|
|
325
319
|
@data.each do |k, v|
|
data/script/generate-specs
CHANGED
|
@@ -61,14 +61,17 @@ class Specs
|
|
|
61
61
|
a = specs.dup
|
|
62
62
|
if a.include?(:transform_value)
|
|
63
63
|
a.delete(:transform_value)
|
|
64
|
-
a << :
|
|
64
|
+
a << :transform_value_expires
|
|
65
65
|
end
|
|
66
|
+
a << :create_expires if a.include?(:create)
|
|
66
67
|
a << :expires
|
|
67
68
|
new(:specs => a)
|
|
68
69
|
end
|
|
69
70
|
|
|
70
71
|
def with_native_expires
|
|
71
|
-
|
|
72
|
+
a = specs.dup
|
|
73
|
+
a << :create_expires if a.include?(:create)
|
|
74
|
+
new(:specs => a.with(:expires))
|
|
72
75
|
end
|
|
73
76
|
|
|
74
77
|
def without_marshallable
|
|
@@ -98,11 +101,15 @@ class Specs
|
|
|
98
101
|
def with_default_expires
|
|
99
102
|
new(:specs => specs.with(:default_expires))
|
|
100
103
|
end
|
|
104
|
+
|
|
105
|
+
def without_create
|
|
106
|
+
new(:specs => specs.without(:create, :create_expires).with(:not_create))
|
|
107
|
+
end
|
|
101
108
|
end
|
|
102
109
|
|
|
103
|
-
ADAPTER_SPECS = Specs.new(:specs => [:null, :store, :returndifferent, :increment, :persist, :multiprocess], :key => %w(string), :value => %w(string))
|
|
104
|
-
STANDARD_SPECS = Specs.new(:specs => [:null, :store, :returndifferent, :marshallable_key, :marshallable_value, :transform_value, :increment, :persist, :multiprocess])
|
|
105
|
-
TRANSFORMER_SPECS = Specs.new(:specs => [:null, :store, :returndifferent, :transform_value, :increment])
|
|
110
|
+
ADAPTER_SPECS = Specs.new(:specs => [:null, :store, :returndifferent, :increment, :persist, :multiprocess, :create], :key => %w(string), :value => %w(string))
|
|
111
|
+
STANDARD_SPECS = Specs.new(:specs => [:null, :store, :returndifferent, :marshallable_key, :marshallable_value, :transform_value, :increment, :persist, :multiprocess, :create])
|
|
112
|
+
TRANSFORMER_SPECS = Specs.new(:specs => [:null, :store, :returndifferent, :transform_value, :increment, :create])
|
|
106
113
|
|
|
107
114
|
header = "# Generated by #{File.basename(__FILE__)}\n"
|
|
108
115
|
|
|
@@ -129,16 +136,16 @@ end
|
|
|
129
136
|
}
|
|
130
137
|
},
|
|
131
138
|
'simple_client_unix' => {
|
|
132
|
-
:preamble => "start_server(Moneta::Adapters::Memory.new, :
|
|
139
|
+
:preamble => "start_server(Moneta::Adapters::Memory.new, :socket => File.join(make_tempdir, 'simple_client_unix'))\n",
|
|
133
140
|
:store => :Client,
|
|
134
|
-
:options => ":
|
|
141
|
+
:options => ":socket => File.join(make_tempdir, 'simple_client_unix')",
|
|
135
142
|
:specs => STANDARD_SPECS
|
|
136
143
|
},
|
|
137
144
|
'simple_restclient' => {
|
|
138
145
|
:preamble => "start_restserver\n",
|
|
139
146
|
:store => :RestClient,
|
|
140
147
|
:options => ":url => 'http://localhost:8808/moneta/'",
|
|
141
|
-
:specs => STANDARD_SPECS.without_increment
|
|
148
|
+
:specs => STANDARD_SPECS.without_increment.without_create
|
|
142
149
|
},
|
|
143
150
|
'simple_memory' => {
|
|
144
151
|
:store => :Memory,
|
|
@@ -215,12 +222,12 @@ end
|
|
|
215
222
|
'simple_cassandra' => {
|
|
216
223
|
:store => :Cassandra,
|
|
217
224
|
:options => ':keyspace => "simple_cassandra"',
|
|
218
|
-
:specs => STANDARD_SPECS.without_increment.with_native_expires,
|
|
225
|
+
:specs => STANDARD_SPECS.without_increment.without_create.with_native_expires,
|
|
219
226
|
},
|
|
220
227
|
'simple_hbase' => {
|
|
221
228
|
:store => :HBase,
|
|
222
229
|
:options => ':table => "simple_hbase"',
|
|
223
|
-
:specs => STANDARD_SPECS
|
|
230
|
+
:specs => STANDARD_SPECS.without_create
|
|
224
231
|
},
|
|
225
232
|
'simple_hbase_with_expires' => {
|
|
226
233
|
:store => :HBase,
|
|
@@ -314,12 +321,12 @@ end
|
|
|
314
321
|
'simple_localmemcache' => {
|
|
315
322
|
:store => :LocalMemCache,
|
|
316
323
|
:options => ':file => File.join(make_tempdir, "simple_localmemcache")',
|
|
317
|
-
:specs => STANDARD_SPECS.without_increment
|
|
324
|
+
:specs => STANDARD_SPECS.without_increment.without_create
|
|
318
325
|
},
|
|
319
326
|
'simple_localmemcache_with_expires' => {
|
|
320
327
|
:store => :LocalMemCache,
|
|
321
328
|
:options => ':file => File.join(make_tempdir, "simple_localmemcache_with_expires"), :expires => true',
|
|
322
|
-
:specs => STANDARD_SPECS.without_increment.with_expires
|
|
329
|
+
:specs => STANDARD_SPECS.without_increment.without_create.with_expires
|
|
323
330
|
},
|
|
324
331
|
'simple_tokyocabinet' => {
|
|
325
332
|
:store => :TokyoCabinet,
|
|
@@ -365,25 +372,25 @@ end
|
|
|
365
372
|
:options => ":bucket => 'simple_riak'",
|
|
366
373
|
# We don't want Riak warnings in tests
|
|
367
374
|
:preamble => "require 'riak'\n\nRiak.disable_list_keys_warnings = true\n\n",
|
|
368
|
-
:specs => STANDARD_SPECS.without_increment
|
|
375
|
+
:specs => STANDARD_SPECS.without_increment.without_create
|
|
369
376
|
},
|
|
370
377
|
'simple_riak_with_expires' => {
|
|
371
378
|
:store => :Riak,
|
|
372
379
|
:options => ":bucket => 'simple_riak_with_expires', :expires => true",
|
|
373
380
|
# We don't want Riak warnings in tests
|
|
374
381
|
:preamble => "require 'riak'\n\nRiak.disable_list_keys_warnings = true\n\n",
|
|
375
|
-
:specs => STANDARD_SPECS.without_increment.with_expires
|
|
382
|
+
:specs => STANDARD_SPECS.without_increment.with_expires.without_create
|
|
376
383
|
},
|
|
377
384
|
'simple_couch' => {
|
|
378
385
|
:store => :Couch,
|
|
379
386
|
:options => ":db => 'simple_couch'",
|
|
380
387
|
:load_value => '::Marshal.load(value.unpack(\'m\').first)',
|
|
381
|
-
:specs => STANDARD_SPECS.without_increment
|
|
388
|
+
:specs => STANDARD_SPECS.without_increment.without_create
|
|
382
389
|
},
|
|
383
390
|
'simple_couch_with_expires' => {
|
|
384
391
|
:store => :Couch,
|
|
385
392
|
:options => ":db => 'simple_couch_with_expires', :expires => true",
|
|
386
|
-
:specs => STANDARD_SPECS.without_increment.with_expires,
|
|
393
|
+
:specs => STANDARD_SPECS.without_increment.without_create.with_expires,
|
|
387
394
|
:load_value => '::Marshal.load(value.unpack(\'m\').first)'
|
|
388
395
|
},
|
|
389
396
|
'simple_mongo' => {
|
|
@@ -393,11 +400,11 @@ end
|
|
|
393
400
|
},
|
|
394
401
|
'simple_null' => {
|
|
395
402
|
:store => :Null,
|
|
396
|
-
:specs => STANDARD_SPECS.without_increment.without_store.without_persist
|
|
403
|
+
:specs => STANDARD_SPECS.without_increment.without_create.without_store.without_persist
|
|
397
404
|
},
|
|
398
405
|
'null_adapter' => {
|
|
399
406
|
:build => 'Moneta::Adapters::Null.new',
|
|
400
|
-
:specs => Specs.new(:specs => [:null, :not_increment, :not_persist])
|
|
407
|
+
:specs => Specs.new(:specs => [:null, :not_increment, :not_create, :not_persist])
|
|
401
408
|
},
|
|
402
409
|
'simple_sequel' => {
|
|
403
410
|
:store => :Sequel,
|
|
@@ -449,7 +456,7 @@ end
|
|
|
449
456
|
},
|
|
450
457
|
'simple_fog' => {
|
|
451
458
|
:store => :Fog,
|
|
452
|
-
:specs => STANDARD_SPECS.without_increment,
|
|
459
|
+
:specs => STANDARD_SPECS.without_increment.without_create,
|
|
453
460
|
:options => ":aws_access_key_id => 'fake_access_key_id',
|
|
454
461
|
:aws_secret_access_key => 'fake_secret_access_key',
|
|
455
462
|
:provider => 'AWS',
|
|
@@ -466,7 +473,21 @@ end
|
|
|
466
473
|
:expires => true",
|
|
467
474
|
# Put Fog into testing mode
|
|
468
475
|
:preamble => "require 'fog'\nFog.mock!\n",
|
|
469
|
-
:specs => STANDARD_SPECS.without_increment.with_expires
|
|
476
|
+
:specs => STANDARD_SPECS.without_increment.without_create.with_expires
|
|
477
|
+
},
|
|
478
|
+
'weak_create' => {
|
|
479
|
+
:build => %{Moneta.build do
|
|
480
|
+
use :WeakCreate
|
|
481
|
+
adapter :Memory
|
|
482
|
+
end},
|
|
483
|
+
:specs => STANDARD_SPECS.without_transform.without_persist.returnsame
|
|
484
|
+
},
|
|
485
|
+
'weak_increment' => {
|
|
486
|
+
:build => %{Moneta.build do
|
|
487
|
+
use :WeakIncrement
|
|
488
|
+
adapter :Memory
|
|
489
|
+
end},
|
|
490
|
+
:specs => STANDARD_SPECS.without_transform.without_persist.returnsame
|
|
470
491
|
},
|
|
471
492
|
'expires_memory' => {
|
|
472
493
|
:build => %{Moneta.build do
|
|
@@ -549,10 +570,27 @@ end
|
|
|
549
570
|
end},
|
|
550
571
|
:specs => ADAPTER_SPECS.without_persist.returnsame
|
|
551
572
|
},
|
|
552
|
-
'
|
|
573
|
+
'shared_tcp' => {
|
|
553
574
|
:build => %{Moneta.build do
|
|
554
575
|
use(:Shared, :port => 9001) do
|
|
555
|
-
adapter :PStore, :file => File.join(make_tempdir, '
|
|
576
|
+
adapter :PStore, :file => File.join(make_tempdir, 'shared_tcp')
|
|
577
|
+
end
|
|
578
|
+
end},
|
|
579
|
+
:specs => ADAPTER_SPECS,
|
|
580
|
+
:tests => %{
|
|
581
|
+
it 'shares values' do
|
|
582
|
+
store['shared_key'] = 'shared_value'
|
|
583
|
+
second = new_store
|
|
584
|
+
second.key?('shared_key').should be_true
|
|
585
|
+
second['shared_key'].should == 'shared_value'
|
|
586
|
+
second.close
|
|
587
|
+
end
|
|
588
|
+
}
|
|
589
|
+
},
|
|
590
|
+
'shared_unix' => {
|
|
591
|
+
:build => %{Moneta.build do
|
|
592
|
+
use(:Shared, :socket => File.join(make_tempdir, 'shared_unix.socket')) do
|
|
593
|
+
adapter :PStore, :file => File.join(make_tempdir, 'shared_unix')
|
|
556
594
|
end
|
|
557
595
|
end},
|
|
558
596
|
:specs => ADAPTER_SPECS,
|
|
@@ -575,7 +613,7 @@ end
|
|
|
575
613
|
add { adapter :Memory }
|
|
576
614
|
end
|
|
577
615
|
end},
|
|
578
|
-
:specs => ADAPTER_SPECS.without_increment
|
|
616
|
+
:specs => ADAPTER_SPECS.without_increment.without_create
|
|
579
617
|
},
|
|
580
618
|
'stack_memory_file' => {
|
|
581
619
|
:build => %{Moneta.build do
|
|
@@ -586,7 +624,7 @@ end},
|
|
|
586
624
|
add { adapter :File, :dir => File.join(make_tempdir, "stack_memory_file") }
|
|
587
625
|
end
|
|
588
626
|
end},
|
|
589
|
-
:specs => STANDARD_SPECS.without_increment.returnsame.without_transform.stringkeys_only.stringvalues_only
|
|
627
|
+
:specs => STANDARD_SPECS.without_increment.without_create.returnsame.without_transform.stringkeys_only.stringvalues_only
|
|
590
628
|
},
|
|
591
629
|
'lock' => {
|
|
592
630
|
:build => %{Moneta.build do
|
|
@@ -810,6 +848,19 @@ end},
|
|
|
810
848
|
it 'compile transformer class' do
|
|
811
849
|
store.should_not be_nil
|
|
812
850
|
Moneta::Transformer::To_sKey.should_not be_nil
|
|
851
|
+
end}
|
|
852
|
+
},
|
|
853
|
+
'transformer_key_inspect' => {
|
|
854
|
+
:build => %{Moneta.build do
|
|
855
|
+
use :Transformer, :key => :inspect
|
|
856
|
+
adapter :Memory
|
|
857
|
+
end},
|
|
858
|
+
:specs => TRANSFORMER_SPECS.returnsame.simplekeys_only,
|
|
859
|
+
:load_value => 'value',
|
|
860
|
+
:tests => %{
|
|
861
|
+
it 'compile transformer class' do
|
|
862
|
+
store.should_not be_nil
|
|
863
|
+
Moneta::Transformer::InspectKey.should_not be_nil
|
|
813
864
|
end}
|
|
814
865
|
},
|
|
815
866
|
'transformer_value_marshal' => {
|
|
@@ -1050,19 +1101,19 @@ end
|
|
|
1050
1101
|
'adapter_restclient' => {
|
|
1051
1102
|
:preamble => "start_restserver\n",
|
|
1052
1103
|
:build => "Moneta::Adapters::RestClient.new(:url => 'http://localhost:8808/moneta/')",
|
|
1053
|
-
:specs => ADAPTER_SPECS.without_increment
|
|
1104
|
+
:specs => ADAPTER_SPECS.without_increment.without_create
|
|
1054
1105
|
},
|
|
1055
1106
|
'adapter_cassandra' => {
|
|
1056
1107
|
:build => "Moneta::Adapters::Cassandra.new(:keyspace => 'adapter_cassandra')",
|
|
1057
|
-
:specs => ADAPTER_SPECS.without_increment.with_native_expires
|
|
1108
|
+
:specs => ADAPTER_SPECS.without_increment.without_create.with_native_expires
|
|
1058
1109
|
},
|
|
1059
1110
|
'adapter_cassandra_with_default_expires' => {
|
|
1060
1111
|
:build => %{Moneta::Adapters::Cassandra.new(:keyspace => 'adapter_cassandra_with_default_expires', :expires => 1)},
|
|
1061
|
-
:specs => ADAPTER_SPECS.without_increment.with_native_expires.with_default_expires
|
|
1112
|
+
:specs => ADAPTER_SPECS.without_increment.without_create.with_native_expires.with_default_expires
|
|
1062
1113
|
},
|
|
1063
1114
|
'adapter_hbase' => {
|
|
1064
1115
|
:build => "Moneta::Adapters::HBase.new(:table => 'adapter_hbase')",
|
|
1065
|
-
:specs => ADAPTER_SPECS
|
|
1116
|
+
:specs => ADAPTER_SPECS.without_create
|
|
1066
1117
|
},
|
|
1067
1118
|
'adapter_cookie' => {
|
|
1068
1119
|
:build => 'Moneta::Adapters::Cookie.new',
|
|
@@ -1070,7 +1121,7 @@ end
|
|
|
1070
1121
|
},
|
|
1071
1122
|
'adapter_couch' => {
|
|
1072
1123
|
:build => "Moneta::Adapters::Couch.new(:db => 'adapter_couch')",
|
|
1073
|
-
:specs => ADAPTER_SPECS.without_increment
|
|
1124
|
+
:specs => ADAPTER_SPECS.without_increment.without_create
|
|
1074
1125
|
},
|
|
1075
1126
|
'adapter_datamapper' => {
|
|
1076
1127
|
:build => 'Moneta::Adapters::DataMapper.new(:setup => "sqlite3://#{make_tempdir}/adapter_datamapper")',
|
|
@@ -1132,15 +1183,15 @@ end
|
|
|
1132
1183
|
# Put Fog into testing mode
|
|
1133
1184
|
:preamble => "require 'fog'\nFog.mock!\n",
|
|
1134
1185
|
# Fog returns same object in mocking mode (in-memory store)
|
|
1135
|
-
:specs => ADAPTER_SPECS.without_increment.returnsame
|
|
1186
|
+
:specs => ADAPTER_SPECS.without_increment.without_create.returnsame
|
|
1136
1187
|
},
|
|
1137
1188
|
'adapter_gdbm' => {
|
|
1138
1189
|
:build => 'Moneta::Adapters::GDBM.new(:file => File.join(make_tempdir, "adapter_gdbm"))',
|
|
1139
|
-
:specs => ADAPTER_SPECS
|
|
1190
|
+
:specs => ADAPTER_SPECS.without_multiprocess
|
|
1140
1191
|
},
|
|
1141
1192
|
'adapter_localmemcache' => {
|
|
1142
1193
|
:build => 'Moneta::Adapters::LocalMemCache.new(:file => File.join(make_tempdir, "adapter_localmemcache"))',
|
|
1143
|
-
:specs => ADAPTER_SPECS.without_increment
|
|
1194
|
+
:specs => ADAPTER_SPECS.without_increment.without_create
|
|
1144
1195
|
},
|
|
1145
1196
|
'adapter_memcached_dalli' => {
|
|
1146
1197
|
:build => 'Moneta::Adapters::MemcachedDalli.new(:namespace => "adapter_memcached_dalli")',
|
|
@@ -1218,7 +1269,7 @@ end}
|
|
|
1218
1269
|
'adapter_riak' => {
|
|
1219
1270
|
:build => 'Moneta::Adapters::Riak.new',
|
|
1220
1271
|
:options => ":bucket => 'adapter_riak'",
|
|
1221
|
-
:specs => ADAPTER_SPECS.without_increment,
|
|
1272
|
+
:specs => ADAPTER_SPECS.without_increment.without_create,
|
|
1222
1273
|
# We don't want Riak warnings in tests
|
|
1223
1274
|
:preamble => "require 'riak'\n\nRiak.disable_list_keys_warnings = true\n\n"
|
|
1224
1275
|
},
|
|
@@ -1250,6 +1301,133 @@ end}
|
|
|
1250
1301
|
:build => 'Moneta::Adapters::YAML.new(:file => File.join(make_tempdir, "adapter_yaml"))',
|
|
1251
1302
|
:specs => STANDARD_SPECS.simplevalues_only.simplekeys_only.without_transform
|
|
1252
1303
|
},
|
|
1304
|
+
'mutex' => {
|
|
1305
|
+
:store => :Memory,
|
|
1306
|
+
:specs => Specs.new,
|
|
1307
|
+
:tests => %{
|
|
1308
|
+
it 'should have #lock' do
|
|
1309
|
+
mutex = Moneta::Mutex.new(store, 'mutex')
|
|
1310
|
+
mutex.lock.should be_true
|
|
1311
|
+
mutex.locked?.should be_true
|
|
1312
|
+
expect do
|
|
1313
|
+
mutex.lock
|
|
1314
|
+
end.to raise_error(RuntimeError)
|
|
1315
|
+
expect do
|
|
1316
|
+
mutex.try_lock
|
|
1317
|
+
end.to raise_error(RuntimeError)
|
|
1318
|
+
mutex.unlock.should be_nil
|
|
1319
|
+
mutex.locked?.should be_false
|
|
1320
|
+
end
|
|
1321
|
+
|
|
1322
|
+
it 'should have #enter' do
|
|
1323
|
+
mutex = Moneta::Mutex.new(store, 'mutex')
|
|
1324
|
+
mutex.enter.should be_true
|
|
1325
|
+
mutex.locked?.should be_true
|
|
1326
|
+
expect do
|
|
1327
|
+
mutex.enter
|
|
1328
|
+
end.to raise_error(RuntimeError)
|
|
1329
|
+
expect do
|
|
1330
|
+
mutex.try_enter
|
|
1331
|
+
end.to raise_error(RuntimeError)
|
|
1332
|
+
mutex.leave.should be_nil
|
|
1333
|
+
mutex.locked?.should be_false
|
|
1334
|
+
end
|
|
1335
|
+
|
|
1336
|
+
it 'should lock with #lock' do
|
|
1337
|
+
a = Moneta::Mutex.new(store, 'mutex')
|
|
1338
|
+
b = Moneta::Mutex.new(store, 'mutex')
|
|
1339
|
+
a.lock.should be_true
|
|
1340
|
+
b.try_lock.should be_false
|
|
1341
|
+
a.unlock.should be_nil
|
|
1342
|
+
end
|
|
1343
|
+
|
|
1344
|
+
it 'should have lock timeout' do
|
|
1345
|
+
a = Moneta::Mutex.new(store, 'mutex')
|
|
1346
|
+
b = Moneta::Mutex.new(store, 'mutex')
|
|
1347
|
+
a.lock.should be_true
|
|
1348
|
+
b.lock(1).should be_false
|
|
1349
|
+
a.unlock.should be_nil
|
|
1350
|
+
end
|
|
1351
|
+
|
|
1352
|
+
it 'should have #synchronize' do
|
|
1353
|
+
mutex = Moneta::Mutex.new(store, 'mutex')
|
|
1354
|
+
mutex.synchronize do
|
|
1355
|
+
mutex.locked?.should be_true
|
|
1356
|
+
end
|
|
1357
|
+
mutex.locked?.should be_false
|
|
1358
|
+
end
|
|
1359
|
+
}
|
|
1360
|
+
},
|
|
1361
|
+
'semaphore' => {
|
|
1362
|
+
:store => :Memory,
|
|
1363
|
+
:specs => Specs.new,
|
|
1364
|
+
:tests => %{
|
|
1365
|
+
it 'should have #lock' do
|
|
1366
|
+
mutex = Moneta::Semaphore.new(store, 'semaphore')
|
|
1367
|
+
mutex.lock.should be_true
|
|
1368
|
+
mutex.locked?.should be_true
|
|
1369
|
+
expect do
|
|
1370
|
+
mutex.lock
|
|
1371
|
+
end.to raise_error(RuntimeError)
|
|
1372
|
+
expect do
|
|
1373
|
+
mutex.try_lock
|
|
1374
|
+
end.to raise_error(RuntimeError)
|
|
1375
|
+
mutex.unlock.should be_nil
|
|
1376
|
+
mutex.locked?.should be_false
|
|
1377
|
+
end
|
|
1378
|
+
|
|
1379
|
+
it 'should have #enter' do
|
|
1380
|
+
mutex = Moneta::Semaphore.new(store, 'semaphore')
|
|
1381
|
+
mutex.enter.should be_true
|
|
1382
|
+
mutex.locked?.should be_true
|
|
1383
|
+
expect do
|
|
1384
|
+
mutex.enter
|
|
1385
|
+
end.to raise_error(RuntimeError)
|
|
1386
|
+
expect do
|
|
1387
|
+
mutex.try_enter
|
|
1388
|
+
end.to raise_error(RuntimeError)
|
|
1389
|
+
mutex.leave.should be_nil
|
|
1390
|
+
mutex.locked?.should be_false
|
|
1391
|
+
end
|
|
1392
|
+
|
|
1393
|
+
it 'should lock with #lock' do
|
|
1394
|
+
a = Moneta::Semaphore.new(store, 'semaphore')
|
|
1395
|
+
b = Moneta::Semaphore.new(store, 'semaphore')
|
|
1396
|
+
a.lock.should be_true
|
|
1397
|
+
b.try_lock.should be_false
|
|
1398
|
+
a.unlock.should be_nil
|
|
1399
|
+
end
|
|
1400
|
+
|
|
1401
|
+
it 'should have lock timeout' do
|
|
1402
|
+
a = Moneta::Semaphore.new(store, 'semaphore')
|
|
1403
|
+
b = Moneta::Semaphore.new(store, 'semaphore')
|
|
1404
|
+
a.lock.should be_true
|
|
1405
|
+
b.lock(1).should be_false
|
|
1406
|
+
a.unlock.should be_nil
|
|
1407
|
+
end
|
|
1408
|
+
|
|
1409
|
+
it 'should count concurrent accesses' do
|
|
1410
|
+
a = Moneta::Semaphore.new(store, 'semaphore', 2)
|
|
1411
|
+
b = Moneta::Semaphore.new(store, 'semaphore', 2)
|
|
1412
|
+
c = Moneta::Semaphore.new(store, 'semaphore', 2)
|
|
1413
|
+
a.synchronize do
|
|
1414
|
+
a.locked?.should be_true
|
|
1415
|
+
b.synchronize do
|
|
1416
|
+
b.locked?.should be_true
|
|
1417
|
+
c.try_lock.should be_false
|
|
1418
|
+
end
|
|
1419
|
+
end
|
|
1420
|
+
end
|
|
1421
|
+
|
|
1422
|
+
it 'should have #synchronize' do
|
|
1423
|
+
semaphore = Moneta::Semaphore.new(store, 'semaphore')
|
|
1424
|
+
semaphore.synchronize do
|
|
1425
|
+
semaphore.locked?.should be_true
|
|
1426
|
+
end
|
|
1427
|
+
semaphore.locked?.should be_false
|
|
1428
|
+
end
|
|
1429
|
+
}
|
|
1430
|
+
},
|
|
1253
1431
|
'optionmerger' => {
|
|
1254
1432
|
:store => :Memory,
|
|
1255
1433
|
:specs => Specs.new,
|
|
@@ -1314,22 +1492,20 @@ it 'merges options except for some methods' do
|
|
|
1314
1492
|
end
|
|
1315
1493
|
|
|
1316
1494
|
it 'has method #raw' do
|
|
1317
|
-
store.raw.default_options.should == {:store=>{:raw=>true},:load=>{:raw=>true},:delete=>{:raw=>true}}
|
|
1495
|
+
store.raw.default_options.should == {:store=>{:raw=>true},:create=>{:raw=>true},:load=>{:raw=>true},:delete=>{:raw=>true}}
|
|
1318
1496
|
store.raw.should equal(store.raw.raw)
|
|
1319
1497
|
end
|
|
1320
1498
|
|
|
1321
1499
|
it 'has method #prefix' do
|
|
1322
|
-
store.prefix('a').default_options.should == {:store=>{:prefix=>'a'},:load=>{:prefix=>'a'},
|
|
1500
|
+
store.prefix('a').default_options.should == {:store=>{:prefix=>'a'},:load=>{:prefix=>'a'},:create=>{:prefix=>'a'},
|
|
1323
1501
|
:delete=>{:prefix=>'a'},:key? => {:prefix=>'a'},:increment=>{:prefix=>'a'}}
|
|
1324
1502
|
|
|
1325
|
-
store.prefix('a').prefix('b').default_options.should == {:store=>{:prefix=>'ab'},:load=>{:prefix=>'ab'},
|
|
1503
|
+
store.prefix('a').prefix('b').default_options.should == {:store=>{:prefix=>'ab'},:load=>{:prefix=>'ab'},:create=>{:prefix=>'ab'},
|
|
1326
1504
|
:delete=>{:prefix=>'ab'},:key? => {:prefix=>'ab'},:increment=>{:prefix=>'ab'}}
|
|
1327
1505
|
|
|
1328
|
-
store.raw.prefix('b').default_options.should == {:store=>{:raw=>true,:prefix=>'b'},:load=>{:raw=>true,:prefix=>'b'}
|
|
1329
|
-
:delete=>{:raw=>true,:prefix=>'b'},:key? => {:prefix=>'b'},:increment=>{:prefix=>'b'}}
|
|
1506
|
+
store.raw.prefix('b').default_options.should == {:store=>{:raw=>true,:prefix=>'b'},:load=>{:raw=>true,:prefix=>'b'},:create=>{:raw=>true,:prefix=>'b'},:delete=>{:raw=>true,:prefix=>'b'},:key? => {:prefix=>'b'},:increment=>{:prefix=>'b'}}
|
|
1330
1507
|
|
|
1331
|
-
store.prefix('a').raw.default_options.should == {:store=>{:raw=>true,:prefix=>'a'},:load=>{:raw=>true,:prefix=>'a'}
|
|
1332
|
-
:delete=>{:raw=>true,:prefix=>'a'},:key? => {:prefix=>'a'},:increment=>{:prefix=>'a'}}
|
|
1508
|
+
store.prefix('a').raw.default_options.should == {:store=>{:raw=>true,:prefix=>'a'},:load=>{:raw=>true,:prefix=>'a'},:create=>{:raw=>true,:prefix=>'a'},:delete=>{:raw=>true,:prefix=>'a'},:key? => {:prefix=>'a'},:increment=>{:prefix=>'a'}}
|
|
1333
1509
|
end
|
|
1334
1510
|
|
|
1335
1511
|
it 'supports adding proxis using #with' do
|
|
@@ -1796,6 +1972,67 @@ it 'raises error in #decrement on non integer value' do
|
|
|
1796
1972
|
expect do
|
|
1797
1973
|
store.decrement('strkey')
|
|
1798
1974
|
end.to raise_error
|
|
1975
|
+
end
|
|
1976
|
+
|
|
1977
|
+
it 'supports Semaphore' do
|
|
1978
|
+
a = Moneta::Semaphore.new(store, 'semaphore', 2)
|
|
1979
|
+
b = Moneta::Semaphore.new(store, 'semaphore', 2)
|
|
1980
|
+
c = Moneta::Semaphore.new(store, 'semaphore', 2)
|
|
1981
|
+
a.synchronize do
|
|
1982
|
+
a.locked?.should be_true
|
|
1983
|
+
b.synchronize do
|
|
1984
|
+
b.locked?.should be_true
|
|
1985
|
+
c.try_lock.should be_false
|
|
1986
|
+
end
|
|
1987
|
+
end
|
|
1988
|
+
end
|
|
1989
|
+
}
|
|
1990
|
+
|
|
1991
|
+
SPECS['create'] = %{it 'creates the given key' do
|
|
1992
|
+
store.create('key','value').should be_true
|
|
1993
|
+
store['key'].should == 'value'
|
|
1994
|
+
end
|
|
1995
|
+
|
|
1996
|
+
it 'creates raw value with the given key' do
|
|
1997
|
+
store.raw.create('key','value').should be_true
|
|
1998
|
+
store.raw['key'].should == 'value'
|
|
1999
|
+
end
|
|
2000
|
+
|
|
2001
|
+
it 'does not create a key if it exists' do
|
|
2002
|
+
store['key'] = 'value'
|
|
2003
|
+
store.create('key','another value').should be_false
|
|
2004
|
+
store['key'].should == 'value'
|
|
2005
|
+
end
|
|
2006
|
+
|
|
2007
|
+
it 'supports Mutex' do
|
|
2008
|
+
a = Moneta::Mutex.new(store, 'mutex')
|
|
2009
|
+
b = Moneta::Mutex.new(store, 'mutex')
|
|
2010
|
+
a.lock.should be_true
|
|
2011
|
+
b.try_lock.should be_false
|
|
2012
|
+
a.unlock.should be_nil
|
|
2013
|
+
end
|
|
2014
|
+
}
|
|
2015
|
+
|
|
2016
|
+
SPECS['not_create'] = %{it 'does not support #create' do
|
|
2017
|
+
expect do
|
|
2018
|
+
store.create('key','value')
|
|
2019
|
+
end.to raise_error(NotImplementedError)
|
|
2020
|
+
end}
|
|
2021
|
+
|
|
2022
|
+
SPECS['create_expires'] = %{it 'creates the given key and expires it' do
|
|
2023
|
+
store.create('key','value', :expires => 1).should be_true
|
|
2024
|
+
store['key'].should == 'value'
|
|
2025
|
+
sleep 2
|
|
2026
|
+
store.key?('key').should be_false
|
|
2027
|
+
end
|
|
2028
|
+
|
|
2029
|
+
it 'does not change expires if the key exists' do
|
|
2030
|
+
store.store('key', 'value', :expires => false).should == 'value'
|
|
2031
|
+
store.create('key','another value', :expires => 1).should be_false
|
|
2032
|
+
store['key'].should == 'value'
|
|
2033
|
+
sleep 2
|
|
2034
|
+
store['key'].should == 'value'
|
|
2035
|
+
store.key?('key').should be_true
|
|
1799
2036
|
end}
|
|
1800
2037
|
|
|
1801
2038
|
SPECS['marshallable_key'] = %{it 'refuses to #[] from keys that cannot be marshalled' do
|
|
@@ -1889,7 +2126,7 @@ it 'might raise exception on invalid value' do
|
|
|
1889
2126
|
end
|
|
1890
2127
|
end}
|
|
1891
2128
|
|
|
1892
|
-
SPECS['
|
|
2129
|
+
SPECS['transform_value_expires'] = %{it 'allows to bypass transformer with :raw' do
|
|
1893
2130
|
store['key'] = 'value'
|
|
1894
2131
|
load_value(store.load('key', :raw => true)).should == 'value'
|
|
1895
2132
|
store['key'] = [1,2,3]
|