moneta 0.7.13 → 0.7.14

Sign up to get free protection for your applications and to get access to all the features.
Files changed (163) hide show
  1. data/.travis.yml +2 -0
  2. data/CHANGES +5 -0
  3. data/Rakefile +7 -2
  4. data/lib/moneta/adapters/activerecord.rb +68 -27
  5. data/lib/moneta/adapters/file.rb +7 -5
  6. data/lib/moneta/adapters/sequel.rb +1 -1
  7. data/lib/moneta/transformer/config.rb +2 -2
  8. data/lib/moneta/version.rb +1 -1
  9. data/script/benchmarks +2 -1
  10. data/script/generate-specs +60 -16
  11. data/spec/moneta/adapter_activerecord_exisiting_connection_spec.rb +31 -0
  12. data/spec/moneta/adapter_activerecord_spec.rb +23 -4
  13. data/spec/moneta/adapter_cassandra_spec.rb +1 -0
  14. data/spec/moneta/adapter_cassandra_with_default_expires_spec.rb +1 -0
  15. data/spec/moneta/adapter_client_spec.rb +2 -1
  16. data/spec/moneta/adapter_cookie_spec.rb +1 -0
  17. data/spec/moneta/adapter_couch_spec.rb +1 -0
  18. data/spec/moneta/adapter_datamapper_spec.rb +3 -2
  19. data/spec/moneta/adapter_daybreak_spec.rb +1 -0
  20. data/spec/moneta/adapter_dbm_spec.rb +1 -0
  21. data/spec/moneta/adapter_file_spec.rb +1 -0
  22. data/spec/moneta/adapter_fog_spec.rb +3 -2
  23. data/spec/moneta/adapter_gdbm_spec.rb +1 -0
  24. data/spec/moneta/adapter_hbase_spec.rb +1 -0
  25. data/spec/moneta/adapter_kyotocabinet_spec.rb +1 -0
  26. data/spec/moneta/adapter_leveldb_spec.rb +1 -0
  27. data/spec/moneta/adapter_localmemcache_spec.rb +1 -0
  28. data/spec/moneta/adapter_lruhash_spec.rb +1 -0
  29. data/spec/moneta/adapter_memcached_dalli_spec.rb +1 -0
  30. data/spec/moneta/adapter_memcached_dalli_with_default_expires_spec.rb +1 -0
  31. data/spec/moneta/adapter_memcached_native_spec.rb +1 -0
  32. data/spec/moneta/adapter_memcached_native_with_default_expires_spec.rb +1 -0
  33. data/spec/moneta/adapter_memcached_spec.rb +1 -0
  34. data/spec/moneta/adapter_memcached_with_default_expires_spec.rb +1 -0
  35. data/spec/moneta/adapter_memory_spec.rb +1 -0
  36. data/spec/moneta/adapter_mongo_spec.rb +1 -0
  37. data/spec/moneta/adapter_mongo_with_default_expires_spec.rb +1 -0
  38. data/spec/moneta/adapter_pstore_spec.rb +1 -0
  39. data/spec/moneta/adapter_redis_spec.rb +1 -0
  40. data/spec/moneta/adapter_redis_with_default_expires_spec.rb +1 -0
  41. data/spec/moneta/adapter_restclient_spec.rb +2 -1
  42. data/spec/moneta/adapter_riak_spec.rb +5 -4
  43. data/spec/moneta/adapter_sequel_spec.rb +1 -0
  44. data/spec/moneta/adapter_sqlite_spec.rb +1 -0
  45. data/spec/moneta/adapter_tdb_spec.rb +1 -0
  46. data/spec/moneta/adapter_tokyocabinet_bdb_spec.rb +1 -0
  47. data/spec/moneta/adapter_tokyocabinet_hdb_spec.rb +1 -0
  48. data/spec/moneta/adapter_tokyotyrant_spec.rb +1 -0
  49. data/spec/moneta/adapter_yaml_spec.rb +1 -0
  50. data/spec/moneta/cache_file_memory_spec.rb +1 -0
  51. data/spec/moneta/cache_memory_null_spec.rb +1 -0
  52. data/spec/moneta/expires_file_spec.rb +1 -0
  53. data/spec/moneta/expires_memory_spec.rb +1 -0
  54. data/spec/moneta/expires_memory_with_default_expires_spec.rb +1 -0
  55. data/spec/moneta/lock_spec.rb +1 -0
  56. data/spec/moneta/pool_spec.rb +1 -0
  57. data/spec/moneta/proxy_expires_memory_spec.rb +1 -0
  58. data/spec/moneta/proxy_redis_spec.rb +1 -0
  59. data/spec/moneta/shared_tcp_spec.rb +1 -0
  60. data/spec/moneta/shared_unix_spec.rb +1 -0
  61. data/spec/moneta/simple_activerecord_spec.rb +1 -0
  62. data/spec/moneta/simple_activerecord_with_expires_spec.rb +1 -0
  63. data/spec/moneta/simple_cassandra_spec.rb +1 -0
  64. data/spec/moneta/simple_client_tcp_spec.rb +2 -1
  65. data/spec/moneta/simple_client_unix_spec.rb +2 -1
  66. data/spec/moneta/simple_couch_spec.rb +1 -0
  67. data/spec/moneta/simple_couch_with_expires_spec.rb +1 -0
  68. data/spec/moneta/simple_datamapper_spec.rb +3 -2
  69. data/spec/moneta/simple_datamapper_with_expires_spec.rb +3 -2
  70. data/spec/moneta/simple_datamapper_with_repository_spec.rb +3 -2
  71. data/spec/moneta/simple_daybreak_spec.rb +1 -0
  72. data/spec/moneta/simple_daybreak_with_expires_spec.rb +1 -0
  73. data/spec/moneta/simple_dbm_spec.rb +1 -0
  74. data/spec/moneta/simple_dbm_with_expires_spec.rb +1 -0
  75. data/spec/moneta/simple_file_spec.rb +1 -0
  76. data/spec/moneta/simple_file_with_expires_spec.rb +1 -0
  77. data/spec/moneta/simple_fog_spec.rb +3 -2
  78. data/spec/moneta/simple_fog_with_expires_spec.rb +3 -2
  79. data/spec/moneta/simple_gdbm_spec.rb +1 -0
  80. data/spec/moneta/simple_gdbm_with_expires_spec.rb +1 -0
  81. data/spec/moneta/simple_hashfile_spec.rb +1 -0
  82. data/spec/moneta/simple_hashfile_with_expires_spec.rb +1 -0
  83. data/spec/moneta/simple_hbase_spec.rb +1 -0
  84. data/spec/moneta/simple_hbase_with_expires_spec.rb +1 -0
  85. data/spec/moneta/simple_kyotocabinet_spec.rb +1 -0
  86. data/spec/moneta/simple_kyotocabinet_with_expires_spec.rb +1 -0
  87. data/spec/moneta/simple_leveldb_spec.rb +1 -0
  88. data/spec/moneta/simple_leveldb_with_expires_spec.rb +1 -0
  89. data/spec/moneta/simple_localmemcache_spec.rb +1 -0
  90. data/spec/moneta/simple_localmemcache_with_expires_spec.rb +1 -0
  91. data/spec/moneta/simple_lruhash_spec.rb +1 -0
  92. data/spec/moneta/simple_lruhash_with_expires_spec.rb +1 -0
  93. data/spec/moneta/simple_memcached_dalli_spec.rb +1 -0
  94. data/spec/moneta/simple_memcached_native_spec.rb +1 -0
  95. data/spec/moneta/simple_memcached_spec.rb +1 -0
  96. data/spec/moneta/simple_memory_spec.rb +1 -0
  97. data/spec/moneta/simple_memory_with_compress_spec.rb +1 -0
  98. data/spec/moneta/simple_memory_with_expires_spec.rb +1 -0
  99. data/spec/moneta/simple_memory_with_json_key_serializer_spec.rb +1 -0
  100. data/spec/moneta/simple_memory_with_json_serializer_spec.rb +1 -0
  101. data/spec/moneta/simple_memory_with_json_value_serializer_spec.rb +1 -0
  102. data/spec/moneta/simple_memory_with_prefix_spec.rb +1 -0
  103. data/spec/moneta/simple_memory_with_snappy_compress_spec.rb +1 -0
  104. data/spec/moneta/simple_mongo_spec.rb +1 -0
  105. data/spec/moneta/simple_pstore_spec.rb +1 -0
  106. data/spec/moneta/simple_pstore_with_expires_spec.rb +1 -0
  107. data/spec/moneta/simple_redis_spec.rb +1 -0
  108. data/spec/moneta/simple_restclient_spec.rb +2 -1
  109. data/spec/moneta/simple_riak_spec.rb +5 -4
  110. data/spec/moneta/simple_riak_with_expires_spec.rb +5 -4
  111. data/spec/moneta/simple_sequel_spec.rb +1 -0
  112. data/spec/moneta/simple_sequel_with_expires_spec.rb +1 -0
  113. data/spec/moneta/simple_sqlite_spec.rb +1 -0
  114. data/spec/moneta/simple_sqlite_with_expires_spec.rb +1 -0
  115. data/spec/moneta/simple_tdb_spec.rb +1 -0
  116. data/spec/moneta/simple_tdb_with_expires_spec.rb +1 -0
  117. data/spec/moneta/simple_tokyocabinet_spec.rb +1 -0
  118. data/spec/moneta/simple_tokyocabinet_with_expires_spec.rb +1 -0
  119. data/spec/moneta/simple_tokyotyrant_spec.rb +1 -0
  120. data/spec/moneta/simple_tokyotyrant_with_expires_spec.rb +1 -0
  121. data/spec/moneta/simple_yaml_spec.rb +1 -0
  122. data/spec/moneta/simple_yaml_with_expires_spec.rb +1 -0
  123. data/spec/moneta/stack_file_memory_spec.rb +1 -0
  124. data/spec/moneta/stack_memory_file_spec.rb +1 -0
  125. data/spec/moneta/transformer_bencode_spec.rb +1 -0
  126. data/spec/moneta/transformer_bert_spec.rb +1 -0
  127. data/spec/moneta/transformer_bson_spec.rb +1 -0
  128. data/spec/moneta/transformer_bzip2_spec.rb +1 -0
  129. data/spec/moneta/transformer_json_spec.rb +1 -0
  130. data/spec/moneta/transformer_key_inspect_spec.rb +1 -0
  131. data/spec/moneta/transformer_key_marshal_spec.rb +1 -0
  132. data/spec/moneta/transformer_key_to_s_spec.rb +1 -0
  133. data/spec/moneta/transformer_key_yaml_spec.rb +1 -0
  134. data/spec/moneta/transformer_lzma_spec.rb +1 -0
  135. data/spec/moneta/transformer_lzo_spec.rb +1 -0
  136. data/spec/moneta/transformer_marshal_base64_spec.rb +1 -0
  137. data/spec/moneta/transformer_marshal_escape_spec.rb +1 -0
  138. data/spec/moneta/transformer_marshal_hmac_spec.rb +1 -0
  139. data/spec/moneta/transformer_marshal_md5_spec.rb +1 -0
  140. data/spec/moneta/transformer_marshal_md5_spread_spec.rb +1 -0
  141. data/spec/moneta/transformer_marshal_prefix_spec.rb +1 -0
  142. data/spec/moneta/transformer_marshal_qp_spec.rb +1 -0
  143. data/spec/moneta/transformer_marshal_rmd160_spec.rb +1 -0
  144. data/spec/moneta/transformer_marshal_sha1_spec.rb +1 -0
  145. data/spec/moneta/transformer_marshal_sha256_spec.rb +1 -0
  146. data/spec/moneta/transformer_marshal_sha384_spec.rb +1 -0
  147. data/spec/moneta/transformer_marshal_sha512_spec.rb +1 -0
  148. data/spec/moneta/transformer_marshal_spec.rb +1 -0
  149. data/spec/moneta/transformer_marshal_truncate_spec.rb +1 -0
  150. data/spec/moneta/transformer_marshal_uuencode_spec.rb +1 -0
  151. data/spec/moneta/transformer_msgpack_spec.rb +1 -0
  152. data/spec/moneta/transformer_ox_spec.rb +1 -0
  153. data/spec/moneta/transformer_quicklz_spec.rb +1 -0
  154. data/spec/moneta/transformer_snappy_spec.rb +1 -0
  155. data/spec/moneta/transformer_tnet_spec.rb +1 -0
  156. data/spec/moneta/transformer_value_marshal_spec.rb +1 -0
  157. data/spec/moneta/transformer_value_yaml_spec.rb +1 -0
  158. data/spec/moneta/transformer_yaml_spec.rb +1 -0
  159. data/spec/moneta/transformer_zlib_spec.rb +1 -0
  160. data/spec/moneta/weak_create_spec.rb +1 -0
  161. data/spec/moneta/weak_increment_spec.rb +1 -0
  162. data/spec/monetaspecs.rb +23 -2
  163. metadata +4 -3
