juno 0.1.1 → 0.2.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 (161) hide show
  1. data/.gitignore +2 -1
  2. data/.travis.yml +6 -0
  3. data/Gemfile +16 -9
  4. data/README.md +92 -34
  5. data/Rakefile +23 -5
  6. data/benchmarks/run.rb +19 -22
  7. data/juno.gemspec +0 -3
  8. data/lib/juno/adapters/activerecord.rb +58 -0
  9. data/lib/juno/adapters/cassandra.rb +47 -0
  10. data/lib/juno/adapters/couch.rb +43 -0
  11. data/lib/juno/adapters/datamapper.rb +64 -0
  12. data/lib/juno/adapters/dbm.rb +17 -0
  13. data/lib/juno/adapters/file.rb +58 -0
  14. data/lib/juno/adapters/fog.rb +42 -0
  15. data/lib/juno/adapters/gdbm.rb +17 -0
  16. data/lib/juno/adapters/localmemcache.rb +18 -0
  17. data/lib/juno/adapters/memcached.rb +11 -0
  18. data/lib/juno/adapters/memcached_dalli.rb +46 -0
  19. data/lib/juno/adapters/memcached_native.rb +47 -0
  20. data/lib/juno/adapters/memory.rb +30 -0
  21. data/lib/juno/adapters/mongo.rb +43 -0
  22. data/lib/juno/adapters/null.rb +28 -0
  23. data/lib/juno/adapters/pstore.rb +51 -0
  24. data/lib/juno/adapters/redis.rb +43 -0
  25. data/lib/juno/adapters/riak.rb +46 -0
  26. data/lib/juno/adapters/sdbm.rb +27 -0
  27. data/lib/juno/adapters/sequel.rb +50 -0
  28. data/lib/juno/adapters/sqlite.rb +52 -0
  29. data/lib/juno/adapters/tokyocabinet.rb +33 -0
  30. data/lib/juno/adapters/yaml.rb +13 -0
  31. data/lib/juno/base.rb +11 -89
  32. data/lib/juno/builder.rb +30 -0
  33. data/lib/juno/cache.rb +64 -0
  34. data/lib/juno/expires.rb +6 -10
  35. data/lib/juno/proxy.rb +62 -3
  36. data/lib/juno/stack.rb +27 -11
  37. data/lib/juno/transformer.rb +106 -0
  38. data/lib/juno/version.rb +1 -1
  39. data/lib/juno.rb +81 -29
  40. data/spec/adapter_activerecord_spec.rb +41 -0
  41. data/spec/adapter_cassandra_spec.rb +27 -0
  42. data/spec/adapter_couch_spec.rb +27 -0
  43. data/spec/adapter_datamapper_spec.rb +61 -0
  44. data/spec/adapter_dbm_spec.rb +27 -0
  45. data/spec/adapter_file_spec.rb +27 -0
  46. data/spec/adapter_fog_spec.rb +35 -0
  47. data/spec/adapter_gdbm_spec.rb +27 -0
  48. data/spec/adapter_localmemcache_spec.rb +27 -0
  49. data/spec/adapter_memcached_dalli_spec.rb +28 -0
  50. data/spec/adapter_memcached_native_spec.rb +28 -0
  51. data/spec/adapter_memcached_spec.rb +28 -0
  52. data/spec/adapter_memory_spec.rb +42 -0
  53. data/spec/adapter_mongo_spec.rb +27 -0
  54. data/spec/adapter_pstore_spec.rb +30 -0
  55. data/spec/adapter_redis_spec.rb +28 -0
  56. data/spec/adapter_riak_spec.rb +31 -0
  57. data/spec/adapter_sdbm_spec.rb +27 -0
  58. data/spec/adapter_sequel_spec.rb +27 -0
  59. data/spec/adapter_sqlite_spec.rb +27 -0
  60. data/spec/adapter_tokyocabinet_spec.rb +27 -0
  61. data/spec/adapter_yaml_spec.rb +30 -0
  62. data/spec/cache_file_memory_spec.rb +50 -0
  63. data/spec/cache_memory_null_spec.rb +39 -0
  64. data/spec/expires_file_spec.rb +82 -0
  65. data/spec/expires_memory_spec.rb +59 -0
  66. data/spec/generate.rb +736 -0
  67. data/spec/helper.rb +39 -0
  68. data/spec/junospecs.rb +1540 -0
  69. data/spec/null_adapter_spec.rb +33 -0
  70. data/spec/proxy_expires_memory_spec.rb +63 -0
  71. data/spec/proxy_redis_spec.rb +38 -0
  72. data/spec/simple_activerecord_spec.rb +52 -0
  73. data/spec/simple_cassandra_spec.rb +53 -0
  74. data/spec/simple_couch_spec.rb +52 -0
  75. data/spec/simple_datamapper_spec.rb +54 -0
  76. data/spec/simple_datamapper_with_repository_spec.rb +54 -0
  77. data/spec/simple_dbm_spec.rb +52 -0
  78. data/spec/simple_file_spec.rb +52 -0
  79. data/spec/simple_fog_spec.rb +60 -0
  80. data/spec/simple_gdbm_spec.rb +52 -0
  81. data/spec/simple_hashfile_spec.rb +52 -0
  82. data/spec/simple_localmemcache_spec.rb +52 -0
  83. data/spec/simple_memcached_dalli_spec.rb +53 -0
  84. data/spec/simple_memcached_native_spec.rb +53 -0
  85. data/spec/simple_memcached_spec.rb +53 -0
  86. data/spec/simple_memory_spec.rb +52 -0
  87. data/spec/simple_mongo_spec.rb +52 -0
  88. data/spec/simple_null_spec.rb +43 -0
  89. data/spec/simple_pstore_spec.rb +52 -0
  90. data/spec/simple_redis_spec.rb +53 -0
  91. data/spec/simple_riak_spec.rb +56 -0
  92. data/spec/simple_sdbm_spec.rb +52 -0
  93. data/spec/simple_sequel_spec.rb +52 -0
  94. data/spec/simple_sqlite_spec.rb +52 -0
  95. data/spec/simple_tokyocabinet_spec.rb +52 -0
  96. data/spec/simple_yaml_spec.rb +52 -0
  97. data/spec/stack_file_memory_spec.rb +43 -0
  98. data/spec/stack_memory_file_spec.rb +42 -0
  99. data/spec/transformer_bson_spec.rb +44 -0
  100. data/spec/transformer_json_spec.rb +44 -0
  101. data/spec/transformer_marshal_base64_spec.rb +60 -0
  102. data/spec/transformer_marshal_escape_spec.rb +60 -0
  103. data/spec/transformer_marshal_md5_spec.rb +60 -0
  104. data/spec/transformer_marshal_md5_spread_spec.rb +60 -0
  105. data/spec/transformer_msgpack_spec.rb +44 -0
  106. data/spec/transformer_yaml_spec.rb +59 -0
  107. metadata +164 -108
  108. data/lib/juno/activerecord.rb +0 -55
  109. data/lib/juno/cassandra.rb +0 -45
  110. data/lib/juno/couch.rb +0 -43
  111. data/lib/juno/datamapper.rb +0 -63
  112. data/lib/juno/dbm.rb +0 -15
  113. data/lib/juno/file.rb +0 -62
  114. data/lib/juno/fog.rb +0 -48
  115. data/lib/juno/gdbm.rb +0 -15
  116. data/lib/juno/hashfile.rb +0 -12
  117. data/lib/juno/localmemcache.rb +0 -16
  118. data/lib/juno/memcached.rb +0 -7
  119. data/lib/juno/memcached_dalli.rb +0 -55
  120. data/lib/juno/memcached_native.rb +0 -56
  121. data/lib/juno/memory.rb +0 -7
  122. data/lib/juno/mongodb.rb +0 -43
  123. data/lib/juno/null.rb +0 -23
  124. data/lib/juno/pstore.rb +0 -49
  125. data/lib/juno/redis.rb +0 -46
  126. data/lib/juno/riak.rb +0 -45
  127. data/lib/juno/sdbm.rb +0 -15
  128. data/lib/juno/sequel.rb +0 -48
  129. data/lib/juno/sqlite.rb +0 -50
  130. data/lib/juno/tokyocabinet.rb +0 -36
  131. data/lib/juno/yaml.rb +0 -9
  132. data/test/helper.rb +0 -212
  133. data/test/test_activerecord.rb +0 -33
  134. data/test/test_cassandra.rb +0 -13
  135. data/test/test_couch.rb +0 -13
  136. data/test/test_datamapper.rb +0 -64
  137. data/test/test_dbm.rb +0 -13
  138. data/test/test_expires.rb +0 -9
  139. data/test/test_file.rb +0 -9
  140. data/test/test_fog.rb +0 -17
  141. data/test/test_gdbm.rb +0 -13
  142. data/test/test_hashfile.rb +0 -9
  143. data/test/test_localmemcache.rb +0 -13
  144. data/test/test_memcached.rb +0 -14
  145. data/test/test_memcached_dalli.rb +0 -14
  146. data/test/test_memcached_native.rb +0 -14
  147. data/test/test_memory.rb +0 -9
  148. data/test/test_mongodb.rb +0 -13
  149. data/test/test_null.rb +0 -9
  150. data/test/test_proxy.rb +0 -9
  151. data/test/test_pstore.rb +0 -9
  152. data/test/test_redis.rb +0 -13
  153. data/test/test_riak.rb +0 -13
  154. data/test/test_sdbm.rb +0 -13
  155. data/test/test_sequel.rb +0 -13
  156. data/test/test_sqlite.rb +0 -13
  157. data/test/test_stack.rb +0 -10
  158. data/test/test_tokyocabinet.rb +0 -13
  159. data/test/test_yaml.rb +0 -9
  160. data/unsupported/test_tokyotyrant.rb +0 -13
  161. data/unsupported/tokyotyrant.rb +0 -29
