moneta 0.6.0 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (212) hide show
  1. data/.gitignore +7 -0
  2. data/.travis.yml +39 -0
  3. data/Gemfile +61 -0
  4. data/LICENSE +2 -2
  5. data/README.md +450 -0
  6. data/Rakefile +29 -51
  7. data/SPEC.md +75 -0
  8. data/benchmarks/run.rb +195 -0
  9. data/lib/action_dispatch/middleware/session/moneta_store.rb +11 -0
  10. data/lib/active_support/cache/moneta_store.rb +55 -0
  11. data/lib/moneta.rb +121 -67
  12. data/lib/moneta/adapters/activerecord.rb +87 -0
  13. data/lib/moneta/adapters/cassandra.rb +91 -0
  14. data/lib/moneta/adapters/client.rb +69 -0
  15. data/lib/moneta/adapters/cookie.rb +35 -0
  16. data/lib/moneta/adapters/couch.rb +57 -0
  17. data/lib/moneta/adapters/datamapper.rb +75 -0
  18. data/lib/moneta/adapters/dbm.rb +25 -0
  19. data/lib/moneta/adapters/file.rb +79 -0
  20. data/lib/moneta/adapters/fog.rb +51 -0
  21. data/lib/moneta/adapters/gdbm.rb +25 -0
  22. data/lib/moneta/adapters/hbase.rb +101 -0
  23. data/lib/moneta/adapters/leveldb.rb +35 -0
  24. data/lib/moneta/adapters/localmemcache.rb +28 -0
  25. data/lib/moneta/adapters/lruhash.rb +85 -0
  26. data/lib/moneta/adapters/memcached.rb +11 -0
  27. data/lib/moneta/adapters/memcached_dalli.rb +69 -0
  28. data/lib/moneta/adapters/memcached_native.rb +70 -0
  29. data/lib/moneta/adapters/memory.rb +10 -0
  30. data/lib/moneta/adapters/mongo.rb +50 -0
  31. data/lib/moneta/adapters/null.rb +30 -0
  32. data/lib/moneta/adapters/pstore.rb +69 -0
  33. data/lib/moneta/adapters/redis.rb +68 -0
  34. data/lib/moneta/adapters/riak.rb +57 -0
  35. data/lib/moneta/adapters/sdbm.rb +35 -0
  36. data/lib/moneta/adapters/sequel.rb +79 -0
  37. data/lib/moneta/adapters/sqlite.rb +65 -0
  38. data/lib/moneta/adapters/tokyocabinet.rb +41 -0
  39. data/lib/moneta/adapters/yaml.rb +15 -0
  40. data/lib/moneta/base.rb +78 -0
  41. data/lib/moneta/builder.rb +39 -0
  42. data/lib/moneta/cache.rb +84 -0
  43. data/lib/moneta/expires.rb +71 -0
  44. data/lib/moneta/lock.rb +25 -0
  45. data/lib/moneta/logger.rb +61 -0
  46. data/lib/moneta/mixins.rb +65 -0
  47. data/lib/moneta/net.rb +18 -0
  48. data/lib/moneta/optionmerger.rb +39 -0
  49. data/lib/moneta/proxy.rb +86 -0
  50. data/lib/moneta/server.rb +81 -0
  51. data/lib/moneta/shared.rb +60 -0
  52. data/lib/moneta/stack.rb +78 -0
  53. data/lib/moneta/transformer.rb +159 -0
  54. data/lib/moneta/transformer/config.rb +42 -0
  55. data/lib/moneta/transformer/helper.rb +37 -0
  56. data/lib/moneta/version.rb +5 -0
  57. data/lib/moneta/wrapper.rb +33 -0
  58. data/lib/rack/cache/moneta.rb +93 -0
  59. data/lib/rack/moneta_cookies.rb +64 -0
  60. data/lib/rack/session/moneta.rb +63 -0
  61. data/moneta.gemspec +19 -0
  62. data/spec/action_dispatch/fixtures/session_autoload_test/foo.rb +10 -0
  63. data/spec/action_dispatch/session_moneta_store_spec.rb +196 -0
  64. data/spec/active_support/cache_moneta_store_spec.rb +197 -0
  65. data/spec/generate.rb +1489 -0
  66. data/spec/helper.rb +91 -0
  67. data/spec/moneta/adapter_activerecord_spec.rb +32 -0
  68. data/spec/moneta/adapter_cassandra_spec.rb +30 -0
  69. data/spec/moneta/adapter_client_spec.rb +19 -0
  70. data/spec/moneta/adapter_cookie_spec.rb +18 -0
  71. data/spec/moneta/adapter_couch_spec.rb +18 -0
  72. data/spec/moneta/adapter_datamapper_spec.rb +49 -0
  73. data/spec/moneta/adapter_dbm_spec.rb +18 -0
  74. data/spec/moneta/adapter_file_spec.rb +18 -0
  75. data/spec/moneta/adapter_fog_spec.rb +23 -0
  76. data/spec/moneta/adapter_gdbm_spec.rb +18 -0
  77. data/spec/moneta/adapter_hbase_spec.rb +18 -0
  78. data/spec/moneta/adapter_leveldb_spec.rb +18 -0
  79. data/spec/moneta/adapter_localmemcache_spec.rb +18 -0
  80. data/spec/moneta/adapter_lruhash_spec.rb +31 -0
  81. data/spec/moneta/adapter_memcached_dalli_spec.rb +30 -0
  82. data/spec/moneta/adapter_memcached_native_spec.rb +31 -0
  83. data/spec/moneta/adapter_memcached_spec.rb +30 -0
  84. data/spec/moneta/adapter_memory_spec.rb +39 -0
  85. data/spec/moneta/adapter_mongo_spec.rb +18 -0
  86. data/spec/moneta/adapter_pstore_spec.rb +21 -0
  87. data/spec/moneta/adapter_redis_spec.rb +30 -0
  88. data/spec/moneta/adapter_riak_spec.rb +22 -0
  89. data/spec/moneta/adapter_sdbm_spec.rb +18 -0
  90. data/spec/moneta/adapter_sequel_spec.rb +18 -0
  91. data/spec/moneta/adapter_sqlite_spec.rb +18 -0
  92. data/spec/moneta/adapter_tokyocabinet_bdb_spec.rb +18 -0
  93. data/spec/moneta/adapter_tokyocabinet_hdb_spec.rb +18 -0
  94. data/spec/moneta/adapter_yaml_spec.rb +21 -0
  95. data/spec/moneta/cache_file_memory_spec.rb +34 -0
  96. data/spec/moneta/cache_memory_null_spec.rb +23 -0
  97. data/spec/moneta/expires_file_spec.rb +76 -0
  98. data/spec/moneta/expires_memory_spec.rb +65 -0
  99. data/spec/moneta/lock_spec.rb +42 -0
  100. data/spec/moneta/null_adapter_spec.rb +26 -0
  101. data/spec/moneta/optionmerger_spec.rb +92 -0
  102. data/spec/moneta/proxy_expires_memory_spec.rb +55 -0
  103. data/spec/moneta/proxy_redis_spec.rb +23 -0
  104. data/spec/moneta/shared_spec.rb +30 -0
  105. data/spec/moneta/simple_activerecord_spec.rb +51 -0
  106. data/spec/moneta/simple_activerecord_with_expires_spec.rb +52 -0
  107. data/spec/moneta/simple_cassandra_spec.rb +52 -0
  108. data/spec/moneta/simple_client_tcp_spec.rb +67 -0
  109. data/spec/moneta/simple_client_unix_spec.rb +53 -0
  110. data/spec/moneta/simple_couch_spec.rb +51 -0
  111. data/spec/moneta/simple_couch_with_expires_spec.rb +52 -0
  112. data/spec/moneta/simple_datamapper_spec.rb +53 -0
  113. data/spec/moneta/simple_datamapper_with_expires_spec.rb +54 -0
  114. data/spec/moneta/simple_datamapper_with_repository_spec.rb +53 -0
  115. data/spec/moneta/simple_dbm_spec.rb +51 -0
  116. data/spec/moneta/simple_dbm_with_expires_spec.rb +52 -0
  117. data/spec/moneta/simple_file_spec.rb +51 -0
  118. data/spec/moneta/simple_file_with_expires_spec.rb +52 -0
  119. data/spec/moneta/simple_fog_spec.rb +56 -0
  120. data/spec/moneta/simple_fog_with_expires_spec.rb +58 -0
  121. data/spec/moneta/simple_gdbm_spec.rb +51 -0
  122. data/spec/moneta/simple_gdbm_with_expires_spec.rb +52 -0
  123. data/spec/moneta/simple_hashfile_spec.rb +51 -0
  124. data/spec/moneta/simple_hashfile_with_expires_spec.rb +52 -0
  125. data/spec/moneta/simple_hbase_spec.rb +51 -0
  126. data/spec/moneta/simple_hbase_with_expires_spec.rb +52 -0
  127. data/spec/moneta/simple_leveldb_spec.rb +51 -0
  128. data/spec/moneta/simple_leveldb_with_expires_spec.rb +52 -0
  129. data/spec/moneta/simple_localmemcache_spec.rb +51 -0
  130. data/spec/moneta/simple_localmemcache_with_expires_spec.rb +52 -0
  131. data/spec/moneta/simple_lruhash_spec.rb +51 -0
  132. data/spec/moneta/simple_lruhash_with_expires_spec.rb +52 -0
  133. data/spec/moneta/simple_memcached_dalli_spec.rb +52 -0
  134. data/spec/moneta/simple_memcached_native_spec.rb +52 -0
  135. data/spec/moneta/simple_memcached_spec.rb +52 -0
  136. data/spec/moneta/simple_memory_spec.rb +51 -0
  137. data/spec/moneta/simple_memory_with_compress_spec.rb +51 -0
  138. data/spec/moneta/simple_memory_with_expires_spec.rb +52 -0
  139. data/spec/moneta/simple_memory_with_json_key_serializer_spec.rb +37 -0
  140. data/spec/moneta/simple_memory_with_json_serializer_spec.rb +28 -0
  141. data/spec/moneta/simple_memory_with_json_value_serializer_spec.rb +35 -0
  142. data/spec/moneta/simple_memory_with_prefix_spec.rb +51 -0
  143. data/spec/moneta/simple_memory_with_snappy_compress_spec.rb +51 -0
  144. data/spec/moneta/simple_mongo_spec.rb +51 -0
  145. data/spec/moneta/simple_mongo_with_expires_spec.rb +52 -0
  146. data/spec/moneta/simple_null_spec.rb +36 -0
  147. data/spec/moneta/simple_pstore_spec.rb +51 -0
  148. data/spec/moneta/simple_pstore_with_expires_spec.rb +52 -0
  149. data/spec/moneta/simple_redis_spec.rb +52 -0
  150. data/spec/moneta/simple_riak_spec.rb +55 -0
  151. data/spec/moneta/simple_riak_with_expires_spec.rb +56 -0
  152. data/spec/moneta/simple_sdbm_spec.rb +51 -0
  153. data/spec/moneta/simple_sdbm_with_expires_spec.rb +52 -0
  154. data/spec/moneta/simple_sequel_spec.rb +51 -0
  155. data/spec/moneta/simple_sequel_with_expires_spec.rb +52 -0
  156. data/spec/moneta/simple_sqlite_spec.rb +51 -0
  157. data/spec/moneta/simple_sqlite_with_expires_spec.rb +52 -0
  158. data/spec/moneta/simple_tokyocabinet_spec.rb +51 -0
  159. data/spec/moneta/simple_tokyocabinet_with_expires_spec.rb +52 -0
  160. data/spec/moneta/simple_yaml_spec.rb +50 -0
  161. data/spec/moneta/simple_yaml_with_expires_spec.rb +51 -0
  162. data/spec/moneta/stack_file_memory_spec.rb +25 -0
  163. data/spec/moneta/stack_memory_file_spec.rb +24 -0
  164. data/spec/moneta/transformer_bencode_spec.rb +30 -0
  165. data/spec/moneta/transformer_bert_spec.rb +30 -0
  166. data/spec/moneta/transformer_bson_spec.rb +30 -0
  167. data/spec/moneta/transformer_bzip2_spec.rb +27 -0
  168. data/spec/moneta/transformer_json_spec.rb +30 -0
  169. data/spec/moneta/transformer_lzma_spec.rb +27 -0
  170. data/spec/moneta/transformer_lzo_spec.rb +27 -0
  171. data/spec/moneta/transformer_marshal_base64_spec.rb +54 -0
  172. data/spec/moneta/transformer_marshal_escape_spec.rb +54 -0
  173. data/spec/moneta/transformer_marshal_hmac_spec.rb +54 -0
  174. data/spec/moneta/transformer_marshal_md5_spec.rb +54 -0
  175. data/spec/moneta/transformer_marshal_md5_spread_spec.rb +54 -0
  176. data/spec/moneta/transformer_marshal_prefix_spec.rb +54 -0
  177. data/spec/moneta/transformer_marshal_rmd160_spec.rb +54 -0
  178. data/spec/moneta/transformer_marshal_sha1_spec.rb +54 -0
  179. data/spec/moneta/transformer_marshal_sha256_spec.rb +54 -0
  180. data/spec/moneta/transformer_marshal_sha384_spec.rb +54 -0
  181. data/spec/moneta/transformer_marshal_sha512_spec.rb +54 -0
  182. data/spec/moneta/transformer_marshal_truncate_spec.rb +54 -0
  183. data/spec/moneta/transformer_marshal_uuencode_spec.rb +54 -0
  184. data/spec/moneta/transformer_msgpack_spec.rb +30 -0
  185. data/spec/moneta/transformer_ox_spec.rb +51 -0
  186. data/spec/moneta/transformer_quicklz_spec.rb +27 -0
  187. data/spec/moneta/transformer_snappy_spec.rb +27 -0
  188. data/spec/moneta/transformer_tnet_spec.rb +30 -0
  189. data/spec/moneta/transformer_yaml_spec.rb +51 -0
  190. data/spec/moneta/transformer_zlib_spec.rb +27 -0
  191. data/spec/monetaspecs.rb +2663 -0
  192. data/spec/rack/cache_moneta_spec.rb +355 -0
  193. data/spec/rack/moneta_cookies_spec.rb +81 -0
  194. data/spec/rack/session_moneta_spec.rb +305 -0
  195. metadata +359 -56
  196. data/README +0 -51
  197. data/TODO +0 -4
  198. data/lib/moneta/basic_file.rb +0 -111
  199. data/lib/moneta/berkeley.rb +0 -53
  200. data/lib/moneta/couch.rb +0 -63
  201. data/lib/moneta/datamapper.rb +0 -117
  202. data/lib/moneta/file.rb +0 -91
  203. data/lib/moneta/lmc.rb +0 -52
  204. data/lib/moneta/memcache.rb +0 -52
  205. data/lib/moneta/memory.rb +0 -11
  206. data/lib/moneta/mongodb.rb +0 -58
  207. data/lib/moneta/redis.rb +0 -49
  208. data/lib/moneta/rufus.rb +0 -41
  209. data/lib/moneta/s3.rb +0 -162
  210. data/lib/moneta/sdbm.rb +0 -33
  211. data/lib/moneta/tyrant.rb +0 -58
  212. 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