source: greenstone3/trunk/src/java/org/greenstone/gsdl3/util/GDBMWrapper.java@ 18663

Last change on this file since 18663 was 18663, checked in by kjdon, 15 years ago

we now use gdb all the time internally for database extension. In the open database method, if gdb not there check for ldb/bdb for legacy collections

  • Property svn:keywords set to Author Date Id Revision
File size: 7.1 KB
Line 
1/*
2 * GDBMWrapper.java
3 * Copyright (C) 2008 New Zealand Digital Library, http://www.nzdl.org
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19package org.greenstone.gsdl3.util;
20
21import au.com.pharos.gdbm.GdbmFile;
22import au.com.pharos.packing.*;
23import au.com.pharos.gdbm.GdbmException;
24
25import org.apache.log4j.Logger;
26
27import java.io.UnsupportedEncodingException;
28import java.io.File;
29
30/** java wrapper class for gdbm - uses Java-GDBM written by Martin Pool
31 * replaces gdbmclass in the old version
32 */
33
34public class GDBMWrapper
35 implements FlatDatabaseWrapper {
36
37 static Logger logger = Logger.getLogger(org.greenstone.gsdl3.util.GDBMWrapper.class.getName());
38
39 /* GdbmFile modes:
40 READER - read access, many readers may share the database
41 WRITER - read/write access, exclusive access
42 WRCREAT - read/write access, create db if doesn't exist
43 NEWDB - read/write access, db should be replaced if exists
44 */
45
46
47 protected GdbmFile db_=null;
48
49 /** open the database filename, with mode mode - uses the constants
50 above, eg GdbmFile.WRITER */
51 public boolean openDatabase(String filename, int mode) {
52 // need to convert mode to GdbmFile mode
53 if (mode == READ) {
54 mode = GdbmFile.READER;
55 } else if (mode == WRITE) {
56 mode = GdbmFile.WRITER;
57 } else {
58 logger.error ("invalid mode, "+mode+ ", opening db for reading only");
59 mode = GdbmFile.READER;
60 }
61 try {
62 if (db_!=null) {
63 db_.close();
64 }
65
66 // The java version of the C++ code in common-src/src/lib/gdbmclass.cpp
67 if(mode == GdbmFile.READER) {
68 // Looking to read in the database
69 // we now use gdb extension. Check for ldb/bdb in case of legacy collection
70 // if not (first time) then generate using txt2db
71 if (!new File(filename).exists()) {
72 logger.warn("Database file " + filename + " does not exist. Looking for ldb/bdb version");
73 int extension = filename.lastIndexOf('.');
74 String filename_head = filename.substring(0, extension);
75 filename = filename_head + ".ldb";
76 if (!new File(filename).exists()) {
77 filename = filename_head + ".bdb";
78
79 if (!new File(filename).exists()) {
80 logger.warn("ldb/bdb version of database file " + filename + " does not exist. Looking for txtgz version of db file.");
81 // put the filename back to gdb
82 filename = filename_head + ".gdb";
83 // need to generate architecture native GDBM file using txt2db
84
85 // replace sought after gdbm filename ext with ".txt.gz"
86
87 String txtgzFilename = filename_head + ".txt.gz";
88 if(new File(txtgzFilename).exists()) {
89 // Test to make sure Perl is on the path
90 // On Linux, the output of the test goes to STDOUT so redirect it to STDERR
91 String cmdTest = "perl -v 2>&1";
92 //String cmdTest = "echo %PATH%";
93 int returnValue = Processing.runProcess(cmdTest);
94 if (returnValue != 0) {
95 logger.error("Tried to find Perl. Return exit value of running "
96 + cmdTest + ": " + returnValue + ", (expected this to be 0)");
97 logger.error("Check that Perl is set in your PATH environment variable.");
98 //log.error("At present, PATH=" + System.getenv("PATH"));
99 }
100
101 String cmd = "perl -S txtgz-to-gdbm.pl \"" + txtgzFilename + "\" \"" + filename + "\"";
102 returnValue = Processing.runProcess(cmd);
103 // For some reason, launching this command with gsdl_system() still returns 1
104 // even when it returns 0 when run from the command-line. We can check whether
105 // we succeeded by looking at whether the output database file was created.
106 if (returnValue != 0) {
107 logger.warn("Warning, non-zero return value on running command \"" + cmd + "\": " + returnValue);
108 if (!new File(filename).exists()) {
109 logger.error("Tried to run command \"" + cmd + "\", but it failed");
110 }
111 }
112 }
113 }
114 }
115
116 }
117 }
118
119 db_ = new GdbmFile(filename, mode);
120 } catch ( GdbmException e) { // the database wasn't opened or created
121 logger.error("couldn't open database "+filename);
122 return false;
123 }
124 db_.setKeyPacking(new StringPacking());
125 db_.setValuePacking(new StringPacking());
126 return true;
127 }
128
129 /** close the database associated with this wrapper */
130 public void closeDatabase() {
131 try {
132 if (db_ != null) {
133 db_.close();
134 db_ = null;
135 }
136 } catch (GdbmException e) {
137 // should never get here - close never actually throws an exception
138 logger.error("error on close()");
139 }
140 }
141
142 public String getValue(String key) {
143 if (db_==null) {
144 return null;
145 }
146 String s_info;
147 try {
148 try {
149 // The key is UTF8: do db lookup using the UTF8 version of key
150 s_info = (String)db_.fetch(key.getBytes("UTF-8"));
151 } catch(UnsupportedEncodingException e) {
152 logger.warn("utf8 key for " + key
153 + " unrecognised. Retrying with default encoding.");
154 // retry db lookup using default encoding of key instead of UTF8
155 s_info = (String)db_.fetch(key);
156 }
157 } catch (GdbmException e) {
158 logger.error("couldn't get record");
159 return null;
160 }
161 if (s_info==null) {
162 // record not present
163 logger.error("key "+key+" not present in db");
164 return null;
165 }
166 return s_info;
167 }
168
169 /** sets the key value as info
170 * TODO - not implemented yet */
171 public boolean setValue (String key, String value) {
172 if (db_==null) {
173 return false;
174 }
175 return false;
176 }
177 /** deletes the entry for key
178 * TODO - not implemented yet */
179 public boolean deleteKey(String key) {
180 if (db_==null) {
181 return false;
182 }
183 return false;
184 }
185
186 /** returns a string of key-value entries that
187 * can be printed for debugging purposes. */
188 public String displayAllEntries() {
189 StringBuffer output = new StringBuffer();
190 try{
191 java.util.Enumeration e = db_.keys();
192 while(e.hasMoreElements()) {
193 Object key = e.nextElement();
194 Object value = db_.fetch(key);
195
196 output.append("key href: ");
197 output.append((String)key);
198 output.append("\tvalue ID: ");
199 output.append((String)value);
200 output.append("\n");
201 //logger.warn("key: " + key + "\tvalue: " + value);
202
203 String urlkey = java.net.URLEncoder.encode((String)key, "UTF8");
204 output.append("URL encoded key: " + urlkey);
205 //logger.warn("URL encoded key: " + urlkey);
206 }
207 } catch(UnsupportedEncodingException e) {
208 logger.warn("Trouble converting key to UTF-8.");
209 } catch(Exception e) {
210 logger.warn("Exception encountered when trying to displayAllEntries():" + e);
211 }
212 return output.toString();
213 }
214}
Note: See TracBrowser for help on using the repository browser.