@@ -0,0 +1,18 @@
1
+ require 'localmemcache'
2
+
3
+ module Juno
4
+ module Adapters
5
+ class LocalMemCache < Memory
6
+ def initialize(options = {})
7
+ raise 'No option :file specified' unless options[:file]
8
+ @memory = ::LocalMemCache.new(:filename => options[:file])
9
+ end
10
+
11
+ def delete(key, options = {})
12
+ value = load(key, options)
13
+ @memory.delete(key)
14
+ value
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,11 @@
1
+ module Juno
2
+ module Adapters
3
+ begin
4
+ require 'juno/adapters/memcached_native'
5
+ Memcached = MemcachedNative
6
+ rescue LoadError
7
+ require 'juno/adapters/memcached_dalli'
8
+ Memcached = MemcachedDalli
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,46 @@
1
+ require 'dalli'
2
+
3
+ module Juno
4
+ module Adapters
5
+ class MemcachedDalli < Base
6
+ def initialize(options = {})
7
+ server = options.delete(:server) || 'localhost:11211'
8
+ @cache = ::Dalli::Client.new(server, options)
9
+ end
10
+
11
+ def key?(key, options = {})
12
+ !!@cache.get(key)
13
+ end
14
+
15
+ def load(key, options = {})
16
+ value = @cache.get(key)
17
+ if value && options.include?(:expires)
18
+ store(key, value, options)
19
+ else
20
+ value
21
+ end
22
+ end
23
+
24
+ def store(key, value, options = {})
25
+ @cache.set(key, value, options[:expires])
26
+ value
27
+ end
28
+
29
+ def delete(key, options = {})
30
+ value = @cache.get(key)
31
+ @cache.delete(key)
32
+ value
33
+ end
34
+
35
+ def clear(options = {})
36
+ @cache.flush_all
37
+ self
38
+ end
39
+
40
+ def close
41
+ @cache.close
42
+ nil
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,47 @@
1
+ require 'memcached'
2
+
3
+ module Juno
4
+ module Adapters
5
+ class MemcachedNative < Base
6
+ def initialize(options = {})
7
+ server = options.delete(:server) || 'localhost:11211'
8
+ options.merge!(:prefix_key => options.delete(:namespace)) if options[:namespace]
9
+ @cache = ::Memcached.new(server, options)
10
+ end
11
+
12
+ def key?(key, options = {})
13
+ @cache.get(key, false)
14
+ true
15
+ rescue ::Memcached::NotFound
16
+ false
17
+ end
18
+
19
+ def load(key, options = {})
20
+ value = @cache.get(key, false)
21
+ if value && options.include?(:expires)
22
+ store(key, value, options)
23
+ else
24
+ value
25
+ end
26
+ rescue ::Memcached::NotFound
27
+ end
28
+
29
+ def delete(key, options = {})
30
+ value = @cache.get(key, false)
31
+ @cache.delete(key)
32
+ value
33
+ rescue ::Memcached::NotFound
34
+ end
35
+
36
+ def store(key, value, options = {})
37
+ @cache.set(key, value, options[:expires] || @cache.options[:default_ttl], false)
38
+ value
39
+ end
40
+
41
+ def clear(options = {})
42
+ @cache.flush
43
+ self
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,30 @@
1
+ module Juno
2
+ module Adapters
3
+ class Memory < Base
4
+ def initialize(options = {})
5
+ @memory = {}
6
+ end
7
+
8
+ def key?(key, options = {})
9
+ @memory.has_key?(key)
10
+ end
11
+
12
+ def load(key, options = {})
13
+ @memory[key]
14
+ end
15
+
16
+ def store(key, value, options = {})
17
+ @memory[key] = value
18
+ end
19
+
20
+ def delete(key, options = {})
21
+ @memory.delete(key)
22
+ end
23
+
24
+ def clear(options = {})
25
+ @memory.clear
26
+ self
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,43 @@
1
+ require 'mongo'
2
+
3
+ module Juno
4
+ module Adapters
5
+ class Mongo < Base
6
+ def initialize(options = {})
7
+ collection = options.delete(:collection) || 'juno'
8
+ host = options.delete(:host) || 'localhost'
9
+ port = options.delete(:port) || ::Mongo::Connection::DEFAULT_PORT
10
+ db = options.delete(:db) || 'juno'
11
+ connection = ::Mongo::Connection.new(host, port, options)
12
+ @collection = connection.db(db).collection(collection)
13
+ end
14
+
15
+ def key?(key, options = {})
16
+ !!load(key, options)
17
+ end
18
+
19
+ def load(key, options = {})
20
+ value = @collection.find_one('_id' => key)
21
+ value ? value['data'] : nil
22
+ end
23
+
24
+ def delete(key, options = {})
25
+ value = load(key, options)
26
+ @collection.remove('_id' => key) if value
27
+ value
28
+ end
29
+
30
+ def store(key, value, options = {})
31
+ @collection.update({ '_id' => key },
32
+ { '_id' => key, 'data' => value },
33
+ { :upsert => true })
34
+ value
35
+ end
36
+
37
+ def clear(options = {})
38
+ @collection.remove
39
+ self
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,28 @@
1
+ module Juno
2
+ module Adapters
3
+ class Null < Base
4
+ def initialize(options = {})
5
+ end
6
+
7
+ def key?(key, options = {})
8
+ false
9
+ end
10
+
11
+ def load(key, options = {})
12
+ nil
13
+ end
14
+
15
+ def store(key, value, options = {})
16
+ value
17
+ end
18
+
19
+ def delete(key, options = {})
20
+ nil
21
+ end
22
+
23
+ def clear(options = {})
24
+ self
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,51 @@
1
+ require 'pstore'
2
+
3
+ module Juno
4
+ module Adapters
5
+ class PStore < Base
6
+ def initialize(options = {})
7
+ raise 'No option :file specified' unless options[:file]
8
+ FileUtils.mkpath(::File.dirname(options[:file]))
9
+ @pstore = new_store(options)
10
+ end
11
+
12
+ def key?(key, options = {})
13
+ @pstore.transaction(true) { @pstore.root?(key) }
14
+ end
15
+
16
+ def load(key, options = {})
17
+ @pstore.transaction(true) { @pstore[key] }
18
+ end
19
+
20
+ def delete(key, options = {})
21
+ @pstore.transaction { @pstore.delete(key) }
22
+ end
23
+
24
+ def store(key, value, options = {})
25
+ @pstore.transaction { @pstore[key] = value }
26
+ end
27
+
28
+ def clear(options = {})
29
+ @pstore.transaction do
30
+ @pstore.roots.each do |key|
31
+ @pstore.delete(key)
32
+ end
33
+ end
34
+ self
35
+ end
36
+
37
+ protected
38
+
39
+ if RUBY_VERSION > '1.9'
40
+ def new_store(options)
41
+ # Create a thread-safe pstore by default
42
+ ::PStore.new(options[:file], options.include?(:thread_safe) ? options[:thread_safe] : true)
43
+ end
44
+ else
45
+ def new_store(options)
46
+ ::PStore.new(options[:file])
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,43 @@
1
+ require 'redis'
2
+
3
+ module Juno
4
+ module Adapters
5
+ class Redis < Base
6
+ def initialize(options = {})
7
+ @redis = ::Redis.new(options)
8
+ end
9
+
10
+ def key?(key, options = {})
11
+ @redis.exists(key)
12
+ end
13
+
14
+ def load(key, options = {})
15
+ value = @redis.get(key)
16
+ if value && (expires = options[:expires])
17
+ @redis.expire(key, expires)
18
+ end
19
+ value
20
+ end
21
+
22
+ def delete(key, options = {})
23
+ if value = load(key, options)
24
+ @redis.del(key)
25
+ value
26
+ end
27
+ end
28
+
29
+ def store(key, value, options = {})
30
+ @redis.set(key, value)
31
+ if expires = options[:expires]
32
+ @redis.expire(key, expires)
33
+ end
34
+ value
35
+ end
36
+
37
+ def clear(options = {})
38
+ @redis.flushdb
39
+ self
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,46 @@
1
+ # Copyright: 2011 TMX Credit
2
+ # Author: Potapov Sergey (aka Blake)
3
+
4
+ require 'riak'
5
+
6
+ module Juno
7
+ module Adapters
8
+ class Riak < Base
9
+ def initialize(options = {})
10
+ bucket = options.delete(:bucket) || 'juno'
11
+ @bucket = ::Riak::Client.new(options).bucket(bucket)
12
+ end
13
+
14
+ def key?(key, options = {})
15
+ @bucket.exists?(key, options)
16
+ end
17
+
18
+ def load(key, options = {})
19
+ @bucket.get(key, options).raw_data
20
+ rescue ::Riak::FailedRequest => ex
21
+ nil
22
+ end
23
+
24
+ def delete(key, options = {})
25
+ value = load(key, options)
26
+ @bucket.delete(key, options)
27
+ value
28
+ end
29
+
30
+ def store(key, value, options = {})
31
+ obj = ::Riak::RObject.new(@bucket, key)
32
+ obj.content_type = 'application/octet-stream'
33
+ obj.raw_data = value
34
+ obj.store(options)
35
+ value
36
+ end
37
+
38
+ def clear(options = {})
39
+ @bucket.keys do |keys|
40
+ keys.each{ |key| @bucket.delete(key) }
41
+ end
42
+ self
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,27 @@
1
+ require 'sdbm'
2
+
3
+ module Juno
4
+ module Adapters
5
+ class SDBM < Memory
6
+ def initialize(options = {})
7
+ raise 'No option :file specified' unless options[:file]
8
+ @memory = ::SDBM.new(options[:file])
9
+ end
10
+
11
+ def close
12
+ @memory.close
13
+ nil
14
+ end
15
+
16
+ def store(key, value, options = {})
17
+ super
18
+ value
19
+ rescue SDBMError
20
+ # SDBM is not very robust!
21
+ # You shouldn't put to much data into it, otherwise
22
+ # it might raise a SDBMError.
23
+ value
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,50 @@
1
+ require 'sequel'
2
+
3
+ module Juno
4
+ module Adapters
5
+ class Sequel < Base
6
+ def initialize(options = {})
7
+ raise 'No option :db specified' unless db = options.delete(:db)
8
+ @table = options.delete(:table) || :juno
9
+ @db = ::Sequel.connect(db, options)
10
+ @db.create_table?(@table) do
11
+ primary_key :k
12
+ String :k
13
+ String :v
14
+ end
15
+ end
16
+
17
+ def key?(key, options = {})
18
+ !!sequel_table[:k => key]
19
+ end
20
+
21
+ def load(key, options = {})
22
+ result = sequel_table[:k => key]
23
+ result ? result[:v] : nil
24
+ end
25
+
26
+ def store(key, value, options = {})
27
+ sequel_table.insert(:k => key, :v => value)
28
+ value
29
+ end
30
+
31
+ def delete(key, options = {})
32
+ if value = load(key, options)
33
+ sequel_table.filter(:k => key).delete
34
+ value
35
+ end
36
+ end
37
+
38
+ def clear(options = {})
39
+ sequel_table.delete
40
+ self
41
+ end
42
+
43
+ private
44
+
45
+ def sequel_table
46
+ @sequel_table ||= @db[@table]
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,52 @@
1
+ require 'sqlite3'
2
+
3
+ module Juno
4
+ module Adapters
5
+ class Sqlite < Base
6
+ def initialize(options = {})
7
+ raise 'No option :file specified' unless options[:file]
8
+ table = options[:table] || 'juno'
9
+ @db = ::SQLite3::Database.new(options[:file])
10
+ @db.execute("create table if not exists #{table} (key string primary key, value string)")
11
+ @select = @db.prepare("select value from #{table} where key = ?")
12
+ @insert = @db.prepare("insert into #{table} values (?, ?)")
13
+ @delete = @db.prepare("delete from #{table} where key = ?")
14
+ @clear = @db.prepare("delete from #{table}")
15
+ end
16
+
17
+ def key?(key, options = {})
18
+ !@select.execute!(key).empty?
19
+ end
20
+
21
+ def load(key, options = {})
22
+ rows = @select.execute!(key)
23
+ rows.empty? ? nil : rows.first.first
24
+ end
25
+
26
+ def store(key, value, options = {})
27
+ @insert.execute!(key, value)
28
+ value
29
+ end
30
+
31
+ def delete(key, options = {})
32
+ value = load(key, options)
33
+ @delete.execute!(key)
34
+ value
35
+ end
36
+
37
+ def clear(options = {})
38
+ @clear.execute!
39
+ self
40
+ end
41
+
42
+ def close
43
+ @select.close
44
+ @insert.close
45
+ @delete.close
46
+ @clear.close
47
+ @db.close
48
+ nil
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,33 @@
1
+ require 'tokyocabinet'
2
+
3
+ module Juno
4
+ module Adapters
5
+ class TokyoCabinet < Memory
6
+ def initialize(options = {})
7
+ file = options[:file]
8
+ raise 'No option :file specified' unless options[:file]
9
+ @memory = ::TokyoCabinet::HDB.new
10
+ unless @memory.open(file, ::TokyoCabinet::HDB::OWRITER | ::TokyoCabinet::HDB::OCREAT)
11
+ raise @memory.errmsg(@memory.ecode)
12
+ end
13
+ end
14
+
15
+ def key?(key, options = {})
16
+ !!load(key, options)
17
+ end
18
+
19
+ def delete(key, options = {})
20
+ value = load(key, options)
21
+ if value
22
+ @memory.delete(key)
23
+ value
24
+ end
25
+ end
26
+
27
+ def close
28
+ @memory.close
29
+ nil
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,13 @@
1
+ require 'yaml/store'
2
+
3
+ module Juno
4
+ module Adapters
5
+ class YAML < Juno::Adapters::PStore
6
+ protected
7
+
8
+ def new_store(options)
9
+ ::YAML::Store.new(options[:file])
10
+ end
11
+ end
12
+ end
13
+ end
data/lib/juno/base.rb CHANGED
@@ -1,72 +1,29 @@
1
1
  module Juno
