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