juno 0.2.5 → 0.2.6

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 (130) hide show
  1. data/.travis.yml +5 -1
  2. data/Gemfile +27 -21
  3. data/README.md +41 -2
  4. data/Rakefile +3 -3
  5. data/juno.gemspec +12 -12
  6. data/lib/juno.rb +4 -4
  7. data/lib/juno/adapters/couch.rb +1 -1
  8. data/lib/juno/adapters/datamapper.rb +1 -1
  9. data/lib/juno/adapters/dbm.rb +1 -1
  10. data/lib/juno/adapters/file.rb +1 -1
  11. data/lib/juno/adapters/fog.rb +1 -1
  12. data/lib/juno/adapters/gdbm.rb +1 -1
  13. data/lib/juno/adapters/localmemcache.rb +1 -1
  14. data/lib/juno/adapters/pstore.rb +1 -1
  15. data/lib/juno/adapters/redis.rb +3 -2
  16. data/lib/juno/adapters/sdbm.rb +1 -1
  17. data/lib/juno/adapters/sequel.rb +1 -1
  18. data/lib/juno/adapters/sqlite.rb +1 -1
  19. data/lib/juno/adapters/tokyocabinet.rb +1 -1
  20. data/lib/juno/builder.rb +10 -0
  21. data/lib/juno/cache.rb +1 -0
  22. data/lib/juno/expires.rb +1 -1
  23. data/lib/juno/proxy.rb +2 -0
  24. data/lib/juno/stack.rb +1 -0
  25. data/lib/juno/transformer.rb +34 -18
  26. data/lib/juno/version.rb +1 -1
  27. data/lib/rack/cache/juno.rb +93 -0
  28. data/lib/rack/session/juno.rb +63 -0
  29. data/spec/generate.rb +41 -2
  30. data/spec/{adapter_activerecord_spec.rb → juno/adapter_activerecord_spec.rb} +0 -0
  31. data/spec/{adapter_cassandra_spec.rb → juno/adapter_cassandra_spec.rb} +0 -0
  32. data/spec/{adapter_couch_spec.rb → juno/adapter_couch_spec.rb} +0 -0
  33. data/spec/{adapter_datamapper_spec.rb → juno/adapter_datamapper_spec.rb} +0 -0
  34. data/spec/{adapter_dbm_spec.rb → juno/adapter_dbm_spec.rb} +0 -0
  35. data/spec/{adapter_file_spec.rb → juno/adapter_file_spec.rb} +0 -0
  36. data/spec/{adapter_fog_spec.rb → juno/adapter_fog_spec.rb} +0 -0
  37. data/spec/{adapter_gdbm_spec.rb → juno/adapter_gdbm_spec.rb} +0 -0
  38. data/spec/{adapter_localmemcache_spec.rb → juno/adapter_localmemcache_spec.rb} +0 -0
  39. data/spec/{adapter_lruhash_spec.rb → juno/adapter_lruhash_spec.rb} +0 -0
  40. data/spec/{adapter_memcached_dalli_spec.rb → juno/adapter_memcached_dalli_spec.rb} +0 -0
  41. data/spec/{adapter_memcached_native_spec.rb → juno/adapter_memcached_native_spec.rb} +0 -0
  42. data/spec/{adapter_memcached_spec.rb → juno/adapter_memcached_spec.rb} +0 -0
  43. data/spec/{adapter_memory_spec.rb → juno/adapter_memory_spec.rb} +0 -0
  44. data/spec/{adapter_mongo_spec.rb → juno/adapter_mongo_spec.rb} +0 -0
  45. data/spec/{adapter_pstore_spec.rb → juno/adapter_pstore_spec.rb} +0 -0
  46. data/spec/{adapter_redis_spec.rb → juno/adapter_redis_spec.rb} +0 -0
  47. data/spec/{adapter_riak_spec.rb → juno/adapter_riak_spec.rb} +0 -0
  48. data/spec/{adapter_sdbm_spec.rb → juno/adapter_sdbm_spec.rb} +0 -0
  49. data/spec/{adapter_sequel_spec.rb → juno/adapter_sequel_spec.rb} +0 -0
  50. data/spec/{adapter_sqlite_spec.rb → juno/adapter_sqlite_spec.rb} +0 -0
  51. data/spec/{adapter_tokyocabinet_bdb_spec.rb → juno/adapter_tokyocabinet_bdb_spec.rb} +0 -0
  52. data/spec/{adapter_tokyocabinet_hdb_spec.rb → juno/adapter_tokyocabinet_hdb_spec.rb} +0 -0
  53. data/spec/{adapter_yaml_spec.rb → juno/adapter_yaml_spec.rb} +0 -0
  54. data/spec/{cache_file_memory_spec.rb → juno/cache_file_memory_spec.rb} +0 -0
  55. data/spec/{cache_memory_null_spec.rb → juno/cache_memory_null_spec.rb} +0 -0
  56. data/spec/{expires_file_spec.rb → juno/expires_file_spec.rb} +0 -0
  57. data/spec/{expires_memory_spec.rb → juno/expires_memory_spec.rb} +0 -0
  58. data/spec/{lock_spec.rb → juno/lock_spec.rb} +0 -0
  59. data/spec/{null_adapter_spec.rb → juno/null_adapter_spec.rb} +0 -0
  60. data/spec/{proxy_expires_memory_spec.rb → juno/proxy_expires_memory_spec.rb} +0 -0
  61. data/spec/{proxy_redis_spec.rb → juno/proxy_redis_spec.rb} +0 -0
  62. data/spec/{simple_activerecord_spec.rb → juno/simple_activerecord_spec.rb} +0 -0
  63. data/spec/{simple_activerecord_with_expires_spec.rb → juno/simple_activerecord_with_expires_spec.rb} +0 -0
  64. data/spec/{simple_cassandra_spec.rb → juno/simple_cassandra_spec.rb} +0 -0
  65. data/spec/{simple_couch_spec.rb → juno/simple_couch_spec.rb} +0 -0
  66. data/spec/{simple_couch_with_expires_spec.rb → juno/simple_couch_with_expires_spec.rb} +0 -0
  67. data/spec/{simple_datamapper_spec.rb → juno/simple_datamapper_spec.rb} +0 -0
  68. data/spec/{simple_datamapper_with_expires_spec.rb → juno/simple_datamapper_with_expires_spec.rb} +0 -0
  69. data/spec/{simple_datamapper_with_repository_spec.rb → juno/simple_datamapper_with_repository_spec.rb} +0 -0
  70. data/spec/{simple_dbm_spec.rb → juno/simple_dbm_spec.rb} +0 -0
  71. data/spec/{simple_dbm_with_expires_spec.rb → juno/simple_dbm_with_expires_spec.rb} +0 -0
  72. data/spec/{simple_file_spec.rb → juno/simple_file_spec.rb} +0 -0
  73. data/spec/{simple_file_with_expires_spec.rb → juno/simple_file_with_expires_spec.rb} +0 -0
  74. data/spec/{simple_fog_spec.rb → juno/simple_fog_spec.rb} +0 -0
  75. data/spec/{simple_fog_with_expires_spec.rb → juno/simple_fog_with_expires_spec.rb} +0 -0
  76. data/spec/{simple_gdbm_spec.rb → juno/simple_gdbm_spec.rb} +0 -0
  77. data/spec/{simple_gdbm_with_expires_spec.rb → juno/simple_gdbm_with_expires_spec.rb} +0 -0
  78. data/spec/{simple_hashfile_spec.rb → juno/simple_hashfile_spec.rb} +0 -0
  79. data/spec/{simple_hashfile_with_expires_spec.rb → juno/simple_hashfile_with_expires_spec.rb} +0 -0
  80. data/spec/{simple_localmemcache_spec.rb → juno/simple_localmemcache_spec.rb} +0 -0
  81. data/spec/{simple_localmemcache_with_expires_spec.rb → juno/simple_localmemcache_with_expires_spec.rb} +0 -0
  82. data/spec/{simple_lruhash_spec.rb → juno/simple_lruhash_spec.rb} +0 -0
  83. data/spec/{simple_lruhash_with_expires_spec.rb → juno/simple_lruhash_with_expires_spec.rb} +0 -0
  84. data/spec/{simple_memcached_dalli_spec.rb → juno/simple_memcached_dalli_spec.rb} +0 -0
  85. data/spec/{simple_memcached_native_spec.rb → juno/simple_memcached_native_spec.rb} +0 -0
  86. data/spec/{simple_memcached_spec.rb → juno/simple_memcached_spec.rb} +0 -0
  87. data/spec/{simple_memory_spec.rb → juno/simple_memory_spec.rb} +0 -0
  88. data/spec/{simple_memory_with_expires_spec.rb → juno/simple_memory_with_expires_spec.rb} +0 -0
  89. data/spec/{simple_mongo_spec.rb → juno/simple_mongo_spec.rb} +0 -0
  90. data/spec/{simple_mongo_with_expires_spec.rb → juno/simple_mongo_with_expires_spec.rb} +0 -0
  91. data/spec/{simple_null_spec.rb → juno/simple_null_spec.rb} +0 -0
  92. data/spec/{simple_pstore_spec.rb → juno/simple_pstore_spec.rb} +0 -0
  93. data/spec/{simple_pstore_with_expires_spec.rb → juno/simple_pstore_with_expires_spec.rb} +0 -0
  94. data/spec/{simple_redis_spec.rb → juno/simple_redis_spec.rb} +0 -0
  95. data/spec/{simple_riak_spec.rb → juno/simple_riak_spec.rb} +0 -0
  96. data/spec/{simple_riak_with_expires_spec.rb → juno/simple_riak_with_expires_spec.rb} +0 -0
  97. data/spec/{simple_sdbm_spec.rb → juno/simple_sdbm_spec.rb} +0 -0
  98. data/spec/{simple_sdbm_with_expires_spec.rb → juno/simple_sdbm_with_expires_spec.rb} +0 -0
  99. data/spec/{simple_sequel_spec.rb → juno/simple_sequel_spec.rb} +0 -0
  100. data/spec/{simple_sequel_with_expires_spec.rb → juno/simple_sequel_with_expires_spec.rb} +0 -0
  101. data/spec/{simple_sqlite_spec.rb → juno/simple_sqlite_spec.rb} +0 -0
  102. data/spec/{simple_sqlite_with_expires_spec.rb → juno/simple_sqlite_with_expires_spec.rb} +0 -0
  103. data/spec/{simple_tokyocabinet_spec.rb → juno/simple_tokyocabinet_spec.rb} +0 -0
  104. data/spec/{simple_tokyocabinet_with_expires_spec.rb → juno/simple_tokyocabinet_with_expires_spec.rb} +0 -0
  105. data/spec/{simple_yaml_spec.rb → juno/simple_yaml_spec.rb} +0 -0
  106. data/spec/{simple_yaml_with_expires_spec.rb → juno/simple_yaml_with_expires_spec.rb} +0 -0
  107. data/spec/{stack_file_memory_spec.rb → juno/stack_file_memory_spec.rb} +0 -0
  108. data/spec/{stack_memory_file_spec.rb → juno/stack_memory_file_spec.rb} +0 -0
  109. data/spec/{transformer_bencode_spec.rb → juno/transformer_bencode_spec.rb} +0 -0
  110. data/spec/{transformer_bert_spec.rb → juno/transformer_bert_spec.rb} +0 -0
  111. data/spec/{transformer_bson_spec.rb → juno/transformer_bson_spec.rb} +0 -0
  112. data/spec/{transformer_compress_spec.rb → juno/transformer_compress_spec.rb} +0 -0
  113. data/spec/{transformer_json_spec.rb → juno/transformer_json_spec.rb} +0 -0
  114. data/spec/juno/transformer_lzma_spec.rb +22 -0
  115. data/spec/juno/transformer_lzo_spec.rb +22 -0
  116. data/spec/{transformer_marshal_base64_spec.rb → juno/transformer_marshal_base64_spec.rb} +0 -0
  117. data/spec/{transformer_marshal_escape_spec.rb → juno/transformer_marshal_escape_spec.rb} +0 -0
  118. data/spec/{transformer_marshal_md5_spec.rb → juno/transformer_marshal_md5_spec.rb} +0 -0
  119. data/spec/{transformer_marshal_md5_spread_spec.rb → juno/transformer_marshal_md5_spread_spec.rb} +0 -0
  120. data/spec/juno/transformer_marshal_prefix_spec.rb +41 -0
  121. data/spec/{transformer_marshal_uuencode_spec.rb → juno/transformer_marshal_uuencode_spec.rb} +0 -0
  122. data/spec/{transformer_msgpack_spec.rb → juno/transformer_msgpack_spec.rb} +0 -0
  123. data/spec/{transformer_ox_spec.rb → juno/transformer_ox_spec.rb} +0 -0
  124. data/spec/juno/transformer_quicklz_spec.rb +22 -0
  125. data/spec/juno/transformer_snappy_spec.rb +22 -0
  126. data/spec/{transformer_tnet_spec.rb → juno/transformer_tnet_spec.rb} +0 -0
  127. data/spec/{transformer_yaml_spec.rb → juno/transformer_yaml_spec.rb} +0 -0
  128. data/spec/rack/cache_juno_spec.rb +355 -0
  129. data/spec/rack/session_juno_spec.rb +305 -0
  130. metadata +206 -190
