juno 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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,30 @@
1
+ module Juno
2
+ class Builder
3
+ def build
4
+ klass, options, block = @proxies.first
5
+ store = klass.new(@options.merge(options), &block)
6
+ @proxies[1..-1].each do |proxy|
7
+ klass, options, block = proxy
8
+ store = klass.new(store, @options.merge(options), &block)
9
+ end
10
+ store
11
+ end
12
+
13
+ def initialize(options = {}, &block)
14
+ raise 'No block given' unless block_given?
15
+ raise 'Options must be Hash' unless Hash === options
16
+ @options = options
17
+ @proxies = []
18
+ instance_eval(&block)
19
+ end
20
+
21
+ def use(proxy, options = {}, &block)
22
+ proxy = Juno.const_get(proxy) if Symbol === proxy
23
+ @proxies.unshift [proxy, options, block]
24
+ end
25
+
26
+ def adapter(name, options = {}, &block)
27
+ use(Adapters.const_get(name), options, &block)
28
+ end
29
+ end
30
+ end
data/lib/juno/cache.rb ADDED
@@ -0,0 +1,64 @@
1
+ module Juno
2
+ class Cache < Base
3
+ class DSL
4
+ def initialize(options, &block)
5
+ @cache, @backend = options[:cache], options[:backend]
6
+ instance_eval(&block)
7
+ end
8
+
9
+ def backend(options = {}, &block)
10
+ raise 'Backend already set' if @backend
11
+ @backend = Hash === options ? Juno.build(options, &block) : options
12
+ end
13
+
14
+ def cache(options = {}, &block)
15
+ raise 'Cache already set' if @cache
16
+ @cache = Hash === options ? Juno.build(options, &block) : options
17
+ end
18
+
19
+ def result
20
+ [@cache, @backend]
21
+ end
22
+ end
23
+
24
+ attr_reader :cache, :backend
25
+
26
+ def initialize(options = {}, &block)
27
+ @cache, @backend = DSL.new(options, &block).result
28
+ end
29
+
30
+ def key?(key, options = {})
31
+ @cache.key?(key, options) || @backend.key?(key, options)
32
+ end
33
+
34
+ def load(key, options = {})
35
+ value = @cache.load(key, options)
36
+ unless value
37
+ value = @backend.load(key, options)
38
+ @cache.store(key, value, options) if value
39
+ end
40
+ value
41
+ end
42
+
43
+ def store(key, value, options = {})
44
+ @cache.store(key, value, options)
45
+ @backend.store(key, value, options)
46
+ end
47
+
48
+ def delete(key, options = {})
49
+ @cache.delete(key, options)
50
+ @backend.delete(key, options)
51
+ end
52
+
53
+ def clear(options = {})
54
+ @cache.clear(options)
55
+ @backend.clear(options)
56
+ self
57
+ end
58
+
59
+ def close
60
+ @cache.close
61
+ @backend.close
62
+ end
63
+ end
64
+ end
data/lib/juno/expires.rb CHANGED
@@ -1,22 +1,18 @@
1
1
  module Juno
2
2
  class Expires < Proxy
3
3
  def key?(key, options = {})
4
- !!self[key]
4
+ !!load(key, options)
5
5
  end
6
6
 
7
- def fetch(key, value = nil, options = {}, &block)
8
- result = check_expired(key, super(key, value, options, &block))
9
- if result && options.include?(:expires)
10
- store(key, result, options)
7
+ def load(key, options = {})
8
+ value = check_expired(key, super(key, options))
9
+ if value && options.include?(:expires)
10
+ store(key, value, options)
11
11
  else
12
- result
12
+ value
13
13
  end
14
14
  end
15
15
 
16
- def [](key)
17
- check_expired(key, super(key))
18
- end
19
-
20
16
  def store(key, value, options = {})
21
17
  if expires = options.delete(:expires)
22
18
  super(key, [value, Time.now.to_i + expires].compact, options)
