blob: 94a23cb422c5e9e44f6bd5dabd6b14a65928e4d3 [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
Jeff Brown4c1241d2012-02-02 17:05:00 -080019import android.content.CancellationSignal;
Vasu Norice38b982010-07-22 13:57:13 -070020import android.database.DatabaseUtils;
Vasu Norie25539f2010-07-08 17:06:13 -070021
Jeff Browne5360fb2011-10-31 17:48:13 -070022import java.util.Arrays;
Vasu Nori36957092010-03-11 14:57:53 -080023
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080024/**
25 * A base class for compiled SQLite programs.
Jeff Browne5360fb2011-10-31 17:48:13 -070026 * <p>
27 * This class is not thread-safe.
28 * </p>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080029 */
30public abstract class SQLiteProgram extends SQLiteClosable {
Jeff Browne5360fb2011-10-31 17:48:13 -070031 private static final String[] EMPTY_STRING_ARRAY = new String[0];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080032
Jeff Browne5360fb2011-10-31 17:48:13 -070033 private final SQLiteDatabase mDatabase;
34 private final String mSql;
35 private final boolean mReadOnly;
36 private final String[] mColumnNames;
37 private final int mNumParameters;
38 private final Object[] mBindArgs;
Vasu Nori36957092010-03-11 14:57:53 -080039
Jeff Brown75ea64f2012-01-25 19:37:13 -080040 SQLiteProgram(SQLiteDatabase db, String sql, Object[] bindArgs,
Jeff Brown4c1241d2012-02-02 17:05:00 -080041 CancellationSignal cancellationSignalForPrepare) {
Jeff Browne5360fb2011-10-31 17:48:13 -070042 mDatabase = db;
Vasu Norid606b4b2010-02-24 12:54:20 -080043 mSql = sql.trim();
Jeff Browne5360fb2011-10-31 17:48:13 -070044
Vasu Nori4e874ed2010-09-15 18:40:49 -070045 int n = DatabaseUtils.getSqlStatementType(mSql);
46 switch (n) {
Vasu Nori4e874ed2010-09-15 18:40:49 -070047 case DatabaseUtils.STATEMENT_BEGIN:
48 case DatabaseUtils.STATEMENT_COMMIT:
49 case DatabaseUtils.STATEMENT_ABORT:
Jeff Browne5360fb2011-10-31 17:48:13 -070050 mReadOnly = false;
51 mColumnNames = EMPTY_STRING_ARRAY;
52 mNumParameters = 0;
Vasu Nori4e874ed2010-09-15 18:40:49 -070053 break;
Jeff Browne5360fb2011-10-31 17:48:13 -070054
Vasu Nori4e874ed2010-09-15 18:40:49 -070055 default:
Jeff Browne5360fb2011-10-31 17:48:13 -070056 boolean assumeReadOnly = (n == DatabaseUtils.STATEMENT_SELECT);
57 SQLiteStatementInfo info = new SQLiteStatementInfo();
58 db.getThreadSession().prepare(mSql,
Jeff Brown75ea64f2012-01-25 19:37:13 -080059 db.getThreadDefaultConnectionFlags(assumeReadOnly),
Jeff Brown4c1241d2012-02-02 17:05:00 -080060 cancellationSignalForPrepare, info);
Jeff Browne5360fb2011-10-31 17:48:13 -070061 mReadOnly = info.readOnly;
62 mColumnNames = info.columnNames;
63 mNumParameters = info.numParameters;
64 break;
Vasu Norib729dcc2010-09-14 11:35:49 -070065 }
66
Jeff Browne5360fb2011-10-31 17:48:13 -070067 if (mNumParameters != 0) {
68 mBindArgs = new Object[mNumParameters];
Vasu Norib729dcc2010-09-14 11:35:49 -070069 } else {
Jeff Browne5360fb2011-10-31 17:48:13 -070070 mBindArgs = null;
71 }
72
73 if (bindArgs != null) {
74 if (bindArgs.length > mNumParameters) {
75 throw new IllegalArgumentException("Too many bind arguments. "
76 + bindArgs.length + " arguments were provided but the statement needs "
77 + mNumParameters + " arguments.");
Vasu Norib729dcc2010-09-14 11:35:49 -070078 }
Jeff Browne5360fb2011-10-31 17:48:13 -070079 System.arraycopy(bindArgs, 0, mBindArgs, 0, bindArgs.length);
Vasu Norib729dcc2010-09-14 11:35:49 -070080 }
Vasu Norib729dcc2010-09-14 11:35:49 -070081 }
82
Jeff Browne5360fb2011-10-31 17:48:13 -070083 final SQLiteDatabase getDatabase() {
84 return mDatabase;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080085 }
Vasu Nori5a03f362009-10-20 15:16:35 -070086
Jeff Browne5360fb2011-10-31 17:48:13 -070087 final String getSql() {
Vasu Nori5a03f362009-10-20 15:16:35 -070088 return mSql;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080089 }
90
Jeff Browne5360fb2011-10-31 17:48:13 -070091 final Object[] getBindArgs() {
92 return mBindArgs;
93 }
94
95 final String[] getColumnNames() {
96 return mColumnNames;
97 }
98
99 /** @hide */
100 protected final SQLiteSession getSession() {
101 return mDatabase.getThreadSession();
102 }
103
104 /** @hide */
105 protected final int getConnectionFlags() {
106 return mDatabase.getThreadDefaultConnectionFlags(mReadOnly);
107 }
108
109 /** @hide */
110 protected final void onCorruption() {
111 mDatabase.onCorruption();
112 }
113
114 /**
115 * Unimplemented.
116 * @deprecated This method is deprecated and must not be used.
117 */
118 @Deprecated
119 public final int getUniqueId() {
120 return -1;
Vasu Nori0732f792010-07-29 17:24:12 -0700121 }
122
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800123 /**
124 * Bind a NULL value to this statement. The value remains bound until
125 * {@link #clearBindings} is called.
126 *
127 * @param index The 1-based index to the parameter to bind null to
128 */
129 public void bindNull(int index) {
Jeff Browne5360fb2011-10-31 17:48:13 -0700130 bind(index, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800131 }
132
133 /**
134 * Bind a long value to this statement. The value remains bound until
135 * {@link #clearBindings} is called.
Vasu Nori0732f792010-07-29 17:24:12 -0700136 *addToBindArgs
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800137 * @param index The 1-based index to the parameter to bind
138 * @param value The value to bind
139 */
140 public void bindLong(int index, long value) {
Jeff Browne5360fb2011-10-31 17:48:13 -0700141 bind(index, value);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800142 }
143
144 /**
145 * Bind a double value to this statement. The value remains bound until
146 * {@link #clearBindings} is called.
147 *
148 * @param index The 1-based index to the parameter to bind
149 * @param value The value to bind
150 */
151 public void bindDouble(int index, double value) {
Jeff Browne5360fb2011-10-31 17:48:13 -0700152 bind(index, value);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800153 }
154
155 /**
156 * Bind a String value to this statement. The value remains bound until
157 * {@link #clearBindings} is called.
158 *
159 * @param index The 1-based index to the parameter to bind
Jeff Browne5360fb2011-10-31 17:48:13 -0700160 * @param value The value to bind, must not be null
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800161 */
162 public void bindString(int index, String value) {
163 if (value == null) {
164 throw new IllegalArgumentException("the bind value at index " + index + " is null");
165 }
Jeff Browne5360fb2011-10-31 17:48:13 -0700166 bind(index, value);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800167 }
168
169 /**
170 * Bind a byte array value to this statement. The value remains bound until
171 * {@link #clearBindings} is called.
172 *
173 * @param index The 1-based index to the parameter to bind
Jeff Browne5360fb2011-10-31 17:48:13 -0700174 * @param value The value to bind, must not be null
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800175 */
176 public void bindBlob(int index, byte[] value) {
177 if (value == null) {
178 throw new IllegalArgumentException("the bind value at index " + index + " is null");
179 }
Jeff Browne5360fb2011-10-31 17:48:13 -0700180 bind(index, value);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800181 }
182
183 /**
184 * Clears all existing bindings. Unset bindings are treated as NULL.
185 */
186 public void clearBindings() {
Jeff Browne5360fb2011-10-31 17:48:13 -0700187 if (mBindArgs != null) {
188 Arrays.fill(mBindArgs, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800189 }
190 }
191
192 /**
Vasu Nori0732f792010-07-29 17:24:12 -0700193 * Given an array of String bindArgs, this method binds all of them in one single call.
194 *
Jeff Browne5360fb2011-10-31 17:48:13 -0700195 * @param bindArgs the String array of bind args, none of which must be null.
Vasu Nori0732f792010-07-29 17:24:12 -0700196 */
197 public void bindAllArgsAsStrings(String[] bindArgs) {
Jeff Browne5360fb2011-10-31 17:48:13 -0700198 if (bindArgs != null) {
199 for (int i = bindArgs.length; i != 0; i--) {
200 bindString(i, bindArgs[i - 1]);
201 }
Vasu Norie25539f2010-07-08 17:06:13 -0700202 }
203 }
204
Jeff Browne5360fb2011-10-31 17:48:13 -0700205 @Override
206 protected void onAllReferencesReleased() {
207 clearBindings();
Vasu Nori19666322010-09-10 14:09:00 -0700208 }
209
Jeff Browne5360fb2011-10-31 17:48:13 -0700210 private void bind(int index, Object value) {
211 if (index < 1 || index > mNumParameters) {
212 throw new IllegalArgumentException("Cannot bind argument at index "
213 + index + " because the index is out of range. "
214 + "The statement has " + mNumParameters + " parameters.");
215 }
216 mBindArgs[index - 1] = value;
217 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800218}