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