juno 0.2.5 → 0.2.6

Sign up to get free protection for your applications and to get access to all the features.
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