]> git.netwichtig.de Git - user/henk/code/ruby/rbot.git/blob - rbot/dbhash.rb
initial import of rbot
[user/henk/code/ruby/rbot.git] / rbot / dbhash.rb
1 # Copyright (C) 2002 Tom Gilbert.
2 #
3 # Permission is hereby granted, free of charge, to any person obtaining a copy
4 # of this software and associated documentation files (the "Software"), to
5 # deal in the Software without restriction, including without limitation the
6 # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7 # sell copies of the Software, and to permit persons to whom the Software is
8 # furnished to do so, subject to the following conditions:
9 #
10 # The above copyright notice and this permission notice shall be included in
11 # all copies of the Software and its documentation and acknowledgment shall be
12 # given in the documentation and software packages that this Software was
13 # used.
14 #
15 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 # THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 # IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
22 require 'bdb'
23 # make BTree lookups case insensitive
24 module BDB
25   class CIBtree < Btree
26     def bdb_bt_compare(a, b)
27       a.downcase <=> b.downcase
28     end
29   end
30 end
31
32 module Irc
33
34   # DBHash is for tying a hash to disk (using bdb).
35   # Call it with an identifier, for example "mydata". It'll look for
36   # mydata.db, if it exists, it will load and reference that db.
37   # Otherwise it'll create and empty db called mydata.db
38   class DBHash
39     
40     # absfilename:: use +key+ as an actual filename, don't prepend the bot's
41     #               config path and don't append ".db"
42     def initialize(bot, key, absfilename=false)
43       @bot = bot
44       @key = key
45       if absfilename && File.exist?(key)
46         # db already exists, use it
47         @db = DBHash.open_db(key)
48       elsif File.exist?(@bot.botclass + "/#{key}.db")
49         # db already exists, use it
50         @db = DBHash.open_db(@bot.botclass + "/#{key}.db")
51       elsif absfilename
52         # create empty db
53         @db = DBHash.create_db(key)
54       else
55         # create empty db
56         @db = DBHash.create_db(@bot.botclass + "/#{key}.db")
57       end
58     end
59
60     def method_missing(method, *args, &block)
61       return @db.send(method, *args, &block)
62     end
63
64     def DBHash.create_db(name)
65       debug "DBHash: creating empty db #{name}"
66       return BDB::Hash.open(name, nil, 
67                              BDB::CREATE | BDB::EXCL | BDB::TRUNCATE,
68                              0600, "set_pagesize" => 1024,
69                              "set_cachesize" => [(0), (32 * 1024), (0)])
70     end
71
72     def DBHash.open_db(name)
73       debug "DBHash: opening existing db #{name}"
74       return BDB::Hash.open(name, nil, 
75                              "r+", 0600, "set_pagesize" => 1024,
76                              "set_cachesize" => [(0), (32 * 1024), (0)])
77     end
78     
79   end
80
81   
82   # DBTree is a BTree equivalent of DBHash, with case insensitive lookups.
83   class DBTree
84     
85     # absfilename:: use +key+ as an actual filename, don't prepend the bot's
86     #               config path and don't append ".db"
87     def initialize(bot, key, absfilename=false)
88       @bot = bot
89       @key = key
90       if absfilename && File.exist?(key)
91         # db already exists, use it
92         @db = DBTree.open_db(key)
93       elsif absfilename
94         # create empty db
95         @db = DBTree.create_db(key)
96       elsif File.exist?(@bot.botclass + "/#{key}.db")
97         # db already exists, use it
98         @db = DBTree.open_db(@bot.botclass + "/#{key}.db")
99       else
100         # create empty db
101         @db = DBTree.create_db(@bot.botclass + "/#{key}.db")
102       end
103     end
104
105     def method_missing(method, *args, &block)
106       return @db.send(method, *args, &block)
107     end
108
109     def DBTree.create_db(name)
110       debug "DBTree: creating empty db #{name}"
111       return BDB::CIBtree.open(name, nil, 
112                              BDB::CREATE | BDB::EXCL | BDB::TRUNCATE,
113                              0600, "set_pagesize" => 1024,
114                              "set_cachesize" => [(0), (32 * 1024), (0)])
115     end
116
117     def DBTree.open_db(name)
118       debug "DBTree: opening existing db #{name}"
119       return BDB::CIBtree.open(name, nil, 
120                              "r+", 0600, "set_pagesize" => 1024,
121                              "set_cachesize" => [0, 32 * 1024, 0])
122     end
123     
124   end
125
126 end