1<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3<html xmlns="http://www.w3.org/1999/xhtml">
4  <head>
5    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
6    <title>Getting Records Using the Cursor</title>
7    <link rel="stylesheet" href="gettingStarted.css" type="text/css" />
8    <meta name="generator" content="DocBook XSL Stylesheets V1.73.2" />
9    <link rel="start" href="index.html" title="Getting Started with Berkeley DB" />
10    <link rel="up" href="Cursors.html" title="Chapter��9.��Using Cursors" />
11    <link rel="prev" href="Cursors.html" title="Chapter��9.��Using Cursors" />
12    <link rel="next" href="PutEntryWCursor.html" title="Putting Records Using Cursors" />
13  </head>
14  <body>
15    <div class="navheader">
16      <table width="100%" summary="Navigation header">
17        <tr>
18          <th colspan="3" align="center">Getting Records Using the Cursor</th>
19        </tr>
20        <tr>
21          <td width="20%" align="left"><a accesskey="p" href="Cursors.html">Prev</a>��</td>
22          <th width="60%" align="center">Chapter��9.��Using Cursors</th>
23          <td width="20%" align="right">��<a accesskey="n" href="PutEntryWCursor.html">Next</a></td>
24        </tr>
25      </table>
26      <hr />
27    </div>
28    <div class="sect1" lang="en" xml:lang="en">
29      <div class="titlepage">
30        <div>
31          <div>
32            <h2 class="title" style="clear: both"><a id="Positioning"></a>Getting Records Using the Cursor</h2>
33          </div>
34        </div>
35      </div>
36      <div class="toc">
37        <dl>
38          <dt>
39            <span class="sect2">
40              <a href="Positioning.html#cursorsearch">Searching for Records</a>
41            </span>
42          </dt>
43          <dt>
44            <span class="sect2">
45              <a href="Positioning.html#getdups">Working with Duplicate Records</a>
46            </span>
47          </dt>
48        </dl>
49      </div>
50      <p>
51        To iterate over database records, from the first record to
52        the last, simply open the cursor and then use the
53            <code class="methodname">Cursor.getNext()</code>
54            
55            
56        method.  
57        
58        For example:
59     </p>
60      <a id="java_cursor3"></a>
61      <pre class="programlisting">package db.GettingStarted;
62
63import com.sleepycat.db.Database;
64import com.sleepycat.db.DatabaseEntry;
65import com.sleepycat.db.DatabaseException;
66import com.sleepycat.db.Cursor;
67import com.sleepycat.db.LockMode;  
68import com.sleepycat.db.OperationStatus; 
69
70...
71
72Cursor cursor = null;
73try {
74    ...
75    Database myDatabase = null;
76    // Database open omitted for brevity
77    ...
78
79    // Open the cursor. 
80    cursor = myDatabase.openCursor(null, null);
81
82    // Cursors need a pair of DatabaseEntry objects to operate. These hold
83    // the key and data found at any given position in the database.
84    DatabaseEntry foundKey = new DatabaseEntry();
85    DatabaseEntry foundData = new DatabaseEntry();
86
87    // To iterate, just call getNext() until the last database record has been 
88    // read. All cursor operations return an OperationStatus, so just read 
89    // until we no longer see OperationStatus.SUCCESS
90    while (cursor.getNext(foundKey, foundData, LockMode.DEFAULT) ==
91        OperationStatus.SUCCESS) {
92        // getData() on the DatabaseEntry objects returns the byte array
93        // held by that object. We use this to get a String value. If the
94        // DatabaseEntry held a byte array representation of some other data
95        // type (such as a complex object) then this operation would look 
96        // considerably different.
97        String keyString = new String(foundKey.getData(), "UTF-8");
98        String dataString = new String(foundData.getData(), "UTF-8");
99        System.out.println("Key | Data : " + keyString + " | " + 
100                       dataString + "");
101    }
102} catch (DatabaseException de) {
103    System.err.println("Error accessing database." + de);
104} finally {
105    // Cursors must be closed.
106    cursor.close();
107}</pre>
108      <p>
109    To iterate over the database from the last record to the first,
110    instantiate the cursor, and then
111    use <code class="methodname">Cursor.getPrev()</code> until you read the first record in
112    the database. For example:
113    </p>
114      <a id="java_cursor4"></a>
115      <pre class="programlisting">package db.GettingStarted;
116    
117import com.sleepycat.db.Cursor;
118import com.sleepycat.db.Database;
119import com.sleepycat.db.DatabaseEntry;
120import com.sleepycat.db.DatabaseException;
121import com.sleepycat.db.LockMode;  
122import com.sleepycat.db.OperationStatus; 
123
124...
125
126Cursor cursor = null;
127Database myDatabase = null;
128try {
129    ...
130    // Database open omitted for brevity
131    ...
132
133    // Open the cursor. 
134    cursor = myDatabase.openCursor(null, null);
135
136    // Get the DatabaseEntry objects that the cursor will use.
137    DatabaseEntry foundKey = new DatabaseEntry();
138    DatabaseEntry foundData = new DatabaseEntry();
139
140    // Iterate from the last record to the first in the database
141    while (cursor.getPrev(foundKey, foundData, LockMode.DEFAULT) == 
142        OperationStatus.SUCCESS) {
143
144        String theKey = new String(foundKey.getData(), "UTF-8");
145        String theData = new String(foundData.getData(), "UTF-8");
146        System.out.println("Key | Data : " +  theKey + " | " + theData + "");
147    }
148} catch (DatabaseException de) {
149    System.err.println("Error accessing database." + de);
150} finally {
151    // Cursors must be closed.
152    cursor.close();
153}</pre>
154      <div class="sect2" lang="en" xml:lang="en">
155        <div class="titlepage">
156          <div>
157            <div>
158              <h3 class="title"><a id="cursorsearch"></a>Searching for Records</h3>
159            </div>
160          </div>
161        </div>
162        <p>
163        You can use cursors to search for database records. You can search based
164        on just a key, or you can search based on both the key and the data.
165        You can also perform partial matches if your database supports sorted
166        duplicate sets. In all cases, the key and data parameters of these
167        methods are filled with the key and data values of the database record
168        to which the cursor is positioned as a result of the search. 
169      </p>
170        <p>
171        Also, if the search fails, then cursor's state is left unchanged
172        and 
173            <code class="literal">OperationStatus.NOTFOUND</code> 
174             
175        is returned. 
176        
177        
178      </p>
179        <p>
180        The following <code class="classname">Cursor</code> methods allow you to
181        perform database searches:
182      </p>
183        <div class="itemizedlist">
184          <ul type="disc">
185            <li>
186              <p>
187            <code class="methodname">Cursor.getSearchKey()</code>
188            
189           </p>
190              <p>
191            Moves the cursor to the first record in the database with
192            the specified key.
193          </p>
194            </li>
195            <li>
196              <p>
197            <code class="methodname">Cursor.getSearchKeyRange()</code>
198            
199          </p>
200              <p>
201            <span>Identical to 
202                
203                <code class="methodname">Cursor.getSearchKey()</code>
204            unless you are using the BTree access. In this case, the cursor
205            moves</span>
206            
207            
208            to the first record in the database whose
209            key is greater than or equal to the specified key. This comparison
210            is determined by the 
211                <span>comparator</span> 
212                 
213            that you provide for the database. If no 
214                <span>comparator</span> 
215                 
216                is provided, then the default 
217                
218                lexicographical sorting is used.
219          </p>
220              <p>
221            For example, suppose you have database records that use the
222            following 
223                <span>Strings</span>
224                
225            as keys:
226          </p>
227              <pre class="programlisting">Alabama
228Alaska
229Arizona</pre>
230              <p>
231            Then providing a search key of <code class="literal">Alaska</code> moves the
232            cursor to the second key noted above. Providing a key of
233            <code class="literal">Al</code> moves the cursor to the first key (<code class="literal">Alabama</code>), providing
234            a search key of <code class="literal">Alas</code> moves the cursor to the second key
235            (<code class="literal">Alaska</code>), and providing a key of <code class="literal">Ar</code> moves the
236            cursor to the last key (<code class="literal">Arizona</code>).
237          </p>
238            </li>
239            <li>
240              <p>
241            <code class="methodname">Cursor.getSearchBoth()</code>
242            
243           </p>
244              <p>
245            Moves the cursor to the first record in the database that uses
246            the specified key and data.
247          </p>
248            </li>
249            <li>
250              <p>
251            <code class="methodname">Cursor.getSearchBothRange()</code>
252            
253          </p>
254              <p>
255            Moves the cursor to the first record in the database whose key matches the specified
256            key and whose data is
257            greater than or equal to the specified data. If the database supports
258            duplicate records, then on matching the key, the cursor is moved to
259            the duplicate record with the smallest data that is greater than or
260            equal to the specified data.
261          </p>
262              <p>
263            For example, 
264                
265                <span>suppose your database uses BTree
266                and it has </span>
267            database records that use the following key/data pairs:
268          </p>
269              <pre class="programlisting">Alabama/Athens
270Alabama/Florence
271Alaska/Anchorage
272Alaska/Fairbanks
273Arizona/Avondale
274Arizona/Florence </pre>
275              <p>then providing:</p>
276              <div class="informaltable">
277                <table border="1" width="80%">
278                  <colgroup>
279                    <col />
280                    <col />
281                    <col />
282                  </colgroup>
283                  <thead>
284                    <tr>
285                      <th>a search key of ...</th>
286                      <th>and a search data of ...</th>
287                      <th>moves the cursor to ...</th>
288                    </tr>
289                  </thead>
290                  <tbody>
291                    <tr>
292                      <td>Alaska</td>
293                      <td>Fa</td>
294                      <td>Alaska/Fairbanks</td>
295                    </tr>
296                    <tr>
297                      <td>Arizona</td>
298                      <td>Fl</td>
299                      <td>Arizona/Florence</td>
300                    </tr>
301                    <tr>
302                      <td>Alaska</td>
303                      <td>An</td>
304                      <td>Alaska/Anchorage</td>
305                    </tr>
306                  </tbody>
307                </table>
308              </div>
309            </li>
310          </ul>
311        </div>
312        <p>
313        For example, assuming a database containing sorted duplicate records of
314        U.S. States/U.S Cities key/data pairs (both as 
315            <span>Strings),</span> 
316             
317        then the following code fragment can be used to position the cursor 
318        to any record in the database and print its key/data values:
319        
320      </p>
321        <a id="java_cursor5"></a>
322        <pre class="programlisting">package db.GettingStarted;
323
324import com.sleepycat.db.Cursor;
325import com.sleepycat.db.Database;
326import com.sleepycat.db.DatabaseEntry;
327import com.sleepycat.db.DatabaseException;
328import com.sleepycat.db.LockMode;
329import com.sleepycat.db.OperationStatus; 
330
331...
332  
333// For this example, hard code the search key and data
334String searchKey = "Alaska";
335String searchData = "Fa";
336
337Cursor cursor = null;
338Database myDatabase = null;
339try {
340    ...
341    // Database open omitted for brevity
342    ...
343
344    // Open the cursor. 
345    cursor = myDatabase.openCursor(null, null);
346
347    DatabaseEntry theKey = 
348         new DatabaseEntry(searchKey.getBytes("UTF-8"));
349    DatabaseEntry theData = 
350         new DatabaseEntry(searchData.getBytes("UTF-8"));
351
352    // Open a cursor using a database handle
353    cursor = myDatabase.openCursor(null, null);
354
355    // Perform the search
356    OperationStatus retVal = cursor.getSearchBothRange(theKey, theData, 
357                                                       LockMode.DEFAULT);
358    // NOTFOUND is returned if a record cannot be found whose key 
359    // matches the search key AND whose data begins with the search data.
360    if (retVal == OperationStatus.NOTFOUND) {
361        System.out.println(searchKey + "/" + searchData + 
362                           " not matched in database " + 
363                           myDatabase.getDatabaseName());
364    } else {
365        // Upon completing a search, the key and data DatabaseEntry 
366        // parameters for getSearchBothRange() are populated with the 
367        // key/data values of the found record.
368        String foundKey = new String(theKey.getData(), "UTF-8");
369        String foundData = new String(theData.getData(), "UTF-8");
370        System.out.println("Found record " + foundKey + "/" + foundData + 
371                           "for search key/data: " + searchKey + 
372                           "/" + searchData);
373    }
374
375} catch (Exception e) {
376    // Exception handling goes here
377} finally {
378   // Make sure to close the cursor
379   cursor.close();
380}</pre>
381      </div>
382      <div class="sect2" lang="en" xml:lang="en">
383        <div class="titlepage">
384          <div>
385            <div>
386              <h3 class="title"><a id="getdups"></a>Working with Duplicate Records</h3>
387            </div>
388          </div>
389        </div>
390        <p>
391        A record is a duplicate of another record if the two records share the
392        same key. For duplicate records, only the data portion of the record is unique.
393      </p>
394        <p>
395        Duplicate records are supported only for the BTree or Hash access methods.
396        For information on configuring your database to use duplicate records,
397        see <a class="xref" href="btree.html#duplicateRecords" title="Allowing Duplicate Records">Allowing Duplicate Records</a>.
398      </p>
399        <p>
400		If your database supports duplicate records, then it can potentially
401		contain multiple records that share the same key. 
402        
403        
404        
405        <span>By default, normal database
406		get operations will only return the first such record in a set
407		of duplicate records. Typically, subsequent duplicate records are
408        accessed using a cursor.
409        </span>
410
411        The following 
412            <span><code class="methodname">Cursor</code> methods</span>
413            
414            
415        are interesting when working with databases that support duplicate records:
416	  </p>
417        <div class="itemizedlist">
418          <ul type="disc">
419            <li>
420              <p>
421            <span>
422                <code class="methodname">Cursor.getNext()</code>,
423                <code class="methodname">Cursor.getPrev()</code>
424            </span>
425            
426          </p>
427              <p>
428            Shows the next/previous record in the database, regardless of
429            whether it is a duplicate of the current record. For an example of
430            using these methods, see <a class="xref" href="Positioning.html" title="Getting Records Using the Cursor">Getting Records Using the Cursor</a>.
431          </p>
432            </li>
433            <li>
434              <p>
435            <code class="methodname">Cursor.getSearchBothRange()</code>
436            
437          </p>
438              <p>
439            Useful for seeking the cursor to a specific record, regardless of
440            whether it is a duplicate record. See <a class="xref" href="Positioning.html#cursorsearch" title="Searching for Records">Searching for Records</a> for more
441            information.
442          </p>
443            </li>
444            <li>
445              <p>
446            <span>
447                <code class="methodname">Cursor.getNextNoDup()</code>,
448                <code class="methodname">Cursor.getPrevNoDup()</code>
449            </span>
450            
451          </p>
452              <p>
453            Gets the next/previous non-duplicate record in the database.  This
454            allows you to skip over all the duplicates in a set of duplicate
455            records. If you call 
456                <span><code class="methodname">Cursor.getPrevNoDup()</code>,</span> 
457                 
458            then the cursor is positioned to the last record for the previous
459            key in the database.  For example, if you have the following records
460            in your database:
461          </p>
462              <pre class="programlisting">Alabama/Athens
463Alabama/Florence
464Alaska/Anchorage
465Alaska/Fairbanks
466Arizona/Avondale
467Arizona/Florence</pre>
468              <p>
469          and your cursor is positioned to <code class="literal">Alaska/Fairbanks</code>,
470          and you then call 
471                <span><code class="methodname">Cursor.getPrevNoDup()</code>,</span> 
472                 
473          then the cursor is positioned to Alabama/Florence. Similarly, if
474          you call 
475                <span><code class="methodname">Cursor.getNextNoDup()</code>,</span> 
476                 
477            
478          then the cursor is positioned to the first record corresponding to 
479          the next key in the database.
480          </p>
481              <p>
482            If there is no next/previous key in the database, then
483                <code class="literal">OperationStatus.NOTFOUND</code> 
484                 
485            is returned, and the cursor is left unchanged.
486          </p>
487            </li>
488            <li>
489              <p>
490            
491                
492          </p>
493              <p>
494
495            Gets the 
496                 
497                <span>next</span> 
498            record that shares the current key. If the
499            cursor is positioned at the last record in the duplicate set and
500            you call 
501                <span><code class="methodname">Cursor.getNextDup()</code>,</span> 
502                 
503
504            then 
505                <code class="literal">OperationStatus.NOTFOUND</code> 
506                 
507            is returned and the cursor is left unchanged. 
508            <span>
509                Likewise, if you call 
510                <code class="methodname">getPrevDup()</code> and the
511                cursor is positioned at the first record in the duplicate set, then
512                <code class="literal">OperationStatus.NOTFOUND</code> is returned and the
513                cursor is left unchanged.
514             </span>
515          </p>
516            </li>
517            <li>
518              <p>
519                <code class="methodname">Cursor.count()</code>
520              </p>
521              <p>Returns the total number of records that share the current key.</p>
522            </li>
523          </ul>
524        </div>
525        <p>
526        For example, the following code fragment positions a cursor to a key
527
528        
529
530        <span>and displays it and all its
531        duplicates.</span>
532
533        <span>Note that the following code fragment assumes that the database contains
534        only String objects for the keys and data.</span>
535      </p>
536        <a id="java_cursor6"></a>
537        <pre class="programlisting">package db.GettingStarted;
538      
539import com.sleepycat.db.Cursor;
540import com.sleepycat.db.Database;
541import com.sleepycat.db.DatabaseEntry;
542import com.sleepycat.db.DatabaseException;
543import com.sleepycat.db.LockMode;
544import com.sleepycat.db.OperationStatus; 
545
546...
547  
548Cursor cursor = null;
549Database myDatabase = null;
550try {
551    ...
552    // Database open omitted for brevity
553    ...
554
555    // Create DatabaseEntry objects
556    // searchKey is some String.
557    DatabaseEntry theKey = new DatabaseEntry(searchKey.getBytes("UTF-8"));
558    DatabaseEntry theData = new DatabaseEntry();
559
560    // Open a cursor using a database handle
561    cursor = myDatabase.openCursor(null, null);
562
563    // Position the cursor
564    // Ignoring the return value for clarity
565    OperationStatus retVal = cursor.getSearchKey(theKey, theData, 
566                                                 LockMode.DEFAULT);
567    
568    // Count the number of duplicates. If the count is greater than 1, 
569    // print the duplicates.
570    if (cursor.count() &gt; 1) {
571        while (retVal == OperationStatus.SUCCESS) {
572            String keyString = new String(theKey.getData(), "UTF-8");
573            String dataString = new String(theData.getData(), "UTF-8");
574            System.out.println("Key | Data : " +  keyString + " | " + 
575                               dataString + "");
576   
577            retVal = cursor.getNextDup(theKey, theData, LockMode.DEFAULT);
578        }
579    }
580} catch (Exception e) {
581    // Exception handling goes here
582} finally {
583   // Make sure to close the cursor
584   cursor.close();
585}</pre>
586      </div>
587    </div>
588    <div class="navfooter">
589      <hr />
590      <table width="100%" summary="Navigation footer">
591        <tr>
592          <td width="40%" align="left"><a accesskey="p" href="Cursors.html">Prev</a>��</td>
593          <td width="20%" align="center">
594            <a accesskey="u" href="Cursors.html">Up</a>
595          </td>
596          <td width="40%" align="right">��<a accesskey="n" href="PutEntryWCursor.html">Next</a></td>
597        </tr>
598        <tr>
599          <td width="40%" align="left" valign="top">Chapter��9.��Using Cursors��</td>
600          <td width="20%" align="center">
601            <a accesskey="h" href="index.html">Home</a>
602          </td>
603          <td width="40%" align="right" valign="top">��Putting Records Using Cursors</td>
604        </tr>
605      </table>
606    </div>
607  </body>
608</html>
609