data/.travis.yml CHANGED
@@ -16,6 +16,8 @@ before_install:
16
16
  install: 'echo "Bundle installed"'
17
17
  before_script:
18
18
  - mysql -e 'create database moneta;'
19
+ - mysql -e 'create database moneta_activerecord1;'
20
+ - mysql -e 'create database moneta_activerecord2;'
19
21
  env:
20
22
  global:
21
23
  - secure: "B0vx1g1CB1A6mM3B/iy2ATicfS4OXT80bb2RVe8mSRsPzez1B4q4Q4hJcaMI\nrMARONN8Krtnti+IqvmDnB0Z0AKYMEyIc+zT37zJOCjLdkLJl+x/thuU/MbC\nvlLVwjMf6JE2EUzTfORDRFYc5ycCqfsfgNk1Go0D2CPT6P9u9uQ="
data/CHANGES CHANGED
@@ -1,3 +1,8 @@
1
+ 0.7.14
2
+
3
+ * Adapters::ActiveRecord, Adapters::Sequel: store values as blobs
4
+ * Adapters::ActiveRecord fixed and improved
5
+
1
6
  0.7.13
2
7
 
3
8
  * Adapters::ActiveRecord: Use connection_pool
data/Rakefile CHANGED
@@ -35,8 +35,13 @@ task :test do
35
35
  #