data/lib/juno/proxy.rb CHANGED
@@ -1,5 +1,64 @@
1
- require 'delegate'
2
-
3
1
  module Juno
4
- Proxy = DelegateClass(Base)
2
+ class Proxy < Base
3
+ attr_reader :adapter
4
+
5
+ def initialize(adapter, options = {})
6
+ @adapter = adapter
7
+ end
8
+
9
+ # Exists the value with key
10
+ #
11
+ # @param [Object] key
12
+ # @return [Boolean]
13
+ # @param [Hash] options
14
+ # @api public
15
+ def key?(key, options = {})
16
+ @adapter.key?(key, options)
17
+ end
18
+
19
+ # Fetch value with key. Return nil if the key doesn't exist
20
+ #
21
+ # @param [Object] key
22
+ # @param [Hash] options
23
+ # @return [Object] value
24
+ # @api public
25
+ def load(key, options = {})
26
+ @adapter.load(key, options)
27
+ end
28
+
29
+ # Store value with key
30
+ #
31
+ # @param [Object] key
32
+ # @param [Object] value
33
+ # @param [Hash] options
34
+ # @return value
35
+ # @api public
36
+ def store(key, value, options = {})
37
+ @adapter.store(key, value, options)
38
+ end
39
+
40
+ # Delete the key from the store and return the current value
41
+ #
42
+ # @param [Object] key
43
+ # @return [Object] current value
44
+ # @param [Hash] options
45
+ # @api public
46
+ def delete(key, options = {})
47
+ @adapter.delete(key, options)
48
+ end
49
+
50
+ # Clear all keys in this store
51
+ #
52
+ # @param [Hash] options
53
+ # @return [void]
54
+ # @api public
55
+ def clear(options = {})
56
+ @adapter.clear(options)
57
+ self
58
+ end
59
+
60
+ def close
61
+ @adapter.close
62
+ end
63
+ end
5
64
  end
data/lib/juno/stack.rb CHANGED
@@ -1,40 +1,56 @@
1
1
  module Juno
2
2
  class Stack < Base
3
- def initialize(options = {})
4
- raise 'No option :stores specified' unless @stores = options[:stores]
3
+ class DSL
4
+ attr_reader :stack
5
+
6
+ def initialize(options, &block)
7
+ @stack = options[:stack].to_a
8
+ instance_eval(&block)
9
+ end
10
+
11
+ def add(options = {}, &block)
12
+ @stack << (Hash === options ? Juno.build(options, &block) : options)
13
+ nil
14
+ end
15
+ end
16
+
17
+ attr_reader :stack
18
+
19
+ def initialize(options = {}, &block)
20
+ @stack = DSL.new(options, &block).stack
5
21
  end
6
22
 
7
23
  def key?(key, options = {})
8
- @stores.any? {|s| s.key?(key) }
24
+ @stack.any? {|s| s.key?(key) }
9
25
  end
10
26
 
11
- def [](key)
12
- @stores.each do |s|
13
- value = s[key]
27
+ def load(key, options = {})
28
+ @stack.each do |s|
29
+ value = s.load(key, options)
14
30
  return value if value
15
31
  end
16
32
  nil
17
33
  end
18
34
 
19
35
  def store(key, value, options = {})
20
- @stores.each {|s| s.store(key, value, options) }
36
+ @stack.each {|s| s.store(key, value, options) }
21
37
  value
22
38
  end
23
39
 
24
40
  def delete(key, options = {})
25
- @stores.inject(nil) do |value, s|
41
+ @stack.inject(nil) do |value, s|
26
42
  v = s.delete(key, options)
27
43
  value || v
28
44
  end
29
45
  end
30
46
 
31
47
  def clear(options = {})
32
- @stores.each {|s| s.clear }
33
- nil
48
+ @stack.each {|s| s.clear }
49
+ self
34
50
  end
35
51
 
36
52
  def close