2
2
  # Simple interface to key/value stores with Hash-like interface.
3
- #
4
- # @abstract
5
3
  class Base
6
- # Exists the value with key
7
- #
8
- # @param [Object] key
9
- # @return [Boolean]
10
- # @param [Hash] options
11
- # @api public
12
- def key?(key, options = {})
13
- @store.has_key?(key_for(key))
14
- end
15
-
16
- def has_key?(key, options = {})
17
- key?(key, options)
18
- end
19
-
20
- # Fetch value with key. Return nil if the key doesn't exist
21
- #
22
- # @param [Object] key
23
- # @return [Object] value
24
- # @api public
25
- def [](key)
26
- deserialize(@store[key_for(key)])
27
- end
28
-
29
- # Store value with key
30
- #
31
- # @param [Object] key
32
- # @param [Object] value
33
- # @param [Hash] options
34
- # @return value
4
+ # Explicitly close the store
35
5
  # @api public
36
- def store(key, value, options = {})
37
- @store[key_for(key)] = serialize(value)
38
- value
6
+ def close
39
7
  end
40
8
 
41
- # Delete the key from the store and return the current value
9
+ # Fetch value with key. Return default if value is nil.
42
10
  #
43
11
  # @param [Object] key
44
- # @return [Object] current value
45
- # @param [Hash] options
46
- # @api public
47
- def delete(key, options = {})
48
- deserialize(@store.delete(key_for(key)))
49
- end
50
-
51
- # Clear all keys in this store
52
- #
12
+ # @param [Object] value Default value
53
13
  # @param [Hash] options
