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
17package android.database;
18
19import android.content.ContentResolver;
20import android.net.Uri;
21import android.os.Bundle;
22
23import 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 */
35public 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