moneta 1.4.2 → 1.5.0

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 (63) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +35 -38
  3. data/CHANGES +9 -0
  4. data/CONTRIBUTORS +2 -0
  5. data/Gemfile +143 -55
  6. data/README.md +5 -4
  7. data/lib/moneta/adapter.rb +52 -0
  8. data/lib/moneta/adapters/activerecord.rb +77 -68
  9. data/lib/moneta/adapters/activesupportcache.rb +22 -31
  10. data/lib/moneta/adapters/cassandra.rb +114 -116
  11. data/lib/moneta/adapters/client.rb +17 -18
  12. data/lib/moneta/adapters/couch.rb +31 -26
  13. data/lib/moneta/adapters/datamapper.rb +9 -5
  14. data/lib/moneta/adapters/daybreak.rb +15 -21
  15. data/lib/moneta/adapters/dbm.rb +6 -12
  16. data/lib/moneta/adapters/file.rb +21 -13
  17. data/lib/moneta/adapters/fog.rb +5 -6
  18. data/lib/moneta/adapters/gdbm.rb +6 -12
  19. data/lib/moneta/adapters/hbase.rb +10 -12
  20. data/lib/moneta/adapters/kyotocabinet.rb +22 -27
  21. data/lib/moneta/adapters/leveldb.rb +14 -20
  22. data/lib/moneta/adapters/lmdb.rb +19 -22
  23. data/lib/moneta/adapters/localmemcache.rb +7 -13
  24. data/lib/moneta/adapters/lruhash.rb +20 -20
  25. data/lib/moneta/adapters/memcached/dalli.rb +25 -33
  26. data/lib/moneta/adapters/memcached/native.rb +14 -20
  27. data/lib/moneta/adapters/memory.rb +5 -7
  28. data/lib/moneta/adapters/mongo.rb +53 -52
  29. data/lib/moneta/adapters/pstore.rb +21 -27
  30. data/lib/moneta/adapters/redis.rb +42 -37
  31. data/lib/moneta/adapters/restclient.rb +17 -25
  32. data/lib/moneta/adapters/riak.rb +8 -9
  33. data/lib/moneta/adapters/sdbm.rb +6 -12
  34. data/lib/moneta/adapters/sequel/mysql.rb +8 -8
  35. data/lib/moneta/adapters/sequel/postgres.rb +17 -17
  36. data/lib/moneta/adapters/sequel/postgres_hstore.rb +47 -47
  37. data/lib/moneta/adapters/sequel/sqlite.rb +9 -9
  38. data/lib/moneta/adapters/sequel.rb +56 -65
  39. data/lib/moneta/adapters/sqlite.rb +37 -35
  40. data/lib/moneta/adapters/tdb.rb +8 -14
  41. data/lib/moneta/adapters/tokyocabinet.rb +19 -17
  42. data/lib/moneta/adapters/tokyotyrant.rb +29 -30
  43. data/lib/moneta/adapters/yaml.rb +1 -5
  44. data/lib/moneta/config.rb +101 -0
  45. data/lib/moneta/expires.rb +0 -1
  46. data/lib/moneta/expires_support.rb +3 -4
  47. data/lib/moneta/pool.rb +1 -1
  48. data/lib/moneta/proxy.rb +29 -0
  49. data/lib/moneta/server.rb +21 -14
  50. data/lib/moneta/version.rb +1 -1
  51. data/lib/moneta/wrapper.rb +5 -0
  52. data/lib/moneta.rb +2 -0
  53. data/moneta.gemspec +1 -0
  54. data/spec/moneta/adapters/client/client_helper.rb +4 -3
  55. data/spec/moneta/adapters/faraday_helper.rb +3 -2
  56. data/spec/moneta/adapters/lruhash/adapter_lruhash_spec.rb +10 -6
  57. data/spec/moneta/adapters/mongo/adapter_mongo_spec.rb +2 -2
  58. data/spec/moneta/config_spec.rb +219 -0
  59. data/spec/moneta/proxies/transformer/transformer_bson_spec.rb +3 -1
  60. data/spec/moneta/proxies/transformer/transformer_marshal_escape_spec.rb +2 -0
  61. data/spec/rack/session_moneta_spec.rb +44 -25
  62. data/spec/restserver.rb +3 -14
  63. metadata +24 -6
@@ -4,16 +4,31 @@ module Moneta
4
4
  module Adapters
5
5
  # Sequel backend
