Main Page | Class Hierarchy | Data Structures | Directories | File List | Data Fields | Related Pages

Cursor.java

00001 /*-
00002  * See the file LICENSE for redistribution information.
00003  *
00004  * Copyright (c) 2002-2005
00005  *      Sleepycat Software.  All rights reserved.
00006  *
00007  * $Id: Cursor.java,v 12.1 2005/06/16 20:22:58 bostic Exp $
00008  */
00009 
00010 package com.sleepycat.db;
00011 
00012 import com.sleepycat.db.internal.DbConstants;
00013 import com.sleepycat.db.internal.Dbc;
00014 
00015 public class Cursor {
00016     /* package */ Dbc dbc;
00017     protected Database database;
00018     protected CursorConfig config;
00019 
00020     protected Cursor() {
00021     }
00022 
00023     Cursor(final Database database, final Dbc dbc, final CursorConfig config)
00024         throws DatabaseException {
00025 
00026         this.dbc = dbc;
00027         this.database = database;
00028         this.config = config;
00029     }
00030 
00031     public synchronized void close()
00032         throws DatabaseException {
00033 
00034         if (dbc != null) {
00035             try {
00036                 dbc.close();
00037             } finally {
00038                 dbc = null;
00039             }
00040         }
00041     }
00042 
00043     public Cursor dup(final boolean samePosition)
00044         throws DatabaseException {
00045 
00046         return new Cursor(database,
00047             dbc.dup(samePosition ? DbConstants.DB_POSITION : 0), config);
00048     }
00049 
00050     public CursorConfig getConfig() {
00051         return config;
00052     }
00053 
00054     public Database getDatabase() {
00055         return database;
00056     }
00057 
00058     public int count()
00059         throws DatabaseException {
00060 
00061         return dbc.count(0);
00062     }
00063 
00064     public OperationStatus delete()
00065         throws DatabaseException {
00066 
00067         return OperationStatus.fromInt(dbc.del(0));
00068     }
00069 
00070     public OperationStatus getCurrent(final DatabaseEntry key,
00071                                       final DatabaseEntry data,
00072                                       LockMode lockMode)
00073         throws DatabaseException {
00074 
00075         return OperationStatus.fromInt(
00076             dbc.get(key, data, DbConstants.DB_CURRENT |
00077                 LockMode.getFlag(lockMode) |
00078                 ((data == null) ? 0 : data.getMultiFlag())));
00079     }
00080 
00081     public OperationStatus getFirst(final DatabaseEntry key,
00082                                     final DatabaseEntry data,
00083                                     LockMode lockMode)
00084         throws DatabaseException {
00085 
00086         return OperationStatus.fromInt(
00087             dbc.get(key, data, DbConstants.DB_FIRST |
00088                 LockMode.getFlag(lockMode) |
00089                 ((data == null) ? 0 : data.getMultiFlag())));
00090     }
00091 
00092     public OperationStatus getLast(final DatabaseEntry key,
00093                                    final DatabaseEntry data,
00094                                    LockMode lockMode)
00095         throws DatabaseException {
00096 
00097         return OperationStatus.fromInt(
00098             dbc.get(key, data, DbConstants.DB_LAST |
00099                 LockMode.getFlag(lockMode) |
00100                 ((data == null) ? 0 : data.getMultiFlag())));
00101     }
00102 
00103     public OperationStatus getNext(final DatabaseEntry key,
00104                                    final DatabaseEntry data,
00105                                    LockMode lockMode)
00106         throws DatabaseException {
00107 
00108         return OperationStatus.fromInt(
00109             dbc.get(key, data, DbConstants.DB_NEXT |
00110                 LockMode.getFlag(lockMode) |
00111                 ((data == null) ? 0 : data.getMultiFlag())));
00112     }
00113 
00114     public OperationStatus getNextDup(final DatabaseEntry key,
00115                                       final DatabaseEntry data,
00116                                       LockMode lockMode)
00117         throws DatabaseException {
00118 
00119         return OperationStatus.fromInt(
00120             dbc.get(key, data, DbConstants.DB_NEXT_DUP |
00121                 LockMode.getFlag(lockMode) |
00122                 ((data == null) ? 0 : data.getMultiFlag())));
00123     }
00124 
00125     public OperationStatus getNextNoDup(final DatabaseEntry key,
00126                                         final DatabaseEntry data,
00127                                         LockMode lockMode)
00128         throws DatabaseException {
00129 
00130         return OperationStatus.fromInt(
00131             dbc.get(key, data, DbConstants.DB_NEXT_NODUP |
00132                 LockMode.getFlag(lockMode) |
00133                 ((data == null) ? 0 : data.getMultiFlag())));
00134     }
00135 
00136     public OperationStatus getPrev(final DatabaseEntry key,
00137                                    final DatabaseEntry data,
00138                                    LockMode lockMode)
00139         throws DatabaseException {
00140 
00141         return OperationStatus.fromInt(
00142             dbc.get(key, data, DbConstants.DB_PREV |
00143                 LockMode.getFlag(lockMode) |
00144                 ((data == null) ? 0 : data.getMultiFlag())));
00145     }
00146 
00147     public OperationStatus getPrevDup(final DatabaseEntry key,
00148                                       final DatabaseEntry data,
00149                                       LockMode lockMode)
00150         throws DatabaseException {
00151 
00152         /*
00153          * "Get the previous duplicate" isn't directly supported by the C API,
00154          * so here's how to get it: dup the cursor and call getPrev, then dup
00155          * the result and call getNextDup.  If both succeed then there was a
00156          * previous duplicate and the first dup is sitting on it.  Keep that,
00157          * and call getCurrent to fill in the user's buffers.
00158          */
00159         Dbc dup1 = dbc.dup(DbConstants.DB_POSITION);
00160         try {
00161             int errCode = dup1.get(DatabaseEntry.IGNORE, DatabaseEntry.IGNORE,
00162                 DbConstants.DB_PREV | LockMode.getFlag(lockMode));
00163             if (errCode == 0) {
00164                 Dbc dup2 = dup1.dup(DbConstants.DB_POSITION);
00165                 try {
00166                     errCode = dup2.get(DatabaseEntry.IGNORE,
00167                         DatabaseEntry.IGNORE,
00168                         DbConstants.DB_NEXT_DUP | LockMode.getFlag(lockMode));
00169                 } finally {
00170                     dup2.close();
00171                 }
00172             }
00173             if (errCode == 0)
00174                 errCode = dup1.get(key, data,
00175                     DbConstants.DB_CURRENT | LockMode.getFlag(lockMode) |
00176                         ((data == null) ? 0 : data.getMultiFlag()));
00177             if (errCode == 0) {
00178                 Dbc tdbc = dbc;
00179                 dbc = dup1;
00180                 dup1 = tdbc;
00181             }
00182             return OperationStatus.fromInt(errCode);
00183         } finally {
00184             dup1.close();
00185         }
00186     }
00187 
00188     public OperationStatus getPrevNoDup(final DatabaseEntry key,
00189                                         final DatabaseEntry data,
00190                                         LockMode lockMode)
00191         throws DatabaseException {
00192 
00193         return OperationStatus.fromInt(
00194             dbc.get(key, data, DbConstants.DB_PREV_NODUP |
00195                 LockMode.getFlag(lockMode) |
00196                 ((data == null) ? 0 : data.getMultiFlag())));
00197     }
00198 
00199     public OperationStatus getRecordNumber(final DatabaseEntry data,
00200                                            LockMode lockMode)
00201         throws DatabaseException {
00202 
00203         return OperationStatus.fromInt(
00204             dbc.get(DatabaseEntry.IGNORE, data,
00205                 DbConstants.DB_GET_RECNO |
00206                 LockMode.getFlag(lockMode) |
00207                 ((data == null) ? 0 : data.getMultiFlag())));
00208     }
00209 
00210     public OperationStatus getSearchKey(final DatabaseEntry key,
00211                                         final DatabaseEntry data,
00212                                         LockMode lockMode)
00213         throws DatabaseException {
00214 
00215         return OperationStatus.fromInt(
00216             dbc.get(key, data, DbConstants.DB_SET |
00217                 LockMode.getFlag(lockMode) |
00218                 ((data == null) ? 0 : data.getMultiFlag())));
00219     }
00220 
00221     public OperationStatus getSearchKeyRange(final DatabaseEntry key,
00222                                              final DatabaseEntry data,
00223                                              LockMode lockMode)
00224         throws DatabaseException {
00225 
00226         return OperationStatus.fromInt(
00227             dbc.get(key, data, DbConstants.DB_SET_RANGE |
00228                 LockMode.getFlag(lockMode) |
00229                 ((data == null) ? 0 : data.getMultiFlag())));
00230     }
00231 
00232     public OperationStatus getSearchBoth(final DatabaseEntry key,
00233                                          final DatabaseEntry data,
00234                                          LockMode lockMode)
00235         throws DatabaseException {
00236 
00237         return OperationStatus.fromInt(
00238             dbc.get(key, data, DbConstants.DB_GET_BOTH |
00239                 LockMode.getFlag(lockMode) |
00240                 ((data == null) ? 0 : data.getMultiFlag())));
00241     }
00242 
00243     public OperationStatus getSearchBothRange(final DatabaseEntry key,
00244                                               final DatabaseEntry data,
00245                                               LockMode lockMode)
00246         throws DatabaseException {
00247 
00248         return OperationStatus.fromInt(
00249             dbc.get(key, data,
00250                 DbConstants.DB_GET_BOTH_RANGE |
00251                 LockMode.getFlag(lockMode) |
00252                 ((data == null) ? 0 : data.getMultiFlag())));
00253     }
00254 
00255     public OperationStatus getSearchRecordNumber(final DatabaseEntry key,
00256                                                  final DatabaseEntry data,
00257                                                  LockMode lockMode)
00258         throws DatabaseException {
00259 
00260         return OperationStatus.fromInt(
00261             dbc.get(key, data, DbConstants.DB_SET_RECNO |
00262                 LockMode.getFlag(lockMode) |
00263                 ((data == null) ? 0 : data.getMultiFlag())));
00264     }
00265 
00266     public OperationStatus put(final DatabaseEntry key,
00267                                final DatabaseEntry data)
00268         throws DatabaseException {
00269 
00270         return OperationStatus.fromInt(
00271             dbc.put(key, data, DbConstants.DB_KEYLAST));
00272     }
00273 
00274     public OperationStatus putAfter(final DatabaseEntry key,
00275                                     final DatabaseEntry data)
00276         throws DatabaseException {
00277 
00278         return OperationStatus.fromInt(
00279             dbc.put(key, data, DbConstants.DB_AFTER));
00280     }
00281 
00282     public OperationStatus putBefore(final DatabaseEntry key,
00283                                      final DatabaseEntry data)
00284         throws DatabaseException {
00285 
00286         return OperationStatus.fromInt(
00287             dbc.put(key, data, DbConstants.DB_BEFORE));
00288     }
00289 
00290     public OperationStatus putNoOverwrite(final DatabaseEntry key,
00291                                           final DatabaseEntry data)
00292         throws DatabaseException {
00293 
00294         /*
00295          * The tricks here are making sure the cursor doesn't move on error and
00296          * noticing that if the key exists, that's an error and we don't want
00297          * to return the data.
00298          */
00299         Dbc tempDbc = dbc.dup(0);
00300         try {
00301             int errCode = tempDbc.get(key, DatabaseEntry.IGNORE,
00302                 DbConstants.DB_SET | database.rmwFlag);
00303             if (errCode == 0)
00304                 return OperationStatus.KEYEXIST;
00305             else if (errCode != DbConstants.DB_NOTFOUND &&
00306                 errCode != DbConstants.DB_KEYEMPTY)
00307                 return OperationStatus.fromInt(errCode);
00308             else {
00309                 Dbc tdbc = dbc;
00310                 dbc = tempDbc;
00311                 tempDbc = tdbc;
00312 
00313                 return OperationStatus.fromInt(
00314                     dbc.put(key, data, DbConstants.DB_KEYLAST));
00315             }
00316         } finally {
00317             tempDbc.close();
00318         }
00319     }
00320 
00321     public OperationStatus putKeyFirst(final DatabaseEntry key,
00322                                        final DatabaseEntry data)
00323         throws DatabaseException {
00324 
00325         return OperationStatus.fromInt(
00326             dbc.put(key, data, DbConstants.DB_KEYFIRST));
00327     }
00328 
00329     public OperationStatus putKeyLast(final DatabaseEntry key,
00330                                       final DatabaseEntry data)
00331         throws DatabaseException {
00332 
00333         return OperationStatus.fromInt(
00334             dbc.put(key, data, DbConstants.DB_KEYLAST));
00335     }
00336 
00337     public OperationStatus putNoDupData(final DatabaseEntry key,
00338                                         final DatabaseEntry data)
00339         throws DatabaseException {
00340 
00341         return OperationStatus.fromInt(
00342             dbc.put(key, data, DbConstants.DB_NODUPDATA));
00343     }
00344 
00345     public OperationStatus putCurrent(final DatabaseEntry data)
00346         throws DatabaseException {
00347 
00348         return OperationStatus.fromInt(
00349             dbc.put(DatabaseEntry.UNUSED, data, DbConstants.DB_CURRENT));
00350     }
00351 }

Generated on Sun Dec 25 12:14:32 2005 for Berkeley DB 4.4.16 by  doxygen 1.4.2