thoughtless-moneta 0.6.0.1 → 0.6.0.2

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -5,7 +5,7 @@ require 'spec/rake/spectask'
5
5
  require 'date'
6
6
 
7
7
  GEM = "thoughtless-moneta"
8
- GEM_VERSION = "0.6.0.1"
8
+ GEM_VERSION = "0.6.0.2"
9
9
  AUTHOR = "Yehuda Katz"
10
10
  EMAIL = "wycats@gmail.com"
11
11
  HOMEPAGE = "http://www.yehudakatz.com"
data/lib/moneta.rb CHANGED
@@ -1,77 +1,30 @@
1
+ require "moneta/builder"
2
+
1
3
  module Moneta
2
- MONETA_VERSION = '0.6.0.1'
3
- module Expires
4
- def check_expired(key)
5
- if @expiration[key] && Time.now > @expiration[key]
6
- @expiration.delete(key)
7
- self.delete(key)
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 key?(key)
12
- check_expired(key)
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
- def store(key, value, options = {})
36
- ret = super(key, value)
37
- update_options(key, options)
38
- ret
17
+ private
18
+ def key_for(key)
19
+ key.is_a?(String) ? key : Marshal.dump(key)
39
20
  end
40
21
 
41
- private
42
- def update_options(key, options)
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
- private
60
- def update_options(key, options)
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