thoughtless-moneta 0.6.0.1 → 0.6.0.2
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/README +6 -1
- data/Rakefile +1 -1
- data/lib/moneta.rb +17 -64
- data/lib/moneta/adapters/basic_file.rb +84 -0
- data/lib/moneta/adapters/couch.rb +51 -0
- data/lib/moneta/adapters/datamapper.rb +76 -0
- data/lib/moneta/adapters/file.rb +52 -0
- data/lib/moneta/adapters/fog.rb +62 -0
- data/lib/moneta/adapters/lmc.rb +40 -0
- data/lib/moneta/adapters/memcache.rb +49 -0
- data/lib/moneta/adapters/memory.rb +23 -0
- data/lib/moneta/adapters/mongodb.rb +52 -0
- data/lib/moneta/adapters/rackspace.rb +14 -0
- data/lib/moneta/adapters/redis.rb +41 -0
- data/lib/moneta/adapters/s3.rb +14 -0
- data/lib/moneta/adapters/sdbm.rb +34 -0
- data/lib/moneta/adapters/tokyo_cabinet.rb +51 -0
- data/lib/moneta/adapters/tyrant.rb +45 -0
- data/lib/moneta/adapters/xattr.rb +50 -0
- data/lib/moneta/adapters/yaml.rb +53 -0
- data/lib/moneta/builder.rb +72 -0
- metadata +20 -18
- data/lib/moneta/basic_file.rb +0 -113
- 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 -53
- 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
- data/lib/moneta/yaml.rb +0 -92
data/README
CHANGED
@@ -31,6 +31,11 @@ The API:
|
|
31
31
|
|
32
32
|
#[](key):: retrieve a key. if the key is not available, return nil
|
33
33
|
|
34
|
+
#fetch(key, &block):: retrieve a key. if the key is not available, execute the
|
35
|
+
block and return its return value.
|
36
|
+
|
37
|
+
#fetch(key, value) retrieve a key. if the key is not available, return the value
|
38
|
+
|
34
39
|
#[]=(key, value):: set a value for a key. if the key is already used, clobber it.
|
35
40
|
keys set using []= will never expire
|
36
41
|
|
@@ -40,7 +45,7 @@ The API:
|
|
40
45
|
|
41
46
|
#has_key?(key):: alias for key?
|
42
47
|
|
43
|
-
#store(key, value, options):: same as []=, but you can supply an :expires_in option,
|
48
|
+
#store(key, value, options):: same as []=, but you can supply an :expires_in option,
|
44
49
|
which will specify a number of seconds before the key
|
45
50
|
should expire. In order to support the same features
|
46
51
|
across all stores, only full seconds are supported
|
data/Rakefile
CHANGED
data/lib/moneta.rb
CHANGED
@@ -1,77 +1,30 @@
|
|
1
|
+
require "moneta/builder"
|
2
|
+
|
1
3
|
module Moneta
|
2
|
-
MONETA_VERSION = '0.6.0.
|
3
|
-
module
|
4
|
-
def
|
5
|
-
|
6
|
-
|
7
|
-
self
|
4
|
+
MONETA_VERSION = '0.6.0.2'
|
5
|
+
module Defaults
|
6
|
+
def fetch(key, value = nil, *)
|
7
|
+
self[key] || begin
|
8
|
+
value ||= block_given? ? yield(key) : default
|
9
|
+
self[key] || value
|
8
10
|
end
|
9
11
|
end
|
10
12
|
|
11
|
-
def
|
12
|
-
|
13
|
-
super
|
14
|
-
end
|
15
|
-
|
16
|
-
def [](key)
|
17
|
-
check_expired(key)
|
18
|
-
super
|
19
|
-
end
|
20
|
-
|
21
|
-
def fetch(key, default = nil, &blk)
|
22
|
-
check_expired(key)
|
23
|
-
super
|
24
|
-
end
|
25
|
-
|
26
|
-
def delete(key)
|
27
|
-
check_expired(key)
|
28
|
-
super
|
29
|
-
end
|
30
|
-
|
31
|
-
def update_key(key, options)
|
32
|
-
update_options(key, options)
|
13
|
+
def []=(key, value)
|
14
|
+
store(key, value)
|
33
15
|
end
|
34
16
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
ret
|
17
|
+
private
|
18
|
+
def key_for(key)
|
19
|
+
key.is_a?(String) ? key : Marshal.dump(key)
|
39
20
|
end
|
40
21
|
|
41
|
-
|
42
|
-
|
43
|
-
if options[:expires_in]
|
44
|
-
@expiration[key] = (Time.now + options[:expires_in])
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
module StringExpires
|
50
|
-
include Expires
|
51
|
-
|
52
|
-
def check_expired(key)
|
53
|
-
if @expiration[key] && Time.now > Time.at(@expiration[key].to_i)
|
54
|
-
@expiration.delete(key)
|
55
|
-
delete(key)
|
56
|
-
end
|
22
|
+
def serialize(value)
|
23
|
+
Marshal.dump(value)
|
57
24
|
end
|
58
25
|
|
59
|
-
|
60
|
-
|
61
|
-
if options[:expires_in]
|
62
|
-
@expiration[key] = (Time.now + options[:expires_in]).to_i.to_s
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
module Defaults
|
68
|
-
def fetch(key, value = nil)
|
69
|
-
value ||= block_given? ? yield(key) : default
|
70
|
-
self[key] || value
|
26
|
+
def deserialize(value)
|
27
|
+
value && Marshal.load(value)
|
71
28
|
end
|
72
|
-
|
73
|
-
def store(key, value, options = {})
|
74
|
-
self[key] = value
|
75
|
-
end
|
76
29
|
end
|
77
30
|
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
#
|
2
|
+
# Basic File Store
|
3
|
+
# by Hampton Catlin
|
4
|
+
#
|
5
|
+
# This cache simply uses a directory that it creates
|
6
|
+
# and manages to keep your file stores.
|
7
|
+
#
|
8
|
+
# Specify :skip_expires => true if you aren't using
|
9
|
+
# expiration as this will slightly decrease your file size
|
10
|
+
# and memory footprint of the library
|
11
|
+
#
|
12
|
+
# You can optionally also specify a :namespace
|
13
|
+
# option that will create a subfolder.
|
14
|
+
#
|
15
|
+
|
16
|
+
|
17
|
+
require 'fileutils'
|
18
|
+
require "moneta"
|
19
|
+
|
20
|
+
module Moneta
|
21
|
+
module Adapters
|
22
|
+
class BasicFile
|
23
|
+
include Moneta::Defaults
|
24
|
+
|
25
|
+
def initialize(options = {})
|
26
|
+
@namespace = options[:namespace]
|
27
|
+
@directory = ::File.join(options[:path], @namespace.to_s)
|
28
|
+
|
29
|
+
ensure_directory_created(@directory)
|
30
|
+
end
|
31
|
+
|
32
|
+
def key?(key, *)
|
33
|
+
!self[key].nil?
|
34
|
+
end
|
35
|
+
|
36
|
+
def [](key)
|
37
|
+
if ::File.exist?(path(key))
|
38
|
+
raw_get(key)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def store(key, value, *)
|
43
|
+
ensure_directory_created(::File.dirname(path(key)))
|
44
|
+
::File.open(path(key), "w") do |file|
|
45
|
+
file.puts(serialize(value))
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def delete(key, *)
|
50
|
+
value = self[key]
|
51
|
+
delete!(key)
|
52
|
+
value
|
53
|
+
end
|
54
|
+
|
55
|
+
def clear(*)
|
56
|
+
FileUtils.rm_rf(@directory)
|
57
|
+
FileUtils.mkdir(@directory)
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
def path(key)
|
62
|
+
::File.join(@directory, key_for(key))
|
63
|
+
end
|
64
|
+
|
65
|
+
def raw_get(key)
|
66
|
+
deserialize(::File.read(path(key)))
|
67
|
+
end
|
68
|
+
|
69
|
+
def delete!(key)
|
70
|
+
FileUtils.rm(path(key))
|
71
|
+
nil
|
72
|
+
rescue Errno::ENOENT
|
73
|
+
end
|
74
|
+
|
75
|
+
def ensure_directory_created(directory_path)
|
76
|
+
if ::File.file?(directory_path)
|
77
|
+
raise StandardError, "The path you supplied #{directory_path} is a file"
|
78
|
+
elsif !::File.exists?(directory_path)
|
79
|
+
FileUtils.mkdir_p(directory_path)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
begin
|
2
|
+
require "couchrest"
|
3
|
+
rescue LoadError
|
4
|
+
puts "You need the couchrest gem to use the CouchDB store"
|
5
|
+
exit
|
6
|
+
end
|
7
|
+
|
8
|
+
module Moneta
|
9
|
+
module Adapters
|
10
|
+
class Couch
|
11
|
+
include Defaults
|
12
|
+
|
13
|
+
def initialize(options = {})
|
14
|
+
@db = ::CouchRest.database!(options[:db])
|
15
|
+
end
|
16
|
+
|
17
|
+
def key?(key, *)
|
18
|
+
!self[key_for(key)].nil?
|
19
|
+
rescue RestClient::ResourceNotFound
|
20
|
+
false
|
21
|
+
end
|
22
|
+
|
23
|
+
def [](key)
|
24
|
+
deserialize(@db.get(key_for(key))["data"])
|
25
|
+
rescue RestClient::ResourceNotFound
|
26
|
+
nil
|
27
|
+
end
|
28
|
+
|
29
|
+
def store(key, value, *)
|
30
|
+
@db.save_doc("_id" => key_for(key), :data => serialize(value))
|
31
|
+
rescue RestClient::RequestFailed
|
32
|
+
self[key_for(key)]
|
33
|
+
end
|
34
|
+
|
35
|
+
def delete(key, *)
|
36
|
+
value = @db.get(key_for(key))
|
37
|
+
|
38
|
+
if value
|
39
|
+
@db.delete_doc({"_id" => value["_id"], "_rev" => value["_rev"]}) if value
|
40
|
+
deserialize(value["data"])
|
41
|
+
end
|
42
|
+
rescue RestClient::ResourceNotFound
|
43
|
+
nil
|
44
|
+
end
|
45
|
+
|
46
|
+
def clear(*)
|
47
|
+
@db.recreate!
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
begin
|
2
|
+
gem "dm-core", "~> 1.0.0"
|
3
|
+
gem "dm-migrations", "~> 1.0.0"
|
4
|
+
gem "dm-sqlite-adapter", "~> 1.0.0"
|
5
|
+
require "dm-core"
|
6
|
+
require "dm-migrations"
|
7
|
+
rescue LoadError
|
8
|
+
puts "You need the dm-core gem in order to use the DataMapper moneta store"
|
9
|
+
exit
|
10
|
+
end
|
11
|
+
|
12
|
+
class MonetaHash
|
13
|
+
include DataMapper::Resource
|
14
|
+
|
15
|
+
property :the_key, String, :key => true
|
16
|
+
property :value, Object, :lazy => false
|
17
|
+
|
18
|
+
def self.value(key)
|
19
|
+
obj = self.get(key)
|
20
|
+
obj && obj.value
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
module Moneta
|
25
|
+
module Adapters
|
26
|
+
class DataMapper
|
27
|
+
include Moneta::Defaults
|
28
|
+
|
29
|
+
def initialize(options = {})
|
30
|
+
@repository = options.delete(:repository) || :moneta
|
31
|
+
::DataMapper.setup(@repository, options[:setup])
|
32
|
+
MonetaHash.auto_upgrade!(@repository)
|
33
|
+
@hash = MonetaHash
|
34
|
+
end
|
35
|
+
|
36
|
+
def key?(key, *)
|
37
|
+
repository_context { !!@hash.get(key_for(key)) }
|
38
|
+
end
|
39
|
+
|
40
|
+
def [](key)
|
41
|
+
repository_context { @hash.value(key_for(key)) }
|
42
|
+
end
|
43
|
+
|
44
|
+
def store(key, value, *)
|
45
|
+
string_key = key_for(key)
|
46
|
+
repository_context {
|
47
|
+
obj = @hash.get(string_key)
|
48
|
+
if obj
|
49
|
+
obj.update(string_key, value)
|
50
|
+
else
|
51
|
+
@hash.create(:the_key => string_key, :value => value)
|
52
|
+
end
|
53
|
+
}
|
54
|
+
end
|
55
|
+
|
56
|
+
def delete(key, *)
|
57
|
+
string_key = key_for(key)
|
58
|
+
|
59
|
+
repository_context {
|
60
|
+
value = self[key]
|
61
|
+
@hash.all(:the_key => string_key).destroy!
|
62
|
+
value
|
63
|
+
}
|
64
|
+
end
|
65
|
+
|
66
|
+
def clear(*)
|
67
|
+
repository_context { @hash.all.destroy! }
|
68
|
+
end
|
69
|
+
|
70
|
+
private
|
71
|
+
def repository_context
|
72
|
+
repository(@repository) { yield }
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require "fileutils"
|
2
|
+
|
3
|
+
module Moneta
|
4
|
+
module Adapters
|
5
|
+
class File
|
6
|
+
include Moneta::Defaults
|
7
|
+
|
8
|
+
def initialize(options = {})
|
9
|
+
@directory = options[:path]
|
10
|
+
if ::File.file?(@directory)
|
11
|
+
raise StandardError, "The path you supplied #{@directory} is a file"
|
12
|
+
elsif !::File.exists?(@directory)
|
13
|
+
FileUtils.mkdir_p(@directory)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def key?(key, *)
|
18
|
+
::File.exist?(path(key))
|
19
|
+
end
|
20
|
+
|
21
|
+
def [](key)
|
22
|
+
if ::File.exist?(path(key))
|
23
|
+
Marshal.load(::File.read(path(key)))
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def store(key, value, *)
|
28
|
+
::File.open(path(key), "w") do |file|
|
29
|
+
contents = Marshal.dump(value)
|
30
|
+
file.puts(contents)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def delete(key, *)
|
35
|
+
value = self[key]
|
36
|
+
FileUtils.rm(path(key))
|
37
|
+
value
|
38
|
+
rescue Errno::ENOENT
|
39
|
+
end
|
40
|
+
|
41
|
+
def clear(*)
|
42
|
+
FileUtils.rm_rf(@directory)
|
43
|
+
FileUtils.mkdir(@directory)
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
def path(key)
|
48
|
+
::File.join(@directory, key_for(key))
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
begin
|
2
|
+
require "fog"
|
3
|
+
rescue LoadError
|
4
|
+
puts "You need the Fog gem to use the S3 moneta store"
|
5
|
+
exit
|
6
|
+
end
|
7
|
+
|
8
|
+
module Moneta
|
9
|
+
module Adapters
|
10
|
+
class Fog
|
11
|
+
include Moneta::Defaults
|
12
|
+
|
13
|
+
def initialize(options = {})
|
14
|
+
bucket = options.delete(:namespace)
|
15
|
+
s3 = options.delete(:cloud).new(options)
|
16
|
+
@directory = s3.directories.create(:key => bucket)
|
17
|
+
end
|
18
|
+
|
19
|
+
def key?(key)
|
20
|
+
!@directory.files.head(key_for(key)).nil?
|
21
|
+
end
|
22
|
+
|
23
|
+
def [](key)
|
24
|
+
if value = get(key)
|
25
|
+
deserialize(value.body)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def delete(key)
|
30
|
+
value = get(key)
|
31
|
+
if value
|
32
|
+
value.destroy
|
33
|
+
deserialize(value.body)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def store(key, value, options = {})
|
38
|
+
#perms = options[:perms]
|
39
|
+
#headers = options[:headers] || {}
|
40
|
+
@directory.files.create(:key => key_for(key), :body => serialize(value))
|
41
|
+
end
|
42
|
+
|
43
|
+
# def update_key(key, options = {})
|
44
|
+
# debug "update_key(key=#{key}, options=#{options.inspect})"
|
45
|
+
# k = s3_key(key, false)
|
46
|
+
# k.save_meta(meta_headers_from_options(options)) unless k.nil?
|
47
|
+
# end
|
48
|
+
|
49
|
+
def clear
|
50
|
+
@directory.files.all.each do |file|
|
51
|
+
file.destroy
|
52
|
+
end
|
53
|
+
self
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
def get(key)
|
58
|
+
@directory.files.get(key_for(key))
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|