Module: Rufus::Edo::CabinetCore

Includes:
Tokyo::HashMethods, Tokyo::Transactions
Included in:
Cabinet, NetTyrant
Defined in:
lib/rufus/edo/cabcore.rb

Overview

The base cabinet methods are gathered here. They focus on wrapping Hirabayashi-san’s methods.

This module is included by Edo::Cabinet and Edo::NTyrant. Placing the methods in this module avoids having to load ‘TokyoCabinet’ when using only rufus/edo/ntyrant.

Instance Attribute Summary

Attributes included from Tokyo::HashMethods

#default_proc

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Tokyo::Transactions

#abort, #transaction

Methods included from Tokyo::HashMethods

#[], #default, #default=, #each, #merge, #to_a, #to_h, #values

Class Method Details

.included(target) ⇒ Object

Add the open() method to all Cabinet type classes.



47
48
49
# File 'lib/rufus/edo/cabcore.rb', line 47

def self.included(target)
  target.extend(Rufus::Tokyo::Openable)
end

Instance Method Details

#[]=(k, v) ⇒ Object

No comment



60
61
62
63
64
65
# File 'lib/rufus/edo/cabcore.rb', line 60

def []= (k, v)

  k = k.to_s; v = v.to_s

  @db.put(k, v) || raise_error
end

#clearObject

Removes all the records in the cabinet (use with care)

Returns self (like Ruby’s Hash does).



119
120
121
122
123
124
# File 'lib/rufus/edo/cabcore.rb', line 119

def clear

  @db.vanish || raise_error

  self
end

#closeObject

Closes the cabinet (and frees the datastructure allocated for it), returns true in case of success.



136
137
138
139
# File 'lib/rufus/edo/cabcore.rb', line 136

def close

  @db.close || raise_error
end

#compact_copy(target_path) ⇒ Object

Copies the current cabinet to a new file.

Does it by copying each entry afresh to the target file. Spares some space, hence the ‘compact’ label…



155
156
157
158
159
160
# File 'lib/rufus/edo/cabcore.rb', line 155

def compact_copy (target_path)

  @other_db = self.class.new(target_path)
  self.each { |k, v| @other_db[k] = v }
  @other_db.close
end

#copy(target_path) ⇒ Object

Copies the current cabinet to a new file.

Returns true if it was successful.



145
146
147
148
# File 'lib/rufus/edo/cabcore.rb', line 145

def copy (target_path)

  @db.copy(target_path)
end

#counter_value(key) ⇒ Object

Returns the current value for a counter (a float or an int).

See #incr



291
292
293
294
# File 'lib/rufus/edo/cabcore.rb', line 291

def counter_value (key)

  incr(key, 0.0) rescue incr(key, 0)
end

#defragObject

Triggers a defrag (TC >= 1.4.21 only)



298
299
300
301
302
303
304
305
# File 'lib/rufus/edo/cabcore.rb', line 298

def defrag

  #raise(NotImplementedError.new(
  #  "defrag (misc) only available when opening db with :type => :abstract"
  #)) unless @db.respond_to?(:misc)

  @db.misc('defrag', [])
end

#delete(k) ⇒ Object

Removes a record from the cabinet, returns the value if successful else nil.



100
101
102
103
104
105
106
# File 'lib/rufus/edo/cabcore.rb', line 100

def delete (k)

  k = k.to_s
  v = self[k]

  @db.out(k) ? v : nil
end

#delete_keys_with_prefix(prefix) ⇒ Object

Deletes all the entries whose keys begin with the given prefix



194
195
196
197
198
199
200
201
202
203
204
205
# File 'lib/rufus/edo/cabcore.rb', line 194

def delete_keys_with_prefix (prefix)

  # only ADB has the #misc method...

  if @db.respond_to?(:misc)
    @db.misc('outlist', @db.fwmkeys(prefix, -1))
  else
    @db.fwmkeys(prefix, -1).each { |k| self.delete(k) }
  end

  nil
end

#incr(key, val = 1) ⇒ Object Also known as: adddouble, addint, add_double, add_int

Increments the value stored under the given key with the given increment (defaults to 1 (integer)).

