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