SQLiteQuery.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.sqlite; 18 19import android.database.CursorWindow; 20 21/** 22 * A SQLite program that represents a query that reads the resulting rows into a CursorWindow. 23 * This class is used by SQLiteCursor and isn't useful itself. 24 */ 25public class SQLiteQuery extends SQLiteProgram { 26 //private static final String TAG = "Cursor"; 27 28 /** The index of the unbound OFFSET parameter */ 29 private int mOffsetIndex; 30 31 /** The SQL used to create this query */ 32 private String mQuery; 33 34 /** Args to bind on requery */ 35 private String[] mBindArgs; 36 37 private boolean mClosed = false; 38 39 /** 40 * Create a persistent query object. 41 * 42 * @param db The database that this query object is associated with 43 * @param query The SQL string for this query. It must include "INDEX -1 44 * OFFSET ?" at the end 45 * @param offsetIndex The 1-based index to the OFFSET parameter 46 */ 47 /* package */ SQLiteQuery(SQLiteDatabase db, String query, int offsetIndex, String[] bindArgs) { 48 super(db, query); 49 50 mOffsetIndex = offsetIndex; 51 mQuery = query; 52 mBindArgs = bindArgs; 53 } 54 55 /** 56 * Reads rows into a buffer. This method acquires the database lock. 57 * 58 * @param window The window to fill into 59 * @param startPos The position to start reading rows from 60 * @return number of total rows in the query 61 */ 62 /* package */ int fillWindow(CursorWindow window, int startPos) { 63 if (startPos < 0) { 64 throw new IllegalArgumentException("startPos should > 0"); 65 } 66 window.setStartPosition(startPos); 67 mDatabase.lock(); 68 try { 69 acquireReference(); 70 window.acquireReference(); 71 return native_fill_window(window, startPos, mOffsetIndex); 72 } catch (IllegalStateException e){ 73 // simply ignore it 74 return 0; 75 } catch (SQLiteDatabaseCorruptException e) { 76 mDatabase.onCorruption(); 77 throw e; 78 } finally { 79 window.releaseReference(); 80 releaseReference(); 81 mDatabase.unlock(); 82 } 83 } 84 85 /** 86 * Get the column count for the statement. Only valid on query based 87 * statements. The database must be locked 88 * when calling this method. 89 * 90 * @return The number of column in the statement's result set. 91 */ 92 /* package */ int columnCountLocked() { 93 acquireReference(); 94 try { 95 return native_column_count(); 96 } finally { 97 releaseReference(); 98 } 99 } 100 101 /** 102 * Retrieves the column name for the given column index. The database must be locked 103 * when calling this method. 104 * 105 * @param columnIndex the index of the column to get the name for 106 * @return The requested column's name 107 */ 108 /* package */ String columnNameLocked(int columnIndex) { 109 acquireReference(); 110 try { 111 return native_column_name(columnIndex); 112 } finally { 113 releaseReference(); 114 } 115 } 116 117 @Override 118 public void close() { 119 super.close(); 120 mClosed = true; 121 } 122 123 /** 124 * Called by SQLiteCursor when it is requeried. 125 */ 126 /* package */ void requery() { 127 boolean oldMClosed = mClosed; 128 if (mClosed) { 129 mClosed = false; 130 compile(mQuery, false); 131 } 132 if (mBindArgs != null) { 133 int len = mBindArgs.length; 134 try { 135 for (int i = 0; i < len; i++) { 136 super.bindString(i + 1, mBindArgs[i]); 137 } 138 } catch (SQLiteMisuseException e) { 139 StringBuilder errMsg = new StringBuilder 140 ("old mClosed " + oldMClosed + " mQuery " + mQuery); 141 for (int i = 0; i < len; i++) { 142 errMsg.append(" "); 143 errMsg.append(mBindArgs[i]); 144 } 145 errMsg.append(" "); 146 IllegalStateException leakProgram = new IllegalStateException( 147 errMsg.toString(), e); 148 throw leakProgram; 149 } 150 } 151 } 152 153 @Override 154 public void bindNull(int index) { 155 mBindArgs[index - 1] = null; 156 if (!mClosed) super.bindNull(index); 157 } 158 159 @Override 160 public void bindLong(int index, long value) { 161 mBindArgs[index - 1] = Long.toString(value); 162 if (!mClosed) super.bindLong(index, value); 163 } 164 165 @Override 166 public void bindDouble(int index, double value) { 167 mBindArgs[index - 1] = Double.toString(value); 168 if (!mClosed) super.bindDouble(index, value); 169 } 170 171 @Override 172 public void bindString(int index, String value) { 173 mBindArgs[index - 1] = value; 174 if (!mClosed) super.bindString(index, value); 175 } 176 177 private final native int native_fill_window(CursorWindow window, int startPos, int offsetParam); 178 179 private final native int native_column_count(); 180 181 private final native String native_column_name(int columnIndex); 182} 183