blob: faf6cba106799d49da60e2e658e79442216e7101 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
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;
Brad Fitzpatrick6a353872010-02-11 18:04:49 -080020import android.os.SystemClock;
Jeff Brown89101cd92011-10-27 21:24:54 -070021import android.text.TextUtils;
Vasu Norib18f27d2010-08-12 18:16:35 -070022import android.util.Log;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080023
24/**
25 * A SQLite program that represents a query that reads the resulting rows into a CursorWindow.
26 * This class is used by SQLiteCursor and isn't useful itself.
Jeff Hamiltonf3ca9a52010-05-12 15:04:33 -070027 *
28 * SQLiteQuery is not internally synchronized so code using a SQLiteQuery from multiple
29 * threads should perform its own synchronization when using the SQLiteQuery.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080030 */
31public class SQLiteQuery extends SQLiteProgram {
Vasu Nori0732f792010-07-29 17:24:12 -070032 private static final String TAG = "SQLiteQuery";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080033
Jeff Brown7ce74522011-10-07 13:29:37 -070034 private static native int nativeFillWindow(int databasePtr, int statementPtr, int windowPtr,
35 int startPos, int offsetParam);
Jeff Brown89101cd92011-10-27 21:24:54 -070036
Jeff Brown7ce74522011-10-07 13:29:37 -070037 private static native int nativeColumnCount(int statementPtr);
38 private static native String nativeColumnName(int statementPtr, int columnIndex);
39
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080040 /** The index of the unbound OFFSET parameter */
Vasu Nori0732f792010-07-29 17:24:12 -070041 private int mOffsetIndex = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080042
43 private boolean mClosed = false;
44
45 /**
46 * Create a persistent query object.
Vasu Nori0732f792010-07-29 17:24:12 -070047 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080048 * @param db The database that this query object is associated with
49 * @param query The SQL string for this query.
50 * @param offsetIndex The 1-based index to the OFFSET parameter,
51 */
52 /* package */ SQLiteQuery(SQLiteDatabase db, String query, int offsetIndex, String[] bindArgs) {
53 super(db, query);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080054 mOffsetIndex = offsetIndex;
Vasu Nori0732f792010-07-29 17:24:12 -070055 bindAllArgsAsStrings(bindArgs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080056 }
57
58 /**
Vasu Nori65a88832010-07-16 15:14:08 -070059 * Constructor used to create new instance to replace a given instance of this class.
60 * This constructor is used when the current Query object is now associated with a different
61 * {@link SQLiteDatabase} object.
62 *
63 * @param db The database that this query object is associated with
64 * @param query the instance of {@link SQLiteQuery} to be replaced
65 */
66 /* package */ SQLiteQuery(SQLiteDatabase db, SQLiteQuery query) {
Vasu Nori0732f792010-07-29 17:24:12 -070067 super(db, query.mSql);
68 this.mBindArgs = query.mBindArgs;
Vasu Norib18f27d2010-08-12 18:16:35 -070069 this.mOffsetIndex = query.mOffsetIndex;
Vasu Nori65a88832010-07-16 15:14:08 -070070 }
71
72 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080073 * Reads rows into a buffer. This method acquires the database lock.
Brad Fitzpatrick722802e2010-03-23 22:22:16 -070074 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080075 * @param window The window to fill into
76 * @return number of total rows in the query
77 */
Jeff Brown7ce74522011-10-07 13:29:37 -070078 /* package */ int fillWindow(CursorWindow window) {
Vasu Nori16057fa2011-03-18 11:40:37 -070079 mDatabase.lock(mSql);
Brad Fitzpatrick6a353872010-02-11 18:04:49 -080080 long timeStart = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080081 try {
82 acquireReference();
83 try {
84 window.acquireReference();
Jeff Brown89101cd92011-10-27 21:24:54 -070085 int startPos = window.getStartPosition();
Jeff Brown7ce74522011-10-07 13:29:37 -070086 int numRows = nativeFillWindow(nHandle, nStatement, window.mWindowPtr,
Jeff Brown89101cd92011-10-27 21:24:54 -070087 startPos, mOffsetIndex);
88 if (SQLiteDebug.DEBUG_LOG_SLOW_QUERIES) {
89 long elapsed = SystemClock.uptimeMillis() - timeStart;
90 if (SQLiteDebug.shouldLogSlowQuery(elapsed)) {
91 Log.d(TAG, "fillWindow took " + elapsed
92 + " ms: window=\"" + window
93 + "\", startPos=" + startPos
94 + ", offset=" + mOffsetIndex
95 + ", filledRows=" + window.getNumRows()
96 + ", countedRows=" + numRows
97 + ", query=\"" + mSql + "\""
98 + ", args=[" + (mBindArgs != null ?
99 TextUtils.join(", ", mBindArgs.values()) : "")
100 + "]");
101 }
102 }
Dan Egnor12311952009-11-23 14:47:45 -0800103 mDatabase.logTimeStat(mSql, timeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800104 return numRows;
105 } catch (IllegalStateException e){
106 // simply ignore it
107 return 0;
108 } catch (SQLiteDatabaseCorruptException e) {
109 mDatabase.onCorruption();
110 throw e;
Vasu Norib18f27d2010-08-12 18:16:35 -0700111 } catch (SQLiteException e) {
112 Log.e(TAG, "exception: " + e.getMessage() + "; query: " + mSql);
113 throw e;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800114 } finally {
Brad Fitzpatrick722802e2010-03-23 22:22:16 -0700115 window.releaseReference();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800116 }
117 } finally {
118 releaseReference();
119 mDatabase.unlock();
120 }
121 }
122
123 /**
124 * Get the column count for the statement. Only valid on query based
125 * statements. The database must be locked
126 * when calling this method.
127 *
128 * @return The number of column in the statement's result set.
129 */
130 /* package */ int columnCountLocked() {
131 acquireReference();
132 try {
Jeff Brown7ce74522011-10-07 13:29:37 -0700133 return nativeColumnCount(nStatement);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800134 } finally {
135 releaseReference();
136 }
137 }
138
139 /**
140 * Retrieves the column name for the given column index. The database must be locked
141 * when calling this method.
142 *
143 * @param columnIndex the index of the column to get the name for
144 * @return The requested column's name
145 */
146 /* package */ String columnNameLocked(int columnIndex) {
147 acquireReference();
148 try {
Jeff Brown7ce74522011-10-07 13:29:37 -0700149 return nativeColumnName(nStatement, columnIndex);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800150 } finally {
151 releaseReference();
152 }
153 }
Jeff Brown7ce74522011-10-07 13:29:37 -0700154
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800155 @Override
156 public String toString() {
Vasu Nori5a03f362009-10-20 15:16:35 -0700157 return "SQLiteQuery: " + mSql;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800158 }
Jeff Brown7ce74522011-10-07 13:29:37 -0700159
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800160 @Override
161 public void close() {
162 super.close();
163 mClosed = true;
164 }
165
166 /**
167 * Called by SQLiteCursor when it is requeried.
168 */
169 /* package */ void requery() {
Vasu Nori0732f792010-07-29 17:24:12 -0700170 if (mClosed) {
171 throw new IllegalStateException("requerying a closed cursor");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800172 }
Vasu Nori0732f792010-07-29 17:24:12 -0700173 compileAndbindAllArgs();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800174 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800175}