36
36
  # * Cassandra and Riak fail spuriously (An expert has to check the adapters!)
37
37
  #
38
- # * ActiveRecord has some connection problems (An expert has to check the adapter!)
39
- unstable = specs.select {|s| s =~ /quicklz|cassandra|riak|activerecord/ }
38
+ # * PStore and File increment/locking doesn't work correctly on JRuby
39
+ #
40
+ unstable = %w(quicklz cassandra riak)
41
+ unstable += %w(file pstore) if defined?(JRUBY_VERSION)
42
+
43
+ unstable_re = /#{unstable.join('|')}/
44
+ unstable = specs.select {|s| s =~ unstable_re }
40
45
  specs -= unstable
41
46
 
42
47
  if group =~ /^(\d+)\/(\d+)$/
@@ -1,4 +1,5 @@
1
1
  require 'active_record'
2
+ require 'thread'
2
3
 
3
4
  module Moneta
4
5
  module Adapters
@@ -10,44 +11,78 @@ module Moneta
10
11
  supports :create, :increment
11
12
  attr_reader :table
12
13
 
13
- def self.tables
14
- @tables ||= {}
15
- end
14
+ @table_mutex = ::Mutex.new
15
+ @table_refcount = {}
16
16
 
17
- # @param [Hash] options
18
- # @option options [String] :table ('moneta') Table name
19
- # @option options [Hash] :connection ActiveRecord connection configuration
20
- def initialize(options = {})
21
- table = options[:table] || 'moneta'
22
- @table = self.class.tables[table] ||=
23
- begin
24
- c = Class.new(::ActiveRecord::Base)
25
- c.table_name = table
26
- c.primary_key = :k
27
- c
17
+ class << self
18
+ def release(table)
19
+ @table_mutex.synchronize do
20
+ if (@table_refcount[table] -= 1) <= 0
21
+ remove_const(table.name.sub(/^.*::/, ''))
22
+ @table_refcount.delete(table)
23
+ end
28
24
  end
