KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sleepycat > je > util > DbLoad


1 /*-
2  * See the file LICENSE for redistribution information.
3  *
4  * Copyright (c) 2002,2006 Oracle. All rights reserved.
5  *
6  * $Id: DbLoad.java,v 1.46 2006/10/30 21:14:28 bostic Exp $
7  */

8
9 package com.sleepycat.je.util;
10
11 import java.io.BufferedReader JavaDoc;
12 import java.io.File JavaDoc;
13 import java.io.FileInputStream JavaDoc;
14 import java.io.IOException JavaDoc;
15 import java.io.InputStream JavaDoc;
16 import java.io.InputStreamReader JavaDoc;
17 import java.util.Date JavaDoc;
18 import java.util.logging.Level JavaDoc;
19
20 import com.sleepycat.je.Database;
21 import com.sleepycat.je.DatabaseConfig;
22 import com.sleepycat.je.DatabaseEntry;
23 import com.sleepycat.je.DatabaseException;
24 import com.sleepycat.je.DbInternal;
25 import com.sleepycat.je.Environment;
26 import com.sleepycat.je.EnvironmentConfig;
27 import com.sleepycat.je.JEVersion;
28 import com.sleepycat.je.OperationStatus;
29 import com.sleepycat.je.utilint.CmdUtil;
30 import com.sleepycat.je.utilint.Tracer;
31
32 public class DbLoad {
33     private static final boolean DEBUG = false;
34
35     protected Environment env;
36     private boolean formatUsingPrintable;
37     private String JavaDoc dbName;
38     private BufferedReader JavaDoc reader;
39     private boolean noOverwrite;
40     private boolean textFileMode;
41     private boolean dupSort;
42     private boolean ignoreUnknownConfig;
43     private boolean commandLine;
44     private long progressInterval;
45     private long totalLoadBytes;
46
47     private static final String JavaDoc usageString =
48     "usage: " + CmdUtil.getJavaCommand(DbLoad.class) + "\n" +
49         " -h <dir> # environment home directory\n" +
50         " [-f <fileName>] # input file\n" +
51         " [-n ] # no overwrite mode\n" +
52         " [-T] # input file is in text mode\n" +
53         " [-I] # ignore unknown parameters\n" +
54     " [-c name=value] # config values\n" +
55         " [-s <databaseName> ] # database to load\n" +
56         " [-v] # show progress\n" +
57         " [-V] # print JE version number";
58
59     static public void main(String JavaDoc argv[])
60     throws DatabaseException, IOException JavaDoc {
61
62     DbLoad loader = parseArgs(argv);
63
64         try {
65             loader.load();
66         } catch (Throwable JavaDoc e) {
67             e.printStackTrace();
68         }
69
70     loader.env.close();
71     }
72
73     static private void printUsage(String JavaDoc msg) {
74     System.err.println(msg);
75     System.err.println(usageString);
76     System.exit(-1);
77     }
78
79     static private DbLoad parseArgs(String JavaDoc argv[])
80     throws IOException JavaDoc, DatabaseException {
81
82     boolean noOverwrite = false;
83     boolean textFileMode = false;
84     boolean ignoreUnknownConfig = false;
85     boolean showProgressInterval = false;
86
87     int argc = 0;
88     int nArgs = argv.length;
89     String JavaDoc inputFileName = null;
90     File JavaDoc envHome = null;
91     String JavaDoc dbName = null;
92         long progressInterval = 0;
93     DbLoad ret = new DbLoad();
94         ret.setCommandLine(true);
95
96     while (argc < nArgs) {
97         String JavaDoc thisArg = argv[argc++].trim();
98         if (thisArg.equals("-n")) {
99         noOverwrite = true;
100         } else if (thisArg.equals("-T")) {
101         textFileMode = true;
102         } else if (thisArg.equals("-I")) {
103         ignoreUnknownConfig = true;
104         } else if (thisArg.equals("-V")) {
105         System.out.println(JEVersion.CURRENT_VERSION);
106         System.exit(0);
107         } else if (thisArg.equals("-f")) {
108         if (argc < nArgs) {
109             inputFileName = argv[argc++];
110         } else {
111             printUsage("-f requires an argument");
112         }
113         } else if (thisArg.equals("-h")) {
114         if (argc < nArgs) {
115             envHome = new File JavaDoc(argv[argc++]);
116         } else {
117             printUsage("-h requires an argument");
118         }
119         } else if (thisArg.equals("-s")) {
120         if (argc < nArgs) {
121             dbName = argv[argc++];
122         } else {
123             printUsage("-s requires an argument");
124         }
125         } else if (thisArg.equals("-c")) {
126         if (argc < nArgs) {
127                     try {
128                         ret.loadConfigLine(argv[argc++]);
129                     } catch (IllegalArgumentException JavaDoc e) {
130                         printUsage("-c: " + e.getMessage());
131                     }
132         } else {
133             printUsage("-c requires an argument");
134         }
135         } else if (thisArg.equals("-v")) {
136         showProgressInterval = true;
137             }
138     }
139
140     if (envHome == null) {
141         printUsage("-h is a required argument");
142     }
143
144     long totalLoadBytes = 0;
145     InputStream JavaDoc is;
146     if (inputFileName == null) {
147         is = System.in;
148             if (showProgressInterval) {
149
150                 /*
151                  * Can't show progress if we don't know how big the stream
152                  * is.
153                  */

154                 printUsage("-v requires -f");
155             }
156     } else {
157         is = new FileInputStream JavaDoc(inputFileName);
158         if (showProgressInterval) {
159         totalLoadBytes = ((FileInputStream JavaDoc) is).getChannel().size();
160         /* Use 5% intervals. */
161         progressInterval = totalLoadBytes / 20;
162         }
163     }
164     BufferedReader JavaDoc reader = new BufferedReader JavaDoc(new InputStreamReader JavaDoc(is));
165
166         EnvironmentConfig envConfig = new EnvironmentConfig();
167         envConfig.setAllowCreate(true);
168     Environment env = new Environment(envHome, envConfig);
169     ret.setEnv(env);
170     ret.setDbName(dbName);
171     ret.setInputReader(reader);
172     ret.setNoOverwrite(noOverwrite);
173     ret.setTextFileMode(textFileMode);
174     ret.setIgnoreUnknownConfig(ignoreUnknownConfig);
175         ret.setProgressInterval(progressInterval);
176         ret.setTotalLoadBytes(totalLoadBytes);
177     return ret;
178     }
179
180     /*
181      * Begin DbLoad API. From here on there should be no calls to printUsage,
182      * System.xxx.print, or System.exit.
183      */

184
185     public DbLoad() {
186     }
187
188     /**
189      * If true, enables output of warning messages. Command line behavior is
190      * not available via the public API.
191      */

192     private void setCommandLine(boolean commandLine) {
193         this.commandLine = commandLine;
194     }
195
196     public void setEnv(Environment env) {
197     this.env = env;
198     }
199
200     public void setDbName(String JavaDoc dbName) {
201     this.dbName = dbName;
202     }
203
204     public void setInputReader(BufferedReader JavaDoc reader) {
205     this.reader = reader;
206     }
207
208     public void setNoOverwrite(boolean noOverwrite) {
209     this.noOverwrite = noOverwrite;
210     }
211
212     public void setTextFileMode(boolean textFileMode) {
213     this.textFileMode = textFileMode;
214     }
215
216     public void setIgnoreUnknownConfig(boolean ignoreUnknownConfigMode) {
217     this.ignoreUnknownConfig = ignoreUnknownConfigMode;
218     }
219
220     public void setProgressInterval(long progressInterval) {
221         this.progressInterval = progressInterval;
222     }
223
224     public void setTotalLoadBytes(long totalLoadBytes) {
225         this.totalLoadBytes = totalLoadBytes;
226     }
227
228     public boolean load()
229     throws IOException JavaDoc, DatabaseException {
230
231     Tracer.trace(Level.INFO, DbInternal.envGetEnvironmentImpl(env),
232              "DbLoad.load of " + dbName + " starting");
233
234         if (progressInterval > 0) {
235             System.out.println("Load start: " + new Date JavaDoc());
236         }
237
238         if (textFileMode) {
239             formatUsingPrintable = true;
240         } else {
241             loadHeader();
242         }
243
244         if (dbName == null) {
245             throw new IllegalArgumentException JavaDoc
246                 ("Must supply a database name if -l not supplied.");
247         }
248
249         DatabaseConfig dbConfig = new DatabaseConfig();
250         dbConfig.setSortedDuplicates(dupSort);
251         dbConfig.setAllowCreate(true);
252         Database db = env.openDatabase(null, dbName, dbConfig);
253
254         loadData(db);
255
256         db.close();
257
258         Tracer.trace(Level.INFO, DbInternal.envGetEnvironmentImpl(env),
259                      "DbLoad.load of " + dbName + " ending.");
260
261         if (progressInterval > 0) {
262             System.out.println("Load end: " + new Date JavaDoc());
263         }
264
265         return true;
266     }
267
268     private void loadConfigLine(String JavaDoc line)
269     throws DatabaseException {
270
271     int equalsIdx = line.indexOf('=');
272     if (equalsIdx < 0) {
273         throw new IllegalArgumentException JavaDoc
274                 ("Invalid header parameter: " + line);
275     }
276
277     String JavaDoc keyword = line.substring(0, equalsIdx).trim().toLowerCase();
278     String JavaDoc value = line.substring(equalsIdx + 1).trim();
279
280     if (keyword.equals("version")) {
281         if (DEBUG) {
282         System.out.println("Found version: " + line);
283         }
284         if (!value.equals("3")) {
285         throw new IllegalArgumentException JavaDoc
286                     ("Version " + value + " is not supported.");
287         }
288     } else if (keyword.equals("format")) {
289         value = value.toLowerCase();
290         if (value.equals("print")) {
291         formatUsingPrintable = true;
292         } else if (value.equals("bytevalue")) {
293         formatUsingPrintable = false;
294         } else {
295         throw new IllegalArgumentException JavaDoc
296             (value + " is an unknown value for the format keyword");
297         }
298         if (DEBUG) {
299         System.out.println("Found format: " + formatUsingPrintable);
300         }
301     } else if (keyword.equals("dupsort")) {
302         value = value.toLowerCase();
303         if (value.equals("true") ||
304         value.equals("1")) {
305         dupSort = true;
306         } else if (value.equals("false") ||
307                value.equals("0")) {
308         dupSort = false;
309         } else {
310         throw new IllegalArgumentException JavaDoc
311             (value + " is an unknown value for the dupsort keyword");
312         }
313         if (DEBUG) {
314         System.out.println("Found dupsort: " + dupSort);
315         }
316     } else if (keyword.equals("type")) {
317         value = value.toLowerCase();
318         if (!value.equals("btree")) {
319         throw new IllegalArgumentException JavaDoc
320                     (value + " is not a supported database type.");
321         }
322         if (DEBUG) {
323         System.out.println("Found type: " + line);
324         }
325     } else if (keyword.equals("database")) {
326         if (dbName == null) {
327         dbName = value;
328         }
329         if (DEBUG) {
330         System.out.println("DatabaseImpl: " + dbName);
331         }
332     } else if (!ignoreUnknownConfig) {
333         throw new IllegalArgumentException JavaDoc
334                 ("'" + line + "' is not understood.");
335     }
336     }
337
338     private void loadHeader()
339     throws IOException JavaDoc, DatabaseException {
340
341     if (DEBUG) {
342         System.out.println("loading header");
343     }
344     String JavaDoc line = reader.readLine();
345     while (line != null &&
346            !line.equals("HEADER=END")) {
347         loadConfigLine(line);
348         line = reader.readLine();
349     }
350     }
351
352     private void loadData(Database db)
353     throws DatabaseException, IOException JavaDoc {
354
355     String JavaDoc keyLine = reader.readLine();
356     String JavaDoc dataLine = null;
357         int count = 0;
358     long totalBytesRead = 0;
359         long lastTime = System.currentTimeMillis();
360     long bytesReadThisInterval = 0;
361
362     while (keyLine != null &&
363            !keyLine.equals("DATA=END")) {
364         dataLine = reader.readLine();
365             if (dataLine == null) {
366                 throw new DatabaseException("No data to match key " +
367                                             keyLine);
368             }
369         /* Add one for \n or \r. */
370         bytesReadThisInterval += dataLine.length() + 1;
371         byte[] keyBytes = loadLine(keyLine.trim());
372         byte[] dataBytes = loadLine(dataLine.trim());
373
374         DatabaseEntry key = new DatabaseEntry(keyBytes);
375         DatabaseEntry data = new DatabaseEntry(dataBytes);
376
377         if (noOverwrite) {
378         if (db.putNoOverwrite(null, key, data) ==
379             OperationStatus.KEYEXIST) {
380                     /* Calling println is OK only from command line. */
381                     if (commandLine) {
382                         System.err.println("Key exists: " + key);
383                     }
384         }
385         } else {
386         db.put(null, key, data);
387         }
388
389             count++;
390             if ((progressInterval > 0) &&
391         (bytesReadThisInterval > progressInterval)) {
392         totalBytesRead += bytesReadThisInterval;
393         bytesReadThisInterval -= progressInterval;
394                 long now = System.currentTimeMillis();
395                 System.out.println("loaded " + count + " records " +
396                                    (now - lastTime) + " ms - % completed: " +
397                    ((100 * totalBytesRead) / totalLoadBytes));
398                 lastTime = now;
399             }
400
401         keyLine = reader.readLine();
402         if (keyLine == null) {
403         throw new DatabaseException("No \"DATA=END\"");
404         }
405         bytesReadThisInterval += keyLine.length() + 1;
406     }
407     }
408
409     private byte[] loadLine(String JavaDoc line)
410     throws DatabaseException {
411
412     if (formatUsingPrintable) {
413         return readPrintableLine(line);
414     }
415     int nBytes = line.length() / 2;
416     byte[] ret = new byte[nBytes];
417     int charIdx = 0;
418     for (int i = 0; i < nBytes; i++, charIdx += 2) {
419         int b2 = Character.digit(line.charAt(charIdx), 16);
420         b2 <<= 4;
421         b2 += Character.digit(line.charAt(charIdx + 1), 16);
422         ret[i] = (byte) b2;
423     }
424     return ret;
425     }
426
427     static private byte backSlashValue =
428     (byte) (new Character JavaDoc('\\').charValue() & 0xff);
429
430     private byte[] readPrintableLine(String JavaDoc line)
431     throws DatabaseException {
432
433     /* nBytes is the max number of bytes that this line could turn into. */
434     int maxNBytes = line.length();
435     byte[] ba = new byte[maxNBytes];
436     int actualNBytes = 0;
437
438     for (int charIdx = 0; charIdx < maxNBytes; charIdx++) {
439         char c = line.charAt(charIdx);
440         if (c == '\\') {
441         if (++charIdx < maxNBytes) {
442             char c1 = line.charAt(charIdx);
443             if (c1 == '\\') {
444             ba[actualNBytes++] = backSlashValue;
445             } else {
446             if (++charIdx < maxNBytes) {
447                 char c2 = line.charAt(charIdx);
448                 int b = Character.digit(c1, 16);
449                 b <<= 4;
450                 b += Character.digit(c2, 16);
451                 ba[actualNBytes++] = (byte) b;
452             } else {
453                 throw new DatabaseException("Corrupted file");
454             }
455             }
456         } else {
457             throw new DatabaseException("Corrupted file");
458         }
459         } else {
460         ba[actualNBytes++] = (byte) (c & 0xff);
461         }
462     }
463
464     if (maxNBytes == actualNBytes) {
465         return ba;
466     } else {
467         byte[] ret = new byte[actualNBytes];
468         System.arraycopy(ba, 0, ret, 0, actualNBytes);
469         return ret;
470     }
471     }
472 }
473
Popular Tags