Class | Irc::Bot::Registry::Accessor |
In: |
lib/rbot/registry/bdb.rb
lib/rbot/registry/tc.rb |
Parent: | Object |
This class provides persistent storage for plugins via a hash interface. The default mode is an object store, so you can store ruby objects and reference them with hash keys. This is because the default store/restore methods of the plugins’ RegistryAccessor are calls to Marshal.dump and Marshal.restore, for example:
blah = Hash.new blah[:foo] = "fum" @registry[:blah] = blah
then, even after the bot is shut down and disconnected, on the next run you can access the blah object as it was, with:
blah = @registry[:blah]
The registry can of course be used to store simple strings, fixnums, etc as well, and should be useful to store or cache plugin data or dynamic plugin configuration.
WARNING: in object store mode, don‘t make the mistake of treating it like a live object, e.g. (using the example above)
@registry[:blah][:foo] = "flump"
will NOT modify the object in the registry - remember that Registry#[] returns a Marshal.restore‘d object, the object you just modified in place will disappear. You would need to:
blah = @registry[:blah] blah[:foo] = "flump" @registry[:blah] = blah
If you don‘t need to store objects, and strictly want a persistant hash of strings, you can override the store/restore methods to suit your needs, for example (in your plugin):
def initialize class << @registry def store(val) val end def restore(val) val end end end
Your plugins section of the registry is private, it has its own namespace (derived from the plugin‘s class name, so change it and lose your data). Calls to registry.each etc, will only iterate over your namespace.
recovery | [RW] | |
recovery | [RW] |
plugins don‘t call this - a Registry::Accessor is created for them and is accessible via @registry.
# File lib/rbot/registry/bdb.rb, line 330 330: def initialize(bot, name) 331: @bot = bot 332: @name = name.downcase 333: @filename = @bot.path 'registry', @name 334: dirs = File.dirname(@filename).split("/") 335: dirs.length.times { |i| 336: dir = dirs[0,i+1].join("/")+"/" 337: unless File.exist?(dir) 338: debug "creating subregistry directory #{dir}" 339: Dir.mkdir(dir) 340: end 341: } 342: @filename << ".db" 343: @registry = nil 344: @default = nil 345: @recovery = nil 346: # debug "initializing registry accessor with name #{@name}" 347: end
plugins don‘t call this - a Registry::Accessor is created for them and is accessible via @registry.
# File lib/rbot/registry/tc.rb, line 305 305: def initialize(bot, name) 306: @bot = bot 307: @name = name.downcase 308: @filename = @bot.path 'registry', @name 309: dirs = File.dirname(@filename).split("/") 310: dirs.length.times { |i| 311: dir = dirs[0,i+1].join("/")+"/" 312: unless File.exist?(dir) 313: debug "creating subregistry directory #{dir}" 314: Dir.mkdir(dir) 315: end 316: } 317: @filename << ".tdb" 318: @registry = nil 319: @default = nil 320: @recovery = nil 321: # debug "initializing registry accessor with name #{@name}" 322: end
# File lib/rbot/registry/bdb.rb, line 360 360: def close 361: # debug "closing registry #{registry}" 362: return if !@registry 363: registry.close 364: end
# File lib/rbot/registry/tc.rb, line 334 334: def close 335: # debug "closing registry #{registry}" 336: return if !@registry 337: registry.close 338: end
# File lib/rbot/registry/tc.rb, line 396 396: def default 397: @default && (@default.dup rescue @default) 398: end
# File lib/rbot/registry/bdb.rb, line 422 422: def default 423: @default && (@default.dup rescue @default) 424: end
just like Hash#each
# File lib/rbot/registry/bdb.rb, line 427 427: def each(set=nil, bulk=0, &block) 428: return nil unless File.exist?(@filename) 429: registry.each(set, bulk) {|key,value| 430: block.call(key, restore(value)) 431: } 432: end
just like Hash#each
# File lib/rbot/registry/tc.rb, line 401 401: def each(set=nil, bulk=0, &block) 402: return nil unless File.exist?(@filename) 403: registry.fwmkeys(set).each {|key| 404: block.call(key, restore(registry[key])) 405: } 406: end
just like Hash#each_key
# File lib/rbot/registry/tc.rb, line 409 409: def each_key(set=nil, bulk=0, &block) 410: return nil unless File.exist?(@filename) 411: registry.fwmkeys(set).each do |key| 412: block.call(key) 413: end 414: end
just like Hash#each_key
# File lib/rbot/registry/bdb.rb, line 435 435: def each_key(set=nil, bulk=0, &block) 436: return nil unless File.exist?(@filename) 437: registry.each_key(set, bulk) {|key| 438: block.call(key) 439: } 440: end
just like Hash#each_value
# File lib/rbot/registry/tc.rb, line 417 417: def each_value(set=nil, bulk=0, &block) 418: return nil unless File.exist?(@filename) 419: registry.fwmkeys(set).each do |key| 420: block.call(restore(registry[key])) 421: end 422: end
just like Hash#each_value
# File lib/rbot/registry/bdb.rb, line 443 443: def each_value(set=nil, bulk=0, &block) 444: return nil unless File.exist?(@filename) 445: registry.each_value(set, bulk) { |value| 446: block.call(restore(value)) 447: } 448: end
# File lib/rbot/registry/bdb.rb, line 353 353: def flush 354: # debug "fushing registry #{registry}" 355: return if !@registry 356: registry.flush 357: registry.sync 358: end
# File lib/rbot/registry/tc.rb, line 328 328: def flush 329: # debug "fushing registry #{registry}" 330: return if !@registry 331: registry.sync 332: end
# File lib/rbot/registry/tc.rb, line 523 523: def getlist(key) 524: return [] unless File.exist?(@filename) 525: (registry.getlist(key.to_s) || []).map {|v| restore(v)} 526: end
just like Hash#has_both?
# File lib/rbot/registry/tc.rb, line 435 435: def has_both?(key, value) 436: return false unless File.exist?(@filename) 437: registry.has_key?(key.to_s) and registry.has_value?(store(value)) 438: end
just like Hash#has_both?
# File lib/rbot/registry/bdb.rb, line 460 460: def has_both?(key, value) 461: return false unless File.exist?(@filename) 462: return registry.has_both?(key, store(value)) 463: end
just like Hash#has_key?
# File lib/rbot/registry/bdb.rb, line 451 451: def has_key?(key) 452: return false unless File.exist?(@filename) 453: return registry.has_key?(key) 454: end
just like Hash#has_key?
# File lib/rbot/registry/tc.rb, line 425 425: def has_key?(key) 426: return false unless File.exist?(@filename) 427: return registry.has_key?(key.to_s) 428: end
just like Hash#has_value?
# File lib/rbot/registry/bdb.rb, line 466 466: def has_value?(value) 467: return false unless File.exist?(@filename) 468: return registry.has_value?(store(value)) 469: end
just like Hash#has_value?
# File lib/rbot/registry/tc.rb, line 441 441: def has_value?(value) 442: return false unless File.exist?(@filename) 443: return registry.has_value?(store(value)) 444: end
just like Hash#index?
# File lib/rbot/registry/tc.rb, line 447 447: def index(value) 448: self.each do |k,v| 449: return k if v == value 450: end 451: return nil 452: end
just like Hash#index?
# File lib/rbot/registry/bdb.rb, line 472 472: def index(value) 473: return nil unless File.exist?(@filename) 474: ind = registry.index(store(value)) 475: if ind 476: return ind 477: else 478: return nil 479: end 480: end
That is btree!
# File lib/rbot/registry/tc.rb, line 515 515: def putdup(key, value) 516: registry.putdup(key.to_s, store(value)) 517: end
# File lib/rbot/registry/tc.rb, line 519 519: def putlist(key, values) 520: registry.putlist(key.to_s, value.map {|v| store(v)}) 521: end
# File lib/rbot/registry/tc.rb, line 324 324: def registry 325: @registry ||= DBTree.new @bot, "registry/#{@name}" 326: end
# File lib/rbot/registry/bdb.rb, line 349 349: def registry 350: @registry ||= DBTree.new @bot, "registry/#{@name}" 351: end
restores object from string form, restore(store(val)) must return val. If you override store, you should override restore to reverse the action. For example, if you always just handle strings use:
def restore(val) val end
# File lib/rbot/registry/tc.rb, line 358 358: def restore(val) 359: begin 360: Marshal.restore(val) 361: rescue Exception => e 362: error _("failed to restore marshal data for #{val.inspect}, attempting recovery or fallback to default") 363: debug e 364: if defined? @recovery and @recovery 365: begin 366: return @recovery.call(val) 367: rescue Exception => ee 368: error _("marshal recovery failed, trying default") 369: debug ee 370: end 371: end 372: return default 373: end 374: end
restores object from string form, restore(store(val)) must return val. If you override store, you should override restore to reverse the action. For example, if you always just handle strings use:
def restore(val) val end
# File lib/rbot/registry/bdb.rb, line 384 384: def restore(val) 385: begin 386: Marshal.restore(val) 387: rescue Exception => e 388: error _("failed to restore marshal data for #{val.inspect}, attempting recovery or fallback to default") 389: debug e 390: if defined? @recovery and @recovery 391: begin 392: return @recovery.call(val) 393: rescue Exception => ee 394: error _("marshal recovery failed, trying default") 395: debug ee 396: end 397: end 398: return default 399: end 400: end
convert value to string form for storing in the registry defaults to Marshal.dump(val) but you can override this in your module‘s registry object to use any method you like. For example, if you always just handle strings use:
def store(val) val end
# File lib/rbot/registry/tc.rb, line 347 347: def store(val) 348: Marshal.dump(val) 349: end
convert value to string form for storing in the registry defaults to Marshal.dump(val) but you can override this in your module‘s registry object to use any method you like. For example, if you always just handle strings use:
def store(val) val end
# File lib/rbot/registry/bdb.rb, line 373 373: def store(val) 374: Marshal.dump(val) 375: end
# File lib/rbot/registry/tc.rb, line 503 503: def sub_registry(prefix) 504: return Accessor.new(@bot, @name + "/" + prefix.to_s) 505: end
# File lib/rbot/registry/bdb.rb, line 531 531: def sub_registry(prefix) 532: return Accessor.new(@bot, @name + "/" + prefix.to_s) 533: end
Return an array of all associations [key, value] in your namespace
# File lib/rbot/registry/tc.rb, line 467 467: def to_a 468: return [] unless File.exist?(@filename) 469: ret = Array.new 470: registry.each {|key, value| 471: ret << [key, restore(value)] 472: } 473: return ret 474: end
Return an array of all associations [key, value] in your namespace
# File lib/rbot/registry/bdb.rb, line 495 495: def to_a 496: return [] unless File.exist?(@filename) 497: ret = Array.new 498: registry.each {|key, value| 499: ret << [key, restore(value)] 500: } 501: return ret 502: end
Return an hash of all associations {key => value} in your namespace
# File lib/rbot/registry/bdb.rb, line 505 505: def to_hash 506: return {} unless File.exist?(@filename) 507: ret = Hash.new 508: registry.each {|key, value| 509: ret[key] = restore(value) 510: } 511: return ret 512: end
Return an hash of all associations {key => value} in your namespace
# File lib/rbot/registry/tc.rb, line 477 477: def to_hash 478: return {} unless File.exist?(@filename) 479: ret = Hash.new 480: registry.each {|key, value| 481: ret[key] = restore(value) 482: } 483: return ret 484: end