data/.travis.yml CHANGED
@@ -13,7 +13,7 @@ services:
13
13
  - memcached
14
14
  - mongodb
15
15
  before_install:
16
- - sudo apt-get install -qq libtokyocabinet8 libtokyocabinet-dev # tokyotyrant
16
+ - sudo apt-get install -qq libtokyocabinet8 libtokyocabinet-dev liblzo2-dev
17
17
  env:
18
18
  - "TASK=test:parallel"
19
19
  - "TASK=test:non_parallel"
@@ -23,4 +23,8 @@ matrix:
23
23
  - rvm: jruby
24
24
  - rvm: rbx-18mode
25
25
  - rvm: rbx-19mode
26
+ # Parallel tests do not work on jruby
27
+ exclude:
28
+ - rvm: jruby
29
+ env: "TASK=test:parallel"
26
30
  script: "bundle exec rake $TASK"
data/Gemfile CHANGED
@@ -1,17 +1,33 @@
1
1
  source :rubygems
2
2
  gemspec
3
3
 
4
+ def alternatives(gems)
5
+ if defined?(JRUBY_VERSION)
6
+ [gems[:jruby]].flatten.compact.each {|g| gem g }
7
+ else
8
+ [gems[:mri]].flatten.compact.each {|g| gem g }
9
+ end
10
+ end
11
+
4
12
  # Testing