25
+ end
29
26
 
30
- if options[:connection]
31
- begin
32
- @table.establish_connection(options[:connection])
33
- rescue
34
- tries ||= 0
35
- (tries += 1) < 3 ? retry : raise
27
+ def get(options)
28
+ name = 'Table_' << options.inspect.gsub(/[^\w]+/) do
29
+ $&.unpack('H2' * $&.bytesize).join.upcase
30
+ end
31
+ @table_mutex.synchronize do
32
+ table =
33
+ if const_defined?(name)
34
+ const_get(name)
35
+ else
36
+ create(name, options)
37
+ end
38
+ @table_refcount[table] ||= 0
39
+ @table_refcount[table] += 1
40
+ table
36
41
  end
37
42
  end
38
43
 
39
- @table.connection_pool.with_connection do |conn|
40
- unless @table.table_exists?
41
- conn.create_table(table, :id => false) do |t|
42
- # Do not use binary columns (Issue #17)
43
- t.string :k, :null => false
44
- t.string :v
44
+ private
45
+
46
+ def create(name, options)
47
+ table = Class.new(::ActiveRecord::Base)
48
+ const_set(name, table)
49
+ table.table_name = options[:table] || 'moneta'
50
+ table.primary_key = :k
51
+
52
+ if options[:connection]
53
+ begin
54
+ table.establish_connection(options[:connection])
55
+ rescue
56
+ tries ||= 0
57
+ (tries += 1) < 3 ? retry : raise
58
+ end
59
+ end
60
+
61
+ table.connection_pool.with_connection do |conn|
62
+ unless table.table_exists?
63
+ conn.create_table(table.table_name, :id => false) do |t|
64
+ # Do not use binary key (Issue #17)
65
+ t.string :k, :null => false
66
+ t.binary :v
67
+ end
68
+ conn.add_index(table.table_name, :k, :unique => true)
45
69
  end
46
- conn.add_index(table, :k, :unique => true)
47
70
  end
71
+
72
+ table
73
+ rescue
74
+ remove_const(name)
75
+ raise
48
76
  end
49
77
  end
50
78
 
