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.compat.annotation.UnsupportedAppUsage; 20 import android.os.Build; 21 22 /** 23 * A base class for Cursors that store their data in {@link CursorWindow}s. 24 * <p> 25 * The cursor owns the cursor window it uses. When the cursor is closed, 26 * its window is also closed. Likewise, when the window used by the cursor is 27 * changed, its old window is closed. This policy of strict ownership ensures 28 * that cursor windows are not leaked. 29 * </p><p> 30 * Subclasses are responsible for filling the cursor window with data during 31 * {@link #onMove(int, int)}, allocating a new cursor window if necessary. 32 * During {@link #requery()}, the existing cursor window should be cleared and 33 * filled with new data. 34 * </p><p> 35 * If the contents of the cursor change or become invalid, the old window must be closed 36 * (because it is owned by the cursor) and set to null. 37 * </p> 38 */ 39 public abstract class AbstractWindowedCursor extends AbstractCursor { 40 /** 41 * The cursor window owned by this cursor. 42 */ 43 protected CursorWindow mWindow; 44 45 @Override getBlob(int columnIndex)46 public byte[] getBlob(int columnIndex) { 47 checkPosition(); 48 return mWindow.getBlob(mPos, columnIndex); 49 } 50 51 @Override getString(int columnIndex)52 public String getString(int columnIndex) { 53 checkPosition(); 54 return mWindow.getString(mPos, columnIndex); 55 } 56 57 @Override copyStringToBuffer(int columnIndex, CharArrayBuffer buffer)58 public void copyStringToBuffer(int columnIndex, CharArrayBuffer buffer) { 59 checkPosition(); 60 mWindow.copyStringToBuffer(mPos, columnIndex, buffer); 61 } 62 63 @Override getShort(int columnIndex)64 public short getShort(int columnIndex) { 65 checkPosition(); 66 return mWindow.getShort(mPos, columnIndex); 67 } 68 69 @Override getInt(int columnIndex)70 public int getInt(int columnIndex) { 71 checkPosition(); 72 return mWindow.getInt(mPos, columnIndex); 73 } 74 75 @Override getLong(int columnIndex)76 public long getLong(int columnIndex) { 77 checkPosition(); 78 return mWindow.getLong(mPos, columnIndex); 79 } 80 81 @Override getFloat(int columnIndex)82 public float getFloat(int columnIndex) { 83 checkPosition(); 84 return mWindow.getFloat(mPos, columnIndex); 85 } 86 87 @Override getDouble(int columnIndex)88 public double getDouble(int columnIndex) { 89 checkPosition(); 90 return mWindow.getDouble(mPos, columnIndex); 91 } 92 93 @Override isNull(int columnIndex)94 public boolean isNull(int columnIndex) { 95 checkPosition(); 96 return mWindow.getType(mPos, columnIndex) == Cursor.FIELD_TYPE_NULL; 97 } 98 99 /** 100 * @deprecated Use {@link #getType} 101 */ 102 @Deprecated isBlob(int columnIndex)103 public boolean isBlob(int columnIndex) { 104 return getType(columnIndex) == Cursor.FIELD_TYPE_BLOB; 105 } 106 107 /** 108 * @deprecated Use {@link #getType} 109 */ 110 @Deprecated isString(int columnIndex)111 public boolean isString(int columnIndex) { 112 return getType(columnIndex) == Cursor.FIELD_TYPE_STRING; 113 } 114 115 /** 116 * @deprecated Use {@link #getType} 117 */ 118 @Deprecated isLong(int columnIndex)119 public boolean isLong(int columnIndex) { 120 return getType(columnIndex) == Cursor.FIELD_TYPE_INTEGER; 121 } 122 123 /** 124 * @deprecated Use {@link #getType} 125 */ 126 @Deprecated isFloat(int columnIndex)127 public boolean isFloat(int columnIndex) { 128 return getType(columnIndex) == Cursor.FIELD_TYPE_FLOAT; 129 } 130 131 @Override getType(int columnIndex)132 public int getType(int columnIndex) { 133 checkPosition(); 134 return mWindow.getType(mPos, columnIndex); 135 } 136 137 @Override checkPosition()138 protected void checkPosition() { 139 super.checkPosition(); 140 141 if (mWindow == null) { 142 throw new StaleDataException("Attempting to access a closed CursorWindow." + 143 "Most probable cause: cursor is deactivated prior to calling this method."); 144 } 145 } 146 147 @Override getWindow()148 public CursorWindow getWindow() { 149 return mWindow; 150 } 151 152 /** 153 * Sets a new cursor window for the cursor to use. 154 * <p> 155 * The cursor takes ownership of the provided cursor window; the cursor window 156 * will be closed when the cursor is closed or when the cursor adopts a new 157 * cursor window. 158 * </p><p> 159 * If the cursor previously had a cursor window, then it is closed when the 160 * new cursor window is assigned. 161 * </p> 162 * 163 * @param window The new cursor window, typically a remote cursor window. 164 */ setWindow(CursorWindow window)165 public void setWindow(CursorWindow window) { 166 if (window != mWindow) { 167 closeWindow(); 168 mWindow = window; 169 } 170 } 171 172 /** 173 * Returns true if the cursor has an associated cursor window. 174 * 175 * @return True if the cursor has an associated cursor window. 176 */ hasWindow()177 public boolean hasWindow() { 178 return mWindow != null; 179 } 180 181 /** 182 * Closes the cursor window and sets {@link #mWindow} to null. 183 * @hide 184 */ 185 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) closeWindow()186 protected void closeWindow() { 187 if (mWindow != null) { 188 mWindow.close(); 189 mWindow = null; 190 } 191 } 192 193 /** 194 * If there is a window, clear it. 195 * Otherwise, creates a new window. 196 * 197 * @param name The window name. 198 * @hide 199 */ 200 @UnsupportedAppUsage clearOrCreateWindow(String name)201 protected void clearOrCreateWindow(String name) { 202 if (mWindow == null) { 203 mWindow = new CursorWindow(name); 204 } else { 205 mWindow.clear(); 206 } 207 } 208 209 /** @hide */ 210 @Override 211 @UnsupportedAppUsage onDeactivateOrClose()212 protected void onDeactivateOrClose() { 213 super.onDeactivateOrClose(); 214 closeWindow(); 215 } 216 } 217