Warning : Tokyo Cabinet/Tyrant doesn’t store counter values as regular strings (db won’t yield something that replies properly to #to_i)

Use #counter_value(k) to get the current value set for the counter.

Raises:



269
270
271
272
273
274
275
276
277
278
279
280
281
# File 'lib/rufus/edo/cabcore.rb', line 269

def incr (key, val=1)

  key = key.to_s

  v = val.is_a?(Fixnum) ? @db.addint(key, val) : @db.adddouble(key, val)

  raise(EdoError.new(
    "incr failed, there is probably already a string value set " +
    "for the key '#{key}'. Make sure there is no value before incrementing"
  )) unless v

  v
end

#keys(options = {}) ⇒ Object

Returns an array of all the primary keys in the db.

With no options given, this method will return all the keys (strings) in a Ruby array.

:prefix --> returns only the keys who match a given string prefix

:limit --> returns a limited number of keys


179
180
181
182
183
184
185
186
187
188
189
190
# File 'lib/rufus/edo/cabcore.rb', line 179

def keys (options={})

  if @db.respond_to? :fwmkeys
    pref = options.fetch(:prefix, "")

    @db.fwmkeys(pref, options[:limit] || -1)
  elsif @db.respond_to? :range
    @db.range("[min,max]", nil)
  else
    raise NotImplementedError, "Database does not support keys()"
  end
end

#ldelete(*keys) ⇒ Object

Given a list of keys, deletes all the matching entries (in one sweep).

Warning : this is a naive (slow) implementation.



246
247
248
249
250
251
252
253
254
255
256
257
258
259
# File 'lib/rufus/edo/cabcore.rb', line 246

def ldelete (*keys)

  keys = keys.flatten.collect { |k| k.to_s }

  # only ADB has the #misc method...

  if @db.respond_to?(:misc)
    @db.misc('outlist', keys)
  else
    keys.each { |k| self.delete(k) }
  end

  nil
end

#lget(*keys) ⇒ Object Also known as: mget

Given a list of keys, returns a Hash { key => value } of the matching entries (in one sweep).

Warning : this is a naive (slow) implementation.



212
213
214
215
216
217
218
219
220
221
222
223
# File 'lib/rufus/edo/cabcore.rb', line 212

def lget (*keys)

  keys = keys.flatten.collect { |k| k.to_s }

  # only ADB has the #misc method...

  if @db.respond_to?(:misc)
    Hash[*@db.misc('getlist', keys)]
  else
    keys.inject({}) { |h, k| v = self[k]; h[k] = v if v; h }
  end
end

#merge!(hash) ⇒ Object Also known as: lput

Default impl provided by HashMethods



229
230
231
232
233
234
235
236
237
238
239
# File 'lib/rufus/edo/cabcore.rb', line 229

def merge! (hash)

  # only ADB has the #misc method...

  if @db.respond_to?(:misc)
    @db.misc('putlist', hash.to_a.flatten)
  else
    super(hash)
  end
  self
end

#originalObject

Returns the underlying ‘native’ Ruby object (of the class devised by Hirabayashi-san)



310
311
312
313
# File 'lib/rufus/edo/cabcore.rb', line 310

def original

  @db
end

#pathObject

Returns the path to this database.



53
54
55
56
# File 'lib/rufus/edo/cabcore.rb', line 53

def path

  @path
end

#putcat(k, v) ⇒ Object

Appends the given string at the end of the current string value for key k. If there is no record for key k, a new record will be created.

Returns true if successful.



82
83
84
85
86
87
# File 'lib/rufus/edo/cabcore.rb', line 82

def putcat (k, v)

  k = k.to_s; v = v.to_s

  @db.putcat(k, v)
end

#putkeep(k, v) ⇒ Object

Like #put but doesn’t overwrite the value if already set. Returns true only if there no previous entry for k.



70
71
72
73
74
75
# File 'lib/rufus/edo/cabcore.rb', line 70

def putkeep (k, v)

  k = k.to_s; v = v.to_s

  @db.putkeep(k, v)
end

#sizeObject

Returns the number of records in the ‘cabinet’



110
111
112
113
# File 'lib/rufus/edo/cabcore.rb', line 110

def size

  @db.rnum
end

#syncObject

“synchronize updated contents of an abstract database object with the file and the device”



165
166
167
168
# File 'lib/rufus/edo/cabcore.rb', line 165

def sync

  @db.sync || raise_error
end

#tranabortObject

This is rather low-level use #transaction and a block for a higher-level technique.

Note that fixed-length dbs do not support transactions. It will result in a NoMethodError.



346
347
348
# File 'lib/rufus/edo/cabcore.rb', line 346

def tranabort
  @db.tranabort
end

#tranbeginObject

This is rather low-level, you’d better use #transaction like in

db.transaction do
  db['a'] = 'alpha'
  db['b'] = 'bravo'
  db.abort if something_went_wrong?
end

Note that fixed-length dbs do not support transactions. It will result in a NoMethodError.



326
327
328
# File 'lib/rufus/edo/cabcore.rb', line 326

def tranbegin
  @db.tranbegin
end

#trancommitObject

This is rather low-level use #transaction and a block for a higher-level technique.

Note that fixed-length dbs do not support transactions. It will result in a NoMethodError.



336
337
338
# File 'lib/rufus/edo/cabcore.rb', line 336

def trancommit
  @db.trancommit
end

#weightObject

Returns the ‘weight’ of the db (in bytes)



128
129
130
131
# File 'lib/rufus/edo/cabcore.rb', line 128

def weight

  @db.fsiz
end