moneta 0.6.0 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +7 -0
- data/.travis.yml +39 -0
- data/Gemfile +61 -0
- data/LICENSE +2 -2
- data/README.md +450 -0
- data/Rakefile +29 -51
- data/SPEC.md +75 -0
- data/benchmarks/run.rb +195 -0
- data/lib/action_dispatch/middleware/session/moneta_store.rb +11 -0
- data/lib/active_support/cache/moneta_store.rb +55 -0
- data/lib/moneta.rb +121 -67
- data/lib/moneta/adapters/activerecord.rb +87 -0
- data/lib/moneta/adapters/cassandra.rb +91 -0
- data/lib/moneta/adapters/client.rb +69 -0
- data/lib/moneta/adapters/cookie.rb +35 -0
- data/lib/moneta/adapters/couch.rb +57 -0
- data/lib/moneta/adapters/datamapper.rb +75 -0
- data/lib/moneta/adapters/dbm.rb +25 -0
- data/lib/moneta/adapters/file.rb +79 -0
- data/lib/moneta/adapters/fog.rb +51 -0
- data/lib/moneta/adapters/gdbm.rb +25 -0
- data/lib/moneta/adapters/hbase.rb +101 -0
- data/lib/moneta/adapters/leveldb.rb +35 -0
- data/lib/moneta/adapters/localmemcache.rb +28 -0
- data/lib/moneta/adapters/lruhash.rb +85 -0
- data/lib/moneta/adapters/memcached.rb +11 -0
- data/lib/moneta/adapters/memcached_dalli.rb +69 -0
- data/lib/moneta/adapters/memcached_native.rb +70 -0
- data/lib/moneta/adapters/memory.rb +10 -0
- data/lib/moneta/adapters/mongo.rb +50 -0
- data/lib/moneta/adapters/null.rb +30 -0
- data/lib/moneta/adapters/pstore.rb +69 -0
- data/lib/moneta/adapters/redis.rb +68 -0
- data/lib/moneta/adapters/riak.rb +57 -0
- data/lib/moneta/adapters/sdbm.rb +35 -0
- data/lib/moneta/adapters/sequel.rb +79 -0
- data/lib/moneta/adapters/sqlite.rb +65 -0
- data/lib/moneta/adapters/tokyocabinet.rb +41 -0
- data/lib/moneta/adapters/yaml.rb +15 -0
- data/lib/moneta/base.rb +78 -0
- data/lib/moneta/builder.rb +39 -0
- data/lib/moneta/cache.rb +84 -0
- data/lib/moneta/expires.rb +71 -0
- data/lib/moneta/lock.rb +25 -0
- data/lib/moneta/logger.rb +61 -0
- data/lib/moneta/mixins.rb +65 -0
- data/lib/moneta/net.rb +18 -0
- data/lib/moneta/optionmerger.rb +39 -0
- data/lib/moneta/proxy.rb +86 -0
- data/lib/moneta/server.rb +81 -0
- data/lib/moneta/shared.rb +60 -0
- data/lib/moneta/stack.rb +78 -0
- data/lib/moneta/transformer.rb +159 -0
- data/lib/moneta/transformer/config.rb +42 -0
- data/lib/moneta/transformer/helper.rb +37 -0
- data/lib/moneta/version.rb +5 -0
- data/lib/moneta/wrapper.rb +33 -0
- data/lib/rack/cache/moneta.rb +93 -0
- data/lib/rack/moneta_cookies.rb +64 -0
- data/lib/rack/session/moneta.rb +63 -0
- data/moneta.gemspec +19 -0
- data/spec/action_dispatch/fixtures/session_autoload_test/foo.rb +10 -0
- data/spec/action_dispatch/session_moneta_store_spec.rb +196 -0
- data/spec/active_support/cache_moneta_store_spec.rb +197 -0
- data/spec/generate.rb +1489 -0
- data/spec/helper.rb +91 -0
- data/spec/moneta/adapter_activerecord_spec.rb +32 -0
- data/spec/moneta/adapter_cassandra_spec.rb +30 -0
- data/spec/moneta/adapter_client_spec.rb +19 -0
- data/spec/moneta/adapter_cookie_spec.rb +18 -0
- data/spec/moneta/adapter_couch_spec.rb +18 -0
- data/spec/moneta/adapter_datamapper_spec.rb +49 -0
- data/spec/moneta/adapter_dbm_spec.rb +18 -0
- data/spec/moneta/adapter_file_spec.rb +18 -0
- data/spec/moneta/adapter_fog_spec.rb +23 -0
- data/spec/moneta/adapter_gdbm_spec.rb +18 -0
- data/spec/moneta/adapter_hbase_spec.rb +18 -0
- data/spec/moneta/adapter_leveldb_spec.rb +18 -0
- data/spec/moneta/adapter_localmemcache_spec.rb +18 -0
- data/spec/moneta/adapter_lruhash_spec.rb +31 -0
- data/spec/moneta/adapter_memcached_dalli_spec.rb +30 -0
- data/spec/moneta/adapter_memcached_native_spec.rb +31 -0
- data/spec/moneta/adapter_memcached_spec.rb +30 -0
- data/spec/moneta/adapter_memory_spec.rb +39 -0
- data/spec/moneta/adapter_mongo_spec.rb +18 -0
- data/spec/moneta/adapter_pstore_spec.rb +21 -0
- data/spec/moneta/adapter_redis_spec.rb +30 -0
- data/spec/moneta/adapter_riak_spec.rb +22 -0
- data/spec/moneta/adapter_sdbm_spec.rb +18 -0
- data/spec/moneta/adapter_sequel_spec.rb +18 -0
- data/spec/moneta/adapter_sqlite_spec.rb +18 -0
- data/spec/moneta/adapter_tokyocabinet_bdb_spec.rb +18 -0
- data/spec/moneta/adapter_tokyocabinet_hdb_spec.rb +18 -0
- data/spec/moneta/adapter_yaml_spec.rb +21 -0
- data/spec/moneta/cache_file_memory_spec.rb +34 -0
- data/spec/moneta/cache_memory_null_spec.rb +23 -0
- data/spec/moneta/expires_file_spec.rb +76 -0
- data/spec/moneta/expires_memory_spec.rb +65 -0
- data/spec/moneta/lock_spec.rb +42 -0
- data/spec/moneta/null_adapter_spec.rb +26 -0
- data/spec/moneta/optionmerger_spec.rb +92 -0
- data/spec/moneta/proxy_expires_memory_spec.rb +55 -0
- data/spec/moneta/proxy_redis_spec.rb +23 -0
- data/spec/moneta/shared_spec.rb +30 -0
- data/spec/moneta/simple_activerecord_spec.rb +51 -0
- data/spec/moneta/simple_activerecord_with_expires_spec.rb +52 -0
- data/spec/moneta/simple_cassandra_spec.rb +52 -0
- data/spec/moneta/simple_client_tcp_spec.rb +67 -0
- data/spec/moneta/simple_client_unix_spec.rb +53 -0
- data/spec/moneta/simple_couch_spec.rb +51 -0
- data/spec/moneta/simple_couch_with_expires_spec.rb +52 -0
- data/spec/moneta/simple_datamapper_spec.rb +53 -0
- data/spec/moneta/simple_datamapper_with_expires_spec.rb +54 -0
- data/spec/moneta/simple_datamapper_with_repository_spec.rb +53 -0
- data/spec/moneta/simple_dbm_spec.rb +51 -0
- data/spec/moneta/simple_dbm_with_expires_spec.rb +52 -0
- data/spec/moneta/simple_file_spec.rb +51 -0
- data/spec/moneta/simple_file_with_expires_spec.rb +52 -0
- data/spec/moneta/simple_fog_spec.rb +56 -0
- data/spec/moneta/simple_fog_with_expires_spec.rb +58 -0
- data/spec/moneta/simple_gdbm_spec.rb +51 -0
- data/spec/moneta/simple_gdbm_with_expires_spec.rb +52 -0
- data/spec/moneta/simple_hashfile_spec.rb +51 -0
- data/spec/moneta/simple_hashfile_with_expires_spec.rb +52 -0
- data/spec/moneta/simple_hbase_spec.rb +51 -0
- data/spec/moneta/simple_hbase_with_expires_spec.rb +52 -0
- data/spec/moneta/simple_leveldb_spec.rb +51 -0
- data/spec/moneta/simple_leveldb_with_expires_spec.rb +52 -0
- data/spec/moneta/simple_localmemcache_spec.rb +51 -0
- data/spec/moneta/simple_localmemcache_with_expires_spec.rb +52 -0
- data/spec/moneta/simple_lruhash_spec.rb +51 -0
- data/spec/moneta/simple_lruhash_with_expires_spec.rb +52 -0
- data/spec/moneta/simple_memcached_dalli_spec.rb +52 -0
- data/spec/moneta/simple_memcached_native_spec.rb +52 -0
- data/spec/moneta/simple_memcached_spec.rb +52 -0
- data/spec/moneta/simple_memory_spec.rb +51 -0
- data/spec/moneta/simple_memory_with_compress_spec.rb +51 -0
- data/spec/moneta/simple_memory_with_expires_spec.rb +52 -0
- data/spec/moneta/simple_memory_with_json_key_serializer_spec.rb +37 -0
- data/spec/moneta/simple_memory_with_json_serializer_spec.rb +28 -0
- data/spec/moneta/simple_memory_with_json_value_serializer_spec.rb +35 -0
- data/spec/moneta/simple_memory_with_prefix_spec.rb +51 -0
- data/spec/moneta/simple_memory_with_snappy_compress_spec.rb +51 -0
- data/spec/moneta/simple_mongo_spec.rb +51 -0
- data/spec/moneta/simple_mongo_with_expires_spec.rb +52 -0
- data/spec/moneta/simple_null_spec.rb +36 -0
- data/spec/moneta/simple_pstore_spec.rb +51 -0
- data/spec/moneta/simple_pstore_with_expires_spec.rb +52 -0
- data/spec/moneta/simple_redis_spec.rb +52 -0
- data/spec/moneta/simple_riak_spec.rb +55 -0
- data/spec/moneta/simple_riak_with_expires_spec.rb +56 -0
- data/spec/moneta/simple_sdbm_spec.rb +51 -0
- data/spec/moneta/simple_sdbm_with_expires_spec.rb +52 -0
- data/spec/moneta/simple_sequel_spec.rb +51 -0
- data/spec/moneta/simple_sequel_with_expires_spec.rb +52 -0
- data/spec/moneta/simple_sqlite_spec.rb +51 -0
- data/spec/moneta/simple_sqlite_with_expires_spec.rb +52 -0
- data/spec/moneta/simple_tokyocabinet_spec.rb +51 -0
- data/spec/moneta/simple_tokyocabinet_with_expires_spec.rb +52 -0
- data/spec/moneta/simple_yaml_spec.rb +50 -0
- data/spec/moneta/simple_yaml_with_expires_spec.rb +51 -0
- data/spec/moneta/stack_file_memory_spec.rb +25 -0
- data/spec/moneta/stack_memory_file_spec.rb +24 -0
- data/spec/moneta/transformer_bencode_spec.rb +30 -0
- data/spec/moneta/transformer_bert_spec.rb +30 -0
- data/spec/moneta/transformer_bson_spec.rb +30 -0
- data/spec/moneta/transformer_bzip2_spec.rb +27 -0
- data/spec/moneta/transformer_json_spec.rb +30 -0
- data/spec/moneta/transformer_lzma_spec.rb +27 -0
- data/spec/moneta/transformer_lzo_spec.rb +27 -0
- data/spec/moneta/transformer_marshal_base64_spec.rb +54 -0
- data/spec/moneta/transformer_marshal_escape_spec.rb +54 -0
- data/spec/moneta/transformer_marshal_hmac_spec.rb +54 -0
- data/spec/moneta/transformer_marshal_md5_spec.rb +54 -0
- data/spec/moneta/transformer_marshal_md5_spread_spec.rb +54 -0
- data/spec/moneta/transformer_marshal_prefix_spec.rb +54 -0
- data/spec/moneta/transformer_marshal_rmd160_spec.rb +54 -0
- data/spec/moneta/transformer_marshal_sha1_spec.rb +54 -0
- data/spec/moneta/transformer_marshal_sha256_spec.rb +54 -0
- data/spec/moneta/transformer_marshal_sha384_spec.rb +54 -0
- data/spec/moneta/transformer_marshal_sha512_spec.rb +54 -0
- data/spec/moneta/transformer_marshal_truncate_spec.rb +54 -0
- data/spec/moneta/transformer_marshal_uuencode_spec.rb +54 -0
- data/spec/moneta/transformer_msgpack_spec.rb +30 -0
- data/spec/moneta/transformer_ox_spec.rb +51 -0
- data/spec/moneta/transformer_quicklz_spec.rb +27 -0
- data/spec/moneta/transformer_snappy_spec.rb +27 -0
- data/spec/moneta/transformer_tnet_spec.rb +30 -0
- data/spec/moneta/transformer_yaml_spec.rb +51 -0
- data/spec/moneta/transformer_zlib_spec.rb +27 -0
- data/spec/monetaspecs.rb +2663 -0
- data/spec/rack/cache_moneta_spec.rb +355 -0
- data/spec/rack/moneta_cookies_spec.rb +81 -0
- data/spec/rack/session_moneta_spec.rb +305 -0
- metadata +359 -56
- data/README +0 -51
- data/TODO +0 -4
- data/lib/moneta/basic_file.rb +0 -111
- data/lib/moneta/berkeley.rb +0 -53
- data/lib/moneta/couch.rb +0 -63
- data/lib/moneta/datamapper.rb +0 -117
- data/lib/moneta/file.rb +0 -91
- data/lib/moneta/lmc.rb +0 -52
- data/lib/moneta/memcache.rb +0 -52
- data/lib/moneta/memory.rb +0 -11
- data/lib/moneta/mongodb.rb +0 -58
- data/lib/moneta/redis.rb +0 -49
- data/lib/moneta/rufus.rb +0 -41
- data/lib/moneta/s3.rb +0 -162
- data/lib/moneta/sdbm.rb +0 -33
- data/lib/moneta/tyrant.rb +0 -58
- data/lib/moneta/xattr.rb +0 -58
@@ -0,0 +1,87 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
|
3
|
+
module Moneta
|
4
|
+
module Adapters
|
5
|
+
# ActiveRecord as key/value stores
|
6
|
+
# @api public
|
7
|
+
class ActiveRecord < Base
|
8
|
+
def self.tables
|
9
|
+
@tables ||= {}
|
10
|
+
end
|
11
|
+
|
12
|
+
attr_reader :table
|
13
|
+
|
14
|
+
# Constructor
|
15
|
+
#
|
16
|
+
# @param [Hash] options
|
17
|
+
#
|
18
|
+
# Options:
|
19
|
+
# * :table - Table name (default moneta)
|
20
|
+
# * :connection - ActiveRecord connection
|
21
|
+
def initialize(options = {})
|
22
|
+
table = options[:table] || 'moneta'
|
23
|
+
@table = self.class.tables[table] ||=
|
24
|
+
begin
|
25
|
+
c = Class.new(::ActiveRecord::Base)
|
26
|
+
c.table_name = table
|
27
|
+
c.primary_key = :k
|
28
|
+
c
|
29
|
+
end
|
30
|
+
@table.establish_connection(options[:connection]) if options[:connection]
|
31
|
+
unless @table.table_exists?
|
32
|
+
@table.connection.create_table(@table.table_name, :id => false) do |t|
|
33
|
+
# Do not use binary columns (Issue #17)
|
34
|
+
t.string :k, :null => false
|
35
|
+
t.string :v
|
36
|
+
end
|
37
|
+
@table.connection.add_index(@table.table_name, :k, :unique => true)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def key?(key, options = {})
|
42
|
+
!@table.where(:k => key).empty?
|
43
|
+
end
|
44
|
+
|
45
|
+
def load(key, options = {})
|
46
|
+
record = @table.where(:k => key).first
|
47
|
+
record && record.v
|
48
|
+
end
|
49
|
+
|
50
|
+
def store(key, value, options = {})
|
51
|
+
@table.transaction do
|
52
|
+
record = @table.where(:k => key).first_or_initialize
|
53
|
+
record.update_attributes(:v => value)
|
54
|
+
value
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def delete(key, options = {})
|
59
|
+
@table.transaction do
|
60
|
+
if record = @table.where(:k => key).first
|
61
|
+
record.destroy
|
62
|
+
record.v
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def increment(key, amount = 1, options = {})
|
68
|
+
@table.transaction do
|
69
|
+
record = @table.where(:k => key).first_or_initialize
|
70
|
+
record.lock!
|
71
|
+
value = record.v
|
72
|
+
intvalue = value.to_i
|
73
|
+
raise 'Tried to increment non integer value' unless value == nil || intvalue.to_s == value.to_s
|
74
|
+
intvalue += amount
|
75
|
+
record.v = intvalue.to_s
|
76
|
+
record.save!
|
77
|
+
intvalue
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def clear(options = {})
|
82
|
+
@table.delete_all
|
83
|
+
self
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
# Copyright: 2011 TMX Credit
|
2
|
+
# Author: Potapov Sergey (aka Blake)
|
3
|
+
|
4
|
+
require 'cassandra'
|
5
|
+
|
6
|
+
module Moneta
|
7
|
+
module Adapters
|
8
|
+
# Cassandra backend
|
9
|
+
# @api public
|
10
|
+
class Cassandra < Base
|
11
|
+
# Constructor
|
12
|
+
#
|
13
|
+
# @param [Hash] options
|
14
|
+
#
|
15
|
+
# Options:
|
16
|
+
# * :keyspace - Cassandra keyspace (default 'moneta')
|
17
|
+
# * :column_family - Cassandra column family (default 'moneta')
|
18
|
+
# * :host - Server host name (default 127.0.0.1)
|
19
|
+
# * :port - Server port (default 9160)
|
20
|
+
# * :expires - Default expiration time (default none)
|
21
|
+
def initialize(options = {})
|
22
|
+
options[:host] ||= '127.0.0.1'
|
23
|
+
options[:port] ||= 9160
|
24
|
+
@expires = options[:expires]
|
25
|
+
keyspace = (options[:keyspace] ||= 'moneta')
|
26
|
+
@cf = (options[:column_family] || 'moneta').to_sym
|
27
|
+
@client = ::Cassandra.new('system', "#{options[:host]}:#{options[:port]}")
|
28
|
+
unless @client.keyspaces.include?(keyspace)
|
29
|
+
cf_def = ::Cassandra::ColumnFamily.new(:keyspace => keyspace, :name => @cf.to_s)
|
30
|
+
ks_def = ::Cassandra::Keyspace.new(:name => keyspace,
|
31
|
+
:strategy_class => 'SimpleStrategy',
|
32
|
+
:strategy_options => { 'replication_factor' => '1' },
|
33
|
+
:replication_factor => 1,
|
34
|
+
:cf_defs => [cf_def])
|
35
|
+
# Wait for keyspace to be created (issue #24)
|
36
|
+
10.times do
|
37
|
+
begin
|
38
|
+
@client.add_keyspace(ks_def)
|
39
|
+
rescue Exception => ex
|
40
|
+
puts "Cassandra: #{ex.message}"
|
41
|
+
end
|
42
|
+
break if @client.keyspaces.include?(keyspace)
|
43
|
+
sleep 0.1
|
44
|
+
end
|
45
|
+
end
|
46
|
+
@client.keyspace = keyspace
|
47
|
+
end
|
48
|
+
|
49
|
+
def key?(key, options = {})
|
50
|
+
if @client.exists?(@cf, key)
|
51
|
+
if options.include?(:expires) && (value = load(key))
|
52
|
+
store(key, value, options)
|
53
|
+
end
|
54
|
+
true
|
55
|
+
else
|
56
|
+
false
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def load(key, options = {})
|
61
|
+
value = @client.get(@cf, key)
|
62
|
+
if value
|
63
|
+
if options.include?(:expires)
|
64
|
+
store(key, value['value'], options)
|
65
|
+
else
|
66
|
+
value['value']
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def store(key, value, options = {})
|
72
|
+
@client.insert(@cf, key, {'value' => value}, :ttl => (options[:expires] || @expires))
|
73
|
+
value
|
74
|
+
end
|
75
|
+
|
76
|
+
def delete(key, options = {})
|
77
|
+
if value = load(key, options)
|
78
|
+
@client.remove(@cf, key)
|
79
|
+
value
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def clear(options = {})
|
84
|
+
@client.each_key(@cf) do |key|
|
85
|
+
delete(key)
|
86
|
+
end
|
87
|
+
self
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'socket'
|
2
|
+
|
3
|
+
module Moneta
|
4
|
+
module Adapters
|
5
|
+
# Moneta client backend
|
6
|
+
# @api public
|
7
|
+
class Client < Base
|
8
|
+
include Net
|
9
|
+
|
10
|
+
# Constructor
|
11
|
+
#
|
12
|
+
# @param [Hash] options
|
13
|
+
#
|
14
|
+
# Options:
|
15
|
+
# * :port - TCP port (default 9000)
|
16
|
+
# * :host - Hostname (default empty)
|
17
|
+
# * :file - Unix socket file name (default none)
|
18
|
+
def initialize(options = {})
|
19
|
+
@socket = options[:file] ? UNIXSocket.open(options[:file]) :
|
20
|
+
TCPSocket.open(options[:host] || '127.0.0.1', options[:port] || DEFAULT_PORT)
|
21
|
+
end
|
22
|
+
|
23
|
+
def key?(key, options = {})
|
24
|
+
write(@socket, [:key?, key, options])
|
25
|
+
read_result
|
26
|
+
end
|
27
|
+
|
28
|
+
def load(key, options = {})
|
29
|
+
write(@socket, [:load, key, options])
|
30
|
+
read_result
|
31
|
+
end
|
32
|
+
|
33
|
+
def store(key, value, options = {})
|
34
|
+
write(@socket, [:store, key, value, options])
|
35
|
+
read_result
|
36
|
+
value
|
37
|
+
end
|
38
|
+
|
39
|
+
def delete(key, options = {})
|
40
|
+
write(@socket, [:delete, key, options])
|
41
|
+
read_result
|
42
|
+
end
|
43
|
+
|
44
|
+
def increment(key, amount = 1, options = {})
|
45
|
+
write(@socket, [:increment, key, amount, options])
|
46
|
+
read_result
|
47
|
+
end
|
48
|
+
|
49
|
+
def clear(options = {})
|
50
|
+
write(@socket, [:clear, options])
|
51
|
+
read_result
|
52
|
+
self
|
53
|
+
end
|
54
|
+
|
55
|
+
def close
|
56
|
+
@socket.close
|
57
|
+
nil
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
def read_result
|
63
|
+
result = read(@socket)
|
64
|
+
raise result if Error === result
|
65
|
+
result
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Moneta
|
2
|
+
module Adapters
|
3
|
+
class Cookie < Memory
|
4
|
+
attr_reader :cookies
|
5
|
+
|
6
|
+
def initialize(options = {})
|
7
|
+
super
|
8
|
+
@options, @cookies = options, {}
|
9
|
+
end
|
10
|
+
|
11
|
+
def store(key, value, options = {})
|
12
|
+
cookie = @options.merge(options)
|
13
|
+
cookie[:value] = value
|
14
|
+
cookie[:expires] += Time.now.to_i if cookie[:expires]
|
15
|
+
@cookies[key] = cookie
|
16
|
+
super
|
17
|
+
end
|
18
|
+
|
19
|
+
def delete(key, options = {})
|
20
|
+
@cookies[key] = nil
|
21
|
+
super
|
22
|
+
end
|
23
|
+
|
24
|
+
def clear(options = {})
|
25
|
+
@hash.each_key { |key| @cookies[key] = nil }
|
26
|
+
super
|
27
|
+
self
|
28
|
+
end
|
29
|
+
|
30
|
+
def reset(cookies)
|
31
|
+
@cookies, @hash = {}, cookies
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'couchrest'
|
2
|
+
|
3
|
+
module Moneta
|
4
|
+
module Adapters
|
5
|
+
# CouchDB backend
|
6
|
+
# @api public
|
7
|
+
class Couch < Base
|
8
|
+
# Constructor
|
9
|
+
#
|
10
|
+
# @param [Hash] options
|
11
|
+
#
|
12
|
+
# Options:
|
13
|
+
# * :db - Couch database (default moneta)
|
14
|
+
def initialize(options = {})
|
15
|
+
options[:db] ||= 'moneta'
|
16
|
+
@db = ::CouchRest.database!(options[:db])
|
17
|
+
end
|
18
|
+
|
19
|
+
def key?(key, options = {})
|
20
|
+
@db.get(key) != nil
|
21
|
+
rescue RestClient::ResourceNotFound
|
22
|
+
false
|
23
|
+
end
|
24
|
+
|
25
|
+
def load(key, options = {})
|
26
|
+
@db.get(key)['value']
|
27
|
+
rescue RestClient::ResourceNotFound
|
28
|
+
nil
|
29
|
+
end
|
30
|
+
|
31
|
+
def store(key, value, options = {})
|
32
|
+
doc = {'_id' => key, 'value' => value}
|
33
|
+
begin
|
34
|
+
doc['_rev'] = @db.get(key)['_rev']
|
35
|
+
rescue RestClient::ResourceNotFound
|
36
|
+
end
|
37
|
+
@db.save_doc(doc)
|
38
|
+
value
|
39
|
+
rescue RestClient::RequestFailed
|
40
|
+
value
|
41
|
+
end
|
42
|
+
|
43
|
+
def delete(key, options = {})
|
44
|
+
value = @db.get(key)
|
45
|
+
@db.delete_doc('_id' => value['_id'], '_rev' => value['_rev'])
|
46
|
+
value['value']
|
47
|
+
rescue RestClient::ResourceNotFound
|
48
|
+
nil
|
49
|
+
end
|
50
|
+
|
51
|
+
def clear(options = {})
|
52
|
+
@db.recreate!
|
53
|
+
self
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'dm-core'
|
2
|
+
require 'dm-migrations'
|
3
|
+
|
4
|
+
module Moneta
|
5
|
+
module Adapters
|
6
|
+
# Datamapper backend
|
7
|
+
# @api public
|
8
|
+
class DataMapper < Base
|
9
|
+
class Store
|
10
|
+
include ::DataMapper::Resource
|
11
|
+
property :k, Text, :key => true
|
12
|
+
property :v, Text, :lazy => false
|
13
|
+
end
|
14
|
+
|
15
|
+
# Constructor
|
16
|
+
#
|
17
|
+
# @param [Hash] options
|
18
|
+
#
|
19
|
+
# Options:
|
20
|
+
# * :setup - Datamapper setup string
|
21
|
+
# * :repository - Repository name (default :moneta)
|
22
|
+
# * :table - Table name (default :moneta)
|
23
|
+
def initialize(options = {})
|
24
|
+
raise ArgumentError, 'Option :setup is required' unless options[:setup]
|
25
|
+
@repository = options.delete(:repository) || :moneta
|
26
|
+
Store.storage_names[@repository] = (options.delete(:table) || :moneta).to_s
|
27
|
+
::DataMapper.setup(@repository, options[:setup])
|
28
|
+
context { Store.auto_upgrade! }
|
29
|
+
end
|
30
|
+
|
31
|
+
def key?(key, options = {})
|
32
|
+
context { Store.get(key) != nil }
|
33
|
+
end
|
34
|
+
|
35
|
+
def load(key, options = {})
|
36
|
+
context do
|
37
|
+
record = Store.get(key)
|
38
|
+
record && record.v
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def store(key, value, options = {})
|
43
|
+
context do
|
44
|
+
if record = Store.get(key)
|
45
|
+
record.update(:k => key, :v => value)
|
46
|
+
else
|
47
|
+
Store.create(:k => key, :v => value)
|
48
|
+
end
|
49
|
+
value
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def delete(key, options = {})
|
54
|
+
context do
|
55
|
+
if record = Store.get(key)
|
56
|
+
value = record.v
|
57
|
+
record.destroy!
|
58
|
+
value
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def clear(options = {})
|
64
|
+
context { Store.all.destroy! }
|
65
|
+
self
|
66
|
+
end
|
67
|
+
|
68
|
+
private
|
69
|
+
|
70
|
+
def context
|
71
|
+
::DataMapper.repository(@repository) { yield }
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'dbm'
|
2
|
+
|
3
|
+
module Moneta
|
4
|
+
module Adapters
|
5
|
+
# DBM backend (Berkeley DB)
|
6
|
+
# @api public
|
7
|
+
class DBM < Memory
|
8
|
+
# Constructor
|
9
|
+
#
|
10
|
+
# @param [Hash] options
|
11
|
+
#
|
12
|
+
# Options:
|
13
|
+
# * :file - Database file
|
14
|
+
def initialize(options = {})
|
15
|
+
raise ArgumentError, 'Option :file is required' unless options[:file]
|
16
|
+
@hash = ::DBM.new(options[:file])
|
17
|
+
end
|
18
|
+
|
19
|
+
def close
|
20
|
+
@hash.close
|
21
|
+
nil
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
|
3
|
+
module Moneta
|
4
|
+
module Adapters
|
5
|
+
# Filesystem backend
|
6
|
+
# @api public
|
7
|
+
class File < Base
|
8
|
+
include Mixins::IncrementSupport
|
9
|
+
|
10
|
+
def initialize(options = {})
|
11
|
+
raise ArgumentError, 'Option :dir is required' unless @dir = options[:dir]
|
12
|
+
FileUtils.mkpath(@dir)
|
13
|
+
raise "#{@dir} is not a directory" unless ::File.directory?(@dir)
|
14
|
+
end
|
15
|
+
|
16
|
+
def key?(key, options = {})
|
17
|
+
::File.exist?(store_path(key))
|
18
|
+
end
|
19
|
+
|
20
|
+
def load(key, options = {})
|
21
|
+
::File.read(store_path(key))
|
22
|
+
rescue Errno::ENOENT
|
23
|
+
end
|
24
|
+
|
25
|
+
def store(key, value, options = {})
|
26
|
+
path = store_path(key)
|
27
|
+
temp_file = ::File.join(@dir, "value-#{$$}-#{Thread.current.object_id}")
|
28
|
+
FileUtils.mkpath(::File.dirname(path))
|
29
|
+
::File.open(temp_file, 'wb') {|file| file.write(value) }
|
30
|
+
::File.unlink(path) if ::File.exist?(path)
|
31
|
+
::File.rename(temp_file, path)
|
32
|
+
value
|
33
|
+
rescue Errno::ENOENT
|
34
|
+
::File.unlink(temp_file) rescue nil
|
35
|
+
value
|
36
|
+
end
|
37
|
+
|
38
|
+
def delete(key, options = {})
|
39
|
+
value = load(key, options)
|
40
|
+
::File.unlink(store_path(key))
|
41
|
+
value
|
42
|
+
rescue Errno::ENOENT
|
43
|
+
end
|
44
|
+
|
45
|
+
def clear(options = {})
|
46
|
+
temp_dir = "#{@dir}-#{$$}-#{Thread.current.object_id}"
|
47
|
+
::File.rename(@dir, temp_dir)
|
48
|
+
FileUtils.mkpath(@dir)
|
49
|
+
FileUtils.rm_rf(temp_dir)
|
50
|
+
self
|
51
|
+
rescue Errno::ENOENT
|
52
|
+
self
|
53
|
+
end
|
54
|
+
|
55
|
+
def increment(key, amount = 1, options = {})
|
56
|
+
lock(key) { super }
|
57
|
+
end
|
58
|
+
|
59
|
+
protected
|
60
|
+
|
61
|
+
def lock(key, &block)
|
62
|
+
path = store_path(key)
|
63
|
+
return yield unless ::File.exist?(path)
|
64
|
+
::File.open(path, 'r+') do |f|
|
65
|
+
begin
|
66
|
+
f.flock ::File::LOCK_EX
|
67
|
+
yield
|
68
|
+
ensure
|
69
|
+
f.flock ::File::LOCK_UN
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def store_path(key)
|
75
|
+
::File.join(@dir, key)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|