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