79
+ # @param [Hash] options
80
+ # @option options [String] :table ('moneta') Table name
81
+ # @option options [Hash] :connection ActiveRecord connection configuration
82
+ def initialize(options = {})
83
+ @table = self.class.get(options)
84
+ end
85
+
51
86
  # (see Proxy#key?)
52
87
  def key?(key, options = {})
53
88
  @table.connection_pool.with_connection do
@@ -129,6 +164,12 @@ module Moneta
129
164
  end
130
165
  self
131
166
  end
167
+
168
+ # (see Proxy#close)
169
+ def close
170
+ self.class.release(@table)
171
+ @table = nil
172
+ end
132
173
  end
133
174
  end
134
175
  end
@@ -32,7 +32,7 @@ module Moneta
32
32
  path = store_path(key)
33
33
  temp_file = ::File.join(@dir, "value-#{$$}-#{Thread.current.object_id}")
34
34
  FileUtils.mkpath(::File.dirname(path))
35
- ::File.open(temp_file, 'wb') {|file| file.write(value) }
35
+ ::File.open(temp_file, 'wb') {|f| f.write(value) }
36
36
  ::File.rename(temp_file, path)
37
37
  value
38
38
  end
@@ -63,9 +63,11 @@ module Moneta
63
63
  existed = ::File.exists?(path)
64
64
  ::File.open(path, 'ab+') do |f|
65
65
  Thread.pass until f.flock(::File::LOCK_EX)
66
+ # FIXME: JRuby needs synchronous mode, otherwise f.read might return wrong value
67
+ f.sync = true if defined?(JRUBY_VERSION)
66
68
  content = f.read
67
- f.truncate(0)
68
69
  amount += Utils.to_int(content) if existed || !content.empty?
70
+ f.truncate(0)
69
71
  f.write(amount.to_s)
70
72
  amount
71
73
  end
@@ -75,9 +77,9 @@ module Moneta
75
77
  def create(key, value, options = {})
76
78
  path = store_path(key)
77
79
  FileUtils.mkpath(::File.dirname(path))
78
- ::File.open(path, ::File::WRONLY | ::File::CREAT | ::File::EXCL) do |file|
79
- file.binmode
80
- file.write(value)
80
+ ::File.open(path, ::File::WRONLY | ::File::CREAT | ::File::EXCL) do |f|
81
+ f.binmode
82
+ f.write(value)
81
83
  end
82
84
  true
83
85
  rescue Errno::EEXIST
@@ -24,7 +24,7 @@ module Moneta
24
24
  end
25
25
  @backend.create_table?(table) do
26
26
  String :k, :null => false, :primary_key => true
27
- String :v
27
+ Blob :v
28
28
  end
29
29
  @table = @backend[table]
30
30
  end
@@ -18,8 +18,8 @@ module Moneta
18
18
  :snappy => [ :compress, '::Snappy.inflate(%s)', '::Snappy.deflate(%s)', 'snappy' ],
19
19
  :quicklz => [ :compress, '::QuickLZ.decompress(%s)', '::QuickLZ.compress(%s)', 'qlzruby' ],
20
20
  :zlib => [ :compress, '::Zlib::Inflate.inflate(%s)', '::Zlib::Deflate.deflate(%s)', 'zlib' ],
21
- :qp => [ :encode, "%s.unpack('M').first", "[%s].pack('M').strip" ],
22
- :uuencode => [ :encode, "%s.unpack('u').first", "[%s].pack('u').strip" ],
21
+ :qp => [ :encode, "%s.unpack('M').first", "[%s].pack('M')" ],
22
+ :uuencode => [ :encode, "%s.unpack('u').first", "[%s].pack('u')" ],
23
23
  :base64 => RUBY_VERSION > '1.9' ?
24
24
  [ :encode, "%s.unpack('m0').first", "[%s].pack('m0')" ] :
25
25
  [ :encode, "%s.unpack('m').first", "[%s].pack('m').gsub(\"\n\", '')" ],
@@ -1,5 +1,5 @@
1
1
  module Moneta
2
2
  # Moneta version number
3
3
  # @api public
4
- VERSION = '0.7.13'
4
+ VERSION = '0.7.14'
5
5
  end
data/script/benchmarks CHANGED
@@ -31,8 +31,9 @@ class MonetaBenchmarks
31
31
  FileUtils.mkpath(DIR)
32
32
 
