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      */
getCount()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      */
getPosition()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      */
move(int offset)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      */
moveToPosition(int position)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      */
moveToFirst()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      */
moveToLast()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      */
moveToNext()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      */
moveToPrevious()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      */
isFirst()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      */
isLast()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      */
isBeforeFirst()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      */
isAfterLast()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      */
getColumnIndex(String columnName)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      */
getColumnIndexOrThrow(String columnName)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      */
getColumnName(int columnIndex)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      */
getColumnNames()209     String[] getColumnNames();
210 
211     /**
212      * Return total number of columns
213      * @return number of columns
214      */
getColumnCount()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      */
getBlob(int columnIndex)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      */
getString(int columnIndex)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      */
copyStringToBuffer(int columnIndex, CharArrayBuffer buffer)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      */
getShort(int columnIndex)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      */
getInt(int columnIndex)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      */
getLong(int columnIndex)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      */
getFloat(int columnIndex)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      */
getDouble(int columnIndex)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      */
getType(int columnIndex)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      */
isNull(int columnIndex)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
deactivate()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
requery()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      */
close()376     void close();
377 
378     /**
379      * return true if the cursor is closed
380      * @return true if the cursor is closed.
381      */
isClosed()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      */
registerContentObserver(ContentObserver observer)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      */
unregisterContentObserver(ContentObserver observer)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      */
registerDataSetObserver(DataSetObserver observer)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      */
unregisterDataSetObserver(DataSetObserver observer)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      */
setNotificationUri(ContentResolver cr, Uri uri)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      */
getNotificationUri()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      */
getWantsAllOnMoveCalls()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      */
setExtras(Bundle extras)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      */
getExtras()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      */
respond(Bundle extras)476     Bundle respond(Bundle extras);
477 }
478