19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.database.sqlite;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.database.AbstractWindowedCursor;
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.database.CursorWindow;
21650de3dcfcbc7635da3c070410ef1dc4027ae464Jeff Brownimport android.database.DatabaseUtils;
2232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrickimport android.os.StrictMode;
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log;
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.HashMap;
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Map;
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * A Cursor implementation that exposes results from a query on a
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link SQLiteDatabase}.
31f3ca9a5c7e87319c934b5815566054d2e5c2085fJeff Hamilton *
32f3ca9a5c7e87319c934b5815566054d2e5c2085fJeff Hamilton * SQLiteCursor is not internally synchronized so code using a SQLiteCursor from multiple
33f3ca9a5c7e87319c934b5815566054d2e5c2085fJeff Hamilton * threads should perform its own synchronization when using the SQLiteCursor.
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class SQLiteCursor extends AbstractWindowedCursor {
36071df261ed204c0c732570690921389e1c0b9bcdVasu Nori    static final String TAG = "SQLiteCursor";
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final int NO_COUNT = -1;
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** The name of the table to edit */
4065a8883f0e605bb8a73a692987b47ce5da632e72Vasu Nori    private final String mEditTable;
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** The names of the columns in the rows */
4365a8883f0e605bb8a73a692987b47ce5da632e72Vasu Nori    private final String[] mColumns;
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** The query object for the cursor */
46e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown    private final SQLiteQuery mQuery;
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** The compiled query this cursor came from */
4965a8883f0e605bb8a73a692987b47ce5da632e72Vasu Nori    private final SQLiteCursorDriver mDriver;
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** The number of rows in the cursor */
52650de3dcfcbc7635da3c070410ef1dc4027ae464Jeff Brown    private int mCount = NO_COUNT;
53650de3dcfcbc7635da3c070410ef1dc4027ae464Jeff Brown
54650de3dcfcbc7635da3c070410ef1dc4027ae464Jeff Brown    /** The number of rows that can fit in the cursor window, 0 if unknown */
55650de3dcfcbc7635da3c070410ef1dc4027ae464Jeff Brown    private int mCursorWindowCapacity;
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** A mapping of column names to column indices, to speed up lookups */
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private Map<String, Integer> mColumnNameMap;
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
60d606b4bf2c1a2308b40785860853cfb95a77bf58Vasu Nori    /** Used to find out where a cursor was allocated in case it never got released. */
6165a8883f0e605bb8a73a692987b47ce5da632e72Vasu Nori    private final Throwable mStackTrace;
622589716964f99fd0ee29a9b295584c277e23f34fMakoto Onuki
632589716964f99fd0ee29a9b295584c277e23f34fMakoto Onuki    /**
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Execute a query and provide access to its result set through a Cursor
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * interface. For a query such as: {@code SELECT name, birth, phone FROM
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * myTable WHERE ... LIMIT 1,20 ORDER BY...} the column names (name, birth,
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * phone) would be in the projection argument and everything from
68ebc016c01ea9d5707287cfc19ccc59b21a486c00Jeff Brown     * {@code FROM} onward would be in the params argument.
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param db a reference to a Database object that is already constructed
7165a8883f0e605bb8a73a692987b47ce5da632e72Vasu Nori     *     and opened. This param is not used any longer
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param editTable the name of the table used for this query
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param query the rest of the query terms
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *     cursor is finalized
7565a8883f0e605bb8a73a692987b47ce5da632e72Vasu Nori     * @deprecated use {@link #SQLiteCursor(SQLiteCursorDriver, String, SQLiteQuery)} instead
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
7765a8883f0e605bb8a73a692987b47ce5da632e72Vasu Nori    @Deprecated
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public SQLiteCursor(SQLiteDatabase db, SQLiteCursorDriver driver,
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String editTable, SQLiteQuery query) {
8065a8883f0e605bb8a73a692987b47ce5da632e72Vasu Nori        this(driver, editTable, query);
8165a8883f0e605bb8a73a692987b47ce5da632e72Vasu Nori    }
8265a8883f0e605bb8a73a692987b47ce5da632e72Vasu Nori
8365a8883f0e605bb8a73a692987b47ce5da632e72Vasu Nori    /**
8465a8883f0e605bb8a73a692987b47ce5da632e72Vasu Nori     * Execute a query and provide access to its result set through a Cursor
8565a8883f0e605bb8a73a692987b47ce5da632e72Vasu Nori     * interface. For a query such as: {@code SELECT name, birth, phone FROM
8665a8883f0e605bb8a73a692987b47ce5da632e72Vasu Nori     * myTable WHERE ... LIMIT 1,20 ORDER BY...} the column names (name, birth,
8765a8883f0e605bb8a73a692987b47ce5da632e72Vasu Nori     * phone) would be in the projection argument and everything from
88ebc016c01ea9d5707287cfc19ccc59b21a486c00Jeff Brown     * {@code FROM} onward would be in the params argument.
8965a8883f0e605bb8a73a692987b47ce5da632e72Vasu Nori     *
9065a8883f0e605bb8a73a692987b47ce5da632e72Vasu Nori     * @param editTable the name of the table used for this query
9165a8883f0e605bb8a73a692987b47ce5da632e72Vasu Nori     * @param query the {@link SQLiteQuery} object associated with this cursor object.
9265a8883f0e605bb8a73a692987b47ce5da632e72Vasu Nori     */
9365a8883f0e605bb8a73a692987b47ce5da632e72Vasu Nori    public SQLiteCursor(SQLiteCursorDriver driver, String editTable, SQLiteQuery query) {
9465a8883f0e605bb8a73a692987b47ce5da632e72Vasu Nori        if (query == null) {
9565a8883f0e605bb8a73a692987b47ce5da632e72Vasu Nori            throw new IllegalArgumentException("query object cannot be null");
9665a8883f0e605bb8a73a692987b47ce5da632e72Vasu Nori        }
977978a414bbbc737bfb342db8840c29376e33a34dJeff Sharkey        if (StrictMode.vmSqliteObjectLeaksEnabled()) {
987978a414bbbc737bfb342db8840c29376e33a34dJeff Sharkey            mStackTrace = new DatabaseObjectNotClosedException().fillInStackTrace();
997978a414bbbc737bfb342db8840c29376e33a34dJeff Sharkey        } else {
1007978a414bbbc737bfb342db8840c29376e33a34dJeff Sharkey            mStackTrace = null;
1017978a414bbbc737bfb342db8840c29376e33a34dJeff Sharkey        }
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mDriver = driver;
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mEditTable = editTable;
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mColumnNameMap = null;
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mQuery = query;
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
107e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown        mColumns = query.getColumnNames();
108fb5a4964b8d402b39754f406dd2255035ff2148dJeff Brown        mRowIdColumnIndex = DatabaseUtils.findRowIdColumnIndex(mColumns);
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
112e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown     * Get the database that this cursor is associated with.
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return the SQLiteDatabase that this cursor is associated with.
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public SQLiteDatabase getDatabase() {
116e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown        return mQuery.getDatabase();
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean onMove(int oldPosition, int newPosition) {
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Make sure the row at newPosition is present in the window
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mWindow == null || newPosition < mWindow.getStartPosition() ||
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                newPosition >= (mWindow.getStartPosition() + mWindow.getNumRows())) {
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            fillWindow(newPosition);
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return true;
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getCount() {
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mCount == NO_COUNT) {
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            fillWindow(0);
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mCount;
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
138650de3dcfcbc7635da3c070410ef1dc4027ae464Jeff Brown    private void fillWindow(int requiredPos) {
1395e5d6d8ba04d7579df840cda055cd5dfa9d7666fJeff Brown        clearOrCreateWindow(getDatabase().getPath());
140650de3dcfcbc7635da3c070410ef1dc4027ae464Jeff Brown
141650de3dcfcbc7635da3c070410ef1dc4027ae464Jeff Brown        if (mCount == NO_COUNT) {
142650de3dcfcbc7635da3c070410ef1dc4027ae464Jeff Brown            int startPos = DatabaseUtils.cursorPickFillWindowStartPosition(requiredPos, 0);
143e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown            mCount = mQuery.fillWindow(mWindow, startPos, requiredPos, true);
144650de3dcfcbc7635da3c070410ef1dc4027ae464Jeff Brown            mCursorWindowCapacity = mWindow.getNumRows();
145b18f27dbf43ee9028a11cafbca23d3fa318e278bVasu Nori            if (Log.isLoggable(TAG, Log.DEBUG)) {
146650de3dcfcbc7635da3c070410ef1dc4027ae464Jeff Brown                Log.d(TAG, "received count(*) from native_fill_window: " + mCount);
147b18f27dbf43ee9028a11cafbca23d3fa318e278bVasu Nori            }
148650de3dcfcbc7635da3c070410ef1dc4027ae464Jeff Brown        } else {
149650de3dcfcbc7635da3c070410ef1dc4027ae464Jeff Brown            int startPos = DatabaseUtils.cursorPickFillWindowStartPosition(requiredPos,
150650de3dcfcbc7635da3c070410ef1dc4027ae464Jeff Brown                    mCursorWindowCapacity);
151e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown            mQuery.fillWindow(mWindow, startPos, requiredPos, false);
152b18f27dbf43ee9028a11cafbca23d3fa318e278bVasu Nori        }
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getColumnIndex(String columnName) {
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Create mColumnNameMap on demand
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mColumnNameMap == null) {
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String[] columns = mColumns;
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int columnCount = columns.length;
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            HashMap<String, Integer> map = new HashMap<String, Integer>(columnCount, 1);
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (int i = 0; i < columnCount; i++) {
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                map.put(columns[i], i);
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mColumnNameMap = map;
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Hack according to bug 903852
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int periodIndex = columnName.lastIndexOf('.');
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (periodIndex != -1) {
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Exception e = new Exception();
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Log.e(TAG, "requesting column name with table name -- " + columnName, e);
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            columnName = columnName.substring(periodIndex + 1);
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Integer i = mColumnNameMap.get(columnName);
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (i != null) {
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return i.intValue();
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return -1;
1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public String[] getColumnNames() {
1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mColumns;
1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void deactivate() {
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super.deactivate();
1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mDriver.cursorDeactivated();
1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void close() {
1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super.close();
19865a8883f0e605bb8a73a692987b47ce5da632e72Vasu Nori        synchronized (this) {
19965a8883f0e605bb8a73a692987b47ce5da632e72Vasu Nori            mQuery.close();
20065a8883f0e605bb8a73a692987b47ce5da632e72Vasu Nori            mDriver.cursorClosed();
20165a8883f0e605bb8a73a692987b47ce5da632e72Vasu Nori        }
2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean requery() {
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (isClosed()) {
2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return false;
2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
20965a8883f0e605bb8a73a692987b47ce5da632e72Vasu Nori
21065a8883f0e605bb8a73a692987b47ce5da632e72Vasu Nori        synchronized (this) {
211e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown            if (!mQuery.getDatabase().isOpen()) {
212e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown                return false;
213e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown            }
214e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown
2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mWindow != null) {
2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mWindow.clear();
2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mPos = -1;
2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mCount = NO_COUNT;
2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
221e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown            mDriver.cursorRequeried(this);
2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
224ca74897b24e24681e05ed35d13cf7a68bc924673Vasu Nori        try {
225e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown            return super.requery();
226ca74897b24e24681e05ed35d13cf7a68bc924673Vasu Nori        } catch (IllegalStateException e) {
227ca74897b24e24681e05ed35d13cf7a68bc924673Vasu Nori            // for backwards compatibility, just return false
228324dbe508e7afdae201fe378f1aca4227baf6c06Vasu Nori            Log.w(TAG, "requery() failed " + e.getMessage(), e);
229e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown            return false;
230ca74897b24e24681e05ed35d13cf7a68bc924673Vasu Nori        }
2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
2347ce745248d4de0e6543a559c93423df899832100Jeff Brown    public void setWindow(CursorWindow window) {
2357ce745248d4de0e6543a559c93423df899832100Jeff Brown        super.setWindow(window);
2367ce745248d4de0e6543a559c93423df899832100Jeff Brown        mCount = NO_COUNT;
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Changes the selection arguments. The new values take effect after a call to requery().
2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setSelectionArguments(String[] selectionArgs) {
2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mDriver.setBindArguments(selectionArgs);
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Release the native resources, if they haven't been released yet.
2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void finalize() {
2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
25242960e8ddf443f81ceadb9f9390707768d68ab7fVasu Nori            // if the cursor hasn't been closed yet, close it first
2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mWindow != null) {
2547978a414bbbc737bfb342db8840c29376e33a34dJeff Sharkey                if (mStackTrace != null) {
255e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown                    String sql = mQuery.getSql();
256e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown                    int len = sql.length();
25732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick                    StrictMode.onSqliteObjectLeaked(
25832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick                        "Finalizing a Cursor that has not been deactivated or closed. " +
259e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown                        "database = " + mQuery.getDatabase().getLabel() +
260e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown                        ", table = " + mEditTable +
261e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown                        ", query = " + sql.substring(0, (len > 1000) ? 1000 : len),
2622cc1df04381cb13c7d66aa8de0cc32312482d045Vasu Nori                        mStackTrace);
26332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick                }
2642cc1df04381cb13c7d66aa8de0cc32312482d045Vasu Nori                close();
2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } finally {
2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            super.finalize();
2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
271