33
33
  STORES = {
34
- # SDBM is unstable, YAML is too slow
34
+ # SDBM accepts only very short key/value pairs (1k for both)
35
35
  # :SDBM => { :file => "#{DIR}/sdbm" },
36
+ # YAML is too slow
36
37
  # :YAML => { :file => "#{DIR}/yaml" },
37
38
  :ActiveRecord => { :table => 'activerecord', :connection => { :adapter => (defined?(JRUBY_VERSION) ? 'jdbcmysql' : 'mysql2'), :username => 'root', :database => 'moneta' } },
38
39
  :Cassandra => {},
@@ -41,6 +41,10 @@ class Specs
41
41
  new(:specs => specs - [:increment, :concurrent_increment] + [:not_increment])
42
42
  end
43
43
 
44
+ def without_large
45
+ new(:specs => specs - [:store_large])
46
+ end
47
+
44
48
  def without_concurrent
45
49
  new(:specs => specs - [:concurrent_increment, :concurrent_create])
46
50
  end
@@ -91,7 +95,7 @@ class Specs
91
95
  end
92
96
 
93
97
  def without_store
94
- new(:specs => specs - [:store, :transform_value, :marshallable_value])
98
+ new(:specs => specs - [:store, :store_large, :transform_value, :marshallable_value])
95
99
  end
96
100
 
97
101
  def with_default_expires
@@ -103,9 +107,9 @@ class Specs
103
107
  end
104
108
  end
105
109
 
106
- ADAPTER_SPECS = Specs.new(:specs => [:null, :store, :returndifferent, :increment, :concurrent_increment, :concurrent_create, :persist, :multiprocess, :create, :features], :key => %w(string), :value => %w(string))
107
- STANDARD_SPECS = Specs.new(:specs => [:null, :store, :returndifferent, :marshallable_key, :marshallable_value, :transform_value, :increment, :concurrent_increment, :concurrent_create, :persist, :multiprocess, :create, :features])
108
- TRANSFORMER_SPECS = Specs.new(:specs => [:null, :store, :returndifferent, :transform_value, :increment, :create, :features])
110
+ ADAPTER_SPECS = Specs.new(:specs => [:null, :store, :returndifferent, :increment, :concurrent_increment, :concurrent_create, :persist, :multiprocess, :create, :features, :store_large], :key => %w(string), :value => %w(string))
111
+ STANDARD_SPECS = Specs.new(:specs => [:null, :store, :returndifferent, :marshallable_key, :marshallable_value, :transform_value, :increment, :concurrent_increment, :concurrent_create, :persist, :multiprocess, :create, :features, :store_large])
112
+ TRANSFORMER_SPECS = Specs.new(:specs => [:null, :store, :returndifferent, :transform_value, :increment, :create, :features, :store_large])
109
113
 
110
114
  header = "# Generated by #{File.basename(__FILE__)}\n"
111
115
 
@@ -273,12 +277,12 @@ end
273
277
  'simple_sdbm' => {
274
278
  :store => :SDBM,
275
279
  :options => ':file => File.join(make_tempdir, "simple_sdbm")',
276
- :specs => STANDARD_SPECS.without_multiprocess
280
+ :specs => STANDARD_SPECS.without_multiprocess.without_large
277
281
  },
278
282
  'simple_sdbm_with_expires' => {
279
283
  :store => :SDBM,
280
284
  :options => ':file => File.join(make_tempdir, "simple_sdbm_with_expires"), :expires => true',
281
- :specs => STANDARD_SPECS.without_multiprocess.with_expires
285
+ :specs => STANDARD_SPECS.without_multiprocess.with_expires.without_large
282
286
  },
283
287
  'simple_leveldb' => {
284
288
  :store => :LevelDB,
@@ -1111,13 +1115,36 @@ it 'updates an existing key/value' do
1111
1115
  records.count.should == 1
1112
1116
  end
1113
1117
 
1114
- it 'uses an existing connection' do
1115
- ActiveRecord::Base.establish_connection :adapter => (defined?(JRUBY_VERSION) ? 'jdbcmysql' : 'mysql2'), :database => 'moneta', :username => 'root'
1118
+ it 'supports different tables same database' do
1119
+ store1 = Moneta::Adapters::ActiveRecord.new(:table => 'adapter_activerecord1', :connection => { :adapter => (defined?(JRUBY_VERSION) ? 'jdbcmysql' : 'mysql2'), :database => 'moneta', :username => 'root' })
1120
+ store2 = Moneta::Adapters::ActiveRecord.new(:table => 'adapter_activerecord2', :connection => { :adapter => (defined?(JRUBY_VERSION) ? 'jdbcmysql' : 'mysql2'), :database => 'moneta', :username => 'root' })
1121
+
1122
+ store1['key'] = 'value1'
1123
+ store2['key'] = 'value2'
1124
+ store1['key'].should == 'value1'
1125
+ store2['key'].should == 'value2'
1116
1126
 
1117
- store = Moneta::Adapters::ActiveRecord.new(:table => 'activerecord_existing')
1118
- store.table.should be_table_exists
1127
+ store1.close
1128
+ store2.close
1119
1129
  end
1120
- }
1130
+
1131
+ it 'supports different databases same table' do
1132
+ store1 = Moneta::Adapters::ActiveRecord.new(:table => 'adapter_activerecord', :connection => { :adapter => (defined?(JRUBY_VERSION) ? 'jdbcmysql' : 'mysql2'), :database => 'moneta_activerecord1', :username => 'root' })
1133
+ store2 = Moneta::Adapters::ActiveRecord.new(:table => 'adapter_activerecord', :connection => { :adapter => (defined?(JRUBY_VERSION) ? 'jdbcmysql' : 'mysql2'), :database => 'moneta_activerecord2', :username => 'root' })
1134
+
1135
+ store1['key'] = 'value1'
1136
+ store2['key'] = 'value2'
1137
+ store1['key'].should == 'value1'
1138
+ store2['key'].should == 'value2'
1139
+
1140
+ store1.close
1141
+ store2.close
1142
+ end}
1143
+ },
1144
+ 'adapter_activerecord_exisiting_connection' => {
1145
+ :preamble => "require 'active_record'\nActiveRecord::Base.establish_connection :adapter => (defined?(JRUBY_VERSION) ? 'jdbcmysql' : 'mysql2'), :database => 'moneta', :username => 'root'\n",
1146
+ :build => "Moneta::Adapters::ActiveRecord.new(:table => 'adapter_activerecord_existing_connection')",
1147
+ :specs => ADAPTER_SPECS
1121
1148
  },
