SQLiteProgram.java revision 6d1ec0d81cd8ecdd390b31e724bac554bb955a94
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.util.Log; 20 21/** 22 * A base class for compiled SQLite programs. 23 */ 24public abstract class SQLiteProgram extends SQLiteClosable { 25 private static final String TAG = "SQLiteProgram"; 26 27 /** The database this program is compiled against. */ 28 protected SQLiteDatabase mDatabase; 29 30 /** The SQL used to create this query */ 31 /* package */ final String mSql; 32 33 /** 34 * Native linkage, do not modify. This comes from the database and should not be modified 35 * in here or in the native code. 36 */ 37 protected int nHandle = 0; 38 39 /** 40 * the compiledSql object for the given sql statement. 41 */ 42 private SQLiteCompiledSql compiledSql; 43 private boolean myCompiledSqlIsInCache; 44 45 /** 46 * compiledSql statement id is populated with the corresponding object from the above 47 * member compiledSql. 48 * this member is used by the native_bind_* methods 49 */ 50 protected int nStatement = 0; 51 52 /* package */ SQLiteProgram(SQLiteDatabase db, String sql) { 53 if (SQLiteDebug.DEBUG_SQL_STATEMENTS) { 54 Log.d(TAG, "processing sql: " + sql); 55 } 56 57 mDatabase = db; 58 mSql = sql; 59 db.acquireReference(); 60 db.addSQLiteClosable(this); 61 this.nHandle = db.mNativeHandle; 62 63 compiledSql = db.getCompiledStatementForSql(sql); 64 if (compiledSql == null) { 65 // create a new compiled-sql obj 66 compiledSql = new SQLiteCompiledSql(db, sql); 67 68 // add it to the cache of compiled-sqls 69 myCompiledSqlIsInCache = db.addToCompiledQueries(sql, compiledSql); 70 } else { 71 myCompiledSqlIsInCache = true; 72 } 73 nStatement = compiledSql.nStatement; 74 } 75 76 @Override 77 protected void onAllReferencesReleased() { 78 // release the compiled sql statement used by me if it is NOT in cache 79 if (!myCompiledSqlIsInCache && compiledSql != null) { 80 compiledSql.releaseSqlStatement(); 81 compiledSql = null; // so that GC doesn't call finalize() on it 82 } 83 mDatabase.releaseReference(); 84 mDatabase.removeSQLiteClosable(this); 85 } 86 87 @Override 88 protected void onAllReferencesReleasedFromContainer() { 89 // release the compiled sql statement used by me if it is NOT in cache 90 if (!myCompiledSqlIsInCache && compiledSql != null) { 91 compiledSql.releaseSqlStatement(); 92 compiledSql = null; // so that GC doesn't call finalize() on it 93 } 94 mDatabase.releaseReference(); 95 } 96 97 /** 98 * Returns a unique identifier for this program. 99 * 100 * @return a unique identifier for this program 101 */ 102 public final int getUniqueId() { 103 return (compiledSql != null) ? compiledSql.nStatement : 0; 104 } 105 106 /* package */ String getSqlString() { 107 return mSql; 108 } 109 110 /** 111 * @deprecated use this.compiledStatement.compile instead 112 * 113 * @param sql the SQL string to compile 114 * @param forceCompilation forces the SQL to be recompiled in the event that there is an 115 * existing compiled SQL program already around 116 */ 117 @Deprecated 118 protected void compile(String sql, boolean forceCompilation) { 119 // TODO is there a need for this? 120 } 121 122 /** 123 * Bind a NULL value to this statement. The value remains bound until 124 * {@link #clearBindings} is called. 125 * 126 * @param index The 1-based index to the parameter to bind null to 127 */ 128 public void bindNull(int index) { 129 acquireReference(); 130 try { 131 native_bind_null(index); 132 } finally { 133 releaseReference(); 134 } 135 } 136 137 /** 138 * Bind a long value to this statement. The value remains bound until 139 * {@link #clearBindings} is called. 140 * 141 * @param index The 1-based index to the parameter to bind 142 * @param value The value to bind 143 */ 144 public void bindLong(int index, long value) { 145 acquireReference(); 146 try { 147 native_bind_long(index, value); 148 } finally { 149 releaseReference(); 150 } 151 } 152 153 /** 154 * Bind a double value to this statement. The value remains bound until 155 * {@link #clearBindings} is called. 156 * 157 * @param index The 1-based index to the parameter to bind 158 * @param value The value to bind 159 */ 160 public void bindDouble(int index, double value) { 161 acquireReference(); 162 try { 163 native_bind_double(index, value); 164 } finally { 165 releaseReference(); 166 } 167 } 168 169 /** 170 * Bind a String 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 174 * @param value The value to bind 175 */ 176 public void bindString(int index, String value) { 177 if (value == null) { 178 throw new IllegalArgumentException("the bind value at index " + index + " is null"); 179 } 180 acquireReference(); 181 try { 182 native_bind_string(index, value); 183 } finally { 184 releaseReference(); 185 } 186 } 187 188 /** 189 * Bind a byte array value to this statement. The value remains bound until 190 * {@link #clearBindings} is called. 191 * 192 * @param index The 1-based index to the parameter to bind 193 * @param value The value to bind 194 */ 195 public void bindBlob(int index, byte[] value) { 196 if (value == null) { 197 throw new IllegalArgumentException("the bind value at index " + index + " is null"); 198 } 199 acquireReference(); 200 try { 201 native_bind_blob(index, value); 202 } finally { 203 releaseReference(); 204 } 205 } 206 207 /** 208 * Clears all existing bindings. Unset bindings are treated as NULL. 209 */ 210 public void clearBindings() { 211 acquireReference(); 212 try { 213 native_clear_bindings(); 214 } finally { 215 releaseReference(); 216 } 217 } 218 219 /** 220 * Release this program's resources, making it invalid. 221 */ 222 public void close() { 223 mDatabase.lock(); 224 try { 225 releaseReference(); 226 } finally { 227 mDatabase.unlock(); 228 } 229 } 230 231 /** 232 * Compiles SQL into a SQLite program. 233 * 234 * <P>The database lock must be held when calling this method. 235 * @param sql The SQL to compile. 236 */ 237 @Deprecated 238 protected final native void native_compile(String sql); 239 @Deprecated 240 protected final native void native_finalize(); 241 242 protected final native void native_bind_null(int index); 243 protected final native void native_bind_long(int index, long value); 244 protected final native void native_bind_double(int index, double value); 245 protected final native void native_bind_string(int index, String value); 246 protected final native void native_bind_blob(int index, byte[] value); 247 private final native void native_clear_bindings(); 248} 249 250