juno 0.2.3 → 0.2.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (132) hide show
  1. data/.travis.yml +2 -4
  2. data/Gemfile +3 -1
  3. data/README.md +40 -8
  4. data/benchmarks/run.rb +17 -5
  5. data/lib/juno/adapters/activerecord.rb +23 -14
  6. data/lib/juno/adapters/cassandra.rb +11 -0
  7. data/lib/juno/adapters/couch.rb +9 -0
  8. data/lib/juno/adapters/datamapper.rb +10 -0
  9. data/lib/juno/adapters/dbm.rb +8 -0
  10. data/lib/juno/adapters/file.rb +2 -0
  11. data/lib/juno/adapters/fog.rb +9 -0
  12. data/lib/juno/adapters/gdbm.rb +8 -0
  13. data/lib/juno/adapters/localmemcache.rb +8 -0
  14. data/lib/juno/adapters/lruhash.rb +8 -0
  15. data/lib/juno/adapters/memcached_dalli.rb +9 -0
  16. data/lib/juno/adapters/memcached_native.rb +10 -0
  17. data/lib/juno/adapters/memory.rb +2 -0
  18. data/lib/juno/adapters/mongo.rb +11 -0
  19. data/lib/juno/adapters/null.rb +2 -0
  20. data/lib/juno/adapters/pstore.rb +9 -2
  21. data/lib/juno/adapters/redis.rb +5 -0
  22. data/lib/juno/adapters/riak.rb +9 -0
  23. data/lib/juno/adapters/sdbm.rb +8 -0
  24. data/lib/juno/adapters/sequel.rb +10 -0
  25. data/lib/juno/adapters/sqlite.rb +9 -0
  26. data/lib/juno/adapters/tokyocabinet.rb +16 -4
  27. data/lib/juno/adapters/yaml.rb +2 -0
  28. data/lib/juno/base.rb +1 -0
  29. data/lib/juno/builder.rb +2 -0
  30. data/lib/juno/cache.rb +2 -0
  31. data/lib/juno/expires.rb +1 -0
  32. data/lib/juno/lock.rb +37 -0
  33. data/lib/juno/proxy.rb +1 -0
  34. data/lib/juno/stack.rb +2 -0
  35. data/lib/juno/transformer.rb +16 -4
  36. data/lib/juno/version.rb +3 -1
  37. data/lib/juno.rb +33 -2
  38. data/spec/adapter_activerecord_spec.rb +20 -34
  39. data/spec/adapter_cassandra_spec.rb +9 -23
  40. data/spec/adapter_couch_spec.rb +9 -23
  41. data/spec/adapter_datamapper_spec.rb +36 -50
  42. data/spec/adapter_dbm_spec.rb +9 -23
  43. data/spec/adapter_file_spec.rb +9 -23
  44. data/spec/adapter_fog_spec.rb +12 -29
  45. data/spec/adapter_gdbm_spec.rb +9 -23
  46. data/spec/adapter_localmemcache_spec.rb +9 -23
  47. data/spec/adapter_lruhash_spec.rb +24 -38
  48. data/spec/adapter_memcached_dalli_spec.rb +10 -24
  49. data/spec/adapter_memcached_native_spec.rb +10 -24
  50. data/spec/adapter_memcached_spec.rb +10 -24
  51. data/spec/adapter_memory_spec.rb +24 -38
  52. data/spec/adapter_mongo_spec.rb +9 -23
  53. data/spec/adapter_pstore_spec.rb +12 -26
  54. data/spec/adapter_redis_spec.rb +10 -24
  55. data/spec/adapter_riak_spec.rb +9 -23
  56. data/spec/adapter_sdbm_spec.rb +9 -23
  57. data/spec/adapter_sequel_spec.rb +9 -23
  58. data/spec/adapter_sqlite_spec.rb +9 -23
  59. data/spec/adapter_tokyocabinet_bdb_spec.rb +13 -0
  60. data/spec/adapter_tokyocabinet_hdb_spec.rb +13 -0
  61. data/spec/adapter_yaml_spec.rb +12 -26
  62. data/spec/cache_file_memory_spec.rb +22 -43
  63. data/spec/cache_memory_null_spec.rb +13 -34
  64. data/spec/expires_file_spec.rb +56 -76
  65. data/spec/expires_memory_spec.rb +35 -54
  66. data/spec/generate.rb +147 -160
  67. data/spec/helper.rb +39 -0
  68. data/spec/junospecs.rb +612 -610
  69. data/spec/lock_spec.rb +31 -0
  70. data/spec/null_adapter_spec.rb +15 -29
  71. data/spec/proxy_expires_memory_spec.rb +37 -58
  72. data/spec/proxy_redis_spec.rb +13 -33
  73. data/spec/simple_activerecord_spec.rb +34 -48
  74. data/spec/simple_activerecord_with_expires_spec.rb +35 -49
  75. data/spec/simple_cassandra_spec.rb +35 -49
  76. data/spec/simple_couch_spec.rb +34 -48
  77. data/spec/simple_couch_with_expires_spec.rb +35 -49
  78. data/spec/simple_datamapper_spec.rb +34 -48
  79. data/spec/simple_datamapper_with_expires_spec.rb +35 -49
  80. data/spec/simple_datamapper_with_repository_spec.rb +34 -48
  81. data/spec/simple_dbm_spec.rb +34 -48
  82. data/spec/simple_dbm_with_expires_spec.rb +35 -49
  83. data/spec/simple_file_spec.rb +34 -48
  84. data/spec/simple_file_with_expires_spec.rb +35 -49
  85. data/spec/simple_fog_spec.rb +37 -54
  86. data/spec/simple_fog_with_expires_spec.rb +39 -57
  87. data/spec/simple_gdbm_spec.rb +34 -48
  88. data/spec/simple_gdbm_with_expires_spec.rb +35 -49
  89. data/spec/simple_hashfile_spec.rb +34 -48
  90. data/spec/simple_hashfile_with_expires_spec.rb +35 -49
  91. data/spec/simple_localmemcache_spec.rb +34 -48
  92. data/spec/simple_localmemcache_with_expires_spec.rb +35 -49
  93. data/spec/simple_lruhash_spec.rb +34 -48
  94. data/spec/simple_lruhash_with_expires_spec.rb +35 -49
  95. data/spec/simple_memcached_dalli_spec.rb +35 -49
  96. data/spec/simple_memcached_native_spec.rb +35 -49
  97. data/spec/simple_memcached_spec.rb +35 -49
  98. data/spec/simple_memory_spec.rb +34 -48
  99. data/spec/simple_memory_with_expires_spec.rb +35 -49
  100. data/spec/simple_mongo_spec.rb +34 -48
  101. data/spec/simple_mongo_with_expires_spec.rb +35 -49
  102. data/spec/simple_null_spec.rb +25 -39
  103. data/spec/simple_pstore_spec.rb +34 -48
  104. data/spec/simple_pstore_with_expires_spec.rb +35 -49
  105. data/spec/simple_redis_spec.rb +35 -49
  106. data/spec/simple_riak_spec.rb +34 -48
  107. data/spec/simple_riak_with_expires_spec.rb +35 -49
  108. data/spec/simple_sdbm_spec.rb +34 -48
  109. data/spec/simple_sdbm_with_expires_spec.rb +35 -49
  110. data/spec/simple_sequel_spec.rb +34 -48
  111. data/spec/simple_sequel_with_expires_spec.rb +35 -49
  112. data/spec/simple_sqlite_spec.rb +34 -48
  113. data/spec/simple_sqlite_with_expires_spec.rb +35 -49
  114. data/spec/simple_tokyocabinet_spec.rb +34 -48
  115. data/spec/simple_tokyocabinet_with_expires_spec.rb +35 -49
  116. data/spec/simple_yaml_spec.rb +34 -48
  117. data/spec/simple_yaml_with_expires_spec.rb +35 -49
  118. data/spec/stack_file_memory_spec.rb +15 -38
  119. data/spec/stack_memory_file_spec.rb +14 -37
  120. data/spec/transformer_bson_spec.rb +20 -39
  121. data/spec/transformer_compress_spec.rb +17 -36
  122. data/spec/transformer_json_spec.rb +20 -39
  123. data/spec/transformer_marshal_base64_spec.rb +36 -55
  124. data/spec/transformer_marshal_escape_spec.rb +36 -55
  125. data/spec/transformer_marshal_md5_spec.rb +36 -55
  126. data/spec/transformer_marshal_md5_spread_spec.rb +36 -55
  127. data/spec/transformer_msgpack_spec.rb +20 -39
  128. data/spec/transformer_ox_spec.rb +40 -0
  129. data/spec/transformer_yaml_spec.rb +35 -54
  130. metadata +11 -6
  131. data/spec/adapter_tokyocabinet_spec.rb +0 -27
  132. data/spec/simpl_memory_with_expires_spec.rb +0 -53