1122
1149
  'adapter_client' => {
1123
1150
  :preamble => "start_server(Moneta::Adapters::Memory.new)\n",
@@ -1301,7 +1328,7 @@ end}
1301
1328
  },
1302
1329
  'adapter_sdbm' => {
1303
1330
  :build => 'Moneta::Adapters::SDBM.new(:file => File.join(make_tempdir, "adapter_sdbm"))',
1304
- :specs => ADAPTER_SPECS.without_multiprocess
1331
+ :specs => ADAPTER_SPECS.without_multiprocess.without_large
1305
1332
  },
1306
1333
  'adapter_leveldb' => {
1307
1334
  :build => 'Moneta::Adapters::LevelDB.new(:dir => File.join(make_tempdir, "adapter_leveldb"))',
@@ -1720,6 +1747,18 @@ end}
1720
1747
  end
1721
1748
  end
1722
1749
 
1750
+ SPECS['store_large'] = %{it 'should store values up to 32k' do
1751
+ value = 'x' * (32 * 1024)
1752
+ store['large'] = value
1753
+ store['large'].should == value
1754
+ end
1755
+
1756
+ it 'should store keys up to 128 bytes' do
1757
+ key = 'x' * 128
1758
+ store[key] = 'value'
1759
+ store[key].should == 'value'
1760
+ end}
1761
+
1723
1762
  SPECS['not_persist'] = %{it 'does not persist values' do
1724
1763
  store['key'] = 'val'
1725
1764
  store.close
@@ -1985,17 +2024,20 @@ end
1985
2024
  it 'have atomic increment across multiple processes' do
1986
2025
  a = increment_thread('a')
1987
2026
  b = increment_thread('b')
2027
+ c = increment_thread('c')
1988
2028
  a.join
1989
2029
  b.join
2030
+ c.join
1990
2031
  1000.times do |i|
1991
2032
  store["a\#{i}"].should == i.to_s
1992
2033
  store["b\#{i}"].should == i.to_s
2034
+ store["c\#{i}"].should == i.to_s
1993
2035
  end
1994
- store.raw['counter'].should == 2000.to_s
2036
+ store.raw['counter'].should == 3000.to_s
1995
2037
  end}
1996
2038
 
1997
2039
  SPECS['concurrent_create'] = %{def create_thread(name)
1998
- a = Thread.new do
2040
+ Thread.new do
1999
2041
  s = new_store
2000
2042
  1000.times do |i|
2001
2043
  s[i.to_s].should == name if s.create(i.to_s, name, :expires => false)
@@ -2008,8 +2050,10 @@ end
2008
2050
  it 'have atomic create across multiple processes' do
2009
2051
  a = create_thread('a')
2010
2052
  b = create_thread('b')
2053
+ c = create_thread('c')
2011
2054
  a.join
2012
2055
  b.join
2056
+ c.join
2013
2057
  end}
2014
2058
 
