KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sleepycat > collections > RangeCursor


1 /*-
2  * See the file LICENSE for redistribution information.
3  *
4  * Copyright (c) 2002-2005
5  * Sleepycat Software. All rights reserved.
6  *
7  * $Id: RangeCursor.java,v 1.10 2005/06/16 21:04:46 linda Exp $
8  */

9
10 package com.sleepycat.collections;
11
12 import com.sleepycat.compat.DbCompat;
13 import com.sleepycat.je.Cursor;
14 import com.sleepycat.je.CursorConfig;
15 import com.sleepycat.je.DatabaseEntry;
16 import com.sleepycat.je.DatabaseException;
17 import com.sleepycat.je.LockMode;
18 import com.sleepycat.je.OperationStatus;
19 import com.sleepycat.je.SecondaryCursor;
20
21 /**
22  * A cursor-like interface that enforces a key range. The method signatures
23  * are actually those of SecondaryCursor, but the pKey parameter may be null.
24  * It was done this way to avoid doubling the number of methods.
25  *
26  * <p>This is not a general implementation of a range cursor and should not
27  * be used outside this package; however, it may evolve into a generally useful
28  * range cursor some day.</p>
29  *
30  * @author Mark Hayes
31  */

32 class RangeCursor implements Cloneable {
33
34     /**
35      * The cursor and secondary cursor are the same object. The secCursor is
36      * null if the database is not a secondary database.
37      */

38     private Cursor cursor;
39     private SecondaryCursor secCursor;
40     private CurrentTransaction currentTxn;
41     private boolean writeCursor;
42
43     /**
44      * The range is always non-null, but may be unbounded meaning that it is
45      * open and not used.
46      */

47     private KeyRange range;
48
49     /**
50      * If the database is a RECNO or QUEUE database, we know its keys are
51      * record numbers. We treat a non-positive record number as out of bounds,
52      * that is, we return NOTFOUND rather than throwing
53      * IllegalArgumentException as would happen if we passed a non-positive
54      * record number into the DB cursor. This behavior is required by the
55      * collections interface.
56      */

57     private boolean isRecnoOrQueue;
58
59     /**
60      * The privXxx entries are used only when the range is bounded. We read
61      * into these private entries to avoid modifying the caller's entry
62      * parameters in the case where we read successfully but the key is out of
63      * range. In that case we return NOTFOUND and we want to leave the entry
64      * parameters unchanged.
65      */

66     private DatabaseEntry privKey;
67     private DatabaseEntry privPKey;
68     private DatabaseEntry privData;
69
70     /**
71      * The initialized flag is set to true whenever we successfully position
72      * the cursor. It is used to implement the getNext/Prev logic for doing a
73      * getFirst/Last when the cursor is not initialized. We can't rely on
74      * Cursor to do that for us, since if we position the underlying cursor
75      * successfully but the key is out of range, we have no way to set the
76      * underlying cursor to uninitialized. A range cursor always starts in the
77      * uninitialized state.
78      */

79     private boolean initialized;
80
81     /**
82      * Create a range cursor.
83      */

84     RangeCursor(DataView view, KeyRange range, boolean writeAllowed)
85         throws DatabaseException {
86
87         this.range = range;
88         this.currentTxn = view.currentTxn;
89         isRecnoOrQueue = view.recNumAllowed && !view.btreeRecNumDb;
90
91         /*
92          * writeCursor is set to true if requested by the user via the cursor
93          * config, or if this is a writable cursor and the user has not
94          * specified a cursor config. For CDB, a special cursor must be
95          * created for writing. See CurrentTransaction.openCursor.
96          */

97         writeCursor = DbCompat.getWriteCursor(view.cursorConfig) ||
98             (view.cursorConfig == CursorConfig.DEFAULT && writeAllowed);
99
100         cursor = currentTxn.openCursor(view.db, view.cursorConfig, writeCursor,
101                                        view.useTransaction());
102         init();
103     }
104
105     /**
106      * Create a cloned range cursor. The caller must clone the underlying
107      * cursor before using this constructor, because cursor open/close is
108      * handled specially for CDS cursors outside this class.
109      */

110     RangeCursor dup(boolean samePosition)
111         throws DatabaseException {
112
113         try {
114             RangeCursor c = (RangeCursor) super.clone();
115             c.cursor = currentTxn.dupCursor(cursor, writeCursor,
116                                             samePosition);
117             c.init();
118             return c;
119         } catch (CloneNotSupportedException neverHappens) {
120             return null;
121         }
122     }
123
124     /**
125      * Used for opening and duping (cloning).
126      */

127     private void init() {
128
129         if (cursor instanceof SecondaryCursor) {
130             secCursor = (SecondaryCursor) cursor;
131         } else {
132             secCursor = null;
133         }
134
135         if (range.hasBound()) {
136             privKey = new DatabaseEntry();
137             privPKey = new DatabaseEntry();
138             privData = new DatabaseEntry();
139         } else {
140             privKey = null;
141             privPKey = null;
142             privData = null;
143         }
144     }
145
146     /**
147      * Returns the underlying cursor. Used for cloning.
148      */

149     Cursor getCursor() {
150         return cursor;
151     }
152
153     /**
154      * When an unbounded range is used, this method is called to use the
155      * callers entry parameters directly, to avoid the extra step of copying
156      * between the private entries and the caller's entries.
157      */

158     private void setParams(DatabaseEntry key, DatabaseEntry pKey,
159                            DatabaseEntry data) {
160         privKey = key;
161         privPKey = pKey;
162         privData = data;
163     }
164
165     /**
166      * Dups the cursor, sets the cursor and secCursor fields to the duped
167      * cursor, and returns the old cursor. Always call endOperation in a
168      * finally clause after calling beginOperation.
169      *
170      * <p>If the returned cursor == the cursor field, the cursor is
171      * uninitialized and was not duped; this case is handled correctly by
172      * endOperation.</p>
173      */

174     private Cursor beginOperation()
175         throws DatabaseException {
176
177         Cursor oldCursor = cursor;
178         if (initialized) {
179             cursor = currentTxn.dupCursor(cursor, writeCursor, true);
180             if (secCursor != null) {
181                 secCursor = (SecondaryCursor) cursor;
182             }
183         } else {
184             return cursor;
185         }
186         return oldCursor;
187     }
188
189     /**
190      * If the operation succeded, leaves the duped cursor in place and closes
191      * the oldCursor. If the operation failed, moves the oldCursor back in
192      * place and closes the duped cursor. oldCursor may be null if
193      * beginOperation was not called, in cases where we don't need to dup
194      * the cursor. Always call endOperation when a successful operation ends,
195      * in order to set the initialized field.
196      */

197     private void endOperation(Cursor oldCursor, OperationStatus status,
198                               DatabaseEntry key, DatabaseEntry pKey,
199                               DatabaseEntry data)
200         throws DatabaseException {
201
202         if (status == OperationStatus.SUCCESS) {
203             if (oldCursor != null && oldCursor != cursor) {
204                 currentTxn.closeCursor(oldCursor);
205             }
206             if (key != null) {
207                 swapData(key, privKey);
208             }
209             if (pKey != null && secCursor != null) {
210                 swapData(pKey, privPKey);
211             }
212             if (data != null) {
213                 swapData(data, privData);
214             }
215             initialized = true;
216         } else {
217             if (oldCursor != null && oldCursor != cursor) {
218                 currentTxn.closeCursor(cursor);
219                 cursor = oldCursor;
220                 if (secCursor != null) {
221                     secCursor = (SecondaryCursor) cursor;
222                 }
223             }
224         }
225     }
226
227     /**
228      * Swaps the contents of the two entries. Used to return entry data to
229      * the caller when the operation was successful.
230      */

231     private static void swapData(DatabaseEntry e1, DatabaseEntry e2) {
232
233         byte[] d1 = e1.getData();
234         int o1 = e1.getOffset();
235         int s1 = e1.getSize();
236
237         e1.setData(e2.getData(), e2.getOffset(), e2.getSize());
238         e2.setData(d1, o1, s1);
239     }
240
241     /**
242      * Shares the same byte array, offset and size between two entries.
243      * Used when copying the entry data is not necessary because it is known
244      * that the underlying operation will not modify the entry, for example,
245      * with getSearchKey.
246      */

247     private static void shareData(DatabaseEntry from, DatabaseEntry to) {
248
249         if (from != null) {
250             to.setData(from.getData(), from.getOffset(), from.getSize());
251         }
252     }
253
254     public OperationStatus getFirst(DatabaseEntry key,
255                                     DatabaseEntry pKey,
256                                     DatabaseEntry data,
257                                     LockMode lockMode)
258         throws DatabaseException {
259
260         OperationStatus status;
261         if (!range.hasBound()) {
262             setParams(key, pKey, data);
263             status = doGetFirst(lockMode);
264             endOperation(null, status, null, null, null);
265             return status;
266         }
267         if (range.singleKey) {
268             KeyRange.copy(range.beginKey, privKey);
269             status = doGetSearchKey(lockMode);
270             endOperation(null, status, key, pKey, data);
271         } else {
272             status = OperationStatus.NOTFOUND;
273             Cursor oldCursor = beginOperation();
274             try {
275                 if (range.beginKey == null) {
276                     status = doGetFirst(lockMode);
277                 } else {
278                     KeyRange.copy(range.beginKey, privKey);
279                     status = doGetSearchKeyRange(lockMode);
280                     if (status == OperationStatus.SUCCESS &&
281                         !range.beginInclusive &&
282                         range.compare(privKey, range.beginKey) == 0) {
283                         status = doGetNext(lockMode);
284                     }
285                 }
286                 if (status == OperationStatus.SUCCESS &&
287                     !range.check(privKey)) {
288                     status = OperationStatus.NOTFOUND;
289                 }
290             } finally {
291                 endOperation(oldCursor, status, key, pKey, data);
292             }
293         }
294         return status;
295     }
296
297     public OperationStatus getLast(DatabaseEntry key,
298                                    DatabaseEntry pKey,
299                                    DatabaseEntry data,
300                                    LockMode lockMode)
301         throws DatabaseException {
302
303         OperationStatus status = OperationStatus.NOTFOUND;
304         if (!range.hasBound()) {
305             setParams(key, pKey, data);
306             status = doGetLast(lockMode);
307             endOperation(null, status, null, null, null);
308             return status;
309         }
310         Cursor oldCursor = beginOperation();
311         try {
312             if (range.endKey == null) {
313                 status = doGetLast(lockMode);
314             } else {
315                 KeyRange.copy(range.endKey, privKey);
316                 status = doGetSearchKeyRange(lockMode);
317                 if (status == OperationStatus.SUCCESS) {
318                     if (range.endInclusive &&
319                         range.compare(range.endKey, privKey) == 0) {
320                         status = doGetNextNoDup(lockMode);
321                         if (status == OperationStatus.SUCCESS) {
322                             status = doGetPrev(lockMode);
323                         } else {
324                             status = doGetLast(lockMode);
325                         }
326                     } else {
327                         status = doGetPrev(lockMode);
328                     }
329                 } else {
330                     status = doGetLast(lockMode);
331                 }
332             }
333             if (status == OperationStatus.SUCCESS &&
334                 !range.checkBegin(privKey, true)) {
335                 status = OperationStatus.NOTFOUND;
336             }
337         } finally {
338             endOperation(oldCursor, status, key, pKey, data);
339         }
340         return status;
341     }
342
343     public OperationStatus getNext(DatabaseEntry key,
344                                    DatabaseEntry pKey,
345                                    DatabaseEntry data,
346                                    LockMode lockMode)
347         throws DatabaseException {
348
349         OperationStatus status;
350         if (!initialized) {
351             return getFirst(key, pKey, data, lockMode);
352         }
353         if (!range.hasBound()) {
354             setParams(key, pKey, data);
355             status = doGetNext(lockMode);
356             endOperation(null, status, null, null, null);
357             return status;
358         }
359         if (range.singleKey) {
360             status = doGetNextDup(lockMode);
361             endOperation(null, status, key, pKey, data);
362         } else {
363             status = OperationStatus.NOTFOUND;
364             Cursor oldCursor = beginOperation();
365             try {
366                 status = doGetNext(lockMode);
367                 if (status == OperationStatus.SUCCESS &&
368                     !range.check(privKey)) {
369                     status = OperationStatus.NOTFOUND;
370                 }
371             } finally {
372                 endOperation(oldCursor, status, key, pKey, data);
373             }
374         }
375         return status;
376     }
377
378     public OperationStatus getNextNoDup(DatabaseEntry key,
379                                         DatabaseEntry pKey,
380                                         DatabaseEntry data,
381                                         LockMode lockMode)
382         throws DatabaseException {
383
384         OperationStatus status;
385         if (!initialized) {
386             return getFirst(key, pKey, data, lockMode);
387         }
388         if (!range.hasBound()) {
389             setParams(key, pKey, data);
390             status = doGetNextNoDup(lockMode);
391             endOperation(null, status, null, null, null);
392             return status;
393         }
394         if (range.singleKey) {
395             status = OperationStatus.NOTFOUND;
396         } else {
397             status = OperationStatus.NOTFOUND;
398             Cursor oldCursor = beginOperation();
399             try {
400                 status = doGetNextNoDup(lockMode);
401                 if (status == OperationStatus.SUCCESS &&
402                     !range.check(privKey)) {
403                     status = OperationStatus.NOTFOUND;
404                 }
405             } finally {
406                 endOperation(oldCursor, status, key, pKey, data);
407             }
408         }
409         return status;
410     }
411
412     public OperationStatus getPrev(DatabaseEntry key,
413                                    DatabaseEntry pKey,
414                                    DatabaseEntry data,
415                                    LockMode lockMode)
416         throws DatabaseException {
417
418         OperationStatus status;
419         if (!initialized) {
420             return getLast(key, pKey, data, lockMode);
421         }
422         if (!range.hasBound()) {
423             setParams(key, pKey, data);
424             status = doGetPrev(lockMode);
425             endOperation(null, status, null, null, null);
426             return status;
427         }
428         if (range.singleKey) {
429             status = doGetPrevDup(lockMode);
430             endOperation(null, status, key, pKey, data);
431         } else {
432             status = OperationStatus.NOTFOUND;
433             Cursor oldCursor = beginOperation();
434             try {
435                 status = doGetPrev(lockMode);
436                 if (status == OperationStatus.SUCCESS &&
437                     !range.check(privKey)) {
438                     status = OperationStatus.NOTFOUND;
439                 }
440             } finally {
441                 endOperation(oldCursor, status, key, pKey, data);
442             }
443         }
444         return status;
445     }
446
447     public OperationStatus getPrevNoDup(DatabaseEntry key,
448                                         DatabaseEntry pKey,
449                                         DatabaseEntry data,
450                                         LockMode lockMode)
451         throws DatabaseException {
452
453         OperationStatus status;
454         if (!initialized) {
455             return getLast(key, pKey, data, lockMode);
456         }
457         if (!range.hasBound()) {
458             setParams(key, pKey, data);
459             status = doGetPrevNoDup(lockMode);
460             endOperation(null, status, null, null, null);
461             return status;
462         }
463         if (range.singleKey) {
464             status = OperationStatus.NOTFOUND;
465         } else {
466             status = OperationStatus.NOTFOUND;
467             Cursor oldCursor = beginOperation();
468             try {
469                 status = doGetPrevNoDup(lockMode);
470                 if (status == OperationStatus.SUCCESS &&
471                     !range.check(privKey)) {
472                     status = OperationStatus.NOTFOUND;
473                 }
474             } finally {
475                 endOperation(oldCursor, status, key, pKey, data);
476             }
477         }
478         return status;
479     }
480
481     public OperationStatus getSearchKey(DatabaseEntry key,
482                                         DatabaseEntry pKey,
483                                         DatabaseEntry data,
484                                         LockMode lockMode)
485         throws DatabaseException {
486
487         OperationStatus status;
488         if (!range.hasBound()) {
489             setParams(key, pKey, data);
490             status = doGetSearchKey(lockMode);
491             endOperation(null, status, null, null, null);
492             return status;
493         }
494         if (!range.check(key)) {
495             status = OperationStatus.NOTFOUND;
496         } else {
497             shareData(key, privKey);
498             status = doGetSearchKey(lockMode);
499             endOperation(null, status, key, pKey, data);
500         }
501         return status;
502     }
503
504     public OperationStatus getSearchBoth(DatabaseEntry key,
505                                          DatabaseEntry pKey,
506                                          DatabaseEntry data,
507                                          LockMode lockMode)
508         throws DatabaseException {
509
510         OperationStatus status;
511         if (!range.hasBound()) {
512             setParams(key, pKey, data);
513             status = doGetSearchBoth(lockMode);
514             endOperation(null, status, null, null, null);
515             return status;
516         }
517         if (!range.check(key)) {
518             status = OperationStatus.NOTFOUND;
519         } else {
520             shareData(key, privKey);
521             if (secCursor != null) {
522                 shareData(pKey, privPKey);
523             } else {
524                 shareData(data, privData);
525             }
526             status = doGetSearchBoth(lockMode);
527             endOperation(null, status, key, pKey, data);
528         }
529         return status;
530     }
531
532     public OperationStatus getSearchKeyRange(DatabaseEntry key,
533                                              DatabaseEntry pKey,
534                                              DatabaseEntry data,
535                                              LockMode lockMode)
536         throws DatabaseException {
537
538         OperationStatus status = OperationStatus.NOTFOUND;
539         if (!range.hasBound()) {
540             setParams(key, pKey, data);
541             status = doGetSearchKeyRange(lockMode);
542             endOperation(null, status, null, null, null);
543             return status;
544         }
545         Cursor oldCursor = beginOperation();
546         try {
547             shareData(key, privKey);
548             status = doGetSearchKeyRange(lockMode);
549             if (status == OperationStatus.SUCCESS &&
550                 !range.check(privKey)) {
551                 status = OperationStatus.NOTFOUND;
552             }
553         } finally {
554             endOperation(oldCursor, status, key, pKey, data);
555         }
556         return status;
557     }
558
559     public OperationStatus getSearchBothRange(DatabaseEntry key,
560                                               DatabaseEntry pKey,
561                                               DatabaseEntry data,
562                                               LockMode lockMode)
563         throws DatabaseException {
564
565         OperationStatus status = OperationStatus.NOTFOUND;
566         if (!range.hasBound()) {
567             setParams(key, pKey, data);
568             status = doGetSearchBothRange(lockMode);
569             endOperation(null, status, null, null, null);
570             return status;
571         }
572         Cursor oldCursor = beginOperation();
573         try {
574             shareData(key, privKey);
575             if (secCursor != null) {
576                 shareData(pKey, privPKey);
577             } else {
578                 shareData(data, privData);
579             }
580             status = doGetSearchBothRange(lockMode);
581             if (status == OperationStatus.SUCCESS &&
582                 !range.check(privKey)) {
583                 status = OperationStatus.NOTFOUND;
584             }
585         } finally {
586             endOperation(oldCursor, status, key, pKey, data);
587         }
588         return status;
589     }
590
591     public OperationStatus getSearchRecordNumber(DatabaseEntry key,
592                                                  DatabaseEntry pKey,
593                                                  DatabaseEntry data,
594                                                  LockMode lockMode)
595         throws DatabaseException {
596
597         OperationStatus status;
598         if (!range.hasBound()) {
599             setParams(key, pKey, data);
600             status = doGetSearchRecordNumber(lockMode);
601             endOperation(null, status, null, null, null);
602             return status;
603         }
604         if (!range.check(key)) {
605             status = OperationStatus.NOTFOUND;
606         } else {
607             shareData(key, privKey);
608             status = doGetSearchRecordNumber(lockMode);
609             endOperation(null, status, key, pKey, data);
610         }
611         return status;
612     }
613
614     public OperationStatus getNextDup(DatabaseEntry key,
615                                       DatabaseEntry pKey,
616                                       DatabaseEntry data,
617                                       LockMode lockMode)
618         throws DatabaseException {
619
620         if (!initialized) {
621             throw new DatabaseException("Cursor not initialized");
622         }
623         OperationStatus status;
624         if (!range.hasBound()) {
625             setParams(key, pKey, data);
626             status = doGetNextDup(lockMode);
627             endOperation(null, status, null, null, null);
628         } else {
629             status = doGetNextDup(lockMode);
630             endOperation(null, status, key, pKey, data);
631         }
632         return status;
633     }
634
635     public OperationStatus getPrevDup(DatabaseEntry key,
636                                       DatabaseEntry pKey,
637                                       DatabaseEntry data,
638                                       LockMode lockMode)
639         throws DatabaseException {
640
641         if (!initialized) {
642             throw new DatabaseException("Cursor not initialized");
643         }
644         OperationStatus status;
645         if (!range.hasBound()) {
646             setParams(key, pKey, data);
647             status = doGetPrevDup(lockMode);
648             endOperation(null, status, null, null, null);
649         } else {
650             status = doGetPrevDup(lockMode);
651             endOperation(null, status, key, pKey, data);
652         }
653         return status;
654     }
655
656     public OperationStatus getCurrent(DatabaseEntry key,
657                                       DatabaseEntry pKey,
658                                       DatabaseEntry data,
659                                       LockMode lockMode)
660         throws DatabaseException {
661
662         if (!initialized) {
663             throw new DatabaseException("Cursor not initialized");
664         }
665         if (secCursor != null && pKey != null) {
666             return secCursor.getCurrent(key, pKey, data, lockMode);
667         } else {
668             return cursor.getCurrent(key, data, lockMode);
669         }
670     }
671
672     /*
673      * Pass-thru methods.
674      */

675
676     public void close()
677         throws DatabaseException {
678
679         currentTxn.closeCursor(cursor);
680     }
681
682     public int count()
683         throws DatabaseException {
684
685     return cursor.count();
686     }
687
688     public OperationStatus delete()
689         throws DatabaseException {
690
691     return cursor.delete();
692     }
693
694     public OperationStatus put(DatabaseEntry key, DatabaseEntry data)
695         throws DatabaseException {
696
697         return cursor.put(key, data);
698     }
699
700     public OperationStatus putNoOverwrite(DatabaseEntry key,
701                                           DatabaseEntry data)
702         throws DatabaseException {
703
704         return cursor.putNoOverwrite(key, data);
705     }
706
707     public OperationStatus putNoDupData(DatabaseEntry key, DatabaseEntry data)
708         throws DatabaseException {
709
710         return cursor.putNoDupData(key, data);
711     }
712
713     public OperationStatus putCurrent(DatabaseEntry data)
714         throws DatabaseException {
715
716         return cursor.putCurrent(data);
717     }
718
719     public OperationStatus putAfter(DatabaseEntry key, DatabaseEntry data)
720         throws DatabaseException {
721
722         return DbCompat.putAfter(cursor, key, data);
723     }
724
725     public OperationStatus putBefore(DatabaseEntry key, DatabaseEntry data)
726         throws DatabaseException {
727
728         return DbCompat.putBefore(cursor, key, data);
729     }
730
731     private OperationStatus doGetFirst(LockMode lockMode)
732         throws DatabaseException {
733
734         if (secCursor != null && privPKey != null) {
735             return secCursor.getFirst(privKey, privPKey, privData, lockMode);
736         } else {
737             return cursor.getFirst(privKey, privData, lockMode);
738         }
739     }
740
741     private OperationStatus doGetLast(LockMode lockMode)
742         throws DatabaseException {
743
744         if (secCursor != null && privPKey != null) {
745             return secCursor.getLast(privKey, privPKey, privData, lockMode);
746         } else {
747             return cursor.getLast(privKey, privData, lockMode);
748         }
749     }
750
751     private OperationStatus doGetNext(LockMode lockMode)
752         throws DatabaseException {
753
754         if (secCursor != null && privPKey != null) {
755             return secCursor.getNext(privKey, privPKey, privData, lockMode);
756         } else {
757             return cursor.getNext(privKey, privData, lockMode);
758         }
759     }
760
761     private OperationStatus doGetNextDup(LockMode lockMode)
762         throws DatabaseException {
763
764         if (secCursor != null && privPKey != null) {
765             return secCursor.getNextDup(privKey, privPKey, privData, lockMode);
766         } else {
767             return cursor.getNextDup(privKey, privData, lockMode);
768         }
769     }
770
771     private OperationStatus doGetNextNoDup(LockMode lockMode)
772         throws DatabaseException {
773
774         if (secCursor != null && privPKey != null) {
775             return secCursor.getNextNoDup(privKey, privPKey, privData,
776                                           lockMode);
777         } else {
778             return cursor.getNextNoDup(privKey, privData, lockMode);
779         }
780     }
781
782     private OperationStatus doGetPrev(LockMode lockMode)
783         throws DatabaseException {
784
785         if (secCursor != null && privPKey != null) {
786             return secCursor.getPrev(privKey, privPKey, privData, lockMode);
787         } else {
788             return cursor.getPrev(privKey, privData, lockMode);
789         }
790     }
791
792     private OperationStatus doGetPrevDup(LockMode lockMode)
793         throws DatabaseException {
794
795         if (secCursor != null && privPKey != null) {
796             return secCursor.getPrevDup(privKey, privPKey, privData, lockMode);
797         } else {
798             return cursor.getPrevDup(privKey, privData, lockMode);
799         }
800     }
801
802     private OperationStatus doGetPrevNoDup(LockMode lockMode)
803         throws DatabaseException {
804
805         if (secCursor != null && privPKey != null) {
806             return secCursor.getPrevNoDup(privKey, privPKey, privData,
807                                           lockMode);
808         } else {
809             return cursor.getPrevNoDup(privKey, privData, lockMode);
810         }
811     }
812
813     private OperationStatus doGetSearchKey(LockMode lockMode)
814         throws DatabaseException {
815
816         if (isRecnoOrQueue && DbCompat.getRecordNumber(privKey) <= 0) {
817             return OperationStatus.NOTFOUND;
818         }
819         if (secCursor != null && privPKey != null) {
820             return secCursor.getSearchKey(privKey, privPKey, privData,
821                                           lockMode);
822         } else {
823             return cursor.getSearchKey(privKey, privData, lockMode);
824         }
825     }
826
827     private OperationStatus doGetSearchKeyRange(LockMode lockMode)
828         throws DatabaseException {
829
830         if (isRecnoOrQueue && DbCompat.getRecordNumber(privKey) <= 0) {
831             return OperationStatus.NOTFOUND;
832         }
833         if (secCursor != null && privPKey != null) {
834             return secCursor.getSearchKeyRange(privKey, privPKey, privData,
835                                                lockMode);
836         } else {
837             return cursor.getSearchKeyRange(privKey, privData, lockMode);
838         }
839     }
840
841     private OperationStatus doGetSearchBoth(LockMode lockMode)
842         throws DatabaseException {
843
844         if (isRecnoOrQueue && DbCompat.getRecordNumber(privKey) <= 0) {
845             return OperationStatus.NOTFOUND;
846         }
847         if (secCursor != null && privPKey != null) {
848             return secCursor.getSearchBoth(privKey, privPKey, privData,
849                                            lockMode);
850         } else {
851             return cursor.getSearchBoth(privKey, privData, lockMode);
852         }
853     }
854
855     private OperationStatus doGetSearchBothRange(LockMode lockMode)
856         throws DatabaseException {
857
858         if (isRecnoOrQueue && DbCompat.getRecordNumber(privKey) <= 0) {
859             return OperationStatus.NOTFOUND;
860         }
861         if (secCursor != null && privPKey != null) {
862             return secCursor.getSearchBothRange(privKey, privPKey, privData,
863                                                 lockMode);
864         } else {
865             return cursor.getSearchBothRange(privKey, privData, lockMode);
866         }
867     }
868
869     private OperationStatus doGetSearchRecordNumber(LockMode lockMode)
870         throws DatabaseException {
871
872         if (DbCompat.getRecordNumber(privKey) <= 0) {
873             return OperationStatus.NOTFOUND;
874         }
875         if (secCursor != null && privPKey != null) {
876             return DbCompat.getSearchRecordNumber(secCursor, privKey, privPKey,
877                                                   privData, lockMode);
878         } else {
879             return DbCompat.getSearchRecordNumber(cursor, privKey, privData,
880                                                   lockMode);
881         }
882     }
883 }
884
Popular Tags