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