2015
2059
  SPECS['increment'] = %{it 'initializes in #increment with 1' do
@@ -2338,11 +2382,11 @@ TESTS.each do |name, options|
2338
2382
  code = %{#{header}require 'helper'
2339
2383
 
2340
2384
  describe_moneta #{name.inspect} do
2341
- def features
2385
+ #{preamble}def features
2342
2386
  #{specs.features.to_a.inspect}
2343
2387
  end
2344
2388
 
2345
- #{preamble}def new_store
2389
+ def new_store
2346
2390
  #{build.gsub("\n", "\n ")}
2347
2391
  end
2348
2392
 
@@ -0,0 +1,31 @@
1
+ # Generated by generate-specs
2
+ require 'helper'
3
+
4
+ describe_moneta "adapter_activerecord_exisiting_connection" do
5
+ require 'active_record'
6
+ ActiveRecord::Base.establish_connection :adapter => (defined?(JRUBY_VERSION) ? 'jdbcmysql' : 'mysql2'), :database => 'moneta', :username => 'root'
7
+ def features
8
+ [:create, :increment]
9
+ end
10
+
11
+ def new_store
12
+ Moneta::Adapters::ActiveRecord.new(:table => 'adapter_activerecord_existing_connection')
13
+ end
14
+
15
+ def load_value(value)
16
+ Marshal.load(value)
17
+ end
18
+
19
+ include_context 'setup_store'
20
+ it_should_behave_like 'concurrent_create'
21
+ it_should_behave_like 'concurrent_increment'
22
+ it_should_behave_like 'create'
23
+ it_should_behave_like 'features'
24
+ it_should_behave_like 'increment'
25
+ it_should_behave_like 'multiprocess'
26
+ it_should_behave_like 'null_stringkey_stringvalue'
27
+ it_should_behave_like 'persist_stringkey_stringvalue'
28
+ it_should_behave_like 'returndifferent_stringkey_stringvalue'
29
+ it_should_behave_like 'store_stringkey_stringvalue'
30
+ it_should_behave_like 'store_large'
31
+ end
@@ -25,6 +25,7 @@ describe_moneta "adapter_activerecord" do
25
25
  it_should_behave_like 'persist_stringkey_stringvalue'
26
26
  it_should_behave_like 'returndifferent_stringkey_stringvalue'
27
27
  it_should_behave_like 'store_stringkey_stringvalue'
28
+ it_should_behave_like 'store_large'
28
29
  it 'updates an existing key/value' do
29
30
  store['foo/bar'] = '1'
30
31
  store['foo/bar'] = '2'
@@ -32,11 +33,29 @@ describe_moneta "adapter_activerecord" do
32
33
  records.count.should == 1
33
34
  end
34
35
 
35
- it 'uses an existing connection' do
36
- ActiveRecord::Base.establish_connection :adapter => (defined?(JRUBY_VERSION) ? 'jdbcmysql' : 'mysql2'), :database => 'moneta', :username => 'root'
36
+ it 'supports different tables same database' do
37
+ store1 = Moneta::Adapters::ActiveRecord.new(:table => 'adapter_activerecord1', :connection => { :adapter => (defined?(JRUBY_VERSION) ? 'jdbcmysql' : 'mysql2'), :database => 'moneta', :username => 'root' })
38
+ store2 = Moneta::Adapters::ActiveRecord.new(:table => 'adapter_activerecord2', :connection => { :adapter => (defined?(JRUBY_VERSION) ? 'jdbcmysql' : 'mysql2'), :database => 'moneta', :username => 'root' })
37
39
 
38
- store = Moneta::Adapters::ActiveRecord.new(:table => 'activerecord_existing')
39
- store.table.should be_table_exists
40
+ store1['key'] = 'value1'
41
+ store2['key'] = 'value2'
42
+ store1['key'].should == 'value1'
43
+ store2['key'].should == 'value2'
44
+
45
+ store1.close
46
+ store2.close
40
47
  end
41
48
 
49
+ it 'supports different databases same table' do
50
+ store1 = Moneta::Adapters::ActiveRecord.new(:table => 'adapter_activerecord', :connection => { :adapter => (defined?(JRUBY_VERSION) ? 'jdbcmysql' : 'mysql2'), :database => 'moneta_activerecord1', :username => 'root' })
51
+ store2 = Moneta::Adapters::ActiveRecord.new(:table => 'adapter_activerecord', :connection => { :adapter => (defined?(JRUBY_VERSION) ? 'jdbcmysql' : 'mysql2'), :database => 'moneta_activerecord2', :username => 'root' })
52
+
53
+ store1['key'] = 'value1'
54
+ store2['key'] = 'value2'
55
+ store1['key'].should == 'value1'
56
+ store2['key'].should == 'value2'
57
+
58
+ store1.close
59
+ store2.close
60
+ end
42
61
  end