1/*- 2 * See the file LICENSE for redistribution information. 3 * 4 * Copyright (c) 1997,2008 Oracle. All rights reserved. 5 * 6 * $Id: BulkAccessNIOExample.java,v 1.7 2008/01/08 20:58:32 bostic Exp $ 7 */ 8 9package db; 10 11import com.sleepycat.db.*; 12import java.io.File; 13import java.io.FileNotFoundException; 14import java.io.InputStreamReader; 15import java.io.IOException; 16import java.io.PrintStream; 17import java.nio.ByteBuffer; 18 19class BulkAccessNIOExample { 20 private static final String FileName = "access.db"; 21 22 public BulkAccessNIOExample() { 23 } 24 25 public static void main(String[] argv) { 26 try { 27 BulkAccessNIOExample app = new BulkAccessNIOExample(); 28 app.run(); 29 } catch (DatabaseException dbe) { 30 System.err.println("BulkAccessNIOExample: " + dbe.toString()); 31 System.exit(1); 32 } catch (FileNotFoundException fnfe) { 33 System.err.println("BulkAccessNIOExample: " + fnfe.toString()); 34 System.exit(1); 35 } 36 System.exit(0); 37 } 38 39 // Prompts for a line, and keeps prompting until a non blank 40 // line is returned. Returns null on error. 41 // 42 public static String askForLine(InputStreamReader reader, 43 PrintStream out, String prompt) { 44 String result = ""; 45 while (result != null && result.length() == 0) { 46 out.print(prompt); 47 out.flush(); 48 result = getLine(reader); 49 } 50 return result; 51 } 52 53 // Not terribly efficient, but does the job. 54 // Works for reading a line from stdin or a file. 55 // Returns null on EOF. If EOF appears in the middle 56 // of a line, returns that line, then null on next call. 57 // 58 public static String getLine(InputStreamReader reader) { 59 StringBuffer b = new StringBuffer(); 60 int c; 61 try { 62 while ((c = reader.read()) != -1 && c != '\n') { 63 if (c != '\r') 64 b.append((char)c); 65 } 66 } catch (IOException ioe) { 67 c = -1; 68 } 69 70 if (c == -1 && b.length() == 0) 71 return null; 72 else 73 return b.toString(); 74 } 75 76 public void run() throws DatabaseException, FileNotFoundException { 77 // Remove the previous database. 78 new File(FileName).delete(); 79 80 // Create the database object. 81 // There is no environment for this simple example. 82 DatabaseConfig config = new DatabaseConfig(); 83 config.setErrorStream(System.err); 84 config.setErrorPrefix("BulkAccessNIOExample"); 85 config.setType(DatabaseType.BTREE); 86 config.setAllowCreate(true); 87 config.setMode(0644); 88 Database table = new Database(FileName, null, config); 89 90 // 91 // Insert records into the database, where the key is the user 92 // input and the data is the user input in reverse order. 93 // 94 InputStreamReader reader = new InputStreamReader(System.in); 95 96 for (;;) { 97 String line = askForLine(reader, System.out, "input> "); 98 if (line == null || (line.compareToIgnoreCase("end") == 0)) 99 break; 100 101 String reversed = (new StringBuffer(line)).reverse().toString(); 102 103 // See definition of StringEntry below 104 // 105 StringEntry key = new StringEntry(line, true); 106 StringEntry data = new StringEntry(reversed, true); 107 108 try { 109 if (table.putNoOverwrite(null, key, data) == OperationStatus.KEYEXIST) 110 System.out.println("Key " + line + " already exists."); 111 } catch (DatabaseException dbe) { 112 System.out.println(dbe.toString()); 113 } 114 } 115 116 // Acquire a cursor for the table. 117 Cursor cursor = table.openCursor(null, null); 118 DatabaseEntry foo = new DatabaseEntry(); 119 120 MultipleKeyNIODataEntry bulk_data = new MultipleKeyNIODataEntry(); 121 122 ByteBuffer rawData = ByteBuffer.allocateDirect(1024*1024); 123 bulk_data.setDataNIO(rawData); 124 bulk_data.setUserBuffer(1024 * 1024, true); 125 126 // Walk through the table, printing the key/data pairs. 127 // 128 while (cursor.getNext(foo, bulk_data, null) == OperationStatus.SUCCESS) { 129 StringEntry key, data; 130 key = new StringEntry(); 131 data = new StringEntry(); 132 133 while (bulk_data.next(key, data)) 134 System.out.println(key.getString() + " : " + data.getString()); 135 } 136 cursor.close(); 137 table.close(); 138 } 139 140 // Here's an example of how you can extend DatabaseEntry in a 141 // straightforward way to allow easy storage/retrieval of strings, or 142 // whatever kind of data you wish. We've declared it as a static inner 143 // class, but it need not be. 144 // 145 static class StringEntry extends DatabaseEntry { 146 StringEntry() { 147 } 148 149 StringEntry(String value, boolean nioData) { 150 setString(value, nioData); 151 } 152 153 void setString(String value, boolean nioData) { 154 byte[] data = value.getBytes(); 155 if(nioData) { 156 ByteBuffer newBuf = ByteBuffer.allocateDirect(data.length); 157 newBuf.position(0); 158 newBuf.put(data, 0, data.length); 159 setDataNIO(newBuf); 160 setSize(data.length); 161 } else { 162 setData(data); 163 setSize(data.length); 164 } 165 } 166 167 String getString() { 168 String ret; 169 if(getData() == null) { 170 ByteBuffer tmp = getDataNIO(); 171 tmp.position(getOffset()); 172 byte[] data = new byte[getSize()]; 173 tmp.get(data, 0, getSize()); 174 ret = new String(data, 0, getSize()); 175 } else { 176 ret = new String(getData(), getOffset(), getSize()); 177 } 178 return ret; 179 } 180 } 181} 182