MergeCursor.java revision 54b6cfa9a9e5b861a9930af873580d6dc20f773c
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 19/** 20 * A convience class that lets you present an array of Cursors as a single linear Cursor. 21 * The schema of the cursors presented is entirely up to the creator of the MergeCursor, and 22 * may be different if that is desired. Calls to getColumns, getColumnIndex, etc will return the 23 * value for the row that the MergeCursor is currently pointing at. 24 */ 25public class MergeCursor extends AbstractCursor 26{ 27 private DataSetObserver mObserver = new DataSetObserver() { 28 29 @Override 30 public void onChanged() { 31 // Reset our position so the optimizations in move-related code 32 // don't screw us over 33 mPos = -1; 34 } 35 36 @Override 37 public void onInvalidated() { 38 mPos = -1; 39 } 40 }; 41 42 public MergeCursor(Cursor[] cursors) 43 { 44 mCursors = cursors; 45 mCursor = cursors[0]; 46 47 for (int i = 0; i < mCursors.length; i++) { 48 if (mCursors[i] == null) continue; 49 50 mCursors[i].registerDataSetObserver(mObserver); 51 } 52 } 53 54 @Override 55 public int getCount() 56 { 57 int count = 0; 58 int length = mCursors.length; 59 for (int i = 0 ; i < length ; i++) { 60 if (mCursors[i] != null) { 61 count += mCursors[i].getCount(); 62 } 63 } 64 return count; 65 } 66 67 @Override 68 public boolean onMove(int oldPosition, int newPosition) 69 { 70 /* Find the right cursor */ 71 mCursor = null; 72 int cursorStartPos = 0; 73 int length = mCursors.length; 74 for (int i = 0 ; i < length; i++) { 75 if (mCursors[i] == null) { 76 continue; 77 } 78 79 if (newPosition < (cursorStartPos + mCursors[i].getCount())) { 80 mCursor = mCursors[i]; 81 break; 82 } 83 84 cursorStartPos += mCursors[i].getCount(); 85 } 86 87 /* Move it to the right position */ 88 if (mCursor != null) { 89 boolean ret = mCursor.moveToPosition(newPosition - cursorStartPos); 90 return ret; 91 } 92 return false; 93 } 94 95 /** 96 * @hide 97 * @deprecated 98 */ 99 @Override 100 public boolean deleteRow() 101 { 102 return mCursor.deleteRow(); 103 } 104 105 /** 106 * @hide 107 * @deprecated 108 */ 109 @Override 110 public boolean commitUpdates() { 111 int length = mCursors.length; 112 for (int i = 0 ; i < length ; i++) { 113 if (mCursors[i] != null) { 114 mCursors[i].commitUpdates(); 115 } 116 } 117 onChange(true); 118 return true; 119 } 120 121 @Override 122 public String getString(int column) 123 { 124 return mCursor.getString(column); 125 } 126 127 @Override 128 public short getShort(int column) 129 { 130 return mCursor.getShort(column); 131 } 132 133 @Override 134 public int getInt(int column) 135 { 136 return mCursor.getInt(column); 137 } 138 139 @Override 140 public long getLong(int column) 141 { 142 return mCursor.getLong(column); 143 } 144 145 @Override 146 public float getFloat(int column) 147 { 148 return mCursor.getFloat(column); 149 } 150 151 @Override 152 public double getDouble(int column) 153 { 154 return mCursor.getDouble(column); 155 } 156 157 @Override 158 public boolean isNull(int column) 159 { 160 return mCursor.isNull(column); 161 } 162 163 @Override 164 public byte[] getBlob(int column) 165 { 166 return mCursor.getBlob(column); 167 } 168 169 @Override 170 public String[] getColumnNames() 171 { 172 if (mCursor != null) { 173 return mCursor.getColumnNames(); 174 } else { 175 return new String[0]; 176 } 177 } 178 179 @Override 180 public void deactivate() 181 { 182 int length = mCursors.length; 183 for (int i = 0 ; i < length ; i++) { 184 if (mCursors[i] != null) { 185 mCursors[i].deactivate(); 186 } 187 } 188 } 189 190 @Override 191 public void close() { 192 int length = mCursors.length; 193 for (int i = 0 ; i < length ; i++) { 194 if (mCursors[i] == null) continue; 195 mCursors[i].close(); 196 } 197 } 198 199 @Override 200 public void registerContentObserver(ContentObserver observer) { 201 int length = mCursors.length; 202 for (int i = 0 ; i < length ; i++) { 203 if (mCursors[i] != null) { 204 mCursors[i].registerContentObserver(observer); 205 } 206 } 207 } 208 @Override 209 public void unregisterContentObserver(ContentObserver observer) { 210 int length = mCursors.length; 211 for (int i = 0 ; i < length ; i++) { 212 if (mCursors[i] != null) { 213 mCursors[i].unregisterContentObserver(observer); 214 } 215 } 216 } 217 218 @Override 219 public void registerDataSetObserver(DataSetObserver observer) { 220 int length = mCursors.length; 221 for (int i = 0 ; i < length ; i++) { 222 if (mCursors[i] != null) { 223 mCursors[i].registerDataSetObserver(observer); 224 } 225 } 226 } 227 228 @Override 229 public void unregisterDataSetObserver(DataSetObserver observer) { 230 int length = mCursors.length; 231 for (int i = 0 ; i < length ; i++) { 232 if (mCursors[i] != null) { 233 mCursors[i].unregisterDataSetObserver(observer); 234 } 235 } 236 } 237 238 @Override 239 public boolean requery() 240 { 241 int length = mCursors.length; 242 for (int i = 0 ; i < length ; i++) { 243 if (mCursors[i] == null) { 244 continue; 245 } 246 247 if (mCursors[i].requery() == false) { 248 return false; 249 } 250 } 251 252 return true; 253 } 254 255 private Cursor mCursor; // updated in onMove 256 private Cursor[] mCursors; 257} 258