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,10 @@
1
+ module Moneta
2
+ module Adapters
3
+ # Memory backend using a hash to store the entries
4
+ # @api public
5
+ class Memory < Base
6
+ include Mixins::IncrementSupport
7
+ include Mixins::HashAdapter
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,50 @@
1
+ require 'mongo'
2
+
3
+ module Moneta
4
+ module Adapters
5
+ # MongoDB backend
6
+ # @api public
7
+ class Mongo < Base
8
+ # Constructor
9
+ #
10
+ # @param [Hash] options
11
+ #
12
+ # Options:
13
+ # * :collection - MongoDB collection name (default moneta)
14
+ # * :host - MongoDB server host (default localhost)
15
+ # * :port - MongoDB server port (default mongodb default port)
16
+ # * :db - MongoDB database (default moneta)
17
+ def initialize(options = {})
18
+ collection = options.delete(:collection) || 'moneta'
19
+ host = options.delete(:host) || 'localhost'
20
+ port = options.delete(:port) || ::Mongo::Connection::DEFAULT_PORT
21
+ db = options.delete(:db) || 'moneta'
22
+ connection = ::Mongo::Connection.new(host, port, options)
23
+ @collection = connection.db(db).collection(collection)
24
+ end
25
+
26
+ def load(key, options = {})
27
+ value = @collection.find_one('_id' => key)
28
+ value && value['value'].to_s
29
+ end
30
+
31
+ def delete(key, options = {})
32
+ value = load(key, options)
33
+ @collection.remove('_id' => key) if value
34
+ value
35
+ end
36
+
37
+ def store(key, value, options = {})
38
+ @collection.update({ '_id' => key },
39
+ { '_id' => key, 'value' => ::BSON::Binary.new(value) },
40
+ { :upsert => true })
41
+ value
42
+ end
43
+
44
+ def clear(options = {})
45
+ @collection.remove
46
+ self
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,30 @@
1
+ module Moneta
2
+ module Adapters
3
+ # Null backend which doesn't store anything
4
+ # @api public
5
+ class Null < Base
6
+ def initialize(options = {})
7
+ end
8
+
9
+ def key?(key, options = {})
10
+ false
11
+ end
12
+
13
+ def load(key, options = {})
14
+ nil
15
+ end
16
+
17
+ def store(key, value, options = {})
18
+ value
19
+ end
20
+
21
+ def delete(key, options = {})
22
+ nil
23
+ end
24
+
25
+ def clear(options = {})
26
+ self
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,69 @@
1
+ require 'pstore'
2
+
3
+ module Moneta
4
+ module Adapters
5
+ # PStore backend
6
+ # @api public
7
+ class PStore < Base
8
+ # Constructor
9
+ #
10
+ # @param [Hash] options
11
+ #
12
+ # Options:
13
+ # * :file - PStore file
14
+ def initialize(options = {})
15
+ raise ArgumentError, 'Option :file is required' unless options[:file]
16
+ FileUtils.mkpath(::File.dirname(options[:file]))
17
+ @pstore = new_store(options)
18
+ end
19
+
20
+ def key?(key, options = {})
21
+ @pstore.transaction(true) { @pstore.root?(key) }
22
+ end
23
+
24
+ def load(key, options = {})
25
+ @pstore.transaction(true) { @pstore[key] }
26
+ end
27
+
28
+ def store(key, value, options = {})
29
+ @pstore.transaction { @pstore[key] = value }
30
+ end
31
+
32
+ def delete(key, options = {})
33
+ @pstore.transaction { @pstore.delete(key) }
34
+ end
35
+
36
+ def increment(key, amount = 1, options = {})
37
+ @pstore.transaction do
38
+ value = @pstore[key]
39
+ intvalue = value.to_i
40
+ raise 'Tried to increment non integer value' unless value == nil || intvalue.to_s == value.to_s
41
+ intvalue += amount
42
+ @pstore[key] = intvalue.to_s
43
+ intvalue
44
+ end
45
+ end
46
+
47
+ def clear(options = {})
48
+ @pstore.transaction do
49
+ @pstore.roots.each do |key|
50
+ @pstore.delete(key)
51
+ end
52
+ end
53
+ self
54
+ end
55
+
56
+ protected
57
+
58
+ if RUBY_VERSION > '1.9'
59
+ def new_store(options)
60
+ ::PStore.new(options[:file], options[:threadsafe])
61
+ end
62
+ else
63
+ def new_store(options)
64
+ ::PStore.new(options[:file])
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,68 @@
1
+ require 'redis'
2
+
3
+ module Moneta
4
+ module Adapters
5
+ # Redis backend
6
+ # @api public
7
+ class Redis < Base
8
+ # Constructor
9
+ #
10
+ # @param [Hash] options
11
+ #
12
+ # Options:
13
+ # * :expires - Default expiration time (default none)
14
+ # * Other options passed to Redis#new
15
+ def initialize(options = {})
16
+ @expires = options.delete(:expires)
17
+ @redis = ::Redis.new(options)
18
+ end
19
+
20
+ def key?(key, options = {})
21
+ if @redis.exists(key)
22
+ if expires = options[:expires]
23
+ @redis.expire(key, expires)
24
+ end
25
+ true
26
+ else
27
+ false
28
+ end
29
+ end
30
+
31
+ def load(key, options = {})
32
+ value = @redis.get(key)
33
+ if value && (expires = options[:expires])
34
+ @redis.expire(key, expires)
35
+ end
36
+ value
37
+ end
38
+
39
+ def store(key, value, options = {})
40
+ if expires = (options[:expires] || @expires)
41
+ @redis.setex(key, expires, value)
42
+ else
43
+ @redis.set(key, value)
44
+ end
45
+ value
46
+ end
47
+
48
+ def delete(key, options = {})
49
+ if value = load(key, options)
50
+ @redis.del(key)
51
+ value
52
+ end
53
+ end
54
+
55
+ def increment(key, amount = 1, options = {})
56
+ value = @redis.incrby(key, amount)
57
+ expires = (options[:expires] || @expires)
58
+ @redis.expire(key, expires) if expires
59
+ value
60
+ end
61
+
62
+ def clear(options = {})
63
+ @redis.flushdb
64
+ self
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,57 @@
1
+ # Copyright: 2011 TMX Credit
2
+ # Author: Potapov Sergey (aka Blake)
3
+
4
+ require 'riak'
5
+
6
+ module Moneta
7
+ module Adapters
8
+ # Riak backend
9
+ # @api public
10
+ class Riak < Base
11
+ # Constructor
12
+ #
13
+ # @param [Hash] options
14
+ #
15
+ # Options:
16
+ # * :bucket - Bucket name (default moneta)
17
+ # * :content_type - Default content type (default application/octet-stream)
18
+ # * All other options passed to Riak::Client#new
19
+ def initialize(options = {})
20
+ bucket = options.delete(:bucket) || 'moneta'
21
+ @content_type = options.delete(:content_type) || 'application/octet-stream'
22
+ @bucket = ::Riak::Client.new(options).bucket(bucket)
23
+ end
24
+
25
+ def key?(key, options = {})
26
+ @bucket.exists?(key, options)
27
+ end
28
+
29
+ def load(key, options = {})
30
+ @bucket.get(key, options).raw_data
31
+ rescue ::Riak::FailedRequest => ex
32
+ nil
33
+ end
34
+
35
+ def delete(key, options = {})
36
+ value = load(key, options)
37
+ @bucket.delete(key, options)
38
+ value
39
+ end
40
+
41
+ def store(key, value, options = {})
42
+ obj = ::Riak::RObject.new(@bucket, key)
43
+ obj.content_type = options[:content_type] || @content_type
44
+ obj.raw_data = value
45
+ obj.store(options)
46
+ value
47
+ end
48
+
49
+ def clear(options = {})
50
+ @bucket.keys do |keys|
51
+ keys.each{ |key| @bucket.delete(key) }
52
+ end
53
+ self
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,35 @@
1
+ require 'sdbm'
2
+
3
+ module Moneta
4
+ module Adapters
5
+ # SDBM backend
6
+ # @api public
7
+ class SDBM < 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 = ::SDBM.new(options[:file])
17
+ end
18
+
19
+ def close
20
+ @hash.close
21
+ nil
22
+ end
23
+
24
+ def store(key, value, options = {})
25
+ super
26
+ value
27
+ rescue SDBMError
28
+ # SDBM is not very robust!
29
+ # You shouldn't put to much data into it, otherwise
30
+ # it might raise a SDBMError.
31
+ value
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,79 @@
1
+ require 'sequel'
2
+
3
+ module Moneta
4
+ module Adapters
5
+ # Sequel backend
6
+ # @api public
7
+ class Sequel < Base
8
+ # Constructor
9
+ #
10
+ # @param [Hash] options
11
+ #
12
+ # Options:
13
+ # * :db - Sequel database
14
+ # * :table - Table name (default :moneta)
15
+ # * All other options passed to Sequel#connect
16
+ def initialize(options = {})
17
+ raise ArgumentError, 'Option :db is required' unless db = options.delete(:db)
18
+ table = options.delete(:table) || :moneta
19
+ @db = ::Sequel.connect(db, options)
20
+ @db.create_table?(table) do
21
+ String :k, :null => false, :primary_key => true
22
+ String :v
23
+ end
24
+ @table = @db[table]
25
+ end
26
+
27
+ def key?(key, options = {})
28
+ @table[:k => key] != nil
29
+ end
30
+
31
+ def load(key, options = {})
32
+ record = @table[:k => key]
33
+ record && record[:v]
34
+ end
35
+
36
+ def store(key, value, options = {})
37
+ @db.transaction do
38
+ if key?(key, options)
39
+ @table.update(:k => key, :v => value)
40
+ else
41
+ @table.insert(:k => key, :v => value)
42
+ end
43
+ value
44
+ end
45
+ end
46
+
47
+ def increment(key, amount = 1, options = {})
48
+ @db.transaction do
49
+ locked_table = @table.for_update
50
+ if record = locked_table[:k => key]
51
+ value = record[:v]
52
+ intvalue = value.to_i
53
+ raise 'Tried to increment non integer value' unless value == nil || intvalue.to_s == value.to_s
54
+ intvalue += amount
55
+ locked_table.update(:k => key, :v => intvalue.to_s)
56
+ intvalue
57
+ else
58
+ locked_table.insert(:k => key, :v => amount.to_s)
59
+ amount
60
+ end
61
+ end
62
+ end
63
+
64
+ def delete(key, options = {})
65
+ @db.transaction do
66
+ if value = load(key, options)
67
+ @table.filter(:k => key).delete
68
+ value
69
+ end
70
+ end
71
+ end
72
+
73
+ def clear(options = {})
74
+ @table.delete
75
+ self
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,65 @@
1
+ require 'sqlite3'
2
+
3
+ module Moneta
4
+ module Adapters
5
+ # Sqlite3 backend
6
+ # @api public
7
+ class Sqlite < Base
8
+ include Mixins::IncrementSupport
9
+
10
+ # Constructor
11
+ #
12
+ # @param [Hash] options
13
+ #
14
+ # Options:
15
+ # * :file - Database file
16
+ # * :table - Table name (default moneta)
17
+ def initialize(options = {})
18
+ raise ArgumentError, 'Option :file is required' unless options[:file]
19
+ table = options[:table] || 'moneta'
20
+ @db = ::SQLite3::Database.new(options[:file])
21
+ @db.execute("create table if not exists #{table} (k blob not null primary key, v blob)")
22
+ @stmts =
23
+ [@select = @db.prepare("select v from #{table} where k = ?"),
24
+ @replace = @db.prepare("replace into #{table} values (?, ?)"),
25
+ @delete = @db.prepare("delete from #{table} where k = ?"),
26
+ @clear = @db.prepare("delete from #{table}")]
27
+ end
28
+
29
+ def key?(key, options = {})
30
+ !@select.execute!(key).empty?
31
+ end
32
+
33
+ def load(key, options = {})
34
+ rows = @select.execute!(key)
35
+ rows.empty? ? nil : rows.first.first
36
+ end
37
+
38
+ def store(key, value, options = {})
39
+ @replace.execute!(key, value)
40
+ value
41
+ end
42
+
43
+ def delete(key, options = {})
44
+ value = load(key, options)
45
+ @delete.execute!(key)
46
+ value
47
+ end
48
+
49
+ def increment(key, amount = 1, options = {})
50
+ @db.transaction(:exclusive) { return super }
51
+ end
52
+
53
+ def clear(options = {})
54
+ @clear.execute!
55
+ self
56
+ end
57
+
58
+ def close
59
+ @stmts.each {|s| s.close }
60
+ @db.close
61
+ nil
62
+ end
63
+ end
64
+ end
65
+ end