data/.travis.yml CHANGED
@@ -10,12 +10,10 @@ services:
10
10
  - couchdb
11
11
  - redis-server
12
12
  # - cassandra
13
- # - memcached
14
- # - mongodb
13
+ - memcached
14
+ - mongodb
15
15
  before_install:
16
16
  - sudo apt-get install -qq libtokyocabinet8 libtokyocabinet-dev # tokyotyrant
17
- - sudo /bin/bash /etc/init.d/mongodb start
18
- - memcached -d -p 22122
19
17
  env:
20
18
  - "TASK=test:parallel"
21
19
  - "TASK=test:non_parallel"
data/Gemfile CHANGED
@@ -17,7 +17,7 @@ gem 'dm-core'
17
17
  gem 'dm-migrations'
18
18
  gem 'dm-sqlite-adapter'
19
19
  gem 'fog'
20
- gem 'activerecord'
20
+ gem 'activerecord', '>= 3.2.9'
21
21
  gem 'redis'
22
22
  gem 'mongo'
23
23
  gem 'couchrest'
@@ -35,6 +35,8 @@ else
35
35
  gem 'tokyocabinet'
36
36
  gem 'memcached'
37
37
  gem 'sqlite3'
38
+ gem 'ox'
39
+ gem 'bson_ext'
38
40
  end
