a858e8ee59fcff5ed1b9c0c7759167644b9ad2a1
[chise/ruby.git] / chise / chisedb.rb
1 # Copyright (C) 2002-2004 Kouichirou Eto, All rights reserved.
2
3 require "singleton"
4 require "chise/libchise"
5
6 module CHISE
7   module ParseValueModule
8     def parse_value(v)
9       return nil if v.nil?
10       return v.to_i if /\A\d+\Z/ =~ v # number?
11       return $1 if /\A"(.+)"\Z/ =~ v # remove surrounding "
12       v # sexp?
13     end
14   end
15
16   class ChiseDB
17     include Singleton
18
19     def initialize
20       @location = CHISE::DataSource::DB_DIR.path
21       @ds = DataSource.new(CHISE::DataSource::Berkeley_DB, @location.to_s, 0, 0755)
22       @feature_db = {}
23       @ccs_db = {}
24       @byids_db = {}
25     end
26     attr_reader :ds, :location
27
28     def close
29       # @ds.close if @ds # do not close for now
30     end
31
32     def each_feature_name()
33       @ds.each_feature_name {|f|
34         next if f.to_s == "." || f.to_s == ".."
35         next if f.to_s =~ /\.txt\Z/
36         yield(f.path.unescape_win_filename.unescape.to_s)
37       }
38     end
39
40     def each_ccs
41       each_entry("character/by_feature") {|f| yield(f) }
42     end
43
44     def get_feature(name)
45       @feature_db[name] = FeatureDB.new(self, name) if @feature_db[name].nil?
46       @feature_db[name]
47     end
48
49     def load_feature(cid, name)
50       feature = get_feature(name)
51       feature.get_value(cid)
52     end
53
54     def get_ccs(name)
55       @ccs_db[name] = CCS_DB.new(self, name) if @ccs_db[name].nil?
56       @ccs_db[name]
57     end
58
59     def decode_char(ccs, code_point)
60       ccsdb = get_ccs(ccs)
61       ccsdb.decode(code_point)
62     end
63
64     def get_by_ids_db(n)
65       @byids_db[n] = ByIDS_DB.new(self, n) if @byids_db[n].nil?
66       @byids_db[n]
67     end
68
69     private
70     include EachEntryModule
71   end
72
73   module TableManagementModule
74     def to_hash
75       h = {}
76       each_char {|k, v| h[k] = v }
77       h
78     end
79
80     def dump
81       txt = @name.path.escape.escape_win_filename.to_s+".txt"
82       t = @cd.location+@category+@keyvalue+txt
83       t.open("wb"){|out|
84         to_hash.sort.each {|k, v|
85           out.printf("%s\t%s\n", k, v)
86         }
87       }
88     end
89   end
90
91   class FeatureDB
92     include ParseValueModule
93     include TableManagementModule
94
95     def initialize(cd, name)
96       @cd, @name = cd, name
97       @ds = @cd.ds
98       @feature = @ds.get_feature(@name.path.escape.escape_win_filename.to_s)
99       @category, @keyvalue = "character", "feature"
100       at_exit {
101         close
102       }
103     end
104     def setup_db(w) @feature.setup_db(w); end
105     def sync() @feature.sync(); end
106     alias close sync
107
108     def set_value(cid, value)
109       @feature.set_value(cid, value)
110     end
111
112     def get_value(cid)
113       parse_value(@feature.get_value(cid))
114     end
115
116     def each_char
117       @feature.each_char {|cid, value|
118         #qp cid, value
119         yield(cid, parse_value(value))
120       }
121     end
122   end
123
124   class CCS_DB
125     include TableManagementModule
126
127     def initialize(cd, name)
128       @cd, @name = cd, name
129       @ds = @cd.ds
130       @ccs = @ds.get_ccs(@name)
131       @dsr = @ccsr = nil
132       @category, @keyvalue = "character", "by_feature"
133       at_exit {
134         close
135       }
136     end
137     def setup_db(w) @ccs.setup_db(w); end
138     def sync() @ccs.sync(); end
139     alias close sync
140     def set(code_point, cid) @ccs.set(code_point, cid); end
141     def decode(code_point) @ccs.decode(code_point); end
142
143     def setup_ccs_r
144       db_dir = CHISE::DataSource::DB_DIR
145       @dsr = DataSource_R.new(CHISE::DataSource::Berkeley_DB, db_dir, 0, 0755) if @dsr.nil?
146       #qp @name
147       @ccsr = CCS_R.new(@dsr, @name) if @ccsr.nil?
148     end
149
150     def each_char # call CCS_R here.
151       setup_ccs_r
152       @ccsr.each_char {|code_point, cid|
153         yield(code_point, cid)
154       }
155     end
156   end
157
158   class ByIDS_DB
159     include ParseValueModule
160     include ChiseValue
161     include TableAccessModule
162     include TableManagementModule
163
164     def initialize(cd, name)
165       @cd, @name = cd, name
166       @ds = @cd.ds
167       @category, @keyvalue = "character", "by_ids"
168       reset
169       at_exit {
170         close
171       }
172     end
173
174     def decode(ids)
175       setup_db
176       return nil if @db.nil?
177       parse_c_string(@db.get(ids))
178     end
179
180     def set_decoded_char(ids, cid)
181       setup_db(true)
182       raise "@db is nil." if @db.nil?
183       @db.put(ids, format_char_id(cid))
184     end
185
186     def each_char
187       setup_db
188       raise "@db is nil." if @db.nil?
189       @db.each {|k, v|
190         yield(parse_value(k), parse_c_string(v))
191       }
192     end
193   end
194 end