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