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