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 2541cadb7d31c974c259044e1fcfeb2601c6ad60afFyodor Kupolovimport com.android.internal.util.Preconditions; 2641cadb7d31c974c259044e1fcfeb2601c6ad60afFyodor Kupolov 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.HashMap; 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Map; 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * A Cursor implementation that exposes results from a query on a 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link SQLiteDatabase}. 33f3ca9a5c7e87319c934b5815566054d2e5c2085fJeff Hamilton * 34f3ca9a5c7e87319c934b5815566054d2e5c2085fJeff Hamilton * SQLiteCursor is not internally synchronized so code using a SQLiteCursor from multiple 35f3ca9a5c7e87319c934b5815566054d2e5c2085fJeff Hamilton * threads should perform its own synchronization when using the SQLiteCursor. 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class SQLiteCursor extends AbstractWindowedCursor { 38071df261ed204c0c732570690921389e1c0b9bcdVasu Nori static final String TAG = "SQLiteCursor"; 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final int NO_COUNT = -1; 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** The name of the table to edit */ 4265a8883f0e605bb8a73a692987b47ce5da632e72Vasu Nori private final String mEditTable; 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** The names of the columns in the rows */ 4565a8883f0e605bb8a73a692987b47ce5da632e72Vasu Nori private final String[] mColumns; 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** The query object for the cursor */ 48e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown private final SQLiteQuery mQuery; 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** The compiled query this cursor came from */ 5165a8883f0e605bb8a73a692987b47ce5da632e72Vasu Nori private final SQLiteCursorDriver mDriver; 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** The number of rows in the cursor */ 54650de3dcfcbc7635da3c070410ef1dc4027ae464Jeff Brown private int mCount = NO_COUNT; 55650de3dcfcbc7635da3c070410ef1dc4027ae464Jeff Brown 56650de3dcfcbc7635da3c070410ef1dc4027ae464Jeff Brown /** The number of rows that can fit in the cursor window, 0 if unknown */ 57650de3dcfcbc7635da3c070410ef1dc4027ae464Jeff Brown private int mCursorWindowCapacity; 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** A mapping of column names to column indices, to speed up lookups */ 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Map<String, Integer> mColumnNameMap; 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 62d606b4bf2c1a2308b40785860853cfb95a77bf58Vasu Nori /** Used to find out where a cursor was allocated in case it never got released. */ 6365a8883f0e605bb8a73a692987b47ce5da632e72Vasu Nori private final Throwable mStackTrace; 642589716964f99fd0ee29a9b295584c277e23f34fMakoto Onuki 6541cadb7d31c974c259044e1fcfeb2601c6ad60afFyodor Kupolov /** Controls fetching of rows relative to requested position **/ 6641cadb7d31c974c259044e1fcfeb2601c6ad60afFyodor Kupolov private boolean mFillWindowForwardOnly; 6741cadb7d31c974c259044e1fcfeb2601c6ad60afFyodor Kupolov 682589716964f99fd0ee29a9b295584c277e23f34fMakoto Onuki /** 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Execute a query and provide access to its result set through a Cursor 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * interface. For a query such as: {@code SELECT name, birth, phone FROM 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * myTable WHERE ... LIMIT 1,20 ORDER BY...} the column names (name, birth, 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * phone) would be in the projection argument and everything from 73ebc016c01ea9d5707287cfc19ccc59b21a486c00Jeff Brown * {@code FROM} onward would be in the params argument. 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param db a reference to a Database object that is already constructed 7665a8883f0e605bb8a73a692987b47ce5da632e72Vasu Nori * and opened. This param is not used any longer 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param editTable the name of the table used for this query 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param query the rest of the query terms 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * cursor is finalized 8065a8883f0e605bb8a73a692987b47ce5da632e72Vasu Nori * @deprecated use {@link #SQLiteCursor(SQLiteCursorDriver, String, SQLiteQuery)} instead 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8265a8883f0e605bb8a73a692987b47ce5da632e72Vasu Nori @Deprecated 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public SQLiteCursor(SQLiteDatabase db, SQLiteCursorDriver driver, 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String editTable, SQLiteQuery query) { 8565a8883f0e605bb8a73a692987b47ce5da632e72Vasu Nori this(driver, editTable, query); 8665a8883f0e605bb8a73a692987b47ce5da632e72Vasu Nori } 8765a8883f0e605bb8a73a692987b47ce5da632e72Vasu Nori 8865a8883f0e605bb8a73a692987b47ce5da632e72Vasu Nori /** 8965a8883f0e605bb8a73a692987b47ce5da632e72Vasu Nori * Execute a query and provide access to its result set through a Cursor 9065a8883f0e605bb8a73a692987b47ce5da632e72Vasu Nori * interface. For a query such as: {@code SELECT name, birth, phone FROM 9165a8883f0e605bb8a73a692987b47ce5da632e72Vasu Nori * myTable WHERE ... LIMIT 1,20 ORDER BY...} the column names (name, birth, 9265a8883f0e605bb8a73a692987b47ce5da632e72Vasu Nori * phone) would be in the projection argument and everything from 93ebc016c01ea9d5707287cfc19ccc59b21a486c00Jeff Brown * {@code FROM} onward would be in the params argument. 9465a8883f0e605bb8a73a692987b47ce5da632e72Vasu Nori * 9565a8883f0e605bb8a73a692987b47ce5da632e72Vasu Nori * @param editTable the name of the table used for this query 9665a8883f0e605bb8a73a692987b47ce5da632e72Vasu Nori * @param query the {@link SQLiteQuery} object associated with this cursor object. 9765a8883f0e605bb8a73a692987b47ce5da632e72Vasu Nori */ 9865a8883f0e605bb8a73a692987b47ce5da632e72Vasu Nori public SQLiteCursor(SQLiteCursorDriver driver, String editTable, SQLiteQuery query) { 9965a8883f0e605bb8a73a692987b47ce5da632e72Vasu Nori if (query == null) { 10065a8883f0e605bb8a73a692987b47ce5da632e72Vasu Nori throw new IllegalArgumentException("query object cannot be null"); 10165a8883f0e605bb8a73a692987b47ce5da632e72Vasu Nori } 1027978a414bbbc737bfb342db8840c29376e33a34dJeff Sharkey if (StrictMode.vmSqliteObjectLeaksEnabled()) { 1037978a414bbbc737bfb342db8840c29376e33a34dJeff Sharkey mStackTrace = new DatabaseObjectNotClosedException().fillInStackTrace(); 1047978a414bbbc737bfb342db8840c29376e33a34dJeff Sharkey } else { 1057978a414bbbc737bfb342db8840c29376e33a34dJeff Sharkey mStackTrace = null; 1067978a414bbbc737bfb342db8840c29376e33a34dJeff Sharkey } 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDriver = driver; 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEditTable = editTable; 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mColumnNameMap = null; 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mQuery = query; 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 112e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown mColumns = query.getColumnNames(); 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 116e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * Get the database that this cursor is associated with. 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the SQLiteDatabase that this cursor is associated with. 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public SQLiteDatabase getDatabase() { 120e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown return mQuery.getDatabase(); 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean onMove(int oldPosition, int newPosition) { 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Make sure the row at newPosition is present in the window 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mWindow == null || newPosition < mWindow.getStartPosition() || 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project newPosition >= (mWindow.getStartPosition() + mWindow.getNumRows())) { 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fillWindow(newPosition); 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getCount() { 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCount == NO_COUNT) { 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fillWindow(0); 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mCount; 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 142650de3dcfcbc7635da3c070410ef1dc4027ae464Jeff Brown private void fillWindow(int requiredPos) { 1435e5d6d8ba04d7579df840cda055cd5dfa9d7666fJeff Brown clearOrCreateWindow(getDatabase().getPath()); 144c21b5a019c1da00b6d861cd2859e3c349a44b3a7Jeff Brown try { 14541cadb7d31c974c259044e1fcfeb2601c6ad60afFyodor Kupolov Preconditions.checkArgumentNonnegative(requiredPos, 14641cadb7d31c974c259044e1fcfeb2601c6ad60afFyodor Kupolov "requiredPos cannot be negative, but was " + requiredPos); 14741cadb7d31c974c259044e1fcfeb2601c6ad60afFyodor Kupolov 148c21b5a019c1da00b6d861cd2859e3c349a44b3a7Jeff Brown if (mCount == NO_COUNT) { 14941cadb7d31c974c259044e1fcfeb2601c6ad60afFyodor Kupolov mCount = mQuery.fillWindow(mWindow, requiredPos, requiredPos, true); 150c21b5a019c1da00b6d861cd2859e3c349a44b3a7Jeff Brown mCursorWindowCapacity = mWindow.getNumRows(); 151c21b5a019c1da00b6d861cd2859e3c349a44b3a7Jeff Brown if (Log.isLoggable(TAG, Log.DEBUG)) { 152c21b5a019c1da00b6d861cd2859e3c349a44b3a7Jeff Brown Log.d(TAG, "received count(*) from native_fill_window: " + mCount); 153c21b5a019c1da00b6d861cd2859e3c349a44b3a7Jeff Brown } 154c21b5a019c1da00b6d861cd2859e3c349a44b3a7Jeff Brown } else { 15541cadb7d31c974c259044e1fcfeb2601c6ad60afFyodor Kupolov int startPos = mFillWindowForwardOnly ? requiredPos : DatabaseUtils 15641cadb7d31c974c259044e1fcfeb2601c6ad60afFyodor Kupolov .cursorPickFillWindowStartPosition(requiredPos, mCursorWindowCapacity); 157c21b5a019c1da00b6d861cd2859e3c349a44b3a7Jeff Brown mQuery.fillWindow(mWindow, startPos, requiredPos, false); 158b18f27dbf43ee9028a11cafbca23d3fa318e278bVasu Nori } 159c21b5a019c1da00b6d861cd2859e3c349a44b3a7Jeff Brown } catch (RuntimeException ex) { 160c21b5a019c1da00b6d861cd2859e3c349a44b3a7Jeff Brown // Close the cursor window if the query failed and therefore will 161c21b5a019c1da00b6d861cd2859e3c349a44b3a7Jeff Brown // not produce any results. This helps to avoid accidentally leaking 162c21b5a019c1da00b6d861cd2859e3c349a44b3a7Jeff Brown // the cursor window if the client does not correctly handle exceptions 163c21b5a019c1da00b6d861cd2859e3c349a44b3a7Jeff Brown // and fails to close the cursor. 164c21b5a019c1da00b6d861cd2859e3c349a44b3a7Jeff Brown closeWindow(); 165c21b5a019c1da00b6d861cd2859e3c349a44b3a7Jeff Brown throw ex; 166b18f27dbf43ee9028a11cafbca23d3fa318e278bVasu Nori } 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getColumnIndex(String columnName) { 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Create mColumnNameMap on demand 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mColumnNameMap == null) { 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String[] columns = mColumns; 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int columnCount = columns.length; 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project HashMap<String, Integer> map = new HashMap<String, Integer>(columnCount, 1); 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < columnCount; i++) { 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project map.put(columns[i], i); 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mColumnNameMap = map; 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Hack according to bug 903852 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int periodIndex = columnName.lastIndexOf('.'); 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (periodIndex != -1) { 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Exception e = new Exception(); 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.e(TAG, "requesting column name with table name -- " + columnName, e); 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project columnName = columnName.substring(periodIndex + 1); 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Integer i = mColumnNameMap.get(columnName); 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (i != null) { 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return i.intValue(); 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public String[] getColumnNames() { 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mColumns; 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void deactivate() { 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.deactivate(); 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDriver.cursorDeactivated(); 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void close() { 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.close(); 21265a8883f0e605bb8a73a692987b47ce5da632e72Vasu Nori synchronized (this) { 21365a8883f0e605bb8a73a692987b47ce5da632e72Vasu Nori mQuery.close(); 21465a8883f0e605bb8a73a692987b47ce5da632e72Vasu Nori mDriver.cursorClosed(); 21565a8883f0e605bb8a73a692987b47ce5da632e72Vasu Nori } 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean requery() { 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (isClosed()) { 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 22365a8883f0e605bb8a73a692987b47ce5da632e72Vasu Nori 22465a8883f0e605bb8a73a692987b47ce5da632e72Vasu Nori synchronized (this) { 225e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown if (!mQuery.getDatabase().isOpen()) { 226e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown return false; 227e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown } 228e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mWindow != null) { 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWindow.clear(); 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPos = -1; 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCount = NO_COUNT; 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 235e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown mDriver.cursorRequeried(this); 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 238ca74897b24e24681e05ed35d13cf7a68bc924673Vasu Nori try { 239e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown return super.requery(); 240ca74897b24e24681e05ed35d13cf7a68bc924673Vasu Nori } catch (IllegalStateException e) { 241ca74897b24e24681e05ed35d13cf7a68bc924673Vasu Nori // for backwards compatibility, just return false 242324dbe508e7afdae201fe378f1aca4227baf6c06Vasu Nori Log.w(TAG, "requery() failed " + e.getMessage(), e); 243e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown return false; 244ca74897b24e24681e05ed35d13cf7a68bc924673Vasu Nori } 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 2487ce745248d4de0e6543a559c93423df899832100Jeff Brown public void setWindow(CursorWindow window) { 2497ce745248d4de0e6543a559c93423df899832100Jeff Brown super.setWindow(window); 2507ce745248d4de0e6543a559c93423df899832100Jeff Brown mCount = NO_COUNT; 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Changes the selection arguments. The new values take effect after a call to requery(). 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setSelectionArguments(String[] selectionArgs) { 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDriver.setBindArguments(selectionArgs); 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 26141cadb7d31c974c259044e1fcfeb2601c6ad60afFyodor Kupolov * Controls fetching of rows relative to requested position. 26241cadb7d31c974c259044e1fcfeb2601c6ad60afFyodor Kupolov * 26341cadb7d31c974c259044e1fcfeb2601c6ad60afFyodor Kupolov * <p>Calling this method defines how rows will be loaded, but it doesn't affect rows that 26441cadb7d31c974c259044e1fcfeb2601c6ad60afFyodor Kupolov * are already in the window. This setting is preserved if a new window is 26541cadb7d31c974c259044e1fcfeb2601c6ad60afFyodor Kupolov * {@link #setWindow(CursorWindow) set} 26641cadb7d31c974c259044e1fcfeb2601c6ad60afFyodor Kupolov * 26741cadb7d31c974c259044e1fcfeb2601c6ad60afFyodor Kupolov * @param fillWindowForwardOnly if true, rows will be fetched starting from requested position 26841cadb7d31c974c259044e1fcfeb2601c6ad60afFyodor Kupolov * up to the window's capacity. Default value is false. 26941cadb7d31c974c259044e1fcfeb2601c6ad60afFyodor Kupolov */ 27041cadb7d31c974c259044e1fcfeb2601c6ad60afFyodor Kupolov public void setFillWindowForwardOnly(boolean fillWindowForwardOnly) { 27141cadb7d31c974c259044e1fcfeb2601c6ad60afFyodor Kupolov mFillWindowForwardOnly = fillWindowForwardOnly; 27241cadb7d31c974c259044e1fcfeb2601c6ad60afFyodor Kupolov } 27341cadb7d31c974c259044e1fcfeb2601c6ad60afFyodor Kupolov 27441cadb7d31c974c259044e1fcfeb2601c6ad60afFyodor Kupolov /** 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Release the native resources, if they haven't been released yet. 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void finalize() { 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 28042960e8ddf443f81ceadb9f9390707768d68ab7fVasu Nori // if the cursor hasn't been closed yet, close it first 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mWindow != null) { 2827978a414bbbc737bfb342db8840c29376e33a34dJeff Sharkey if (mStackTrace != null) { 283e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown String sql = mQuery.getSql(); 284e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown int len = sql.length(); 28532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick StrictMode.onSqliteObjectLeaked( 28632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick "Finalizing a Cursor that has not been deactivated or closed. " + 287e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown "database = " + mQuery.getDatabase().getLabel() + 288e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown ", table = " + mEditTable + 289e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown ", query = " + sql.substring(0, (len > 1000) ? 1000 : len), 2902cc1df04381cb13c7d66aa8de0cc32312482d045Vasu Nori mStackTrace); 29132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 2922cc1df04381cb13c7d66aa8de0cc32312482d045Vasu Nori close(); 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.finalize(); 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 299