KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sleepycat > je > SecondaryCursor


1 /*-
2  * See the file LICENSE for redistribution information.
3  *
4  * Copyright (c) 2002,2006 Oracle. All rights reserved.
5  *
6  * $Id: SecondaryCursor.java,v 1.35 2006/11/06 20:36:55 linda Exp $
7  */

8
9 package com.sleepycat.je;
10
11 import java.util.HashSet JavaDoc;
12 import java.util.Set JavaDoc;
13 import java.util.logging.Level JavaDoc;
14
15 import com.sleepycat.je.dbi.GetMode;
16 import com.sleepycat.je.dbi.CursorImpl;
17 import com.sleepycat.je.dbi.CursorImpl.SearchMode;
18 import com.sleepycat.je.log.LogUtils;
19 import com.sleepycat.je.txn.Locker;
20 import com.sleepycat.je.utilint.DatabaseUtil;
21
22 /**
23  * Javadoc for this public class is generated via
24  * the doc templates in the doc_src directory.
25  */

26 public class SecondaryCursor extends Cursor {
27
28     private SecondaryDatabase secondaryDb;
29     private Database primaryDb;
30
31     /**
32      * Cursor constructor. Not public. To get a cursor, the user should
33      * call SecondaryDatabase.cursor();
34      */

35     SecondaryCursor(SecondaryDatabase dbHandle,
36                     Transaction txn,
37                     CursorConfig cursorConfig)
38         throws DatabaseException {
39
40         super(dbHandle, txn, cursorConfig);
41         secondaryDb = dbHandle;
42         primaryDb = dbHandle.getPrimaryDatabase();
43     }
44
45     /**
46      * Copy constructor.
47      */

48     private SecondaryCursor(SecondaryCursor cursor, boolean samePosition)
49         throws DatabaseException {
50
51         super(cursor, samePosition);
52         secondaryDb = cursor.secondaryDb;
53         primaryDb = cursor.primaryDb;
54     }
55
56     /**
57      * Javadoc for this public method is generated via
58      * the doc templates in the doc_src directory.
59      */

60     public Database getPrimaryDatabase() {
61     return primaryDb;
62     }
63
64     /**
65      * Javadoc for this public method is generated via
66      * the doc templates in the doc_src directory.
67      */

68     public Cursor dup(boolean samePosition)
69         throws DatabaseException {
70
71         checkState(true);
72         return new SecondaryCursor(this, samePosition);
73     }
74
75     /**
76      * Javadoc for this public method is generated via
77      * the doc templates in the doc_src directory.
78      */

79     public SecondaryCursor dupSecondary(boolean samePosition)
80         throws DatabaseException {
81
82         return (SecondaryCursor) dup(samePosition);
83     }
84
85     /**
86      * Javadoc for this public method is generated via
87      * the doc templates in the doc_src directory.
88      */

89     public OperationStatus delete()
90         throws DatabaseException {
91
92         checkState(true);
93         checkUpdatesAllowed("delete");
94         trace(Level.FINEST, "SecondaryCursor.delete: ", null);
95
96         /* Read the primary key (the data of a secondary). */
97         DatabaseEntry key = new DatabaseEntry();
98         DatabaseEntry pKey = new DatabaseEntry();
99         OperationStatus status = getCurrentInternal(key, pKey,
100                                                     LockMode.RMW);
101
102         /* Delete the primary and all secondaries (including this one). */
103         if (status == OperationStatus.SUCCESS) {
104             status =
105         primaryDb.deleteInternal(cursorImpl.getLocker(), pKey, null);
106             if (status != OperationStatus.SUCCESS) {
107                 SecondaryDatabase secDb = (SecondaryDatabase) getDatabase();
108                 throw secDb.secondaryCorruptException();
109             }
110         }
111         return status;
112     }
113
114     /**
115      * Javadoc for this public method is generated via
116      * the doc templates in the doc_src directory.
117      */

118     public OperationStatus put(DatabaseEntry key, DatabaseEntry data)
119         throws DatabaseException {
120
121         throw SecondaryDatabase.notAllowedException();
122     }
123
124     /**
125      * Javadoc for this public method is generated via
126      * the doc templates in the doc_src directory.
127      */

128     public OperationStatus putNoOverwrite(DatabaseEntry key,
129                                           DatabaseEntry data)
130         throws DatabaseException {
131
132         throw SecondaryDatabase.notAllowedException();
133     }
134
135     /**
136      * Javadoc for this public method is generated via
137      * the doc templates in the doc_src directory.
138      */

139     public OperationStatus putNoDupData(DatabaseEntry key, DatabaseEntry data)
140         throws DatabaseException {
141
142         throw SecondaryDatabase.notAllowedException();
143     }
144
145     /**
146      * Javadoc for this public method is generated via
147      * the doc templates in the doc_src directory.
148      */

149     public OperationStatus putCurrent(DatabaseEntry data)
150         throws DatabaseException {
151
152         throw SecondaryDatabase.notAllowedException();
153     }
154
155     /**
156      * Javadoc for this public method is generated via
157      * the doc templates in the doc_src directory.
158      */

159     public OperationStatus getCurrent(DatabaseEntry key,
160                                       DatabaseEntry data,
161                                       LockMode lockMode)
162         throws DatabaseException {
163
164         return getCurrent(key, new DatabaseEntry(), data, lockMode);
165     }
166
167     /**
168      * Javadoc for this public method is generated via
169      * the doc templates in the doc_src directory.
170      */

171     public OperationStatus getCurrent(DatabaseEntry key,
172                                       DatabaseEntry pKey,
173                                       DatabaseEntry data,
174                                       LockMode lockMode)
175         throws DatabaseException {
176
177         checkState(true);
178         checkArgsNoValRequired(key, pKey, data);
179         trace(Level.FINEST, "SecondaryCursor.getCurrent: ", lockMode);
180
181         return getCurrentInternal(key, pKey, data, lockMode);
182     }
183
184     /**
185      * Javadoc for this public method is generated via
186      * the doc templates in the doc_src directory.
187      */

188     public OperationStatus getFirst(DatabaseEntry key,
189                                     DatabaseEntry data,
190                                     LockMode lockMode)
191         throws DatabaseException {
192
193         return getFirst(key, new DatabaseEntry(), data, lockMode);
194     }
195
196     /**
197      * Javadoc for this public method is generated via
198      * the doc templates in the doc_src directory.
199      */

200     public OperationStatus getFirst(DatabaseEntry key,
201                                     DatabaseEntry pKey,
202                                     DatabaseEntry data,
203                                     LockMode lockMode)
204         throws DatabaseException {
205
206         checkState(false);
207         checkArgsNoValRequired(key, pKey, data);
208         trace(Level.FINEST, "SecondaryCursor.getFirst: ", lockMode);
209
210         return position(key, pKey, data, lockMode, true);
211     }
212
213     /**
214      * Javadoc for this public method is generated via
215      * the doc templates in the doc_src directory.
216      */

217     public OperationStatus getLast(DatabaseEntry key,
218                                    DatabaseEntry data,
219                                    LockMode lockMode)
220         throws DatabaseException {
221
222         return getLast(key, new DatabaseEntry(), data, lockMode);
223     }
224
225     /**
226      * Javadoc for this public method is generated via
227      * the doc templates in the doc_src directory.
228      */

229     public OperationStatus getLast(DatabaseEntry key,
230                                    DatabaseEntry pKey,
231                                    DatabaseEntry data,
232                                    LockMode lockMode)
233         throws DatabaseException {
234
235         checkState(false);
236         checkArgsNoValRequired(key, pKey, data);
237         trace(Level.FINEST, "SecondaryCursor.getLast: ", lockMode);
238
239         return position(key, pKey, data, lockMode, false);
240     }
241
242     /**
243      * Javadoc for this public method is generated via
244      * the doc templates in the doc_src directory.
245      */

246     public OperationStatus getNext(DatabaseEntry key,
247                                    DatabaseEntry data,
248                                    LockMode lockMode)
249         throws DatabaseException {
250
251         return getNext(key, new DatabaseEntry(), data, lockMode);
252     }
253
254     /**
255      * Javadoc for this public method is generated via
256      * the doc templates in the doc_src directory.
257      */

258     public OperationStatus getNext(DatabaseEntry key,
259                                    DatabaseEntry pKey,
260                                    DatabaseEntry data,
261                                    LockMode lockMode)
262         throws DatabaseException {
263
264         checkState(false);
265         checkArgsNoValRequired(key, pKey, data);
266         trace(Level.FINEST, "SecondaryCursor.getNext: ", lockMode);
267
268         if (cursorImpl.isNotInitialized()) {
269             return position(key, pKey, data, lockMode, true);
270         } else {
271             return retrieveNext(key, pKey, data, lockMode, GetMode.NEXT);
272         }
273     }
274
275     /**
276      * Javadoc for this public method is generated via
277      * the doc templates in the doc_src directory.
278      */

279     public OperationStatus getNextDup(DatabaseEntry key,
280                                       DatabaseEntry data,
281                                       LockMode lockMode)
282         throws DatabaseException {
283
284         return getNextDup(key, new DatabaseEntry(), data, lockMode);
285     }
286
287     /**
288      * Javadoc for this public method is generated via
289      * the doc templates in the doc_src directory.
290      */

291     public OperationStatus getNextDup(DatabaseEntry key,
292                                       DatabaseEntry pKey,
293                                       DatabaseEntry data,
294                                       LockMode lockMode)
295         throws DatabaseException {
296
297         checkState(true);
298         checkArgsNoValRequired(key, pKey, data);
299         trace(Level.FINEST, "SecondaryCursor.getNextDup: ", lockMode);
300
301         return retrieveNext(key, pKey, data, lockMode, GetMode.NEXT_DUP);
302     }
303
304     /**
305      * Javadoc for this public method is generated via
306      * the doc templates in the doc_src directory.
307      */

308     public OperationStatus getNextNoDup(DatabaseEntry key,
309                                         DatabaseEntry data,
310                                         LockMode lockMode)
311         throws DatabaseException {
312
313         return getNextNoDup(key, new DatabaseEntry(), data, lockMode);
314     }
315
316     /**
317      * Javadoc for this public method is generated via
318      * the doc templates in the doc_src directory.
319      */

320     public OperationStatus getNextNoDup(DatabaseEntry key,
321                                         DatabaseEntry pKey,
322                                         DatabaseEntry data,
323                                         LockMode lockMode)
324         throws DatabaseException {
325
326         checkState(false);
327         checkArgsNoValRequired(key, pKey, data);
328         trace(Level.FINEST, "SecondaryCursor.getNextNoDup: ", null, null,
329               lockMode);
330
331         if (cursorImpl.isNotInitialized()) {
332             return position(key, pKey, data, lockMode, true);
333         } else {
334             return retrieveNext(key, pKey, data, lockMode,
335                                 GetMode.NEXT_NODUP);
336         }
337     }
338
339     /**
340      * Javadoc for this public method is generated via
341      * the doc templates in the doc_src directory.
342      */

343     public OperationStatus getPrev(DatabaseEntry key,
344                                    DatabaseEntry data,
345                                    LockMode lockMode)
346         throws DatabaseException {
347
348         return getPrev(key, new DatabaseEntry(), data, lockMode);
349     }
350
351     /**
352      * Javadoc for this public method is generated via
353      * the doc templates in the doc_src directory.
354      */

355     public OperationStatus getPrev(DatabaseEntry key,
356                                    DatabaseEntry pKey,
357                                    DatabaseEntry data,
358                                    LockMode lockMode)
359         throws DatabaseException {
360
361         checkState(false);
362         checkArgsNoValRequired(key, pKey, data);
363         trace(Level.FINEST, "SecondaryCursor.getPrev: ", lockMode);
364
365         if (cursorImpl.isNotInitialized()) {
366             return position(key, pKey, data, lockMode, false);
367         } else {
368             return retrieveNext(key, pKey, data, lockMode, GetMode.PREV);
369         }
370     }
371
372     /**
373      * Javadoc for this public method is generated via
374      * the doc templates in the doc_src directory.
375      */

376     public OperationStatus getPrevDup(DatabaseEntry key,
377                                       DatabaseEntry data,
378                                       LockMode lockMode)
379         throws DatabaseException {
380
381         return getPrevDup(key, new DatabaseEntry(), data, lockMode);
382     }
383
384     /**
385      * Javadoc for this public method is generated via
386      * the doc templates in the doc_src directory.
387      */

388     public OperationStatus getPrevDup(DatabaseEntry key,
389                                       DatabaseEntry pKey,
390                                       DatabaseEntry data,
391                                       LockMode lockMode)
392         throws DatabaseException {
393
394         checkState(true);
395         checkArgsNoValRequired(key, pKey, data);
396         trace(Level.FINEST, "SecondaryCursor.getPrevDup: ", lockMode);
397
398         return retrieveNext(key, pKey, data, lockMode, GetMode.PREV_DUP);
399     }
400
401     /**
402      * Javadoc for this public method is generated via
403      * the doc templates in the doc_src directory.
404      */

405     public OperationStatus getPrevNoDup(DatabaseEntry key,
406                                         DatabaseEntry data,
407                                         LockMode lockMode)
408         throws DatabaseException {
409
410         return getPrevNoDup(key, new DatabaseEntry(), data, lockMode);
411     }
412
413     /**
414      * Javadoc for this public method is generated via
415      * the doc templates in the doc_src directory.
416      */

417     public OperationStatus getPrevNoDup(DatabaseEntry key,
418                                         DatabaseEntry pKey,
419                                         DatabaseEntry data,
420                                         LockMode lockMode)
421         throws DatabaseException {
422
423         checkState(false);
424         checkArgsNoValRequired(key, pKey, data);
425         trace(Level.FINEST, "SecondaryCursor.getPrevNoDup: ", lockMode);
426
427         if (cursorImpl.isNotInitialized()) {
428             return position(key, pKey, data, lockMode, false);
429         } else {
430             return retrieveNext(key, pKey, data, lockMode,
431                                 GetMode.PREV_NODUP);
432         }
433     }
434
435     /**
436      * Javadoc for this public method is generated via
437      * the doc templates in the doc_src directory.
438      */

439     public OperationStatus getSearchKey(DatabaseEntry key,
440                                         DatabaseEntry data,
441                                         LockMode lockMode)
442         throws DatabaseException {
443
444         return getSearchKey(key, new DatabaseEntry(), data, lockMode);
445     }
446
447     /**
448      * Javadoc for this public method is generated via
449      * the doc templates in the doc_src directory.
450      */

451     public OperationStatus getSearchKey(DatabaseEntry key,
452                                         DatabaseEntry pKey,
453                                         DatabaseEntry data,
454                                         LockMode lockMode)
455         throws DatabaseException {
456
457         checkState(false);
458         DatabaseUtil.checkForNullDbt(key, "key", true);
459         DatabaseUtil.checkForNullDbt(pKey, "pKey", false);
460         DatabaseUtil.checkForNullDbt(data, "data", false);
461         trace(Level.FINEST, "SecondaryCursor.getSearchKey: ", key, null,
462               lockMode);
463
464         return search(key, pKey, data, lockMode, SearchMode.SET);
465     }
466
467     /**
468      * Javadoc for this public method is generated via
469      * the doc templates in the doc_src directory.
470      */

471     public OperationStatus getSearchKeyRange(DatabaseEntry key,
472                                              DatabaseEntry data,
473                                              LockMode lockMode)
474         throws DatabaseException {
475
476         return getSearchKeyRange(key, new DatabaseEntry(), data, lockMode);
477     }
478
479     /**
480      * Javadoc for this public method is generated via
481      * the doc templates in the doc_src directory.
482      */

483     public OperationStatus getSearchKeyRange(DatabaseEntry key,
484                                              DatabaseEntry pKey,
485                                              DatabaseEntry data,
486                                              LockMode lockMode)
487         throws DatabaseException {
488
489         checkState(false);
490         DatabaseUtil.checkForNullDbt(key, "key", true);
491         DatabaseUtil.checkForNullDbt(pKey, "pKey", false);
492         DatabaseUtil.checkForNullDbt(data, "data", false);
493         trace(Level.FINEST, "SecondaryCursor.getSearchKeyRange: ", key, data,
494               lockMode);
495
496         return search(key, pKey, data, lockMode, SearchMode.SET_RANGE);
497     }
498
499     /**
500      * Javadoc for this public method is generated via
501      * the doc templates in the doc_src directory.
502      */

503     public OperationStatus getSearchBoth(DatabaseEntry key,
504                                          DatabaseEntry data,
505                                          LockMode lockMode)
506         throws DatabaseException {
507
508         throw SecondaryDatabase.notAllowedException();
509     }
510
511     /**
512      * Javadoc for this public method is generated via
513      * the doc templates in the doc_src directory.
514      */

515     public OperationStatus getSearchBoth(DatabaseEntry key,
516                                          DatabaseEntry pKey,
517                                          DatabaseEntry data,
518                                          LockMode lockMode)
519         throws DatabaseException {
520
521         checkState(false);
522         DatabaseUtil.checkForNullDbt(key, "key", true);
523         DatabaseUtil.checkForNullDbt(pKey, "pKey", true);
524         DatabaseUtil.checkForNullDbt(data, "data", false);
525         trace(Level.FINEST, "SecondaryCursor.getSearchBoth: ", key, data,
526               lockMode);
527
528         return search(key, pKey, data, lockMode, SearchMode.BOTH);
529     }
530
531     /**
532      * Javadoc for this public method is generated via
533      * the doc templates in the doc_src directory.
534      */

535     public OperationStatus getSearchBothRange(DatabaseEntry key,
536                                               DatabaseEntry data,
537                                               LockMode lockMode)
538         throws DatabaseException {
539
540         throw SecondaryDatabase.notAllowedException();
541     }
542
543     /**
544      * Javadoc for this public method is generated via
545      * the doc templates in the doc_src directory.
546      */

547     public OperationStatus getSearchBothRange(DatabaseEntry key,
548                                               DatabaseEntry pKey,
549                                               DatabaseEntry data,
550                                               LockMode lockMode)
551         throws DatabaseException {
552
553         checkState(false);
554         DatabaseUtil.checkForNullDbt(key, "key", true);
555         DatabaseUtil.checkForNullDbt(pKey, "pKey", true);
556         DatabaseUtil.checkForNullDbt(data, "data", false);
557         trace(Level.FINEST, "SecondaryCursor.getSearchBothRange: ", key, data,
558               lockMode);
559
560         return search(key, pKey, data, lockMode, SearchMode.BOTH_RANGE);
561     }
562
563     /**
564      * Returns the current key and data.
565      */

566     private OperationStatus getCurrentInternal(DatabaseEntry key,
567                                                DatabaseEntry pKey,
568                                                DatabaseEntry data,
569                                                LockMode lockMode)
570         throws DatabaseException {
571
572         OperationStatus status = getCurrentInternal(key, pKey, lockMode);
573         if (status == OperationStatus.SUCCESS) {
574
575             /*
576              * May return KEYEMPTY if read-uncommitted and the primary was
577              * deleted.
578              */

579             status = readPrimaryAfterGet(key, pKey, data, lockMode);
580         }
581         return status;
582     }
583
584     /**
585      * Calls search() and retrieves primary data.
586      */

587     OperationStatus search(DatabaseEntry key,
588                            DatabaseEntry pKey,
589                            DatabaseEntry data,
590                            LockMode lockMode,
591                            SearchMode searchMode)
592         throws DatabaseException {
593
594         /*
595          * Perform retries to account for deletions during a read-uncommitted.
596          */

597         while (true) {
598             OperationStatus status = search(key, pKey, lockMode, searchMode);
599             if (status != OperationStatus.SUCCESS) {
600                 return status;
601             }
602             status = readPrimaryAfterGet(key, pKey, data, lockMode);
603             if (status == OperationStatus.SUCCESS) {
604                 return status;
605             }
606         }
607     }
608
609     /**
610      * Calls position() and retrieves primary data.
611      */

612     OperationStatus position(DatabaseEntry key,
613                              DatabaseEntry pKey,
614                              DatabaseEntry data,
615                              LockMode lockMode,
616                              boolean first)
617         throws DatabaseException {
618
619         /*
620          * Perform retries to account for deletions during a read-uncommitted.
621          */

622         while (true) {
623             OperationStatus status = position(key, pKey, lockMode, first);
624             if (status != OperationStatus.SUCCESS) {
625                 return status;
626             }
627             status = readPrimaryAfterGet(key, pKey, data, lockMode);
628             if (status == OperationStatus.SUCCESS) {
629                 return status;
630             }
631         }
632     }
633
634     /**
635      * Calls retrieveNext() and retrieves primary data.
636      */

637     OperationStatus retrieveNext(DatabaseEntry key,
638                                  DatabaseEntry pKey,
639                                  DatabaseEntry data,
640                                  LockMode lockMode,
641                                  GetMode getMode)
642         throws DatabaseException {
643
644         /*
645          * Perform retries to account for deletions during a read-uncommitted.
646          */

647         while (true) {
648             OperationStatus status = retrieveNext(key, pKey, lockMode,
649                                                   getMode);
650             if (status != OperationStatus.SUCCESS) {
651                 return status;
652             }
653             status = readPrimaryAfterGet(key, pKey, data, lockMode);
654             if (status == OperationStatus.SUCCESS) {
655                 return status;
656             }
657         }
658     }
659
660     /**
661      * Reads the primary data for a primary key that was read via a secondary.
662      * When SUCCESS is returned by this method, the caller should return
663      * SUCCESS. When KEYEMPTY is returned, the caller should treat this as a
664      * deleted record and either retry the operation (in the case of position,
665      * search, and retrieveNext) or return KEYEMPTY (in the case of
666      * getCurrent). KEYEMPTY is only returned when read-uncommitted is used.
667      *
668      * @return SUCCESS if the primary was read succesfully, or KEYEMPTY if
669      * using read-uncommitted and the primary has been deleted, or KEYEMPTY if
670      * using read-uncommitted and the primary has been updated and no longer
671      * contains the secondary key.
672      *
673      * @throws DatabaseException to indicate a corrupt secondary reference if
674      * the primary record is not found and read-uncommitted is not used (or
675      * read-uncommitted is used, but we cannot verify that a valid deletion has
676      * occured).
677      */

678     private OperationStatus readPrimaryAfterGet(DatabaseEntry key,
679                                                 DatabaseEntry pKey,
680                                                 DatabaseEntry data,
681                                                 LockMode lockMode)
682         throws DatabaseException {
683
684         /*
685          * There is no need to read the primary if no data and no locking
686          * (read-uncommitted) are requested by the caller. However, if partial
687          * data is requested along with read-uncommitted, then we must read all
688          * data in order to call the key creator below. [#14966]
689          */

690         DatabaseEntry copyToPartialEntry = null;
691         boolean readUncommitted = isReadUncommittedMode(lockMode);
692         if (readUncommitted && data.getPartial()) {
693             if (data.getPartialLength() == 0) {
694                 /* No need to read the primary. */
695                 data.setData(LogUtils.ZERO_LENGTH_BYTE_ARRAY);
696                 return OperationStatus.SUCCESS;
697             } else {
698                 /* Read all data and then copy the requested partial data. */
699                 copyToPartialEntry = data;
700                 data = new DatabaseEntry();
701             }
702         }
703
704         Locker locker = cursorImpl.getLocker();
705         Cursor cursor = null;
706         try {
707         cursor = new Cursor(primaryDb, locker, null);
708             OperationStatus status =
709                 cursor.search(pKey, data, lockMode, SearchMode.SET);
710             if (status != OperationStatus.SUCCESS) {
711
712                 /*
713                  * If using read-uncommitted and the primary is not found,
714                  * check to see if the secondary key also has been deleted. If
715                  * so, the primary was deleted in between reading the secondary
716                  * and the primary. It is not corrupt, so we return KEYEMPTY.
717                  */

718                 if (readUncommitted) {
719                     status = getCurrentInternal(key, pKey, lockMode);
720                     if (status == OperationStatus.KEYEMPTY) {
721                         return status;
722                     }
723                 }
724
725                 /* Secondary reference is corrupt. */
726                 SecondaryDatabase secDb = (SecondaryDatabase) getDatabase();
727                 throw secDb.secondaryCorruptException();
728             }
729
730             /*
731              * If using read-uncommitted and the primary was found, check to
732              * see if primary was updated so that it no longer contains the
733              * secondary key. If it has been, return KEYEMPTY.
734              */

735             if (readUncommitted) {
736                 SecondaryConfig config =
737                     secondaryDb.getPrivateSecondaryConfig();
738
739                 /*
740                  * If the secondary key is immutable, or the key creators are
741                  * null (the database is read only), then we can skip this
742                  * check.
743                  */

744                 if (config.getImmutableSecondaryKey()) {
745                     /* Do nothing. */
746                 } else if (config.getKeyCreator() != null) {
747
748                     /*
749                      * Check that the key we're using is equal to the key
750                      * returned by the key creator.
751                      */

752                     DatabaseEntry secKey = new DatabaseEntry();
753                     if (!config.getKeyCreator().createSecondaryKey
754                             (secondaryDb, pKey, data, secKey) ||
755                         !secKey.equals(key)) {
756                         return OperationStatus.KEYEMPTY;
757                     }
758                 } else if (config.getMultiKeyCreator() != null) {
759
760                     /*
761                      * Check that the key we're using is in the set returned by
762                      * the key creator.
763                      */

764                     Set JavaDoc results = new HashSet JavaDoc();
765                     config.getMultiKeyCreator().createSecondaryKeys
766                         (secondaryDb, pKey, data, results);
767                     if (!results.contains(key)) {
768                         return OperationStatus.KEYEMPTY;
769                     }
770                 }
771             }
772             
773             /*
774              * When a partial entry was requested but we read all the data,
775              * copy the requested partial data to the caller's entry. [#14966]
776              */

777             if (copyToPartialEntry != null) {
778                 CursorImpl.setDbt(copyToPartialEntry, data.getData());
779             }
780             return OperationStatus.SUCCESS;
781         } finally {
782             if (cursor != null) {
783                 cursor.close();
784             }
785         }
786     }
787
788     /**
789      * Note that this flavor of checkArgs doesn't require that the
790      * dbt data is set.
791      */

792     private void checkArgsNoValRequired(DatabaseEntry key,
793                                         DatabaseEntry pKey,
794                                         DatabaseEntry data) {
795         DatabaseUtil.checkForNullDbt(key, "key", false);
796         DatabaseUtil.checkForNullDbt(pKey, "pKey", false);
797         DatabaseUtil.checkForNullDbt(data, "data", false);
798     }
799 }
800
Popular Tags