5
13
  gem 'rake'
6
14
  gem 'rspec'
7
15
  gem 'parallel_tests'
8
16
 
9
- # Serializer
17
+ # Serializer used by Transformer
10
18
  gem 'tnetstring'
11
- gem 'bert'
12
19
  gem 'bencode'
13
- gem 'bson'
14
20
  gem 'multi_json'
21
+ alternatives :mri => 'bson_ext', :jruby => 'bson'
22
+ alternatives :mri => 'ox'
23
+ alternatives :mri => 'msgpack', :jruby => 'msgpack-jruby'
24
+ alternatives :mri => 'bert'
25
+
26
+ # Compressors used by Transformer
27
+ alternatives :mri => 'ruby-lzma'
28
+ alternatives :mri => 'qlzruby'
29
+ alternatives :mri => 'lzoruby'
30
+ alternatives :mri => 'snappy'
15
31
 
16
32
  # Backends
17
33
  gem 'dm-core'
@@ -26,23 +42,13 @@ gem 'sequel'
26
42
  gem 'dalli'
27
43
  gem 'riak-client'
28
44
  gem 'hashery'
29
-
30
- if defined?(JRUBY_VERSION)
31
- gem 'msgpack-jruby'
32
- gem 'jdbc-sqlite3'
33
- gem 'activerecord-jdbc-adapter'
34
- gem 'activerecord-jdbcsqlite3-adapter'
35
- gem 'jruby-memcached'
36
- gem 'ffi' # gdbm for jruby needs ffi
37
- gem 'gdbm'
38
- else
39
- gem 'msgpack'
40
- gem 'tokyocabinet'
41
- gem 'memcached'
42
- gem 'sqlite3'
43
- gem 'ox'
44
- gem 'bson_ext'
45
- end
46
-
47
45
  #gem 'cassandra'
