moneta 0.6.0 → 0.7.0

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