6
6
  # @api public
7
- class Sequel
8
- include Defaults
9
-
7
+ class Sequel < Adapter
10
8
  autoload :MySQL, 'moneta/adapters/sequel/mysql'
11
9
  autoload :Postgres, 'moneta/adapters/sequel/postgres'
12
10
  autoload :PostgresHStore, 'moneta/adapters/sequel/postgres_hstore'
13
11
  autoload :SQLite, 'moneta/adapters/sequel/sqlite'
14
12
 
15
13
  supports :create, :increment, :each_key
16
- attr_reader :backend, :key_column, :value_column
14
+
15
+ config :table, default: :moneta, coerce: :to_sym
16
+ config :optimize, default: true
17
+ config :create_table, default: true
18
+ config :key_column, default: :k
19
+ config :value_column, default: :v
20
+ config :hstore, coerce: :to_s
21
+ config :each_key_server
22
+
23
+ backend do |db:, extensions: [], connection_validation_timeout: nil, **options|
24
+ ::Sequel.connect(db, options).tap do |backend|
25
+ extensions.map(&:to_sym).each(&backend.method(:extension))
26
+
27
+ if connection_validation_timeout
28
+ backend.pool.connection_validation_timeout = connection_validation_timeout
29
+ end
30
+ end
31
+ end
17
32
 
18
33
  # @param [Hash] options
19
34
  # @option options [String] :db Sequel database
@@ -22,7 +37,7 @@ module Moneta
22
37
  # @option options [Integer] :connection_validation_timeout (nil) Sequel connection_validation_timeout
23
38
  # @option options [Sequel::Database] :backend Use existing backend instance
24
39
  # @option options [Boolean] :optimize (true) Set to false to prevent database-specific optimisations
25
- # @option options [Proc, Boolean] :create_table Provide a Proc for creating the table, or
40
+ # @option options [Proc, Boolean] :create_table (true) Provide a Proc for creating the table, or
26
41
  # set to false to disable table creation all together. If a Proc is given, it will be
27
42
  # called regardless of whether the table exists already.
28
43
  # @option options [Symbol] :key_column (:k) The name of the key column
@@ -37,32 +52,21 @@ module Moneta
37
52
  # in conjunction with Sequel's `:servers` option
38
53
  # @option options All other options passed to `Sequel#connect`
39
54
  def initialize(options = {})
40
- extensions = options.delete(:extensions)
41
- connection_validation_timeout = options.delete(:connection_validation_timeout)
42
- optimize = options.delete(:optimize)
43
- @backend = options.delete(:backend) ||
44
- connect(extensions: extensions, connection_validation_timeout: connection_validation_timeout, **options)
45
-
46
- if hstore = options.delete(:hstore)
47
- @row = hstore.to_s
55
+ super
56
+
57
+ if config.hstore
48
58
  extend Sequel::PostgresHStore
49
- elsif optimize == nil || optimize
59
+ elsif config.optimize
50
60
  add_optimizations
51
61
  end
52
62
 
53
- @table_name = (options.delete(:table) || :moneta).to_sym
54
- @key_column = options.delete(:key_column) || :k
55
- @value_column = options.delete(:value_column) || :v
56
- @each_key_server = options.delete(:each_key_server)
57
-
58
- create_proc = options.delete(:create_table)
59
- if create_proc == nil
63
+ if config.create_table.respond_to?(:call)
64
+ config.create_table.call(backend)
65
+ elsif config.create_table
60
66
  create_table
61
- elsif create_proc
62
- create_proc.call(@backend)
63
67
  end
64
68
 
65
- @table = @backend[@table_name]
69
+ @table = backend[config.table]
66
70
  prepare_statements
67
71
  end
68
72
 
@@ -74,7 +78,7 @@ module Moneta
74
78
  # (see Proxy#load)
75
79
  def load(key, options = {})
76
80
  if row = @load.call(key: key)
77
- row[value_column]
81
+ row[config.value_column]
78
82
  end
79
83
  end
80
84
 
@@ -100,9 +104,9 @@ module Moneta
100
104
 
101
105
  # (see Proxy#increment)
102
106
  def increment(key, amount = 1, options = {})
103
- @backend.transaction do
107
+ backend.transaction do
104
108
  if existing = @load_for_update.call(key: key)
105
- existing_value = existing[value_column]
109
+ existing_value = existing[config.value_column]
106
110
  amount += Integer(existing_value)
