4
Ruby support library for dhelp database access
6
Copyright (C) 2005 Esteban Manchado Vel�zquez
8
This program is free software; you can redistribute it and/or modify
9
it under the terms of the GNU General Public License as published by
10
the Free Software Foundation; either version 2 of the License, or
11
(at your option) any later version.
13
This program is distributed in the hope that it will be useful,
14
but WITHOUT ANY WARRANTY; without even the implied warranty of
15
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
GNU General Public License for more details.
18
You should have received a copy of the GNU General Public License
19
along with this program; if not, write to the Free Software
20
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25
# Dhelp-related classes
31
# Get/Set the pack format
32
def pack_fmt(fmt = nil)
36
# Get/Set the field list. It can be set as an array, or as several
41
# Just get the value, do nothing
44
@fieldList = first.kind_of?(Array) ? first : [first]
48
@fieldList.map {|f| f.to_sym}
57
@data = keys.map {|f| data[f]}.pack(pack_fmt)
59
raise ArgumentError, "Argument must be either String or Hash"
63
# Handy shortcut methods
64
def keys; self.class.field_list; end
65
def pack_fmt; self.class.pack_fmt; end
68
i = keys.index(f.to_sym)
70
@data.unpack(pack_fmt)[i]
72
raise ArgumentError, "Unknown field '#{f}'"
76
# Returns a Hash object with all the C struct fields
85
# Returns the data in C format
90
# Catches missing methods, to get the field values
91
def method_missing(meth, *args)
92
if keys.include? meth.to_sym
102
class KeyData < CStructWrapper
103
pack_fmt 'Z100 Z100 Z100'
104
field_list %w(file dir name)
109
class ValueData < CStructWrapper
111
field_list %w(descrip)
115
# Title database key data entry
116
class TitleKeyData < CStructWrapper
122
# Title database value data entry
123
class TitleValueData < CStructWrapper
125
field_list %w(dtitle)
130
class ItemData < CStructWrapper
131
pack_fmt 'Z100 Z100 Z100 Z100 Z1000'
132
field_list %w(dir dtitle name file descrip)
137
class Database < BDB::Btree
138
STD_COMPARISON = lambda {|a,b|
139
dataA, dataB = KeyData.new(a), KeyData.new(b)
140
r = dataA.dir <=> dataB.dir
141
r == 0 ? (dataA.name <=> dataB.name) : r
144
def Database.open(flags = BDB::RDONLY,
147
# name = 'dhelpdbase',
148
name = '/var/lib/dhelp/dbase',
150
defaultOptions = {"flags" => 0,
151
"cachesize" => 10000,
154
"compare" => STD_COMPARISON,
157
super(name, subname, flags, mode, defaultOptions.merge(options))
160
# Writes an ItemData object to the database
162
key = KeyData.new(:file => data.file, :dir => data.dir,
164
value = ValueData.new(:descrip => data.descrip)
165
put(key.to_raw_data, value.to_raw_data)
169
key = KeyData.new(:file => data.file, :dir => data.dir,
171
delete(key.to_raw_data)
174
# Hide delete method, always use the high-level one
177
# Traverse entire BD, passing each item to the block
180
key, value = KeyData.new(k), ValueData.new(v)
181
# Note: missing dtitle field
182
yield ItemData.new(:file => key.file,
185
:descrip => value.descrip)
189
# Traverse each _item_, collecting their categories, and pass the
190
# category and item list to the given block
194
itemList[item.dir] ||= []
195
itemList[item.dir] << item
198
orderedCategories = itemList.keys.sort {|a,b|
199
# Order subcategories first
200
case tmp = a.scan('/').size <=> b.scan('/').size
207
orderedCategories.each do |cat|
208
yield cat, itemList[cat].sort {|a,b| a.name <=> b.name}
214
# Dhelp titles database
215
class TitleDatabase < BDB::Hash
216
def TitleDatabase.open(flags = BDB::RDONLY,
219
name = '/var/lib/dhelp/titles',
220
# name = 'dhelptitles',
222
defaultOptions = {"ffactor" => 8,
227
super(name, subname, flags, mode, defaultOptions.merge(options))
230
# Traverse entire BD, passing each item to the block
233
key, value = KeyData.new(k), ValueData.new(v)
234
# Note: missing dtitle field
235
yield ItemData.new(:file => key.file,
238
:descrip => value.descrip)
243
valueData = get(TitleKeyData.new(:dir => dir).to_raw_data)
244
valueData ? TitleValueData.new(valueData).dtitle : nil
247
# Writes an ItemData object to the database
249
key = TitleKeyData.new(:dir => data.dir)
250
value = TitleValueData.new(:dtitle => data.dtitle)
251
put(key.to_raw_data, value.to_raw_data)