moneta 0.7.13 → 0.7.14

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 (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