37
- @stores.each {|s| s.close }
53
+ @stack.each {|s| s.close }
38
54
  nil
39
55
  end
40
56
  end
@@ -0,0 +1,106 @@
1
+ module Juno
2
+ class Transformer < Proxy
3
+ @classes = {}
4
+
5
+ class << self
6
+ alias_method :original_new, :new
7
+ end
8
+
9
+ VALUE_TRANSFORMER = {
10
+ :marshal => { :load => '::Marshal.load(VALUE)', :dump => '::Marshal.dump(VALUE)' },
11
+ :base64 => { :load => "VALUE.unpack('m').first", :dump => "[VALUE].pack('m').strip" },
12
+ :json => { :load => '::MultiJson.load(VALUE).first', :dump => '::MultiJson.dump([VALUE])', :require => 'multi_json' },
13
+ :yaml => { :load => '::YAML.load(VALUE)', :dump => '::YAML.dump(VALUE)', :require => 'yaml' },
14
+ #:tnet => { :load => '::TNetstring.parse(VALUE)', :dump => '::TNetstring.dump(VALUE)', :require => 'tnetstring' },
15
+ :msgpack => { :load => '::MessagePack.unpack(VALUE)', :dump => '::MessagePack.pack(VALUE)', :require => 'msgpack' },
16
+ :bson => { :load => '::BSON.deserialize(VALUE)["v"]', :dump => '::BSON.serialize({"v"=>VALUE})', :require => 'bson' },
17
+ }
18
+
19
+ KEY_TRANSFORMER = {
20
+ :base64 => { :transform => "[KEY].pack('m').strip" },
21
+ :spread => { :transform => '(TMP = KEY; ::File.join(TMP[0..1], TMP[2..-1]))' },
22
+ :escape => { :transform => "KEY.gsub(/[^a-zA-Z0-9_-]+/) { '%%' + $&.unpack('H2' * $&.bytesize).join('%%').upcase }" },
23
+ :md5 => { :transform => '::Digest::MD5.hexdigest(KEY)', :require => 'digest/md5' },
24
+ :json => { :transform => '(TMP = KEY; String === TMP ? TMP : ::MultiJson.dump(TMP))', :require => 'multi_json' },
25
+ :bson => { :transform => '(TMP = KEY; String === TMP ? TMP : ::BSON.serialize({"k"=>TMP}).to_s)', :require => 'bson' },
26
+ :yaml => { :transform => '(TMP = KEY; String === TMP ? TMP : ::YAML.dump(TMP))', :require => 'yaml' },
27
+ :marshal => { :transform => '(TMP = KEY; String === TMP ? TMP : ::Marshal.dump(TMP))' },
28
+ #:tnet => { :transform => '(TMP = KEY; String === TMP ? TMP : ::TNetstring.dump(TMP))', :require => 'tnetstring' },
29
+ :msgpack => { :transform => '(TMP = KEY; String === TMP ? TMP : ::MessagePack.pack(TMP))', :require => 'msgpack' },
30
+ }
31
+
32
+ class << self
33
+ def compile(keys, values)
34
+ tmp, key = 0, 'key'
35
+ keys.each do |tn|
36
+ raise "Unknown key transformer #{tn}" unless t = KEY_TRANSFORMER[tn]
37
+ require t[:require] if t[:require]
38
+ key = t[:transform].gsub('KEY', key).gsub('TMP', "x#{tmp}")
39
+ tmp += 1
40
+ end
41
+
42
+ dumper = 'value'
43
+ values.each do |tn|
44
+ raise "Unknown value transformer #{tn}" unless t = VALUE_TRANSFORMER[tn]
45
+ require t[:require] if t[:require]
46
+ dumper = t[:dump].gsub('VALUE', dumper)
47
+ end
48
+
49
+ loader = 'value'
50
+ values.reverse.each do |t|
51
+ loader = VALUE_TRANSFORMER[t][:load].gsub('VALUE', loader)
52
+ end
53
+
54
+ klass = Class.new(Transformer)
55
+ if loader == 'value'
56
+ klass.class_eval <<-end_eval, __FILE__, __LINE__
57
+ def key?(key, options = {})
58
+ @adapter.key?(#{key}, options)
59
+ end
60
+
61
+ def load(key, options = {})
62
+ @adapter.load(#{key}, options)
63
+ end
64
+
65
+ def store(key, value, options = {})
66
+ @adapter.store(#{key}, value, options)
67
+ end
68
+
69
+ def delete(key, options = {})
70
+ @adapter.delete(#{key}, options)
71
+ end
72
+ end_eval
73
+ else
74
+ klass.class_eval <<-end_eval, __FILE__, __LINE__
75
+ def key?(key, options = {})
76
+ @adapter.key?(#{key}, options)
77
+ end
78
+
79
+ def load(key, options = {})
80
+ value = @adapter.load(#{key}, options)
81
+ value && #{loader}
82
+ end
83
+
84
+ def store(key, value, options = {})
85
+ @adapter.store(#{key}, #{dumper}, options)
86
+ value
87
+ end
88
+
89
+ def delete(key, options = {})
90
+ value = @adapter.delete(#{key}, options)
91
+ value && #{loader}
92
+ end
93
+ end_eval
94
+ end
95
+ klass
96
+ end
97
+
98
+ def new(store, options = {})
99
+ keys = [options[:key]].flatten.compact
100
+ values = [options[:value]].flatten.compact
101
+ klass = @classes["#{keys.join('-')}+#{values.join('-')}"] ||= compile(keys, values)
102
+ klass.original_new(store, options)
103
+ end
104
+ end
105
+ end
106
+ end
data/lib/juno/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Juno
2
- VERSION = '0.1.1'
2
+ VERSION = '0.2.0'
3
3
  end
data/lib/juno.rb CHANGED
@@ -1,31 +1,83 @@
1
1
  module Juno
2
- autoload :ActiveRecord, 'juno/activerecord'
3
- autoload :Base, 'juno/base'
4
- autoload :Cassandra, 'juno/cassandra'
5
- autoload :Couch, 'juno/couch'
6
- autoload :DataMapper, 'juno/datamapper'
7
- autoload :DBM, 'juno/dbm'
8
- autoload :Expires, 'juno/expires'
9
- autoload :File, 'juno/file'
10
- autoload :Fog, 'juno/fog'
11
- autoload :GDBM, 'juno/gdbm'
12
- autoload :HashFile, 'juno/hashfile'
13
- autoload :LocalMemCache, 'juno/localmemcache'
14
- autoload :Memcached, 'juno/memcached'
15
- autoload :MemcachedDalli, 'juno/memcached_dalli'
16
- autoload :MemcachedNative, 'juno/memcached_native'
17
- autoload :Memory, 'juno/memory'
18
- autoload :MongoDB, 'juno/mongodb'
19
- autoload :Null, 'juno/null'
20
- autoload :Proxy, 'juno/proxy'
21
- autoload :PStore, 'juno/pstore'
22
- autoload :Redis, 'juno/redis'
23
- autoload :Riak, 'juno/riak'
24
- autoload :SDBM, 'juno/sdbm'
25
- autoload :Sequel, 'juno/sequel'
26
- autoload :Stack, 'juno/stack'
27
- autoload :Sqlite, 'juno/sqlite'
28
- autoload :TokyoCabinet, 'juno/tokyocabinet'
29
- #autoload :TokyoTyrant, 'juno/tokyotyrant'
30
- autoload :YAML, 'juno/yaml'
2
+ autoload :Base, 'juno/base'
3
+ autoload :Builder, 'juno/builder'
4
+ autoload :Cache, 'juno/cache'
5
+ autoload :Expires, 'juno/expires'
6
+ autoload :Proxy, 'juno/proxy'
7
+ autoload :Stack, 'juno/stack'
8
+ autoload :Transformer, 'juno/transformer'
9
+
10
+ module Adapters
11
+ autoload :ActiveRecord, 'juno/adapters/activerecord'
12
+ autoload :Cassandra, 'juno/adapters/cassandra'
13
+ autoload :Couch, 'juno/adapters/couch'
14
+ autoload :DataMapper, 'juno/adapters/datamapper'
15
+ autoload :DBM, 'juno/adapters/dbm'
16
+ autoload :File, 'juno/adapters/file'
17
+ autoload :Fog, 'juno/adapters/fog'
18
+ autoload :GDBM, 'juno/adapters/gdbm'
19
+ autoload :LocalMemCache, 'juno/adapters/localmemcache'
20
+ autoload :Memcached, 'juno/adapters/memcached'
21
+ autoload :MemcachedDalli, 'juno/adapters/memcached_dalli'
22
+ autoload :MemcachedNative, 'juno/adapters/memcached_native'
23
+ autoload :Memory, 'juno/adapters/memory'
24
+ autoload :Mongo, 'juno/adapters/mongo'
25
+ autoload :Null, 'juno/adapters/null'
26
+ autoload :PStore, 'juno/adapters/pstore'
27
+ autoload :Redis, 'juno/adapters/redis'
28
+ autoload :Riak, 'juno/adapters/riak'
29
+ autoload :SDBM, 'juno/adapters/sdbm'
30
+ autoload :Sequel, 'juno/adapters/sequel'
31
+ autoload :Sqlite, 'juno/adapters/sqlite'
32
+ autoload :TokyoCabinet, 'juno/adapters/tokyocabinet'
33
+ autoload :YAML, 'juno/adapters/yaml'
34
+ end
35
+
36
+ def self.new(name, options = {})
37
+ raise 'Name must be Symbol' unless Symbol === name
38
+ case name
39
+ when :Sequel, :ActiveRecord, :Couch
40
+ # Sequel accept only base64 keys and values
41
+ # FIXME: ActiveRecord and Couch should work only with :marshal but this
42
+ # raises an error on 1.9
43
+ build(options) do
44
+ use :Transformer, :key => [:marshal, :base64], :value => [:marshal, :base64]
45
+ adapter name
46
+ end
47
+ when :Memcached, :MemcachedDalli, :MemcachedNative
48
+ # Memcached accept only base64 keys
49
+ build(options) do
50
+ use :Transformer, :key => [:marshal, :base64], :value => :marshal
51
+ adapter name
52
+ end
53
+ when :PStore, :YAML, :DataMapper, :Null
54
+ # For PStore, YAML and DataMapper only the key has to be a string
55
+ build(options) do
56
+ use :Transformer, :key => :marshal
57
+ adapter name
58
+ end
59
+ when :HashFile
60
+ # Use spreading hashes
61
+ build(options) do
62
+ use :Transformer, :key => [:marshal, :md5, :spread], :value => :marshal
63
+ adapter :File
64
+ end
65
+ when :File
66
+ # Use escaping
67
+ build(options) do
68
+ use :Transformer, :key => [:marshal, :escape], :value => :marshal
69
+ adapter :File
70
+ end
71
+ else
72
+ # For all other stores marshal key and value
73
+ build(options) do
74
+ use :Transformer, :key => :marshal, :value => :marshal
75
+ adapter name
76
+ end
77
+ end
78
+ end
79
+
80
+ def self.build(options = {}, &block)
81
+ Builder.new(options, &block).build
82
+ end
31
83
  end
@@ -0,0 +1,41 @@
1
+ # Generated file
2
+ require 'helper'
3
+
4
+ begin
5
+ Juno::Adapters::ActiveRecord.new(:connection => { :adapter => (defined?(JRUBY_VERSION) ? 'jdbcsqlite3' : 'sqlite3'), :database => File.join(make_tempdir, 'adapter_activerecord.sqlite3') }).close
6
+
7
+ describe "adapter_activerecord" do
8
+ before do
9
+ @store = Juno::Adapters::ActiveRecord.new(:connection => { :adapter => (defined?(JRUBY_VERSION) ? 'jdbcsqlite3' : 'sqlite3'), :database => File.join(make_tempdir, 'adapter_activerecord.sqlite3') })
10
+ @store.clear
11
+ end
12
+
13
+ after do
14
+ @store.close.should == nil if @store
15
+ end
16
+
17
+ it_should_behave_like 'null_stringkey_stringvalue'
18
+ it_should_behave_like 'store_stringkey_stringvalue'
19
+ it_should_behave_like 'returndifferent_stringkey_stringvalue'
20
+
21
+ it 'updates an existing key/value' do
22
+ @store['foo/bar'] = '1'
23
+ @store['foo/bar'] = '2'
24
+ records = @store.table.find :all, :conditions => { :key => 'foo/bar' }
25
+ records.count.should == 1
26
+ end
27
+
28
+ it 'uses an existing connection' do
29
+ ActiveRecord::Base.establish_connection :adapter => (defined?(JRUBY_VERSION) ? 'jdbcsqlite3' : 'sqlite3'), :database => File.join(make_tempdir, 'activerecord-existing.sqlite3')
30
+
31
+ store = Juno::Adapters::ActiveRecord.new
32
+ store.table.table_exists?.should == true
33
+ end
34
+
35
+ end
36
+ rescue LoadError => ex
37
+ puts "Test adapter_activerecord not executed: #{ex.message}"
38
+ rescue Exception => ex
39
+ puts "Test adapter_activerecord not executed: #{ex.message}"
40
+ #puts "#{ex.backtrace.join("\n")}"
41
+ end
@@ -0,0 +1,27 @@
1
+ # Generated file
2
+ require 'helper'
3
+
4
+ begin
5
+ Juno::Adapters::Cassandra.new.close
6
+
7
+ describe "adapter_cassandra" do
8
+ before do
9
+ @store = Juno::Adapters::Cassandra.new
10
+ @store.clear
11
+ end
12
+
13
+ after do
14
+ @store.close.should == nil if @store
15
+ end
16
+
17
+ it_should_behave_like 'null_stringkey_stringvalue'
18
+ it_should_behave_like 'store_stringkey_stringvalue'
19
+ it_should_behave_like 'returndifferent_stringkey_stringvalue'
20
+
21
+ end
22
+ rescue LoadError => ex
23
+ puts "Test adapter_cassandra not executed: #{ex.message}"
24
+ rescue Exception => ex
25
+ puts "Test adapter_cassandra not executed: #{ex.message}"
26
+ #puts "#{ex.backtrace.join("\n")}"
27
+ end
@@ -0,0 +1,27 @@
1
+ # Generated file
2
+ require 'helper'
3
+
4
+ begin
5
+ Juno::Adapters::Couch.new(:db => 'adapter_couch').close
6
+
7
+ describe "adapter_couch" do
8
+ before do
9
+ @store = Juno::Adapters::Couch.new(:db => 'adapter_couch')
10
+ @store.clear
11
+ end
12
+
13
+ after do
14
+ @store.close.should == nil if @store
15
+ end
16
+
17
+ it_should_behave_like 'null_stringkey_stringvalue'
18
+ it_should_behave_like 'store_stringkey_stringvalue'
19
+ it_should_behave_like 'returndifferent_stringkey_stringvalue'
20
+
21
+ end
22
+ rescue LoadError => ex
23
+ puts "Test adapter_couch not executed: #{ex.message}"
24
+ rescue Exception => ex
25
+ puts "Test adapter_couch not executed: #{ex.message}"
26
+ #puts "#{ex.backtrace.join("\n")}"
27
+ end
@@ -0,0 +1,61 @@
1
+ # Generated file
2
+ require 'helper'
3
+
4
+ begin
5
+ require 'dm-core'
6
+ DataMapper.setup(:default, :adapter => :in_memory)
7
+ Juno::Adapters::DataMapper.new(:setup => "sqlite3://#{make_tempdir}/adapter_datamapper.sqlite3").close
8
+
9
+ describe "adapter_datamapper" do
10
+ before do
11
+ @store = Juno::Adapters::DataMapper.new(:setup => "sqlite3://#{make_tempdir}/adapter_datamapper.sqlite3")
12
+ @store.clear
13
+ end
14
+
15
+ after do
16
+ @store.close.should == nil if @store
17
+ end
18
+
19
+ it_should_behave_like 'null_stringkey_stringvalue'
20
+ it_should_behave_like 'store_stringkey_stringvalue'
21
+ it_should_behave_like 'returndifferent_stringkey_stringvalue'
22
+ it_should_behave_like 'returndifferent_stringkey_objectvalue'
23
+ it_should_behave_like 'null_stringkey_objectvalue'
24
+ it_should_behave_like 'store_stringkey_objectvalue'
25
+
26
+ it 'does not cross contaminate when storing' do
27
+ first = Juno::Adapters::DataMapper.new(:setup => "sqlite3://#{make_tempdir}/datamapper-first.sqlite3")
28
+ first.clear
29
+
30
+ second = Juno::Adapters::DataMapper.new(:repository => :sample, :setup => "sqlite3://#{make_tempdir}/datamapper-second.sqlite3")
31
+ second.clear
32
+
33
+ first['key'] = 'value'
34
+ second['key'] = 'value2'
35
+
36
+ first['key'].should == 'value'
37
+ second['key'].should == 'value2'
38
+ end
39
+
40
+ it 'does not cross contaminate when deleting' do
41
+ first = Juno::Adapters::DataMapper.new(:setup => "sqlite3://#{make_tempdir}/datamapper-first.sqlite3")
42
+ first.clear
43
+
44
+ second = Juno::Adapters::DataMapper.new(:repository => :sample, :setup => "sqlite3://#{make_tempdir}/datamapper-second.sqlite3")
45
+ second.clear
46
+
47
+ first['key'] = 'value'
48
+ second['key'] = 'value2'
49
+
50
+ first.delete('key').should == 'value'
51
+ first.key?('key').should == false
52
+ second['key'].should == 'value2'
53
+ end
54
+
55
+ end
56
+ rescue LoadError => ex
57
+ puts "Test adapter_datamapper not executed: #{ex.message}"
58
+ rescue Exception => ex
59
+ puts "Test adapter_datamapper not executed: #{ex.message}"
60
+ #puts "#{ex.backtrace.join("\n")}"
61
+ end
@@ -0,0 +1,27 @@
1
+ # Generated file
2
+ require 'helper'
3
+
4
+ begin
5
+ Juno::Adapters::DBM.new(:file => File.join(make_tempdir, "adapter_dbm")).close
6
+
7
+ describe "adapter_dbm" do
8
+ before do
9
+ @store = Juno::Adapters::DBM.new(:file => File.join(make_tempdir, "adapter_dbm"))
10
+ @store.clear
11
+ end
12
+
13
+ after do
14
+ @store.close.should == nil if @store
15
+ end
16
+
17
+ it_should_behave_like 'null_stringkey_stringvalue'
18
+ it_should_behave_like 'store_stringkey_stringvalue'
19
+ it_should_behave_like 'returndifferent_stringkey_stringvalue'
20
+
21
+ end
22
+ rescue LoadError => ex
23
+ puts "Test adapter_dbm not executed: #{ex.message}"
24
+ rescue Exception => ex
25
+ puts "Test adapter_dbm not executed: #{ex.message}"
26
+ #puts "#{ex.backtrace.join("\n")}"
27
+ end