107
111
  raise IncrementError, "no update" unless @increment_update.call(
108
112
  key: key,
@@ -135,13 +139,13 @@ module Moneta
135
139
 
136
140
  # (see Proxy#close)
137
141
  def close
138
- @backend.disconnect
142
+ backend.disconnect
139
143
  nil
140
144
  end
141
145
 
142
146
  # (see Proxy#slice)
143
147
  def slice(*keys, **options)
144
- @slice.all(keys).map! { |row| [row[key_column], row[value_column]] }
148
+ @slice.all(keys).map! { |row| [row[config.key_column], row[config.value_column]] }
145
149
  end
146
150
 
147
151
  # (see Proxy#values_at)
@@ -165,10 +169,10 @@ module Moneta
165
169
 
166
170
  # (see Proxy#merge!)
167
171
  def merge!(pairs, options = {})
168
- @backend.transaction do
172
+ backend.transaction do
169
173
  existing = Hash[slice_for_update(pairs)]
170
174
  update_pairs, insert_pairs = pairs.partition { |k, _| existing.key?(k) }
171
- @table.import([key_column, value_column], blob_pairs(insert_pairs))
175
+ @table.import([config.key_column, config.value_column], blob_pairs(insert_pairs))
172
176
 
173
177
  if block_given?
174
178
  update_pairs.map! do |key, new_value|
@@ -187,8 +191,10 @@ module Moneta
187
191
  # (see Proxy#each_key)
188
192
  def each_key
189
193
  return enum_for(:each_key) { @table.count } unless block_given?
190
- if @each_key_server
191
- @table.server(@each_key_server).order(key_column).select(key_column).paged_each do |row|
194
+
195
+ key_column = config.key_column
196
+ if config.each_key_server
197
+ @table.server(config.each_key_server).order(key_column).select(key_column).paged_each do |row|
192
198
  yield row[key_column]
193
199
  end
194
200
  else
@@ -201,21 +207,6 @@ module Moneta
201
207
 
202
208
  protected
203
209
 
204
- # @api private
205
- def connect(db:, extensions: nil, connection_validation_timeout: nil, **options)
206
- other_cols = [:table, :create_table, :key_column, :value_column, :hstore]
207
- ::Sequel.connect(db, options.reject { |k,| other_cols.member?(k) }).tap do |backend|
208
- if extensions
209
- raise ArgumentError, 'Option :extensions must be an Array' unless extensions.is_a?(Array)
210
- extensions.map(&:to_sym).each(&backend.method(:extension))
211
- end
212
-
213
- if connection_validation_timeout
214
- backend.pool.connection_validation_timeout = connection_validation_timeout
215
- end
216
- end
217
- end
218
-
219
210
  # @api private
220
211
  def add_optimizations
221
212
  case backend.database_type
@@ -243,9 +234,9 @@ module Moneta
243
234
  end
244
235
 
245
236
  def create_table
246
- key_column = self.key_column
247
- value_column = self.value_column
248
- @backend.create_table?(@table_name) do
237
+ key_column = config.key_column
238
+ value_column = config.value_column
239
+ backend.create_table?(config.table) do
249
240
  String key_column, null: false, primary_key: true
250
241
  File value_column
251
242
  end
@@ -253,7 +244,7 @@ module Moneta
253
244
 
254
245
  def slice_for_update(pairs)
255
246
  @slice_for_update.all(pairs.map { |k, _| k }.to_a).map! do |row|
256
- [row[key_column], row[value_column]]
247
+ [row[config.key_column], row[config.value_column]]
257
248
  end
258
249
  end
259
250
 
@@ -266,7 +257,7 @@ module Moneta
266
257
  end
267
258
 
268
259
  def statement_id(id)
269
- "moneta_#{@table_name}_#{id}".to_sym
260
+ "moneta_#{config.table}_#{id}".to_sym
270
261
  end
271
262
 
272
263
  def prepare_statements
@@ -281,49 +272,49 @@ module Moneta
281
272
 
282
273
  def prepare_key
283
274
  @key = @table
284
- .where(key_column => :$key).select(1)
275
+ .where(config.key_column => :$key).select(1)
285
276
  .prepare(:first, statement_id(:key))
286
277
  end
287
278
 
288
279
  def prepare_load
289
280
  @load = @table
290
- .where(key_column => :$key).select(value_column)
281
+ .where(config.key_column => :$key).select(config.value_column)
291
282
  .prepare(:first, statement_id(:load))
292
283
  end
293
284
 
294
285
  def prepare_store
295
286
  @store_update = @table
296
- .where(key_column => :$key)
297
- .prepare(:update, statement_id(:store_update), value_column => :$value)
287
+ .where(config.key_column => :$key)
288
+ .prepare(:update, statement_id(:store_update), config.value_column => :$value)
298
289
  end
299
290
 
300
291
  def prepare_create
301
292
  @create = @table
302
- .prepare(:insert, statement_id(:create), key_column => :$key, value_column => :$value)
293
+ .prepare(:insert, statement_id(:create), config.key_column => :$key, config.value_column => :$value)
303
294
  end
304
295
 
305
296
  def prepare_increment
306
297
  @load_for_update = @table
307
- .where(key_column => :$key).for_update
308
- .select(value_column)
298
+ .where(config.key_column => :$key).for_update
299
+ .select(config.value_column)
309
300
  .prepare(:first, statement_id(:load_for_update))
310
301
  @increment_update ||= @table
311
- .where(key_column => :$key, value_column => :$value)
312
- .prepare(:update, statement_id(:increment_update), value_column => :$new_value)
302
+ .where(config.key_column => :$key, config.value_column => :$value)
303
+ .prepare(:update, statement_id(:increment_update), config.value_column => :$new_value)
313
304
  end
314
305
 
315
306
  def prepare_delete
316
- @delete = @table.where(key_column => :$key)
307
+ @delete = @table.where(config.key_column => :$key)
317
308
  .prepare(:delete, statement_id(:delete))
318
309
  end
319
310
 
320
311
  def prepare_slice
321
312
  @slice_for_update = ::Sequel::Dataset::PlaceholderLiteralizer.loader(@table) do |pl, ds|
322
- ds.filter(key_column => pl.arg).select(key_column, value_column).for_update
313
+ ds.filter(config.key_column => pl.arg).select(config.key_column, config.value_column).for_update
323
314
  end
324
315
 
325
316
  @slice = ::Sequel::Dataset::PlaceholderLiteralizer.loader(@table) do |pl, ds|
326
- ds.filter(key_column => pl.arg).select(key_column, value_column)
317
+ ds.filter(config.key_column => pl.arg).select(config.key_column, config.value_column)
327
318
  end
328
319
  end
329
320
 
@@ -4,12 +4,16 @@ module Moneta
4
4
  module Adapters
5
5
  # Sqlite3 backend
6
6
  # @api public
7
- class Sqlite
8
- include Defaults
7
+ class Sqlite < Adapter
9
8
  include IncrementSupport
10
9
 
11
10
  supports :create, :each_key
12
- attr_reader :backend
11
+
12
+ config :table, default: 'moneta'
13
+ config :busy_timeout, default: 1000
14
+ config :journal_mode
15
+
16
+ backend { |file:| ::SQLite3::Database.new(file) }
13
17
 
14
18
  # @param [Hash] options
15
19
  # @option options [String] :file Database file
@@ -18,31 +22,29 @@ module Moneta
18
22
  # @option options [::Sqlite3::Database] :backend Use existing backend instance
19
23
  # @option options [String, Symbol] :journal_mode Set the journal mode for the connection
20
24
  def initialize(options = {})
21
- @table = options[:table] || 'moneta'
22
- @backend = options[:backend] ||
23
- begin
24
- raise ArgumentError, 'Option :file is required' unless options[:file]
25
- ::SQLite3::Database.new(options[:file])
26
- end
27
- @backend.busy_timeout(options[:busy_timeout] || 1000)
28
- @backend.execute("create table if not exists #{@table} (k blob not null primary key, v blob)")
29
- if journal_mode = options[:journal_mode]
30
- @backend.journal_mode = journal_mode.to_s
25
+ super
26
+
27
+ backend.busy_timeout(config.busy_timeout)
28
+ backend.execute("create table if not exists #{config.table} (k blob not null primary key, v blob)")
29
+
30
+ if journal_mode = config.journal_mode
31
+ backend.journal_mode = journal_mode.to_s
31
32
  end
33
+
32
34
  @stmts =
33
- [@exists = @backend.prepare("select exists(select 1 from #{@table} where k = ?)"),
34
- @select = @backend.prepare("select v from #{@table} where k = ?"),
35
- @replace = @backend.prepare("replace into #{@table} values (?, ?)"),
36
- @delete = @backend.prepare("delete from #{@table} where k = ?"),
37
- @clear = @backend.prepare("delete from #{@table}"),
38
- @create = @backend.prepare("insert into #{@table} values (?, ?)"),
39
- @keys = @backend.prepare("select k from #{@table}"),
40
- @count = @backend.prepare("select count(*) from #{@table}")]
41
-
42
- version = @backend.execute("select sqlite_version()").first.first
35
+ [@exists = backend.prepare("select exists(select 1 from #{config.table} where k = ?)"),
36
+ @select = backend.prepare("select v from #{config.table} where k = ?"),
37
+ @replace = backend.prepare("replace into #{config.table} values (?, ?)"),
38
+ @delete = backend.prepare("delete from #{config.table} where k = ?"),
39
+ @clear = backend.prepare("delete from #{config.table}"),
40
+ @create = backend.prepare("insert into #{config.table} values (?, ?)"),
41
+ @keys = backend.prepare("select k from #{config.table}"),
42
+ @count = backend.prepare("select count(*) from #{config.table}")]
43
+
44
+ version = backend.execute("select sqlite_version()").first.first
43
45
  if @can_upsert = ::Gem::Version.new(version) >= ::Gem::Version.new('3.24.0')
44
- @stmts << (@increment = @backend.prepare <<-SQL)
45
- insert into #{@table} values (?, ?)
46
+ @stmts << (@increment = backend.prepare <<-SQL)
47
+ insert into #{config.table} values (?, ?)
46
48
  on conflict (k)
47
49
  do update set v = cast(cast(v as integer) + ? as blob)
48
50
  where v = '0' or v = X'30' or cast(v as integer) != 0
@@ -76,8 +78,8 @@ module Moneta
76
78
 
77
79
  # (see Proxy#increment)
78
80
  def increment(key, amount = 1, options = {})
79
- @backend.transaction(:exclusive) { return super } unless @can_upsert
80
- @backend.transaction do
81
+ backend.transaction(:exclusive) { return super } unless @can_upsert
82
+ backend.transaction do
81
83
  @increment.execute!(key, amount.to_s, amount)
82
84
  return Integer(load(key))
83
85
  end
@@ -103,14 +105,14 @@ module Moneta
103
105
  # (see Proxy#close)
104
106
  def close
105
107
  @stmts.each { |s| s.close }
106
- @backend.close
108
+ backend.close
107
109
  nil
108
110
  end
109
111
 
110
112
  # (see Proxy#slice)
111
113
  def slice(*keys, **options)
112
- query = "select k, v from #{@table} where k in (#{(['?'] * keys.length).join(',')})"
113
- @backend.execute(query, keys)
114
+ query = "select k, v from #{config.table} where k in (#{(['?'] * keys.length).join(',')})"
115
+ backend.execute(query, keys)
114
116
  end
115
117
 
116
118
  # (see Proxy#values_at)
@@ -134,7 +136,7 @@ module Moneta
134
136
 
135
137
  # (see Proxy#merge!)
136
138
  def merge!(pairs, options = {})
137
- transaction = @backend.transaction if block_given?
139
+ transaction = backend.transaction if block_given?
138
140
 
139
141
  if block_given?
140
142
  existing = Hash[slice(*pairs.map { |k, _| k }.to_a)]
@@ -146,13 +148,13 @@ module Moneta
146
148
  pairs = pairs.to_a
147
149
  end
148
150
 
149
- query = "replace into #{@table} (k, v) values" + (['(?, ?)'] * pairs.length).join(',')
150
- @backend.query(query, pairs.flatten).close
151
+ query = "replace into #{config.table} (k, v) values" + (['(?, ?)'] * pairs.length).join(',')
152
+ backend.query(query, pairs.flatten).close
151
153
  rescue
152
- @backend.rollback if transaction
154
+ backend.rollback if transaction
153
155
  raise
154
156
  else
155
- @backend.commit if transaction
157
+ backend.commit if transaction
156
158
  self
157
159
  end
158
160
 
@@ -4,34 +4,28 @@ module Moneta
4
4
  module Adapters
5
5
  # TDB backend
6
6
  # @api public
7
- class TDB
8
- include Defaults
7
+ class TDB < Adapter
9
8
  include HashAdapter
10
9
  include IncrementSupport
11
10
  include EachKeySupport
12
11
 
13
12
  supports :create
14
13
 
15
- # @param [Hash] options
16
- # @option options [String] :file Database file
17
- # @option options [::TDB] :backend Use existing backend instance
18
- def initialize(options)
19
- @backend = options[:backend] ||
20
- begin
21
- raise ArgumentError, 'Option :file is required' unless file = options.delete(:file)
22
- ::TDB.new(file, options)
23
- end
24
- end
14
+ # @!method initialize(options = {})
15
+ # @param [Hash] options
16
+ # @option options [String] :file Database file
17
+ # @option options [::TDB] :backend Use existing backend instance
18
+ backend { |file:, **options| ::TDB.new(file, options) }
25
19
 
26
20
  # (see Proxy#close)
27
21
  def close
28
- @backend.close
22
+ backend.close
29
23
  nil
30
24
  end
31
25
 
32
26
  # (see Proxy#create)
33
27
  def create(key, value, options = {})
34
- @backend.insert!(key, value)
28
+ backend.insert!(key, value)
35
29
  true
36
30
  rescue ::TDB::ERR::EXISTS
37
31
  false
@@ -4,29 +4,31 @@ module Moneta
4
4
  module Adapters
5
5
  # TokyoCabinet backend
6
6
  # @api public
7
- class TokyoCabinet
8
- include Defaults
7
+ class TokyoCabinet < Adapter
9
8
  include HashAdapter
10
9
  include IncrementSupport
11
10
  include CreateSupport
12
11
  include EachKeySupport
13
12
 
14
- # @param [Hash] options
15
- # @option options [String] :file Database file
16
- # @option options [Symbol] :type (:hdb) Database type (:bdb and :hdb possible)
17
- # @option options [::TokyoCabinet::*DB] :backend Use existing backend instance
18
- def initialize(options = {})
19
- if options[:backend]
20
- @backend = options[:backend]
13
+ # @!method initialize(options = {})
14
+ # @param [Hash] options
15
+ # @option options [String] :file Database file
16
+ # @option options [Symbol] :type (:hdb) Database type (:bdb and :hdb possible)
17
+ # @option options [::TokyoCabinet::*DB] :backend Use existing backend instance
18
+ backend do |file:, type: :hdb|
19
+ case type
20
+ when :bdb
21
+ ::TokyoCabinet::BDB.new.tap do |backend|
22
+ backend.open(file, ::TokyoCabinet::BDB::OWRITER | ::TokyoCabinet::BDB::OCREAT) or
23
+ raise backend.errmsg(backend.ecode)
24
+ end
25
+ when :hdb
26
+ ::TokyoCabinet::HDB.new.tap do |backend|
27
+ backend.open(file, ::TokyoCabinet::HDB::OWRITER | ::TokyoCabinet::HDB::OCREAT) or
28
+ raise backend.errmsg(backend.ecode)
29
+ end
21
30
  else
22
- raise ArgumentError, 'Option :file is required' unless options[:file]
23
- if options[:type] == :bdb
24
- @backend = ::TokyoCabinet::BDB.new
25
- @backend.open(options[:file], ::TokyoCabinet::BDB::OWRITER | ::TokyoCabinet::BDB::OCREAT)
26
- else
27
- @backend = ::TokyoCabinet::HDB.new
28
- @backend.open(options[:file], ::TokyoCabinet::HDB::OWRITER | ::TokyoCabinet::HDB::OCREAT)
29
- end or raise @backend.errmsg(@backend.ecode)
31
+ raise ArgumentError, ":type must be :bdb or :hdb"
30
32
  end
31
33
  end
32
34
 
@@ -10,51 +10,50 @@ module Moneta
10
10
  module Adapters
11
11
  # TokyoTyrant backend
12
12
  # @api public
13
- class TokyoTyrant
14
- include Defaults
13
+ class TokyoTyrant < Adapter
15
14
  include HashAdapter
16
15
 
17
16
  # error code: no record found
18
17
  ENOREC = 7
19
18
 
20
19
  supports :create, :increment
21
- attr_reader :backend
20
+
21
+ backend do |host: '127.0.0.1', port: 1978|
22
+ if defined?(::TokyoTyrant::RDB)
23
+ # Use ruby client
24
+ ::TokyoTyrant::RDB.new.tap do |backend|
25
+ backend.open(host, port) or raise backend.errmsg
26
+ end
27
+ else
28
+ # Use native client
29
+ ::TokyoTyrant::DB.new(host, port)
30
+ end
31
+ end
22
32
 
23
33
  # @param [Hash] options
24
34
  # @option options [String] :host ('127.0.0.1') Server host name
25
35
  # @option options [Integer] :port (1978) Server port
26
36
  # @option options [::TokyoTyrant::RDB] :backend Use existing backend instance
27
37
  def initialize(options = {})
28
- options[:host] ||= '127.0.0.1'
29
- options[:port] ||= 1978
30
- if options[:backend]
31
- @backend = options[:backend]
32
- elsif defined?(::TokyoTyrant::RDB)
33
- # Use ruby client
34
- @backend = ::TokyoTyrant::RDB.new
35
- @backend.open(options[:host], options[:port]) or error
36
- else
37
- # Use native client
38
- @backend = ::TokyoTyrant::DB.new(options[:host], options[:port])
39
- end
40
- @native = @backend.class.name != 'TokyoTyrant::RDB'
38
+ super
39
+ @native = backend.class.name != 'TokyoTyrant::RDB'
41
40
  probe = '__tokyotyrant_endianness_probe'
42
- @backend.delete(probe)
43
- @backend.addint(probe, 1)
44
- @pack = @backend.delete(probe) == [1].pack('l>') ? 'l>' : 'l<'
41
+ backend.delete(probe)
42
+ backend.addint(probe, 1)
43
+ @pack = backend.delete(probe) == [1].pack('l>') ? 'l>' : 'l<'
45
44
  end
46
45
 
47
46
  # (see Proxy#load)
48
47
  def load(key, options = {})
49
- value = @backend[key]
48
+ value = backend[key]
50
49
  # raise if there is an error and the error is not "no record"
51
- error if value == nil && @backend.ecode != ENOREC
50
+ error if value == nil && backend.ecode != ENOREC
52
51
  value && unpack(value)
53
52
  end
54
53
 
55
54
  # (see Proxy#store)
56
55
  def store(key, value, options = {})
57
- @backend.put(key, pack(value)) or error
56
+ backend.put(key, pack(value)) or error
58
57
  value
59
58
  end
60
59
 
@@ -62,14 +61,14 @@ module Moneta
62
61
  def delete(key, options = {})
63
62
  value = load(key, options)
64
63
  if value
65
- @backend.delete(key) or error
64
+ backend.delete(key) or error
66
65
  value
67
66
  end
68
67
  end
69
68
 
70
69
  # (see Proxy#increment)
71
70
  def increment(key, amount = 1, options = {})
72
- @backend.addint(key, amount) or error
71
+ backend.addint(key, amount) or error
73
72
  end
74
73
 
75
74
  # (see Proxy#create)
@@ -77,18 +76,18 @@ module Moneta
77
76
  if @native
78
77
  begin
79
78
  # Native client throws an exception
80
- @backend.putkeep(key, pack(value))
79
+ backend.putkeep(key, pack(value))
81
80
  rescue TokyoTyrantError
82
81
  false
83
82
  end
84
83
  else
85
- @backend.putkeep(key, pack(value))
84
+ backend.putkeep(key, pack(value))
86
85
  end
87
86
  end
88
87
 
89
88
  # (see Proxy#close)
90
89
  def close
91
- @backend.close
90
+ backend.close
92
91
  nil
93
92
  end
94
93
 
@@ -96,10 +95,10 @@ module Moneta
96
95
  def slice(*keys, **options)
97
96
  hash =
98
97
  if @native
99
- @backend.mget(*keys)
98
+ backend.mget(*keys)
100
99
  else
101
100
  hash = Hash[keys.map { |key| [key] }]
102
- raise unless @backend.mget(hash) >= 0
101
+ raise unless backend.mget(hash) >= 0
103
102
  hash
104
103
  end
105
104
 
@@ -142,7 +141,7 @@ module Moneta
142
141
  end
143
142
 
144
143
  def error
145
- raise "#{@backend.class.name} error: #{@backend.errmsg}"
144
+ raise "#{backend.class.name} error: #{backend.errmsg}"
146
145
  end
147
146
  end
148
147
  end
@@ -5,11 +5,7 @@ module Moneta
5
5
  # YAML::Store backend
6
6
  # @api public
7
7
  class YAML < PStore
8
- protected
9
-
10
- def new_store(options)
11
- ::YAML::Store.new(options[:file])
12
- end
8
+ backend { |file:| ::YAML::Store.new(file) }
13
9
  end
14
10
  end
15
11
  end