gotime-moneta 0.6.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,41 @@
1
+ begin
2
+ require "rufus/tokyo"
3
+ rescue LoadError
4
+ puts "You need the rufus gem to use the Rufus moneta store"
5
+ exit
6
+ end
7
+
8
+ module Moneta
9
+ class BasicRufus < ::Rufus::Tokyo::Cabinet
10
+ include Defaults
11
+
12
+ def initialize(options = {})
13
+ file = options[:file]
14
+ super("#{file}.tch")
15
+ end
16
+
17
+ def key?(key)
18
+ !!self[key]
19
+ end
20
+
21
+ def [](key)
22
+ if val = super
23
+ Marshal.load(val.unpack("m")[0])
24
+ end
25
+ end
26
+
27
+ def []=(key, value)
28
+ super(key, [Marshal.dump(value)].pack("m"))
29
+ end
30
+ end
31
+
32
+ class Rufus < BasicRufus
33
+ include Expires
34
+
35
+ def initialize(options = {})
36
+ file = options[:file]
37
+ @expiration = BasicRufus.new(:file => "#{file}_expires")
38
+ super
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,162 @@
1
+ begin
2
+ require "right_aws"
3
+ rescue LoadError
4
+ puts "You need the RightScale AWS gem to use the S3 moneta store"
5
+ exit
6
+ end
7
+
8
+ module Moneta
9
+ # An S3 implementation of Moneta
10
+ #
11
+ # Example usage:
12
+ #
13
+ # require 'rubygems'
14
+ # require 'moneta'
15
+ # require 'moneta/s3'
16
+ #
17
+ # store = Moneta::S3.new(
18
+ # :access_key_id => 'ACCESS_KEY_ID',
19
+ # :secret_access_key => 'SECRET_ACCESS_KEY',
20
+ # :bucket => 'a_bucket'
21
+ # )
22
+ # store['somefile']
23
+ class S3
24
+ # Initialize the Moneta::S3 store.
25
+ #
26
+ # Required values passed in the options hash:
27
+ # * <tt>:access_key_id</tt>: The access id key
28
+ # * <tt>:secret_access_key</tt>: The secret key
29
+ # * <tt>:bucket</tt>: The name of bucket. Will be created if it doesn't
30
+ # exist.
31
+ # * <tt>:multi_thread</tt>: Set to true if using threading
32
+ def initialize(options = {})
33
+ validate_options(options)
34
+ s3 = RightAws::S3.new(
35
+ options[:access_key_id],
36
+ options[:secret_access_key],
37
+ {
38
+ :logger => logger,
39
+ :multi_thread => options.delete(:multi_thread) || false
40
+ }
41
+ )
42
+ @bucket = s3.bucket(options.delete(:bucket), true)
43
+ end
44
+
45
+ def key?(key)
46
+ !s3_key(key).nil?
47
+ end
48
+
49
+ alias has_key? key?
50
+
51
+ def [](key)
52
+ get(key)
53
+ end
54
+
55
+ def []=(key, value)
56
+ store(key, value)
57
+ end
58
+
59
+ def delete(key)
60
+ k = s3_key(key)
61
+ if k
62
+ value = k.get
63
+ k.delete
64
+ value
65
+ end
66
+ end
67
+
68
+ # Store the key/value pair.
69
+ #
70
+ # Options:
71
+ # *<tt>:meta_headers</tt>: Meta headers passed to S3
72
+ # *<tt>:perms</tt>: Permissions passed to S3
73
+ # *<tt>:headers</tt>: Headers sent as part of the PUT request
74
+ # *<tt>:expires_in</tt>: Number of seconds until expiration
75
+ def store(key, value, options = {})
76
+ debug "store(key=#{key}, value=#{value}, options=#{options.inspect})"
77
+ meta_headers = meta_headers_from_options(options)
78
+ perms = options[:perms]
79
+ headers = options[:headers] || {}
80
+
81
+ case value
82
+ when IO
83
+ @bucket.put(key, value.read, meta_headers, perms, headers)
84
+ else
85
+ @bucket.put(key, value, meta_headers, perms, headers)
86
+ end
87
+ end
88
+
89
+ def update_key(key, options = {})
90
+ debug "update_key(key=#{key}, options=#{options.inspect})"
91
+ k = s3_key(key, false)
92
+ k.save_meta(meta_headers_from_options(options)) unless k.nil?
93
+ end
94
+
95
+ def clear
96
+ @bucket.clear
97
+ end
98
+
99
+ protected
100
+ def logger
101
+ @logger ||= begin
102
+ logger = Logger.new(STDOUT)
103
+ logger.level = Logger::FATAL
104
+ logger
105
+ end
106
+ end
107
+
108
+ private
109
+ def validate_options(options)
110
+ unless options[:access_key_id]
111
+ raise RuntimeError, ":access_key_id is required in options"
112
+ end
113
+ unless options[:secret_access_key]
114
+ raise RuntimeError, ":secret_access_key is required in options"
115
+ end
116
+ unless options[:bucket]
117
+ raise RuntimeError, ":bucket is required in options"
118
+ end
119
+ end
120
+
121
+ def get(key)
122
+ k = s3_key(key)
123
+ k.nil? ? nil : k.get
124
+ end
125
+
126
+ def s3_key(key, nil_if_expired=true)
127
+ begin
128
+ s3_key = @bucket.key(key, true)
129
+ if s3_key.exists?
130
+ logger.debug "[Moneta::S3] key exists: #{key}"
131
+ if s3_key.meta_headers.has_key?('expires-at')
132
+ expires_at = Time.parse(s3_key.meta_headers['expires-at'])
133
+ if Time.now > expires_at && nil_if_expired
134
+ # TODO delete the object?
135
+ debug "key expired: #{key} (@#{s3_key.meta_headers['expires-at']})"
136
+ return nil
137
+ end
138
+ end
139
+ return s3_key
140
+ else
141
+ debug "key does not exist: #{key}"
142
+ end
143
+ rescue RightAws::AwsError => e
144
+ debug "key does not exist: #{key}"
145
+ end
146
+ nil
147
+ end
148
+
149
+ def meta_headers_from_options(options={})
150
+ meta_headers = options[:meta_headers] || {}
151
+ if options[:expires_in]
152
+ meta_headers['expires-at'] = (Time.now + options[:expires_in]).rfc2822
153
+ end
154
+ debug "setting expires-at: #{meta_headers['expires-at']}"
155
+ meta_headers
156
+ end
157
+
158
+ def debug(message)
159
+ logger.debug "[Moneta::S3] #{message}"
160
+ end
161
+ end
162
+ end
@@ -0,0 +1,33 @@
1
+ require "sdbm"
2
+
3
+ module Moneta
4
+ class BasicSDBM < ::SDBM
5
+ include Defaults
6
+
7
+ def [](key)
8
+ if val = super
9
+ Marshal.load(val)
10
+ end
11
+ end
12
+
13
+ def []=(key, value)
14
+ super(key, Marshal.dump(value))
15
+ end
16
+
17
+ def delete(key)
18
+ if val = super
19
+ Marshal.load(val)
20
+ end
21
+ end
22
+ end
23
+
24
+ class SDBM < BasicSDBM
25
+ include Expires
26
+
27
+ def initialize(options = {})
28
+ raise "No :file option specified" unless file = options[:file]
29
+ @expiration = BasicSDBM.new("#{file}_expires")
30
+ super(file)
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,58 @@
1
+ begin
2
+ require "rufus/tokyo/tyrant"
3
+ rescue LoadError
4
+ puts "You need the rufus gem to use the Tyrant moneta store"
5
+ exit
6
+ end
7
+
8
+ module Moneta
9
+ class Tyrant < ::Rufus::Tokyo::Tyrant
10
+ include Defaults
11
+
12
+ module Implementation
13
+ def initialize(options = {})
14
+ host = options[:host]
15
+ port = options[:port]
16
+ super(host, port)
17
+ end
18
+
19
+ def key?(key)
20
+ !!self[key]
21
+ end
22
+
23
+ def [](key)
24
+ if val = super
25
+ Marshal.load(val.unpack("m")[0])
26
+ end
27
+ end
28
+
29
+ def []=(key, value)
30
+ super(key, [Marshal.dump(value)].pack("m"))
31
+ end
32
+ end
33
+
34
+ include Implementation
35
+ include Expires
36
+
37
+ def initialize(options = {})
38
+ super
39
+ @expiration = Expiration.new(options)
40
+ end
41
+
42
+ class Expiration < ::Rufus::Tokyo::Tyrant
43
+ include Implementation
44
+
45
+ def [](key)
46
+ super("#{key}__expiration")
47
+ end
48
+
49
+ def []=(key, value)
50
+ super("#{key}__expiration", value)
51
+ end
52
+
53
+ def delete(key)
54
+ super("#{key}__expiration")
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,58 @@
1
+ begin
2
+ require "xattr"
3
+ rescue LoadError
4
+ puts "You need the xattr gem to use the Xattr moneta store"
5
+ exit
6
+ end
7
+ require "fileutils"
8
+
9
+ module Moneta
10
+ class Xattr
11
+ include Defaults
12
+
13
+ def initialize(options = {})
14
+ file = options[:file]
15
+ @hash = ::Xattr.new(file)
16
+ FileUtils.mkdir_p(::File.dirname(file))
17
+ FileUtils.touch(file)
18
+ unless options[:skip_expires]
19
+ @expiration = Moneta::Xattr.new(:file => "#{file}_expiration", :skip_expires => true)
20
+ self.extend(Expires)
21
+ end
22
+ end
23
+
24
+ module Implementation
25
+
26
+ def key?(key)
27
+ @hash.list.include?(key)
28
+ end
29
+
30
+ alias has_key? key?
31
+
32
+ def [](key)
33
+ return nil unless key?(key)
34
+ Marshal.load(@hash.get(key))
35
+ end
36
+
37
+ def []=(key, value)
38
+ @hash.set(key, Marshal.dump(value))
39
+ end
40
+
41
+ def delete(key)
42
+ return nil unless key?(key)
43
+ value = self[key]
44
+ @hash.remove(key)
45
+ value
46
+ end
47
+
48
+ def clear
49
+ @hash.list.each do |item|
50
+ @hash.remove(item)
51
+ end
52
+ end
53
+
54
+ end
55
+ include Implementation
56
+
57
+ end
58
+ end
@@ -0,0 +1,92 @@
1
+ require "yaml"
2
+ require "fileutils"
3
+
4
+ module Moneta
5
+ class YAML
6
+ class Expiration
7
+ def initialize(file)
8
+ @file = file
9
+ end
10
+
11
+ def [](key)
12
+ yaml[key]['expires'] if yaml.has_key?(key)
13
+ end
14
+
15
+ def []=(key, value)
16
+ hash = yaml
17
+ if hash.has_key?(key)
18
+ hash[key]['expires'] = value
19
+ save(hash)
20
+ end
21
+ end
22
+
23
+ def delete(key)
24
+ hash = yaml
25
+ if hash.has_key?(key)
26
+ hash[key].delete("expires")
27
+ save(hash)
28
+ end
29
+ end
30
+
31
+ private
32
+ def yaml
33
+ ::YAML.load_file(@file)
34
+ end
35
+
36
+ def save(hash)
37
+ ::File.open(@file, "w") { |file| file << hash.to_yaml }
38
+ end
39
+ end
40
+
41
+ def initialize(options = {})
42
+ @file = File.expand_path(options[:path])
43
+ unless ::File.exists?(@file)
44
+ File.open(@file, "w") { |file| file << {}.to_yaml }
45
+ end
46
+
47
+ @expiration = Expiration.new(@file)
48
+ end
49
+
50
+ module Implementation
51
+ def key?(key)
52
+ yaml.has_key?(key)
53
+ end
54
+
55
+ alias has_key? key?
56
+
57
+ def [](key)
58
+ yaml[key]['value'] if yaml.has_key?(key)
59
+ end
60
+
61
+ def []=(key, value)
62
+ hash = yaml
63
+ (hash[key] ||= {})['value'] = value
64
+ save(hash)
65
+ end
66
+
67
+ def delete(key)
68
+ hash = yaml
69
+ value = self[key]
70
+ hash.delete(key)
71
+ save(hash)
72
+ value
73
+ end
74
+
75
+ def clear
76
+ save
77
+ end
78
+
79
+ private
80
+ def yaml
81
+ ::YAML.load_file(@file)
82
+ end
83
+
84
+ def save(hash = {})
85
+ ::File.open(@file, "w") { |file| file << hash.to_yaml }
86
+ end
87
+ end
88
+ include Implementation
89
+ include Defaults
90
+ include Expires
91
+ end
92
+ end