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 <= position <= 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