diff options
Diffstat (limited to 'rbot/dbhash.rb')
-rw-r--r-- | rbot/dbhash.rb | 126 |
1 files changed, 126 insertions, 0 deletions
diff --git a/rbot/dbhash.rb b/rbot/dbhash.rb new file mode 100644 index 00000000..1801a38f --- /dev/null +++ b/rbot/dbhash.rb @@ -0,0 +1,126 @@ +# Copyright (C) 2002 Tom Gilbert. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies of the Software and its documentation and acknowledgment shall be +# given in the documentation and software packages that this Software was +# used. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +require 'bdb' +# make BTree lookups case insensitive +module BDB + class CIBtree < Btree + def bdb_bt_compare(a, b) + a.downcase <=> b.downcase + end + end +end + +module Irc + + # DBHash is for tying a hash to disk (using bdb). + # Call it with an identifier, for example "mydata". It'll look for + # mydata.db, if it exists, it will load and reference that db. + # Otherwise it'll create and empty db called mydata.db + class DBHash + + # absfilename:: use +key+ as an actual filename, don't prepend the bot's + # config path and don't append ".db" + def initialize(bot, key, absfilename=false) + @bot = bot + @key = key + if absfilename && File.exist?(key) + # db already exists, use it + @db = DBHash.open_db(key) + elsif File.exist?(@bot.botclass + "/#{key}.db") + # db already exists, use it + @db = DBHash.open_db(@bot.botclass + "/#{key}.db") + elsif absfilename + # create empty db + @db = DBHash.create_db(key) + else + # create empty db + @db = DBHash.create_db(@bot.botclass + "/#{key}.db") + end + end + + def method_missing(method, *args, &block) + return @db.send(method, *args, &block) + end + + def DBHash.create_db(name) + debug "DBHash: creating empty db #{name}" + return BDB::Hash.open(name, nil, + BDB::CREATE | BDB::EXCL | BDB::TRUNCATE, + 0600, "set_pagesize" => 1024, + "set_cachesize" => [(0), (32 * 1024), (0)]) + end + + def DBHash.open_db(name) + debug "DBHash: opening existing db #{name}" + return BDB::Hash.open(name, nil, + "r+", 0600, "set_pagesize" => 1024, + "set_cachesize" => [(0), (32 * 1024), (0)]) + end + + end + + + # DBTree is a BTree equivalent of DBHash, with case insensitive lookups. + class DBTree + + # absfilename:: use +key+ as an actual filename, don't prepend the bot's + # config path and don't append ".db" + def initialize(bot, key, absfilename=false) + @bot = bot + @key = key + if absfilename && File.exist?(key) + # db already exists, use it + @db = DBTree.open_db(key) + elsif absfilename + # create empty db + @db = DBTree.create_db(key) + elsif File.exist?(@bot.botclass + "/#{key}.db") + # db already exists, use it + @db = DBTree.open_db(@bot.botclass + "/#{key}.db") + else + # create empty db + @db = DBTree.create_db(@bot.botclass + "/#{key}.db") + end + end + + def method_missing(method, *args, &block) + return @db.send(method, *args, &block) + end + + def DBTree.create_db(name) + debug "DBTree: creating empty db #{name}" + return BDB::CIBtree.open(name, nil, + BDB::CREATE | BDB::EXCL | BDB::TRUNCATE, + 0600, "set_pagesize" => 1024, + "set_cachesize" => [(0), (32 * 1024), (0)]) + end + + def DBTree.open_db(name) + debug "DBTree: opening existing db #{name}" + return BDB::CIBtree.open(name, nil, + "r+", 0600, "set_pagesize" => 1024, + "set_cachesize" => [0, 32 * 1024, 0]) + end + + end + +end |