Home | History | Annotate | Download | only in database
      1 /*
      2  * Copyright (C) 2006 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package android.database;
     18 
     19 import android.content.ContentResolver;
     20 import android.net.Uri;
     21 import android.os.Bundle;
     22 
     23 import java.io.Closeable;
     24 
     25 /**
     26  * This interface provides random read-write access to the result set returned
     27  * by a database query.
     28  * <p>
     29  * Cursor implementations are not required to be synchronized so code using a Cursor from multiple
     30  * threads should perform its own synchronization when using the Cursor.
     31  * </p><p>
     32  * Implementations should subclass {@link AbstractCursor}.
     33  * </p>
     34  */
     35 public interface Cursor extends Closeable {
     36     /*
     37      * Values returned by {@link #getType(int)}.
     38      * These should be consistent with the corresponding types defined in CursorWindow.h
     39      */
     40     /** Value returned by {@link #getType(int)} if the specified column is null */
     41     static final int FIELD_TYPE_NULL = 0;
     42 
     43     /** Value returned by {@link #getType(int)} if the specified  column type is integer */
     44     static final int FIELD_TYPE_INTEGER = 1;
     45 
     46     /** Value returned by {@link #getType(int)} if the specified column type is float */
     47     static final int FIELD_TYPE_FLOAT = 2;
     48 
     49     /** Value returned by {@link #getType(int)} if the specified column type is string */
     50     static final int FIELD_TYPE_STRING = 3;
     51 
     52     /** Value returned by {@link #getType(int)} if the specified column type is blob */
     53     static final int FIELD_TYPE_BLOB = 4;
     54 
     55     /**
     56      * Returns the numbers of rows in the cursor.
     57      *
     58      * @return the number of rows in the cursor.
     59      */
     60     int getCount();
     61 
     62     /**
     63      * Returns the current position of the cursor in the row set.
     64      * The value is zero-based. When the row set is first returned the cursor
     65      * will be at positon -1, which is before the first row. After the
     66      * last row is returned another call to next() will leave the cursor past
     67      * the last entry, at a position of count().
     68      *
     69      * @return the current cursor position.
     70      */
     71     int getPosition();
     72 
     73     /**
     74      * Move the cursor by a relative amount, forward or backward, from the
     75      * current position. Positive offsets move forwards, negative offsets move
     76      * backwards. If the final position is outside of the bounds of the result
     77      * set then the resultant position will be pinned to -1 or count() depending
     78      * on whether the value is off the front or end of the set, respectively.
     79      *
     80      * <p>This method will return true if the requested destination was
     81      * reachable, otherwise, it returns false. For example, if the cursor is at
     82      * currently on the second entry in the result set and move(-5) is called,
     83      * the position will be pinned at -1, and false will be returned.
     84      *
     85      * @param offset the offset to be applied from the current position.
     86      * @return whether the requested move fully succeeded.
     87      */
     88     boolean move(int offset);
     89 
     90     /**
     91      * Move the cursor to an absolute position. The valid
     92      * range of values is -1 &lt;= position &lt;= count.
     93      *
     94      * <p>This method will return true if the request destination was reachable,
     95      * otherwise, it returns false.
     96      *
     97      * @param position the zero-based position to move to.
     98      * @return whether the requested move fully succeeded.
     99      */
    100     boolean moveToPosition(int position);
    101 
    102     /**
    103      * Move the cursor to the first row.
    104      *
    105      * <p>This method will return false if the cursor is empty.
    106      *
    107      * @return whether the move succeeded.
    108      */
    109     boolean moveToFirst();
    110 
    111     /**
    112      * Move the cursor to the last row.
    113      *
    114      * <p>This method will return false if the cursor is empty.
    115      *
    116      * @return whether the move succeeded.
    117      */
    118     boolean moveToLast();
    119 
    120     /**
    121      * Move the cursor to the next row.
    122      *
    123      * <p>This method will return false if the cursor is already past the
    124      * last entry in the result set.
    125      *
    126      * @return whether the move succeeded.
    127      */
    128     boolean moveToNext();
    129 
    130     /**
    131      * Move the cursor to the previous row.
    132      *
    133      * <p>This method will return false if the cursor is already before the
    134      * first entry in the result set.
    135      *
    136      * @return whether the move succeeded.
    137      */
    138     boolean moveToPrevious();
    139 
    140     /**
    141      * Returns whether the cursor is pointing to the first row.
    142      *
    143      * @return whether the cursor is pointing at the first entry.
    144      */
    145     boolean isFirst();
    146 
    147     /**
    148      * Returns whether the cursor is pointing to the last row.
    149      *
    150      * @return whether the cursor is pointing at the last entry.
    151      */
    152     boolean isLast();
    153 
    154     /**
    155      * Returns whether the cursor is pointing to the position before the first
    156      * row.
    157      *
    158      * @return whether the cursor is before the first result.
    159      */
    160     boolean isBeforeFirst();
    161 
    162     /**
    163      * Returns whether the cursor is pointing to the position after the last
    164      * row.
    165      *
    166      * @return whether the cursor is after the last result.
    167      */
    168     boolean isAfterLast();
    169 
    170     /**
    171      * Returns the zero-based index for the given column name, or -1 if the column doesn't exist.
    172      * If you expect the column to exist use {@link #getColumnIndexOrThrow(String)} instead, which
    173      * will make the error more clear.
    174      *
    175      * @param columnName the name of the target column.
    176      * @return the zero-based column index for the given column name, or -1 if
    177      * the column name does not exist.
    178      * @see #getColumnIndexOrThrow(String)
    179      */
    180     int getColumnIndex(String columnName);
    181 
    182     /**
    183      * Returns the zero-based index for the given column name, or throws
    184      * {@link IllegalArgumentException} if the column doesn't exist. If you're not sure if
    185      * a column will exist or not use {@link #getColumnIndex(String)} and check for -1, which
    186      * is more efficient than catching the exceptions.
    187      *
    188      * @param columnName the name of the target column.
    189      * @return the zero-based column index for the given column name
    190      * @see #getColumnIndex(String)
    191      * @throws IllegalArgumentException if the column does not exist
    192      */
    193     int getColumnIndexOrThrow(String columnName) throws IllegalArgumentException;
    194 
    195     /**
    196      * Returns the column name at the given zero-based column index.
    197      *
    198      * @param columnIndex the zero-based index of the target column.
    199      * @return the column name for the given column index.
    200      */
    201     String getColumnName(int columnIndex);
    202 
    203     /**
    204      * Returns a string array holding the names of all of the columns in the
    205      * result set in the order in which they were listed in the result.
    206      *
    207      * @return the names of the columns returned in this query.
    208      */
    209     String[] getColumnNames();
    210 
    211     /**
    212      * Return total number of columns
    213      * @return number of columns
    214      */
    215     int getColumnCount();
    216 
    217     /**
    218      * Returns the value of the requested column as a byte array.
    219      *
    220      * <p>The result and whether this method throws an exception when the
    221      * column value is null or the column type is not a blob type is
    222      * implementation-defined.
    223      *
    224      * @param columnIndex the zero-based index of the target column.
    225      * @return the value of that column as a byte array.
    226      */
    227     byte[] getBlob(int columnIndex);
    228 
    229     /**
    230      * Returns the value of the requested column as a String.
    231      *
    232      * <p>The result and whether this method throws an exception when the
    233      * column value is null or the column type is not a string type is
    234      * implementation-defined.
    235      *
    236      * @param columnIndex the zero-based index of the target column.
    237      * @return the value of that column as a String.
    238      */
    239     String getString(int columnIndex);
    240 
    241     /**
    242      * Retrieves the requested column text and stores it in the buffer provided.
    243      * If the buffer size is not sufficient, a new char buffer will be allocated
    244      * and assigned to CharArrayBuffer.data
    245      * @param columnIndex the zero-based index of the target column.
    246      *        if the target column is null, return buffer
    247      * @param buffer the buffer to copy the text into.
    248      */
    249     void copyStringToBuffer(int columnIndex, CharArrayBuffer buffer);
    250 
    251     /**
    252      * Returns the value of the requested column as a short.
    253      *
    254      * <p>The result and whether this method throws an exception when the
    255      * column value is null, the column type is not an integral type, or the
    256      * integer value is outside the range [<code>Short.MIN_VALUE</code>,
    257      * <code>Short.MAX_VALUE</code>] is implementation-defined.
    258      *
    259      * @param columnIndex the zero-based index of the target column.
    260      * @return the value of that column as a short.
    261      */
    262     short getShort(int columnIndex);
    263 
    264     /**
    265      * Returns the value of the requested column as an int.
    266      *
    267      * <p>The result and whether this method throws an exception when the
    268      * column value is null, the column type is not an integral type, or the
    269      * integer value is outside the range [<code>Integer.MIN_VALUE</code>,
    270      * <code>Integer.MAX_VALUE</code>] is implementation-defined.
    271      *
    272      * @param columnIndex the zero-based index of the target column.
    273      * @return the value of that column as an int.
    274      */
    275     int getInt(int columnIndex);
    276 
    277     /**
    278      * Returns the value of the requested column as a long.
    279      *
    280      * <p>The result and whether this method throws an exception when the
    281      * column value is null, the column type is not an integral type, or the
    282      * integer value is outside the range [<code>Long.MIN_VALUE</code>,
    283      * <code>Long.MAX_VALUE</code>] is implementation-defined.
    284      *
    285      * @param columnIndex the zero-based index of the target column.
    286      * @return the value of that column as a long.
    287      */
    288     long getLong(int columnIndex);
    289 
    290     /**
    291      * Returns the value of the requested column as a float.
    292      *
    293      * <p>The result and whether this method throws an exception when the
    294      * column value is null, the column type is not a floating-point type, or the
    295      * floating-point value is not representable as a <code>float</code> value is
    296      * implementation-defined.
    297      *
    298      * @param columnIndex the zero-based index of the target column.
    299      * @return the value of that column as a float.
    300      */
    301     float getFloat(int columnIndex);
    302 
    303     /**
    304      * Returns the value of the requested column as a double.
    305      *
    306      * <p>The result and whether this method throws an exception when the
    307      * column value is null, the column type is not a floating-point type, or the
    308      * floating-point value is not representable as a <code>double</code> value is
    309      * implementation-defined.
    310      *
    311      * @param columnIndex the zero-based index of the target column.
    312      * @return the value of that column as a double.
    313      */
    314     double getDouble(int columnIndex);
    315 
    316     /**
    317      * Returns data type of the given column's value.
    318      * The preferred type of the column is returned but the data may be converted to other types
    319      * as documented in the get-type methods such as {@link #getInt(int)}, {@link #getFloat(int)}
    320      * etc.
    321      *<p>
    322      * Returned column types are
    323      * <ul>
    324      *   <li>{@link #FIELD_TYPE_NULL}</li>
    325      *   <li>{@link #FIELD_TYPE_INTEGER}</li>
    326      *   <li>{@link #FIELD_TYPE_FLOAT}</li>
    327      *   <li>{@link #FIELD_TYPE_STRING}</li>
    328      *   <li>{@link #FIELD_TYPE_BLOB}</li>
    329      *</ul>
    330      *</p>
    331      *
    332      * @param columnIndex the zero-based index of the target column.
    333      * @return column value type
    334      */
    335     int getType(int columnIndex);
    336 
    337     /**
    338      * Returns <code>true</code> if the value in the indicated column is null.
    339      *
    340      * @param columnIndex the zero-based index of the target column.
    341      * @return whether the column value is null.
    342      */
    343     boolean isNull(int columnIndex);
    344 
    345     /**
    346      * Deactivates the Cursor, making all calls on it fail until {@link #requery} is called.
    347      * Inactive Cursors use fewer resources than active Cursors.
    348      * Calling {@link #requery} will make the cursor active again.
    349      * @deprecated Since {@link #requery()} is deprecated, so too is this.
    350      */
    351     @Deprecated
    352     void deactivate();
    353 
    354     /**
    355      * Performs the query that created the cursor again, refreshing its
    356      * contents. This may be done at any time, including after a call to {@link
    357      * #deactivate}.
    358      *
    359      * Since this method could execute a query on the database and potentially take
    360      * a while, it could cause ANR if it is called on Main (UI) thread.
    361      * A warning is printed if this method is being executed on Main thread.
    362      *
    363      * @return true if the requery succeeded, false if not, in which case the
    364      *         cursor becomes invalid.
    365      * @deprecated Don't use this. Just request a new cursor, so you can do this
    366      * asynchronously and update your list view once the new cursor comes back.
    367      */
    368     @Deprecated
    369     boolean requery();
    370 
    371     /**
    372      * Closes the Cursor, releasing all of its resources and making it completely invalid.
    373      * Unlike {@link #deactivate()} a call to {@link #requery()} will not make the Cursor valid
    374      * again.
    375      */
    376     void close();
    377 
    378     /**
    379      * return true if the cursor is closed
    380      * @return true if the cursor is closed.
    381      */
    382     boolean isClosed();
    383 
    384     /**
    385      * Register an observer that is called when changes happen to the content backing this cursor.
    386      * Typically the data set won't change until {@link #requery()} is called.
    387      *
    388      * @param observer the object that gets notified when the content backing the cursor changes.
    389      * @see #unregisterContentObserver(ContentObserver)
    390      */
    391     void registerContentObserver(ContentObserver observer);
    392 
    393     /**
    394      * Unregister an observer that has previously been registered with this
    395      * cursor via {@link #registerContentObserver}.
    396      *
    397      * @param observer the object to unregister.
    398      * @see #registerContentObserver(ContentObserver)
    399      */
    400     void unregisterContentObserver(ContentObserver observer);
    401 
    402     /**
    403      * Register an observer that is called when changes happen to the contents
    404      * of the this cursors data set, for example, when the data set is changed via
    405      * {@link #requery()}, {@link #deactivate()}, or {@link #close()}.
    406      *
    407      * @param observer the object that gets notified when the cursors data set changes.
    408      * @see #unregisterDataSetObserver(DataSetObserver)
    409      */
    410     void registerDataSetObserver(DataSetObserver observer);
    411 
    412     /**
    413      * Unregister an observer that has previously been registered with this
    414      * cursor via {@link #registerContentObserver}.
    415      *
    416      * @param observer the object to unregister.
    417      * @see #registerDataSetObserver(DataSetObserver)
    418      */
    419     void unregisterDataSetObserver(DataSetObserver observer);
    420 
    421     /**
    422      * Register to watch a content URI for changes. This can be the URI of a specific data row (for
    423      * example, "content://my_provider_type/23"), or a a generic URI for a content type.
    424      *
    425      * @param cr The content resolver from the caller's context. The listener attached to
    426      * this resolver will be notified.
    427      * @param uri The content URI to watch.
    428      */
    429     void setNotificationUri(ContentResolver cr, Uri uri);
    430 
    431     /**
    432      * Return the URI at which notifications of changes in this Cursor's data
    433      * will be delivered, as previously set by {@link #setNotificationUri}.
    434      * @return Returns a URI that can be used with
    435      * {@link ContentResolver#registerContentObserver(android.net.Uri, boolean, ContentObserver)
    436      * ContentResolver.registerContentObserver} to find out about changes to this Cursor's
    437      * data.  May be null if no notification URI has been set.
    438      */
    439     Uri getNotificationUri();
    440 
    441     /**
    442      * onMove() will only be called across processes if this method returns true.
    443      * @return whether all cursor movement should result in a call to onMove().
    444      */
    445     boolean getWantsAllOnMoveCalls();
    446 
    447     /**
    448      * Sets a {@link Bundle} that will be returned by {@link #getExtras()}.
    449      *
    450      * @param extras {@link Bundle} to set, or null to set an empty bundle.
    451      */
    452     void setExtras(Bundle extras);
    453 
    454     /**
    455      * Returns a bundle of extra values. This is an optional way for cursors to provide out-of-band
    456      * metadata to their users. One use of this is for reporting on the progress of network requests
    457      * that are required to fetch data for the cursor.
    458      *
    459      * <p>These values may only change when requery is called.
    460      * @return cursor-defined values, or {@link android.os.Bundle#EMPTY Bundle.EMPTY} if there
    461      *         are no values. Never <code>null</code>.
    462      */
    463     Bundle getExtras();
    464 
    465     /**
    466      * This is an out-of-band way for the the user of a cursor to communicate with the cursor. The
    467      * structure of each bundle is entirely defined by the cursor.
    468      *
    469      * <p>One use of this is to tell a cursor that it should retry its network request after it
    470      * reported an error.
    471      * @param extras extra values, or {@link android.os.Bundle#EMPTY Bundle.EMPTY}.
    472      *         Never <code>null</code>.
    473      * @return extra values, or {@link android.os.Bundle#EMPTY Bundle.EMPTY}.
    474      *         Never <code>null</code>.
    475      */
    476     Bundle respond(Bundle extras);
    477 }
    478