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 /** 20 * A convenience 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 */ 25 public 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 MergeCursor(Cursor[] cursors)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 getCount()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 onMove(int oldPosition, int newPosition)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 @Override getString(int column)96 public String getString(int column) 97 { 98 return mCursor.getString(column); 99 } 100 101 @Override getShort(int column)102 public short getShort(int column) 103 { 104 return mCursor.getShort(column); 105 } 106 107 @Override getInt(int column)108 public int getInt(int column) 109 { 110 return mCursor.getInt(column); 111 } 112 113 @Override getLong(int column)114 public long getLong(int column) 115 { 116 return mCursor.getLong(column); 117 } 118 119 @Override getFloat(int column)120 public float getFloat(int column) 121 { 122 return mCursor.getFloat(column); 123 } 124 125 @Override getDouble(int column)126 public double getDouble(int column) 127 { 128 return mCursor.getDouble(column); 129 } 130 131 @Override getType(int column)132 public int getType(int column) { 133 return mCursor.getType(column); 134 } 135 136 @Override isNull(int column)137 public boolean isNull(int column) 138 { 139 return mCursor.isNull(column); 140 } 141 142 @Override getBlob(int column)143 public byte[] getBlob(int column) 144 { 145 return mCursor.getBlob(column); 146 } 147 148 @Override getColumnNames()149 public String[] getColumnNames() 150 { 151 if (mCursor != null) { 152 return mCursor.getColumnNames(); 153 } else { 154 return new String[0]; 155 } 156 } 157 158 @Override deactivate()159 public void deactivate() 160 { 161 int length = mCursors.length; 162 for (int i = 0 ; i < length ; i++) { 163 if (mCursors[i] != null) { 164 mCursors[i].deactivate(); 165 } 166 } 167 super.deactivate(); 168 } 169 170 @Override close()171 public void close() { 172 int length = mCursors.length; 173 for (int i = 0 ; i < length ; i++) { 174 if (mCursors[i] == null) continue; 175 mCursors[i].close(); 176 } 177 super.close(); 178 } 179 180 @Override registerContentObserver(ContentObserver observer)181 public void registerContentObserver(ContentObserver observer) { 182 int length = mCursors.length; 183 for (int i = 0 ; i < length ; i++) { 184 if (mCursors[i] != null) { 185 mCursors[i].registerContentObserver(observer); 186 } 187 } 188 } 189 @Override unregisterContentObserver(ContentObserver observer)190 public void unregisterContentObserver(ContentObserver observer) { 191 int length = mCursors.length; 192 for (int i = 0 ; i < length ; i++) { 193 if (mCursors[i] != null) { 194 mCursors[i].unregisterContentObserver(observer); 195 } 196 } 197 } 198 199 @Override registerDataSetObserver(DataSetObserver observer)200 public void registerDataSetObserver(DataSetObserver observer) { 201 int length = mCursors.length; 202 for (int i = 0 ; i < length ; i++) { 203 if (mCursors[i] != null) { 204 mCursors[i].registerDataSetObserver(observer); 205 } 206 } 207 } 208 209 @Override unregisterDataSetObserver(DataSetObserver observer)210 public void unregisterDataSetObserver(DataSetObserver observer) { 211 int length = mCursors.length; 212 for (int i = 0 ; i < length ; i++) { 213 if (mCursors[i] != null) { 214 mCursors[i].unregisterDataSetObserver(observer); 215 } 216 } 217 } 218 219 @Override requery()220 public boolean requery() 221 { 222 int length = mCursors.length; 223 for (int i = 0 ; i < length ; i++) { 224 if (mCursors[i] == null) { 225 continue; 226 } 227 228 if (mCursors[i].requery() == false) { 229 return false; 230 } 231 } 232 233 return true; 234 } 235 236 private Cursor mCursor; // updated in onMove 237 private Cursor[] mCursors; 238 } 239