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 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