48
46
  #gem 'localmemcache'
47
+ alternatives :mri => 'tokyocabinet'
48
+ alternatives :mri => 'memcached', :jruby => 'jruby-memcached'
49
+ alternatives :mri => 'sqlite3', :jruby => %w(jdbc-sqlite3 activerecord-jdbc-adapter activerecord-jdbcsqlite3-adapter)
50
+ alternatives :jruby => %w(ffi gdbm) # gdbm for jruby needs ffi
51
+
52
+ # Integration
53
+ gem 'rack'
54
+ gem 'rack-cache'
data/README.md CHANGED
@@ -13,6 +13,7 @@ Juno is very feature rich:
13
13
  * Supports proxies (Similar to [Rack middlewares](http://rack.github.com/))
14
14
  * Custom serialization via `Juno::Transformer` proxy (Marshal/JSON/YAML and many more)
15
15
  * Custom key transformation via `Juno::Transformer` proxy
16
+ * Value compression via `Juno::Transformer` proxy (Zlib, Snappy, QuickLZ, LZO)
16
17
  * Expiration for all stores (Added via proxy if not supported natively)
17
18
 
18
19
  Supported backends
@@ -130,8 +131,8 @@ If you want to have control over the proxies, you have to use `Juno.build`:
130
131
  store = Juno.build do
131
132
  # Adds expires proxy
132
133
  use :Expires
133
- # Transform key and value using Marshal
134
- use :Transformer, :key => :marshal, :value => :marshal
134
+ # Transform key using Marshal and Base64 and value using Marshal
135
+ use :Transformer, :key => [:marshal, :base64], :value => :marshal
135
136
  # Memory backend
136
137
  adapter :Memory
137
138
  end
@@ -170,6 +171,44 @@ cache = Juno.build do
170
171
  end
171
172
  ~~~
172
173
 
174
+ Framework Integration
175
+ ---------------------
176
+
177
+ Inspired by [redis-store](https://github.com/jodosha/redis-store) there exist integration classes for Rack and Rack-Cache.
178
+
179
+ Use Juno as a Rack session store:
180
+
181
+ ~~~ ruby
182
+ require 'rack/session/juno'
183
+
184
+ use Rack::Session::Juno, :store => :Redis
185
+ use Rack::Session::Juno, :store => Juno.new(:Memory, :expires => true)
186
+
187
+ use Rack::Session::Juno do
188
+ use :Expires
189
+ adapter :Memory
190
+ end
191
+ ~~~
192
+
193
+ Use Juno as a Rack-Cache store:
194
+
195
+ ~~~ ruby
196
+ require 'rack/cache/juno'
197
+
198
+ use Rack::Cache,
199
+ :metastore => 'juno://Memory?expires=true',
200
+ :entitystore => 'juno://Memory?expires=true'
201
+
202
+ # Or used named Juno stores
203
+ Rack::Cache::Juno['named_metastore'] = Juno.build do
204
+ use :Expires
205
+ adapter :Memory
206
+ end
207
+ use Rack::Cache,
208
+ :metastore => 'juno://named_metastore',
209
+ :entity_store => 'juno://named_entitystore'
210
+ ~~~
211
+
173
212
  Alternatives
174
213
  ------------
175
214
 
data/Rakefile CHANGED
@@ -14,7 +14,7 @@ namespace :test do
14
14
  if defined?(JRUBY_VERSION)
15
15
  puts 'No tests executed in parallel in JRuby'
16
16
  else
17
- specs = Dir['spec/*_spec.rb'].reject {|s| s =~ /memcached|redis/ }
17
+ specs = Dir['spec/*/*_spec.rb'].reject {|s| s =~ /memcached|redis/ }
18
18
  sh("parallel_rspec -m 15 #{specs.join(' ')}")
19
19
  end
20
20
  end
@@ -22,9 +22,9 @@ namespace :test do
22
22
  task :non_parallel do
23
23
  if defined?(JRUBY_VERSION)
24
24
  # Run all tests in jruby non-parallel
25
- sh('rspec spec/*_spec.rb')
25
+ sh('rspec spec/*/*_spec.rb')
26
26
  else
27
- specs = Dir['spec/*_spec.rb'].select {|s| s =~ /memcached|redis/ }
27
+ specs = Dir['spec/*/*_spec.rb'].select {|s| s =~ /memcached|redis/ }
28
28
  sh("rspec #{specs.join(' ')}")
29
29
  end
30
30
  end
data/juno.gemspec CHANGED
@@ -3,17 +3,17 @@ require File.dirname(__FILE__) + '/lib/juno/version'
3
3
  require 'date'
4
4
 
5
5
  Gem::Specification.new do |s|
6
- s.name = 'juno'
7
- s.version = Juno::VERSION
8
- s.date = Date.today.to_s
9
- s.authors = ['Yehuda Katz', 'Derek Kastner', 'Daniel Mendler']
10
- s.email = %w{wycats@gmail.com dkastner@gmail.com mail@daniel-mendler.de}
11
- s.description = 'A unified interface to key/value stores (moneta replacement)'
6
+ s.name = 'juno'
7
+ s.version = Juno::VERSION
8
+ s.date = Date.today.to_s
9
+ s.authors = ['Daniel Mendler', 'Yehuda Katz', 'Derek Kastner']
10
+ s.email = %w{mail@daniel-mendler.de wycats@gmail.com dkastner@gmail.com}
11
+ s.description = 'A unified interface to key/value stores (moneta replacement)'
12
12
  s.extra_rdoc_files = %w{README.md SPEC.md LICENSE}
13
- s.files = `git ls-files`.split("\n")
14
- s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
15
- s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
16
- s.homepage = 'http://github.com/minad/juno'
17
- s.require_paths = ['lib']
18
- s.summary = %{A unified interface to key/value stores, including MongoDB, Redis, Tokyo, and ActiveRecord}
13
+ s.files = `git ls-files`.split("\n")
14
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
15
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
16
+ s.homepage = 'http://github.com/minad/juno'
17
+ s.require_paths = ['lib']
18
+ s.summary = %{A unified interface to key/value stores, including MongoDB, Redis, Tokyo, and ActiveRecord}
19
19
  end
data/lib/juno.rb CHANGED
@@ -70,17 +70,17 @@ module Juno
70
70
  when :Memcached, :MemcachedDalli, :MemcachedNative
71
71
  # Memcached accept only base64 keys, expires already supported
72
72
  expires = false
73
- transformer = {:key => [:marshal, :base64], :value => :marshal}
73
+ transformer[:key] = [:marshal, :base64]
74
74
  when :PStore, :YAML, :DataMapper, :Null
75
75
  # For PStore, YAML and DataMapper only the key has to be a string
76
- transformer = {:key => :marshal}
76
+ transformer.delete(:value)
77
77
  when :HashFile
78
78
  # Use spreading hashes
79
- transformer = {:key => [:marshal, :md5, :spread], :value => :marshal}
79
+ transformer[:key] = [:marshal, :md5, :spread]
80
80
  name = :File
81
81
  when :File
82
82
  # Use escaping
83
- transformer = {:key => [:marshal, :escape], :value => :marshal}
83
+ transformer[:key] = [:marshal, :escape]
84
84
  when :Cassandra, :Redis
85
85
  # Expires already supported
86
86
  expires = false
@@ -12,7 +12,7 @@ module Juno
12
12
  # Options:
13
13
  # * :db - Couch database
14
14
  def initialize(options = {})
15
- raise 'No option :db specified' unless options[:db]
15
+ raise 'Option :db is required' unless options[:db]
16
16
  @db = ::CouchRest.database!(options[:db])
17
17
  end
18
18
 
@@ -21,7 +21,7 @@ module Juno
21
21
  # * :repository - Repository name (default :juno)
22
22
  # * :table - Table name (default :juno)
23
23
  def initialize(options = {})
24
- raise 'No option :setup specified' unless options[:setup]
24
+ raise 'Option :setup is required' unless options[:setup]
25
25
  @repository = options.delete(:repository) || :juno
26
26
  Store.storage_names[@repository] = (options.delete(:table) || :juno).to_s
27
27
  ::DataMapper.setup(@repository, options[:setup])
@@ -12,7 +12,7 @@ module Juno
12
12
  # Options:
13
13
  # * :file - Database file
14
14
  def initialize(options = {})
15
- raise 'No option :file specified' unless options[:file]
15
+ raise 'Option :file is required' unless options[:file]
16
16
  @memory = ::DBM.new(options[:file])
17
17
  end
18
18
 
@@ -6,7 +6,7 @@ module Juno
6
6
  # @api public
7
7
  class File < Base
8
8
  def initialize(options = {})
9
- raise 'No option :dir specified' unless @dir = options[:dir]
9
+ raise 'Option :dir is required' unless @dir = options[:dir]
10
10
  FileUtils.mkpath(@dir)
11
11
  raise "#{@dir} is not a dir" unless ::File.directory?(@dir)
12
12
  end
@@ -13,7 +13,7 @@ module Juno
13
13
  # * :dir - Fog directory
14
14
  # * Other options passed to Fog::Storage#new
15
15
  def initialize(options = {})
16
- raise 'No option :dir specified' unless dir = options.delete(:dir)
16
+ raise 'Option :dir is required' unless dir = options.delete(:dir)
17
17
  storage = ::Fog::Storage.new(options)
18
18
  @directory = storage.directories.create(:key => dir)
19
19
  end
@@ -12,7 +12,7 @@ module Juno
12
12
  # Options:
13
13
  # * :file - Database file
14
14
  def initialize(options = {})
15
- raise 'No option :file specified' unless options[:file]
15
+ raise 'Option :file is required' unless options[:file]
16
16
  @memory = ::GDBM.new(options[:file])
17
17
  end
18
18
 
@@ -12,7 +12,7 @@ module Juno
12
12
  # Options:
13
13
  # * :file - Database file
14
14
  def initialize(options = {})
15
- raise 'No option :file specified' unless options[:file]
15
+ raise 'Option :file is required' unless options[:file]
16
16
  @memory = ::LocalMemCache.new(:filename => options[:file])
17
17
  end
18
18
 
@@ -12,7 +12,7 @@ module Juno
12
12
  # Options:
13
13
  # * :file - PStore file
14
14
  def initialize(options = {})
15
- raise 'No option :file specified' unless options[:file]
15
+ raise 'Option :file is required' unless options[:file]
16
16
  FileUtils.mkpath(::File.dirname(options[:file]))
17
17
  @pstore = new_store(options)
18
18
  end
@@ -32,9 +32,10 @@ module Juno
32
32
  end
33
33
 
34
34
  def store(key, value, options = {})
35
- @redis.set(key, value)
36
35
  if expires = options[:expires]
37
- @redis.expire(key, expires)
36
+ @redis.setex(key, expires, value)
37
+ else
38
+ @redis.set(key, value)
38
39
  end
39
40
  value
40
41
  end
@@ -12,7 +12,7 @@ module Juno
12
12
  # Options:
13
13
  # * :file - Database file
14
14
  def initialize(options = {})
15
- raise 'No option :file specified' unless options[:file]
15
+ raise 'Option :file is required' unless options[:file]
16
16
  @memory = ::SDBM.new(options[:file])
17
17
  end
18
18
 
@@ -14,7 +14,7 @@ module Juno
14
14
  # * :table - Table name (default :juno)
15
15
  # * All other options passed to Sequel#connect
16
16
  def initialize(options = {})
17
- raise 'No option :db specified' unless db = options.delete(:db)
17
+ raise 'Option :db is required' unless db = options.delete(:db)
18
18
  @table = options.delete(:table) || :juno
19
19
  @db = ::Sequel.connect(db, options)
20
20
  @db.create_table?(@table) do
@@ -13,7 +13,7 @@ module Juno
13
13
  # * :file - Database file
14
14
  # * :table - Table name (default juno)
15
15
  def initialize(options = {})
16
- raise 'No option :file specified' unless options[:file]
16
+ raise 'Option :file is required' unless options[:file]
17
17
  table = options[:table] || 'juno'
18
18
  @db = ::SQLite3::Database.new(options[:file])
19
19
  @db.execute("create table if not exists #{table} (k blob not null primary key, v blob)")
@@ -14,7 +14,7 @@ module Juno
14
14
  # * :type - Database type (default :hdb, :bdb and :hdb possible)
15
15
  def initialize(options = {})
16
16
  file = options[:file]
17
- raise 'No option :file specified' unless options[:file]
17
+ raise 'Option :file is required' unless options[:file]
18
18
  if options[:type] == :bdb
19
19
  @memory = ::TokyoCabinet::BDB.new
20
20
  @memory.open(file, ::TokyoCabinet::BDB::OWRITER | ::TokyoCabinet::BDB::OCREAT)
data/lib/juno/builder.rb CHANGED
@@ -2,6 +2,7 @@ module Juno
2
2
  # Builder implements the DSL to build a chain of store proxies
3
3
  # @api private
4
4
  class Builder
5
+ # @api private
5
6
  def build
6
7
  klass, options, block = @proxies.first
7
8
  store = klass.new(options, &block)
@@ -18,12 +19,21 @@ module Juno
18
19
  instance_eval(&block)
19
20
  end
20
21
 
22
+ # Add proxy to chain
23
+ #
24
+ # @param [Symbol or Class] proxy Name of proxy class or proxy class
25
+ # @param [Hash] options Options hash
21
26
  def use(proxy, options = {}, &block)
22
27
  proxy = Juno.const_get(proxy) if Symbol === proxy
23
28
  raise 'You must give a Class or a Symbol' unless Class === proxy
24
29
  @proxies.unshift [proxy, options, block]
30
+ nil
25
31
  end
26
32
 
33
+ # Add adapter to chain
34
+ #
35
+ # @param [Symbol] name Name of adapter class
36
+ # @param [Hash] options Options hash
27
37
  def adapter(name, options = {}, &block)
28
38
  use(Adapters.const_get(name), options, &block)
29
39
  end
data/lib/juno/cache.rb CHANGED
@@ -12,6 +12,7 @@ module Juno
12
12
  #
13
13
  # @api public
14
14
  class Cache < Base
15
+ # @api private
15
16
  class DSL
16
17
  def initialize(options, &block)
17
18
  @cache, @backend = options[:cache], options[:backend]
data/lib/juno/expires.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  module Juno
2
2
  # Adds expiration support to the underlying store
3
3
  #
4
- # #store and #load support the :expires options to set/update
4
+ # #store and #load support the :expires option to set/update
5
5
  # the expiration time.
6
6
  #
7
7
  # @api public
data/lib/juno/proxy.rb CHANGED
@@ -63,6 +63,8 @@ module Juno
63
63
  self
64
64
  end
65
65
 
66
+ # Close this store
67
+ # @api public
66
68
  def close
67
69
  @adapter.close
68
70
  end
data/lib/juno/stack.rb CHANGED
@@ -14,6 +14,7 @@ module Juno
14
14
  #
15
15
  # @api public
16
16
  class Stack < Base
17
+ # @api private
17
18
  class DSL
18
19
  attr_reader :stack
19
20
 
@@ -10,6 +10,7 @@ module Juno
10
10
  #
11
11
  # @api public
12
12
  class Transformer < Proxy
13
+ # Available value transformers (Encoding and decoding)
13
14
  VALUE_TRANSFORMER = {
14
15
  :base64 => { :load => "value.unpack('m').first", :dump => "[value].pack('m').strip" },
15
16
  :bencode => { :load => '::BEncode.load(value)', :dump => '::BEncode.dump(value)', :require => 'bencode' },
@@ -17,14 +18,19 @@ module Juno
17
18
  :bson => { :load => "::BSON.deserialize(value)['v']", :dump => "::BSON.serialize('v'=>value)", :require => 'bson' },
18
19
  :compress => { :load => '::Zlib::Inflate.inflate(value)', :dump => '::Zlib::Deflate.deflate(value)', :require => 'zlib' },
19
20
  :json => { :load => '::MultiJson.load(value).first', :dump => '::MultiJson.dump([value])', :require => 'multi_json' },
21
+ :lzma => { :load => '::LZMA.decompress(value)', :dump => '::LZMA.compress(value)', :require => 'lzma' },
22
+ :lzo => { :load => '::LZO.decompress(value)', :dump => '::LZO.compress(value)', :require => 'lzoruby' },
20
23
  :marshal => { :load => '::Marshal.load(value)', :dump => '::Marshal.dump(value)' },
21
24
  :msgpack => { :load => '::MessagePack.unpack(value)', :dump => '::MessagePack.pack(value)', :require => 'msgpack' },
22
25
  :ox => { :load => '::Ox.parse_obj(value)', :dump => '::Ox.dump(value)', :require => 'ox' },
26
+ :snappy => { :load => '::Snappy.inflate(value)', :dump => '::Snappy.deflate(value)', :require => 'snappy' },
27
+ :quicklz => { :load => '::QuickLZ.decompress(value)', :dump => '::QuickLZ.compress(value)', :require => 'qlzruby' },
23
28
  :tnet => { :load => '::TNetstring.parse(value).first', :dump => '::TNetstring.dump(value)', :require => 'tnetstring' },
24
29
  :uuencode => { :load => "value.unpack('u').first", :dump => "[value].pack('u').strip" },
25
- :yaml => { :load => '::YAML.load(value)', :dump => '::YAML.dump(value)', :require => 'yaml' }
30
+ :yaml => { :load => '::YAML.load(value)', :dump => '::YAML.dump(value)', :require => 'yaml' },
26
31
  }
27
32
 
33
+ # Available key transformers (Only encoding, one direction)
28
34
  KEY_TRANSFORMER = {
29
35
  :base64 => { :transform => "[key].pack('m').strip" },
30
36
  :bencode => { :transform => '::BEncode.dump(key)', :require => 'bencode' },
@@ -35,7 +41,8 @@ module Juno
35
41
  :marshal => { :transform => '(tmp = key; String === tmp ? tmp : ::Marshal.dump(tmp))' },
36
42
  :md5 => { :transform => '::Digest::MD5.hexdigest(key)', :require => 'digest/md5' },
37
43
  :msgpack => { :transform => '(tmp = key; String === tmp ? tmp : ::MessagePack.pack(tmp))', :require => 'msgpack' },
38
- :ox => { :transform => '(tmp = key; String === tmp ? tmp : ::Ox.dump(tmp))' },
44
+ :prefix => { :transform => '@prefix+key' },
45
+ :ox => { :transform => '(tmp = key; String === tmp ? tmp : ::Ox.dump(tmp))', :require => 'ox' },
39
46
  :spread => { :transform => '(tmp = key; ::File.join(tmp[0..1], tmp[2..-1]))' },
40
47
  :tnet => { :transform => '(tmp = key; String === tmp ? tmp : ::TNetstring.dump(tmp))', :require => 'tnetstring' },
41
48
  :uuencode => { :transform => "[key].pack('u').strip" },
@@ -44,9 +51,34 @@ module Juno
44
51
 
45
52
  @classes = {}
46
53
 
54
+ def initialize(adapter, options = {})
55
+ super
56
+ @prefix = options[:prefix]
57
+ end
58
+
47
59
  class << self
48
60
  alias_method :original_new, :new
49
61
 
62
+ # Constructor
63
+ #
64
+ # @param [Juno store] adapter The underlying store
65
+ # @param [Hash] options
66
+ #
67
+ # Options:
68
+ # * :key - List of key transformers in the order in which they should be applied
69
+ # * :value - List of value transformers in the order in which they should be applied
70
+ # * :prefix - Prefix string for key namespacing (Used by the :prefix key transformer)
71
+ def new(adapter, options = {})
72
+ keys = [options[:key]].flatten.compact
73
+ values = [options[:value]].flatten.compact
74
+ raise 'Option :key or :value is required' if keys.empty? && values.empty?
75
+ klass = @classes["#{keys.join('-')}+#{values.join('-')}"] ||= compile(keys, values)
76
+ raise 'Option :prefix is required' if keys.include?(:prefix) && !options[:prefix]
77
+ klass.original_new(adapter, options)
78
+ end
79
+
80
+ private
81
+
50
82
  def compile(keys, values)
51
83
  tmp, key = 0, 'key'
52
84
  keys.each do |tn|
@@ -101,22 +133,6 @@ module Juno
101
133
  end
102
134
  klass
103
135
  end
104
-
105
- # Constructor
106
- #
107
- # @param [Juno store] adapter The underlying store
108
- # @param [Hash] options
109
- #
110
- # Options:
111
- # * :key - List of key transformers in the order in which they should be applied
112
- # * :value - List of value transformers in the order in which they should be applied
113
- def new(adapter, options = {})
114
- keys = [options[:key]].flatten.compact
115
- values = [options[:value]].flatten.compact
116
- raise 'No option :key or :value specified' if keys.empty? && values.empty?
117
- klass = @classes["#{keys.join('-')}+#{values.join('-')}"] ||= compile(keys, values)
118
- klass.original_new(adapter, options)
119
- end
120
136
  end
121
137
  end
122
138
  end