39
41
 
40
42
  #gem 'cassandra'
data/README.md CHANGED
@@ -7,7 +7,18 @@ Juno provides a standard interface for interacting with various kinds of key/val
7
7
  is based on Moneta and replaces it with a mostly compatible interface. The reason for the
8
8
  fork was that Moneta was unmaintained for a long time.
9
9
 
10
- Out of the box, it supports:
10
+ Juno is very feature rich:
11
+
12
+ * Supports for a lot of backends (See below)
13
+ * Supports proxies (Similar to [Rack middlewares](http://rack.rubyforge.org/))
14
+ * Custom serialization via `Juno::Transformer` proxy (Marshal/JSON/YAML and many more)
15
+ * Custom key transformation via `Juno::Transformer` proxy
16
+ * Expiration for all stores (Added via proxy if not supported natively)
17
+
18
+ Supported backends
19
+ ------------------
20
+
21
+ Out of the box, it supports the following backends:
11
22
 
12
23
  * Memory:
13
24
  * In-memory store (:Memory)
@@ -39,14 +50,27 @@ Out of the box, it supports:
39
50
  * Fog cloud storage which supports Amazon S3, Rackspace, etc. (:Fog)
40
51
  * Storage which doesn't store anything (:Null)
41
52
 
53
+ Supported serializers:
54
+
55
+ * Marshal
56
+ * YAML
57
+ * JSON (via multi_json)
58
+ * MessagePack
59
+ * BSON
60
+ * Ox
61
+
62
+ Proxies
63
+ -------
64
+
42
65
  In addition it supports proxies (Similar to [Rack middlewares](http://rack.rubyforge.org/)) which
43
66
  add additional features to storage backends:
44
67
 
45
- * Juno::Proxy proxy base class
46
- * Juno::Expires to add expiration support to stores which don't support it natively
47
- * Juno::Stack to stack multiple stores (Read returns result from first where the key is found, writes go to all stores)
48
- * Juno::Transformer transforms keys and values (Marshal, YAML, JSON, Base64, MD5, ...)
49
- * Juno::Cache combine two stores, one as backend and one as cache (e.g. Juno::Adapters::File + Juno::Adapters::Memory)
68
+ * `Juno::Proxy` proxy base class
69
+ * `Juno::Expires` to add expiration support to stores which don't support it natively
70
+ * `Juno::Stack` to stack multiple stores (Read returns result from first where the key is found, writes go to all stores)
71
+ * `Juno::Transformer` transforms keys and values (Marshal, YAML, JSON, Base64, MD5, ...)
72
+ * `Juno::Cache` combine two stores, one as backend and one as cache (e.g. Juno::Adapters::File + Juno::Adapters::Memory)
73
+ * `Juno::Lock` to make store thread safe
50
74
 
51
75
  The Juno API is purposely extremely similar to the Hash API. In order so support an
52
76
  identical API across stores, it does not support iteration or partial matches.
@@ -60,8 +84,8 @@ Links
60
84
  * Latest Gem: <http://rubydoc.info/gems/juno/frames>
61
85
  * GitHub master: <http://rubydoc.info/github/minad/juno/master/frames>
62
86
 
63
- Store API
64
- ---------
87
+ Juno API
88
+ --------
65
89
 
66
90
  ~~~
67
91
  #initialize(options) options differs per-store, and is used to set up the store
@@ -144,6 +168,14 @@ cache = Juno.build do
144
168
  end
145
169
  ~~~
146
170
 
171
+ Alternatives
172
+ ------------
173
+
174
+ * [Moneta](https://github.com/wycats/moneta): Juno is based on Moneta, but Juno supports more features and more backends and is actively developed
175
+ * [Horcrux](https://github.com/technoweenie/horcrux): Used at github, supports batch operations but only Memcached backend
176
+ * [ToyStore](https://github.com/jnunemaker/toystore): ORM mapper for key/value stores
177
+ * [ToyStore Adapter](https://github.com/jnunemaker/adapter): Adapter to key/value stores used by ToyStore, Juno can be used directly with the ToyStore Memory adapter
178
+
147
179
  Authors
148
180
  -------
149
181
 
data/benchmarks/run.rb CHANGED
@@ -1,9 +1,14 @@
1
1
  #!/usr/bin/env ruby
2
+
3
+ $: << File.join(File.dirname(__FILE__), '..', 'lib')
2
4
  require 'benchmark'
3
5
  require 'juno'
4
- require 'dm-core'
5
6
 
6
- DataMapper.setup(:default, :adapter => :in_memory)
7
+ begin
8
+ require 'dm-core'
9
+ DataMapper.setup(:default, :adapter => :in_memory)
10
+ rescue LoadError
11
+ end
7
12
 
8
13
  # Hacked arrays
9
14
  # Array modifications
@@ -37,7 +42,7 @@ stores = {
37
42
  :Redis => { },
38
43
  :MemcachedDalli => { :server => "localhost:11211", :namespace => 'juno_dalli' },
39
44
  :MemcachedNative => { :server => "localhost:11211", :namespace => 'juno_native' },
40
- #:MongoDB => { :host => 'localhost', :port => 27017, :db => 'juno_bench' },
45
+ :Mongo => { :host => 'localhost', :port => 27017, :db => 'juno_bench' },
41
46
  :LocalMemCache => { :file => "bench.lmc" },
42
47
  :DBM => { :file => "bench.dbm" },
43
48
  :SDBM => { :file => "bench.sdbm" },
@@ -51,7 +56,7 @@ stores = {
51
56
  :DataMapper => { :setup => "sqlite3::memory:" },
52
57
  :ActiveRecord => { :connection => { :adapter => 'sqlite3', :database => ':memory:' } },
53
58
  :Sequel => { :db => "sqlite:/" },
54
- # :Couch => {:db => "couch_test"},
59
+ :Couch => {:db => "couch_test"},
55
60
  }
56
61
 
57
62
  stats, keys, data, errors, summary = {}, [], HackedArray.new, HackedArray.new, HackedArray.new
@@ -93,10 +98,17 @@ puts "Lenght Stats % 10i % 10i % 10i % 10i " % [vlen_min, vlen_max, vlen_ttl,
93
98
 
94
99
 
95
100
  stores.each do |name, options|
101
+ begin
102
+ @cache = Juno.new(name, options)
103
+ @cache['test'] = 'test'
104
+ @cache.clear
105
+ rescue Exception => ex
106
+ puts "#{name} not benchmarked - #{ex.message}"
107
+ next
108
+ end
96
109
  puts "======================================================================"
97
110
  puts name
98
111
  puts "----------------------------------------------------------------------"
99
- @cache = Juno.new(name, options)
100
112
  stats[name] = {
101
113
  :writes => [],
102
114
  :reads => [],
@@ -2,6 +2,8 @@ require 'active_record'
2
2
 
3
3
  module Juno
4
4
  module Adapters
5
+ # ActiveRecord as key/value stores
6
+ # @api public
5
7
  class ActiveRecord < Base
6
8
  def self.tables
7
9
  @tables ||= {}
@@ -9,18 +11,28 @@ module Juno
9
11
 
10
12
  attr_reader :table
11
13
 
14
+ # Constructor
15
+ #
16
+ # @param [Hash] options
17
+ #
18
+ # Options:
19
+ # * :table - Table name (default juno)
20
+ # * :connection - ActiveRecord connection
12
21
  def initialize(options = {})
13
22
  table = options[:table] || 'juno'
14
- @table = self.class.tables[table] ||= begin
15
- c = Class.new(::ActiveRecord::Base)
16
- c.table_name = table
17
- c
18
- end
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
19
30
  @table.establish_connection(options[:connection]) if options[:connection]
20
31
  unless @table.table_exists?
21
- @table.connection.create_table(@table.table_name) do |t|
22
- t.binary :k, :null => false
23
- t.binary :v
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
24
36
  end
25
37
  @table.connection.add_index(@table.table_name, :k, :unique => true)
26
38
  end
@@ -39,19 +51,16 @@ module Juno
39
51
  @table.transaction do
40
52
  record = @table.find_by_k(key)
41
53
  if record
42
- value = record.v
43
54
  record.destroy
44
- value
55
+ record.v
45
56
  end
46
57
  end
47
58
  end
48
59
 
49
60
  def store(key, value, options = {})
50
61
  @table.transaction do
51
- record = @table.find_by_k(key)
52
- record ||= @table.new(:k => key)
53
- record.v = value
54
- record.save!
62
+ record = @table.find_or_initialize_by_k(key)
63
+ record.update_attributes(:v => value)
55
64
  value
56
65
  end
57
66
  end
@@ -5,7 +5,18 @@ require 'cassandra'
5
5
 
6
6
  module Juno
7
7
  module Adapters
8
+ # Cassandra backend
9
+ # @api public
8
10
  class Cassandra < Base
11
+ # Constructor
12
+ #
13
+ # @param [Hash] options
14
+ #
15
+ # Options:
16
+ # * :keyspace - Cassandra keyspace (default Juno)
17
+ # * :column_family - Cassandra column family (default :Juno)
18
+ # * :host - Server host name (default 127.0.0.1)
19
+ # * :port - Server port (default 9160)
9
20
  def initialize(options = {})
10
21
  options[:keyspace] ||= 'Juno'
11
22
  options[:host] ||= '127.0.0.1'
@@ -2,8 +2,17 @@ require 'couchrest'
2
2
 
3
3
  module Juno
4
4
  module Adapters
5
+ # CouchDB backend
6
+ # @api public
5
7
  class Couch < Base
8
+ # Constructor
9
+ #
10
+ # @param [Hash] options
11
+ #
12
+ # Options:
13
+ # * :db - Couch database
6
14
  def initialize(options = {})
15
+ raise 'No option :db specified' unless options[:db]
7
16
  @db = ::CouchRest.database!(options[:db])
8
17
  end
9
18
 
@@ -3,6 +3,8 @@ require 'dm-migrations'
3
3
 
4
4
  module Juno
5
5
  module Adapters
6
+ # Datamapper backend
7
+ # @api public
6
8
  class DataMapper < Base
7
9
  class Store
8
10
  include ::DataMapper::Resource
@@ -10,6 +12,14 @@ module Juno
10
12
  property :v, Object, :lazy => false
11
13
  end
12
14
 
15
+ # Constructor
16
+ #
17
+ # @param [Hash] options
18
+ #
19
+ # Options:
20
+ # * :setup - Datamapper setup string
21
+ # * :repository - Repository name (default :juno)
22
+ # * :table - Table name (default :juno)
13
23
  def initialize(options = {})
14
24
  raise 'No option :setup specified' unless options[:setup]
15
25
  @repository = options.delete(:repository) || :juno
@@ -2,7 +2,15 @@ require 'dbm'
2
2
 
3
3
  module Juno
4
4
  module Adapters
5
+ # DBM backend (Berkeley DB)
6
+ # @api public
5
7
  class DBM < Memory
8
+ # Constructor
9
+ #
10
+ # @param [Hash] options
11
+ #
12
+ # Options:
13
+ # * :file - Database file
6
14
  def initialize(options = {})
7
15
  raise 'No option :file specified' unless options[:file]
8
16
  @memory = ::DBM.new(options[:file])
@@ -2,6 +2,8 @@ require 'fileutils'
2
2
 
3
3
  module Juno
4
4
  module Adapters
5
+ # Filesystem backend
6
+ # @api public
5
7
  class File < Base
6
8
  def initialize(options = {})
7
9
  raise 'No option :dir specified' unless @dir = options[:dir]
@@ -2,7 +2,16 @@ require 'fog'
2
2
 
3
3
  module Juno
4
4
  module Adapters
5
+ # Fog backend (Cloud storage services)
6
+ # @api public
5
7
  class Fog < Base
8
+ # Constructor
9
+ #
10
+ # @param [Hash] options
11
+ #
12
+ # Options:
13
+ # * :dir - Fog directory
14
+ # * Other options passed to Fog::Storage#new
6
15
  def initialize(options = {})
7
16
  raise 'No option :dir specified' unless dir = options.delete(:dir)
8
17
  storage = ::Fog::Storage.new(options)
@@ -2,7 +2,15 @@ require 'gdbm'
2
2
 
3
3
  module Juno
4
4
  module Adapters
5
+ # GDBM backend
6
+ # @api public
5
7
  class GDBM < Memory
8
+ # Constructor
9
+ #
10
+ # @param [Hash] options
11
+ #
12
+ # Options:
13
+ # * :file - Database file
6
14
  def initialize(options = {})
7
15
  raise 'No option :file specified' unless options[:file]
8
16
  @memory = ::GDBM.new(options[:file])
@@ -2,7 +2,15 @@ require 'localmemcache'
2
2
 
3
3
  module Juno
4
4
  module Adapters
5
+ # LocalMemCache backend
6
+ # @api public
5
7
  class LocalMemCache < Memory
8
+ # Constructor
9
+ #
10
+ # @param [Hash] options
11
+ #
12
+ # Options:
13
+ # * :file - Database file
6
14
  def initialize(options = {})
7
15
  raise 'No option :file specified' unless options[:file]
8
16
  @memory = ::LocalMemCache.new(:filename => options[:file])
@@ -2,7 +2,15 @@ require 'hashery/lru_hash'
2
2
 
3
3
  module Juno
4
4
  module Adapters
5
+ # LRUHash backend
6
+ # @api public
5
7
  class LRUHash < Memory
8
+ # Constructor
9
+ #
10
+ # @param [Hash] options
11
+ #
12
+ # Options:
13
+ # * :max_size - Maximum size of hash (default 1024)
6
14
  def initialize(options = {})
7
15
  @memory = Hashery::LRUHash.new(options[:max_size] || 1024)
8
16
  end
@@ -2,7 +2,16 @@ require 'dalli'
2
2
 
3
3
  module Juno
4
4
  module Adapters
5
+ # Memcached backend (using gem dalli)
6
+ # @api public
5
7
  class MemcachedDalli < Base
8
+ # Constructor
9
+ #
10
+ # @param [Hash] options
11
+ #
12
+ # Options:
13
+ # * :server - Memcached server (default localhost:11211)
14
+ # * Other options passed to Dalli::Client#new
6
15
  def initialize(options = {})
7
16
  server = options.delete(:server) || 'localhost:11211'
8
17
  @cache = ::Dalli::Client.new(server, options)
@@ -2,7 +2,17 @@ require 'memcached'
2
2
 
3
3
  module Juno
4
4
  module Adapters
5
+ # Memcached backend (using gem memcached)
6
+ # @api public
5
7
  class MemcachedNative < Base
8
+ # Constructor
9
+ #
10
+ # @param [Hash] options
11
+ #
12
+ # Options:
13
+ # * :server - Memcached server (default localhost:11211)
14
+ # * :namespace - Key namespace
15
+ # * Other options passed to Memcached#new
6
16
  def initialize(options = {})
7
17
  server = options.delete(:server) || 'localhost:11211'
8
18
  options.merge!(:prefix_key => options.delete(:namespace)) if options[:namespace]
@@ -1,5 +1,7 @@
1
1
  module Juno
2
2
  module Adapters
3
+ # Memory backend using a hash to store the entries
4
+ # @api public
3
5
  class Memory < Base
4
6
  def initialize(options = {})
5
7
  @memory = {}
@@ -2,7 +2,18 @@ require 'mongo'
2
2
 
3
3
  module Juno
4
4
  module Adapters
5
+ # MongoDB backend
6
+ # @api public
5
7
  class Mongo < Base
8
+ # Constructor
9
+ #
10
+ # @param [Hash] options
11
+ #
12
+ # Options:
13
+ # * :collection - MongoDB collection name (default juno)
14
+ # * :host - MongoDB server host (default localhost)
15
+ # * :port - MongoDB server port (default mongodb default port)
16
+ # * :db - MongoDB database (default juno)
6
17
  def initialize(options = {})
7
18
  collection = options.delete(:collection) || 'juno'
8
19
  host = options.delete(:host) || 'localhost'
@@ -1,5 +1,7 @@
1
1
  module Juno
2
2
  module Adapters
3
+ # Null backend which doesn't store anything
4
+ # @api public
3
5
  class Null < Base
4
6
  def initialize(options = {})
5
7
  end
@@ -2,7 +2,15 @@ require 'pstore'
2
2
 
3
3
  module Juno
4
4
  module Adapters
5
+ # PStore backend
6
+ # @api public
5
7
  class PStore < Base
8
+ # Constructor
9
+ #
10
+ # @param [Hash] options
11
+ #
12
+ # Options:
13
+ # * :file - PStore file
6
14
  def initialize(options = {})
7
15
  raise 'No option :file specified' unless options[:file]
8
16
  FileUtils.mkpath(::File.dirname(options[:file]))
@@ -38,8 +46,7 @@ module Juno
38
46
 
39
47
  if RUBY_VERSION > '1.9'
40
48
  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)
49
+ ::PStore.new(options[:file], options[:threadsafe])
43
50
  end
44
51
  else
45
52
  def new_store(options)
@@ -2,7 +2,12 @@ require 'redis'
2
2
 
3
3
  module Juno
4
4
  module Adapters
5
+ # Redis backend
6
+ # @api public
5
7
  class Redis < Base
8
+ # Constructor
9
+ #
10
+ # @param [Hash] options passed to Redis#new
6
11
  def initialize(options = {})
7
12
  @redis = ::Redis.new(options)
8
13
  end
@@ -5,7 +5,16 @@ require 'riak'
5
5
 
6
6
  module Juno
7
7
  module Adapters
8
+ # Riak backend
9
+ # @api public
8
10
  class Riak < Base
11
+ # Constructor
12
+ #
13
+ # @param [Hash] options
14
+ #
15
+ # Options:
16
+ # * :bucket - Bucket name (default juno)
17
+ # * All other options passed to Riak::Client#new
9
18
  def initialize(options = {})
10
19
  bucket = options.delete(:bucket) || 'juno'
11
20
  @bucket = ::Riak::Client.new(options).bucket(bucket)
@@ -2,7 +2,15 @@ require 'sdbm'
2
2
 
3
3
  module Juno
4
4
  module Adapters
5
+ # SDBM backend
6
+ # @api public
5
7
  class SDBM < Memory
8
+ # Constructor
9
+ #
10
+ # @param [Hash] options
11
+ #
12
+ # Options:
13
+ # * :file - Database file
6
14
  def initialize(options = {})
7
15
  raise 'No option :file specified' unless options[:file]
8
16
  @memory = ::SDBM.new(options[:file])
@@ -2,7 +2,17 @@ require 'sequel'
2
2
 
3
3
  module Juno
4
4
  module Adapters
5
+ # Sequel backend
6
+ # @api public
5
7
  class Sequel < Base
8
+ # Constructor
9
+ #
10
+ # @param [Hash] options
11
+ #
12
+ # Options:
13
+ # * :db - Sequel database
14
+ # * :table - Table name (default :juno)
15
+ # * All other options passed to Sequel#connect
6
16
  def initialize(options = {})
7
17
  raise 'No option :db specified' unless db = options.delete(:db)
8
18
  @table = options.delete(:table) || :juno
@@ -2,7 +2,16 @@ require 'sqlite3'
2
2
 
3
3
  module Juno
4
4
  module Adapters
5
+ # Sqlite3 backend
6
+ # @api public
5
7
  class Sqlite < Base
8
+ # Constructor
9
+ #
10
+ # @param [Hash] options
11
+ #
12
+ # Options:
13
+ # * :file - Database file
14
+ # * :table - Table name (default juno)
6
15
  def initialize(options = {})
7
16
  raise 'No option :file specified' unless options[:file]
8
17
  table = options[:table] || 'juno'
@@ -2,14 +2,26 @@ require 'tokyocabinet'
2
2
 
3
3
  module Juno
4
4
  module Adapters
5
+ # TokyoCabinet backend
6
+ # @api public
5
7
  class TokyoCabinet < Memory
8
+ # Constructor
9
+ #
10
+ # @param [Hash] options
11
+ #
12
+ # Options:
13
+ # * :file - Database file
14
+ # * :type - Database type (default :hdb, :bdb and :hdb possible)
6
15
  def initialize(options = {})
7
16
  file = options[:file]
8
17
  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
18
+ if options[:type] == :bdb
19
+ @memory = ::TokyoCabinet::BDB.new
20
+ @memory.open(file, ::TokyoCabinet::BDB::OWRITER | ::TokyoCabinet::BDB::OCREAT)
21
+ else
22
+ @memory = ::TokyoCabinet::HDB.new
23
+ @memory.open(file, ::TokyoCabinet::HDB::OWRITER | ::TokyoCabinet::HDB::OCREAT)
24
+ end or raise @memory.errmsg(@memory.ecode)
13
25
  end
14
26
 
15
27
  def key?(key, options = {})
@@ -2,6 +2,8 @@ require 'yaml/store'
2
2
 
3
3
  module Juno
4
4
  module Adapters
5
+ # YAML::Store backend
6
+ # @api public
5
7
  class YAML < Juno::Adapters::PStore
6
8
  protected
7
9
 
data/lib/juno/base.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  module Juno
2
2
  # Simple interface to key/value stores with Hash-like interface.
3
+ # @api public
3
4
  class Base
4
5
  # Explicitly close the store
5
6
  # @api public
data/lib/juno/builder.rb CHANGED
@@ -1,4 +1,6 @@
1
1
  module Juno
2
+ # Builder implements the DSL to build a chain of store proxies
3
+ # @api private
2
4
  class Builder
3
5
  def build
4
6
  klass, options, block = @proxies.first
data/lib/juno/cache.rb CHANGED
@@ -9,6 +9,8 @@ module Juno
9
9
  # cache { adapter :Memory }
10
10
  # end
11
11
  # end
12
+ #
13
+ # @api public
12
14
  class Cache < Base
13
15
  class DSL
14
16
  def initialize(options, &block)
data/lib/juno/expires.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  module Juno
2
2
  # Adds expiration support to the underlying store
3
+ # @api public
3
4
  class Expires < Proxy
4
5
  def key?(key, options = {})
5
6
  !!load(key, options)