source: main/trunk/greenstone2/common-src/src/jdbmedit/JdbmAPI.java@ 21403

Last change on this file since 21403 was 21403, checked in by davidb, 14 years ago

Code was working for Ascii characters, but not for Unicode values > 128. More careful prescription of utf-8 used in code

File size: 7.8 KB
Line 
1/**********************************************************************
2 *
3 * JdbmAPI.java --
4 * A component of the Greenstone digital library software
5 * from the New Zealand Digital Library Project at the
6 * University of Waikato, New Zealand.
7 *
8 * Copyright (C) 2010 The New Zealand Digital Library Project
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 *
24 **********************************************************************/
25
26import java.io.BufferedReader;
27import java.io.InputStreamReader;
28import java.io.IOException;
29import java.io.UnsupportedEncodingException;
30import java.io.OutputStreamWriter;
31import java.io.PrintWriter;
32
33import java.util.Properties;
34import java.util.ArrayList;
35
36import jdbm.RecordManager;
37import jdbm.RecordManagerFactory;
38import jdbm.helper.FastIterator;
39import jdbm.htree.HTree;
40
41
42
43public class JdbmAPI
44{
45 static String TNAME = "greenstone";
46
47 RecordManager recman_;
48 HTree hashtable_;
49
50 static private PrintWriter utf8out = null;
51
52 static
53 {
54 try {
55 OutputStreamWriter osw = new OutputStreamWriter(System.out, "UTF-8");
56 utf8out = new PrintWriter(osw, true);
57 }
58 catch (UnsupportedEncodingException e) {
59 System.out.println(e);
60 }
61 }
62
63 public JdbmAPI(String db_filename,boolean must_exist)
64 throws IOException
65 {
66 if (db_filename.endsWith(".jdb")) {
67 // remove file extension as JDBM does not expect it
68 db_filename = db_filename.substring(0,db_filename.length()-4);
69 }
70
71 // create or open a record manager
72 Properties props = new Properties();
73 recman_ = RecordManagerFactory.createRecordManager(db_filename, props);
74
75 // load existing table (if exists) otherwise create new one
76 long recid = recman_.getNamedObject(TNAME);
77
78 if (recid != 0) {
79 System.err.println("# Loading existing database table '" + TNAME +"' ...");
80 hashtable_ = HTree.load(recman_, recid);
81 }
82 else {
83
84 if (must_exist) {
85 recman_.close();
86 System.err.println("Database table '" + TNAME +"' does not exist.");
87 throw new IOException();
88 }
89 else {
90 System.err.println("# No database table '" + TNAME +"' to set. Creating new one");
91 hashtable_ = HTree.createInstance(recman_);
92 recman_.setNamedObject(TNAME, hashtable_.getRecid());
93 }
94 }
95 }
96
97 public JdbmAPI(String db_filename)
98 throws IOException
99 {
100 // default is that database does not have to exist
101 this(db_filename,false);
102 }
103
104 public void append(String key, String val)
105 throws IOException
106 {
107 String orig_val = (String)hashtable_.get(key);
108 String new_val = orig_val + val;
109
110 hashtable_.put(key,new_val);
111 recman_.commit();
112 }
113
114 public void set(String key, String val)
115 throws IOException
116
117 {
118 hashtable_.put(key,val);
119 recman_.commit();
120 }
121
122 public void delete(String key)
123 throws IOException
124 {
125 hashtable_.remove(key);
126 recman_.commit();
127 }
128
129
130 public String get(String key)
131 throws IOException
132 {
133 FastIterator iter;
134 String val;
135
136 val = (String) hashtable_.get(key);
137
138 recman_.commit();
139 return val;
140 }
141
142
143 public ArrayList get_keys()
144 throws IOException
145 {
146 ArrayList keys = new ArrayList();
147
148 FastIterator iter = hashtable_.keys();
149 String next_key = (String) iter.next();
150
151 while (next_key != null) {
152 keys.add(next_key);
153 next_key = (String) iter.next();
154 }
155
156 recman_.commit();
157 return keys;
158 }
159
160 public void close()
161 throws IOException
162 {
163 recman_.close();
164 System.err.println("# Done");
165 }
166
167
168 public static void skip_eol(BufferedReader brin)
169 throws IOException
170 {
171 int c = brin.read();
172 if (c == '\r') {
173 // Assume Windows style EOL
174 // consume another character
175 c = brin.read();
176 }
177 if (c != '\n') {
178 System.err.println("JdbmAPI: Warning, expected end-of-line character, but encountered '" + (char)c + "' ord(" + c + ")");
179 }
180 }
181
182 public static void print_usage()
183 {
184 System.err.println("");
185 System.err.println("Usage: java JdbmAPI database-name");
186 System.err.println("");
187 System.err.println(" - The JDBM commands to perform are then taken from standard-in");
188 System.err.println(" - Commands (with operands) are:");
189 System.err.println(" Keys");
190 System.err.println(" Get\\n<key>");
191 System.err.println(" Set\\n<key>\\n<vallen>\\n<val>");
192 System.err.println(" Append\\n<key>\\n<vallen>\\n<val>");
193 System.err.println(" Delete\\n<key>");
194 System.err.println("");
195 System.err.println(" - Operands are given on separate lines.");
196 System.err.println(" - In the case of <val> it is preceeded by its length.");
197 System.err.println("");
198 System.err.println(" - For example the following would set the key 'HASH0143' to 'testing':");
199 System.err.println(" Set");
200 System.err.println(" HASH0143");
201 System.err.println(" 7");
202 System.err.println(" testing");
203 System.err.println("");
204 System.exit(-1);
205 }
206
207 public static void main(String[] args)
208 {
209 int argc = args.length;
210
211 // sanity check
212 if (argc != 1) {
213 print_usage();
214 }
215
216 try {
217 String dbname = args[0];
218 JdbmAPI jdbm_api = new JdbmAPI(dbname);
219
220 InputStreamReader isr=new InputStreamReader(System.in,"UTF-8");
221 BufferedReader brin = new BufferedReader(isr);
222
223 boolean encountered_error = false;
224
225 String cmd = brin.readLine();
226 while (cmd != null) {
227 if (cmd.equals("Keys")) {
228 ArrayList keys = jdbm_api.get_keys();
229
230 int keys_len = keys.size();
231 utf8out.println(keys_len);
232
233 for (int i=0; i<keys_len; i++) {
234 String key = (String) keys.get(i);
235 utf8out.println(key);
236 }
237 }
238 else if ((cmd.equals("Get")) || (cmd.equals("Delete"))) {
239 String key = brin.readLine();
240 if (key != null) {
241
242 if (cmd.equals("Get")) {
243 String val = jdbm_api.get(key);
244 utf8out.println(val.length());
245 utf8out.println(val);
246 }
247 else {
248 jdbm_api.delete(key);
249 }
250
251 }
252 else {
253 System.err.println("JdbmAPI: Command '" + cmd + "'ended prematurely");
254 encountered_error = true;
255 break;
256 }
257
258 }
259 else if ((cmd.equals("Set")) || (cmd.equals("Append"))) {
260 String key = brin.readLine();
261
262 String vallen_str = brin.readLine();
263 if (vallen_str==null) {
264 System.err.println("JdbmAPI: Command '" + cmd + "'ended prematurely");
265 encountered_error = true;
266 break;
267 }
268 int vallen = Integer.parseInt(vallen_str);
269 char[] valbuffer = new char[vallen];
270 brin.read(valbuffer,0,vallen);
271 skip_eol(brin);
272
273 if (valbuffer.length==0) {
274 System.err.println("JdbmAPI: Command '" + cmd + "'ended prematurely");
275 encountered_error = true;
276 break;
277 }
278
279 String val = new String(valbuffer);
280
281 if (cmd.equals("Set")) {
282 jdbm_api.set(key,val);
283 }
284 else {
285 jdbm_api.append(key,val);
286 }
287 }
288 else {
289 System.err.println("JdbmAPI: Unrecognised command '" + cmd + "'");
290 encountered_error = true;
291 }
292
293 // read in next command (may be null, signifying eof)
294 cmd = brin.readLine();
295 }
296
297 jdbm_api.close();
298
299 if (encountered_error) {
300 System.exit(-1);
301 }
302 }
303
304 catch (IOException e) {
305 e.printStackTrace();
306 }
307
308 }
309
310}
311
312
Note: See TracBrowser for help on using the repository browser.