54
- # @return [void]
14
+ # @return [Object] value from store
55
15
  # @api public
56
- def clear(options = {})
57
- @store.clear
58
- nil
16
+ def fetch(key, value = nil, options = {})
17
+ load(key, options) || (block_given? && yield(key)) || value
59
18
  end
60
19
 
61
- # Fetch value with key. Return default if value is nil.
20
+ # Fetch value with key. Return nil if the key doesn't exist
62
21
  #
63
22
  # @param [Object] key
64
- # @param [Object] value Default value
65
- # @param [Hash] options
66
- # @return [Object] value from store
23
+ # @return [Object] value
67
24
  # @api public
68
- def fetch(key, value = nil, options = {})
69
- self[key] || (block_given? && yield(key)) || value
25
+ def [](key)
26
+ load(key)
70
27
  end
71
28
 
72
29
  # Store value with key
@@ -78,40 +35,5 @@ module Juno
78
35
  def []=(key, value)
79
36
  store(key, value)
80
37
  end
81
-
82
- # Explicitly close the store
83
- # @api public
84
- def close
85
- nil
86
- end
87
-
88
- protected
89
-
90
- # Serialize value
91
- #
92
- # @param [Object] value Serializable object
93
- # @return [String] serialized object
94
- # @api private
95
- def serialize(value)
96
- Marshal.dump(value)
97
- end
98
-
99
- # Deserialize value
100
- #
101
- # @param [String] value Serialized object
102
- # @return [Object] Deserialized object
103
- # @api private
104
- def deserialize(value)
105
- value && Marshal.load(value)
106
- end
107
-
108
- # Convert key to string
109
- #
110
- # @param [Object] key Key
111
- # @return [String] Marshalled key
112
- # @api private
113
- def key_for(key)
114
- String === key ? key : Marshal.dump(key)
115
- end
116
38
  end
117
39
  end