SQLiteStatement.java revision ce38b98feb1e7c9c1799eb270c40798d833aa9ae
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 19ce38b98feb1e7c9c1799eb270c40798d833aa9aeVasu Noriimport android.database.DatabaseUtils; 206a353876178ca2fe4bc61f128130067d2c2574d1Brad Fitzpatrickimport android.os.SystemClock; 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 22cfda9f3a4756c71b3aadd1387419cb3b513dd400Brad Fitzpatrickimport dalvik.system.BlockGuard; 23cfda9f3a4756c71b3aadd1387419cb3b513dd400Brad Fitzpatrick 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * A pre-compiled statement against a {@link SQLiteDatabase} that can be reused. 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The statement cannot return multiple rows, but 1x1 result sets are allowed. 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Don't use SQLiteStatement constructor directly, please use 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link SQLiteDatabase#compileStatement(String)} 29ccd954480c32e9f35357b66023ae912e7f3fa76bVasu Nori *<p> 30f3ca9a5c7e87319c934b5815566054d2e5c2085fJeff Hamilton * SQLiteStatement is not internally synchronized so code using a SQLiteStatement from multiple 31f3ca9a5c7e87319c934b5815566054d2e5c2085fJeff Hamilton * threads should perform its own synchronization when using the SQLiteStatement. 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 332827d6d974beabb12344040a002dcb52dd7106b5Vasu Nori@SuppressWarnings("deprecation") 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class SQLiteStatement extends SQLiteProgram 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 367501010b71d57264a06f82937f5fb29cb9f4b509Vasu Nori private static final boolean READ = true; 377501010b71d57264a06f82937f5fb29cb9f4b509Vasu Nori private static final boolean WRITE = false; 387501010b71d57264a06f82937f5fb29cb9f4b509Vasu Nori 39e25539fdfdf884eee55107efbcc893f44e82e00eVasu Nori private SQLiteDatabase mOrigDb; 40ce38b98feb1e7c9c1799eb270c40798d833aa9aeVasu Nori private int state; 41ce38b98feb1e7c9c1799eb270c40798d833aa9aeVasu Nori /** possible value for {@link #state}. indicates that a transaction is started.} */ 42ce38b98feb1e7c9c1799eb270c40798d833aa9aeVasu Nori private static final int TRANS_STARTED = 1; 43ce38b98feb1e7c9c1799eb270c40798d833aa9aeVasu Nori /** possible value for {@link #state}. indicates that a lock is acquired.} */ 44ce38b98feb1e7c9c1799eb270c40798d833aa9aeVasu Nori private static final int LOCK_ACQUIRED = 2; 45e25539fdfdf884eee55107efbcc893f44e82e00eVasu Nori 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Don't use SQLiteStatement constructor directly, please use 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link SQLiteDatabase#compileStatement(String)} 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param db 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param sql 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* package */ SQLiteStatement(SQLiteDatabase db, String sql) { 532827d6d974beabb12344040a002dcb52dd7106b5Vasu Nori super(db, sql, false /* don't compile sql statement */); 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 57fb16cbd9b2e86d6878d4bff820422bc09c8938deVasu Nori * Execute this SQL statement, if it is not a SELECT / INSERT / DELETE / UPDATE, for example 58fb16cbd9b2e86d6878d4bff820422bc09c8938deVasu Nori * CREATE / DROP table, view, trigger, index etc. 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws android.database.SQLException If the SQL string is invalid for 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * some reason 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void execute() { 64fb16cbd9b2e86d6878d4bff820422bc09c8938deVasu Nori executeUpdateDelete(); 65fb16cbd9b2e86d6878d4bff820422bc09c8938deVasu Nori } 66fb16cbd9b2e86d6878d4bff820422bc09c8938deVasu Nori 67fb16cbd9b2e86d6878d4bff820422bc09c8938deVasu Nori /** 68fb16cbd9b2e86d6878d4bff820422bc09c8938deVasu Nori * Execute this SQL statement, if the the number of rows affected by exection of this SQL 69fb16cbd9b2e86d6878d4bff820422bc09c8938deVasu Nori * statement is of any importance to the caller - for example, UPDATE / DELETE SQL statements. 70fb16cbd9b2e86d6878d4bff820422bc09c8938deVasu Nori * 71fb16cbd9b2e86d6878d4bff820422bc09c8938deVasu Nori * @return the number of rows affected by this SQL statement execution. 72fb16cbd9b2e86d6878d4bff820422bc09c8938deVasu Nori * @throws android.database.SQLException If the SQL string is invalid for 73fb16cbd9b2e86d6878d4bff820422bc09c8938deVasu Nori * some reason 74fb16cbd9b2e86d6878d4bff820422bc09c8938deVasu Nori */ 75fb16cbd9b2e86d6878d4bff820422bc09c8938deVasu Nori public int executeUpdateDelete() { 76e25539fdfdf884eee55107efbcc893f44e82e00eVasu Nori synchronized(this) { 77e25539fdfdf884eee55107efbcc893f44e82e00eVasu Nori long timeStart = acquireAndLock(WRITE); 78e25539fdfdf884eee55107efbcc893f44e82e00eVasu Nori try { 79fb16cbd9b2e86d6878d4bff820422bc09c8938deVasu Nori int numChanges = native_execute(); 80e25539fdfdf884eee55107efbcc893f44e82e00eVasu Nori mDatabase.logTimeStat(mSql, timeStart); 81fb16cbd9b2e86d6878d4bff820422bc09c8938deVasu Nori return numChanges; 82e25539fdfdf884eee55107efbcc893f44e82e00eVasu Nori } finally { 83e25539fdfdf884eee55107efbcc893f44e82e00eVasu Nori releaseAndUnlock(); 84e25539fdfdf884eee55107efbcc893f44e82e00eVasu Nori } 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 895bf67247d2e299f0586de65b2d024f1f835657e0Vasu Nori * Execute this SQL statement and return the ID of the row inserted due to this call. 905bf67247d2e299f0586de65b2d024f1f835657e0Vasu Nori * The SQL statement should be an INSERT for this to be a useful call. 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 925bf67247d2e299f0586de65b2d024f1f835657e0Vasu Nori * @return the row ID of the last row inserted, if this insert is successful. -1 otherwise. 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws android.database.SQLException If the SQL string is invalid for 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * some reason 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public long executeInsert() { 98e25539fdfdf884eee55107efbcc893f44e82e00eVasu Nori synchronized(this) { 99e25539fdfdf884eee55107efbcc893f44e82e00eVasu Nori long timeStart = acquireAndLock(WRITE); 100e25539fdfdf884eee55107efbcc893f44e82e00eVasu Nori try { 101fb16cbd9b2e86d6878d4bff820422bc09c8938deVasu Nori long lastInsertedRowId = native_executeInsert(); 102e25539fdfdf884eee55107efbcc893f44e82e00eVasu Nori mDatabase.logTimeStat(mSql, timeStart); 103fb16cbd9b2e86d6878d4bff820422bc09c8938deVasu Nori return lastInsertedRowId; 104e25539fdfdf884eee55107efbcc893f44e82e00eVasu Nori } finally { 105e25539fdfdf884eee55107efbcc893f44e82e00eVasu Nori releaseAndUnlock(); 106e25539fdfdf884eee55107efbcc893f44e82e00eVasu Nori } 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Execute a statement that returns a 1 by 1 table with a numeric value. 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * For example, SELECT COUNT(*) FROM table; 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The result of the query. 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws android.database.sqlite.SQLiteDoneException if the query returns zero rows 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public long simpleQueryForLong() { 119e25539fdfdf884eee55107efbcc893f44e82e00eVasu Nori synchronized(this) { 120e25539fdfdf884eee55107efbcc893f44e82e00eVasu Nori long timeStart = acquireAndLock(READ); 121e25539fdfdf884eee55107efbcc893f44e82e00eVasu Nori try { 122e25539fdfdf884eee55107efbcc893f44e82e00eVasu Nori long retValue = native_1x1_long(); 123e25539fdfdf884eee55107efbcc893f44e82e00eVasu Nori mDatabase.logTimeStat(mSql, timeStart); 124e25539fdfdf884eee55107efbcc893f44e82e00eVasu Nori return retValue; 125e25539fdfdf884eee55107efbcc893f44e82e00eVasu Nori } finally { 126e25539fdfdf884eee55107efbcc893f44e82e00eVasu Nori releaseAndUnlock(); 127e25539fdfdf884eee55107efbcc893f44e82e00eVasu Nori } 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Execute a statement that returns a 1 by 1 table with a text value. 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * For example, SELECT COUNT(*) FROM table; 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The result of the query. 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws android.database.sqlite.SQLiteDoneException if the query returns zero rows 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public String simpleQueryForString() { 140e25539fdfdf884eee55107efbcc893f44e82e00eVasu Nori synchronized(this) { 141e25539fdfdf884eee55107efbcc893f44e82e00eVasu Nori long timeStart = acquireAndLock(READ); 142e25539fdfdf884eee55107efbcc893f44e82e00eVasu Nori try { 143e25539fdfdf884eee55107efbcc893f44e82e00eVasu Nori String retValue = native_1x1_string(); 144e25539fdfdf884eee55107efbcc893f44e82e00eVasu Nori mDatabase.logTimeStat(mSql, timeStart); 145e25539fdfdf884eee55107efbcc893f44e82e00eVasu Nori return retValue; 146e25539fdfdf884eee55107efbcc893f44e82e00eVasu Nori } finally { 147e25539fdfdf884eee55107efbcc893f44e82e00eVasu Nori releaseAndUnlock(); 148e25539fdfdf884eee55107efbcc893f44e82e00eVasu Nori } 1497501010b71d57264a06f82937f5fb29cb9f4b509Vasu Nori } 1507501010b71d57264a06f82937f5fb29cb9f4b509Vasu Nori } 1517501010b71d57264a06f82937f5fb29cb9f4b509Vasu Nori 1527501010b71d57264a06f82937f5fb29cb9f4b509Vasu Nori /** 1537501010b71d57264a06f82937f5fb29cb9f4b509Vasu Nori * Called before every method in this class before executing a SQL statement, 1547501010b71d57264a06f82937f5fb29cb9f4b509Vasu Nori * this method does the following: 1557501010b71d57264a06f82937f5fb29cb9f4b509Vasu Nori * <ul> 1567501010b71d57264a06f82937f5fb29cb9f4b509Vasu Nori * <li>make sure the database is open</li> 157e25539fdfdf884eee55107efbcc893f44e82e00eVasu Nori * <li>get a database connection from the connection pool,if possible</li> 1587501010b71d57264a06f82937f5fb29cb9f4b509Vasu Nori * <li>notifies {@link BlockGuard} of read/write</li> 159ce38b98feb1e7c9c1799eb270c40798d833aa9aeVasu Nori * <li>if the SQL statement is an update, start transaction if not already in one. 160ce38b98feb1e7c9c1799eb270c40798d833aa9aeVasu Nori * otherwise, get lock on the database</li> 1617501010b71d57264a06f82937f5fb29cb9f4b509Vasu Nori * <li>acquire reference on this object</li> 1627501010b71d57264a06f82937f5fb29cb9f4b509Vasu Nori * <li>and then return the current time _before_ the database lock was acquired</li> 1637501010b71d57264a06f82937f5fb29cb9f4b509Vasu Nori * </ul> 1647501010b71d57264a06f82937f5fb29cb9f4b509Vasu Nori * <p> 165ce38b98feb1e7c9c1799eb270c40798d833aa9aeVasu Nori * This method removes the duplicate code from the other public 1667501010b71d57264a06f82937f5fb29cb9f4b509Vasu Nori * methods in this class. 1677501010b71d57264a06f82937f5fb29cb9f4b509Vasu Nori */ 1687501010b71d57264a06f82937f5fb29cb9f4b509Vasu Nori private long acquireAndLock(boolean rwFlag) { 169ce38b98feb1e7c9c1799eb270c40798d833aa9aeVasu Nori state = 0; 170e25539fdfdf884eee55107efbcc893f44e82e00eVasu Nori // use pooled database connection handles for SELECT SQL statements 171e25539fdfdf884eee55107efbcc893f44e82e00eVasu Nori mDatabase.verifyDbIsOpen(); 172ce38b98feb1e7c9c1799eb270c40798d833aa9aeVasu Nori SQLiteDatabase db = (mStatementType != DatabaseUtils.STATEMENT_SELECT) ? mDatabase 173e25539fdfdf884eee55107efbcc893f44e82e00eVasu Nori : mDatabase.getDbConnection(mSql); 174e25539fdfdf884eee55107efbcc893f44e82e00eVasu Nori // use the database connection obtained above 175e25539fdfdf884eee55107efbcc893f44e82e00eVasu Nori mOrigDb = mDatabase; 176e25539fdfdf884eee55107efbcc893f44e82e00eVasu Nori mDatabase = db; 177e25539fdfdf884eee55107efbcc893f44e82e00eVasu Nori nHandle = mDatabase.mNativeHandle; 1787501010b71d57264a06f82937f5fb29cb9f4b509Vasu Nori if (rwFlag == WRITE) { 1797501010b71d57264a06f82937f5fb29cb9f4b509Vasu Nori BlockGuard.getThreadPolicy().onWriteToDisk(); 1807501010b71d57264a06f82937f5fb29cb9f4b509Vasu Nori } else { 1817501010b71d57264a06f82937f5fb29cb9f4b509Vasu Nori BlockGuard.getThreadPolicy().onReadFromDisk(); 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 183ce38b98feb1e7c9c1799eb270c40798d833aa9aeVasu Nori 184ce38b98feb1e7c9c1799eb270c40798d833aa9aeVasu Nori /* 185ce38b98feb1e7c9c1799eb270c40798d833aa9aeVasu Nori * Special case handling of SQLiteDatabase.execSQL("BEGIN transaction"). 186ce38b98feb1e7c9c1799eb270c40798d833aa9aeVasu Nori * we know it is execSQL("BEGIN transaction") from the caller IF there is no lock held. 187ce38b98feb1e7c9c1799eb270c40798d833aa9aeVasu Nori * beginTransaction() methods in SQLiteDatabase call lockForced() before 188ce38b98feb1e7c9c1799eb270c40798d833aa9aeVasu Nori * calling execSQL("BEGIN transaction"). 189ce38b98feb1e7c9c1799eb270c40798d833aa9aeVasu Nori */ 190ce38b98feb1e7c9c1799eb270c40798d833aa9aeVasu Nori if (mStatementType == DatabaseUtils.STATEMENT_BEGIN) { 191ce38b98feb1e7c9c1799eb270c40798d833aa9aeVasu Nori if (!mDatabase.isDbLockedByCurrentThread()) { 192ce38b98feb1e7c9c1799eb270c40798d833aa9aeVasu Nori // transaction is NOT started by calling beginTransaction() methods in 193ce38b98feb1e7c9c1799eb270c40798d833aa9aeVasu Nori // SQLiteDatabase 194ce38b98feb1e7c9c1799eb270c40798d833aa9aeVasu Nori mDatabase.setTransactionUsingExecSqlFlag(); 195ce38b98feb1e7c9c1799eb270c40798d833aa9aeVasu Nori } 196ce38b98feb1e7c9c1799eb270c40798d833aa9aeVasu Nori } else if (mStatementType == DatabaseUtils.STATEMENT_UPDATE) { 197ce38b98feb1e7c9c1799eb270c40798d833aa9aeVasu Nori // got update SQL statement. if there is NO pending transaction, start one 198ce38b98feb1e7c9c1799eb270c40798d833aa9aeVasu Nori if (!mDatabase.inTransaction()) { 199ce38b98feb1e7c9c1799eb270c40798d833aa9aeVasu Nori mDatabase.beginTransactionNonExclusive(); 200ce38b98feb1e7c9c1799eb270c40798d833aa9aeVasu Nori state = TRANS_STARTED; 201ce38b98feb1e7c9c1799eb270c40798d833aa9aeVasu Nori } 202ce38b98feb1e7c9c1799eb270c40798d833aa9aeVasu Nori } 203ce38b98feb1e7c9c1799eb270c40798d833aa9aeVasu Nori // do I have database lock? if not, grab it. 204ce38b98feb1e7c9c1799eb270c40798d833aa9aeVasu Nori if (!mDatabase.isDbLockedByCurrentThread()) { 205ce38b98feb1e7c9c1799eb270c40798d833aa9aeVasu Nori mDatabase.lock(); 206ce38b98feb1e7c9c1799eb270c40798d833aa9aeVasu Nori state = LOCK_ACQUIRED; 207ce38b98feb1e7c9c1799eb270c40798d833aa9aeVasu Nori } 208ce38b98feb1e7c9c1799eb270c40798d833aa9aeVasu Nori 2097501010b71d57264a06f82937f5fb29cb9f4b509Vasu Nori acquireReference(); 210ce38b98feb1e7c9c1799eb270c40798d833aa9aeVasu Nori long startTime = SystemClock.uptimeMillis(); 2117501010b71d57264a06f82937f5fb29cb9f4b509Vasu Nori mDatabase.closePendingStatements(); 212e25539fdfdf884eee55107efbcc893f44e82e00eVasu Nori compileAndbindAllArgs(); 2137501010b71d57264a06f82937f5fb29cb9f4b509Vasu Nori return startTime; 2147501010b71d57264a06f82937f5fb29cb9f4b509Vasu Nori } 2157501010b71d57264a06f82937f5fb29cb9f4b509Vasu Nori 2167501010b71d57264a06f82937f5fb29cb9f4b509Vasu Nori /** 217ce38b98feb1e7c9c1799eb270c40798d833aa9aeVasu Nori * this method releases locks and references acquired in {@link #acquireAndLock(boolean)} 2187501010b71d57264a06f82937f5fb29cb9f4b509Vasu Nori */ 2197501010b71d57264a06f82937f5fb29cb9f4b509Vasu Nori private void releaseAndUnlock() { 2207501010b71d57264a06f82937f5fb29cb9f4b509Vasu Nori releaseReference(); 221ce38b98feb1e7c9c1799eb270c40798d833aa9aeVasu Nori if (state == TRANS_STARTED) { 222ce38b98feb1e7c9c1799eb270c40798d833aa9aeVasu Nori try { 223ce38b98feb1e7c9c1799eb270c40798d833aa9aeVasu Nori mDatabase.setTransactionSuccessful(); 224ce38b98feb1e7c9c1799eb270c40798d833aa9aeVasu Nori } finally { 225ce38b98feb1e7c9c1799eb270c40798d833aa9aeVasu Nori mDatabase.endTransaction(); 226ce38b98feb1e7c9c1799eb270c40798d833aa9aeVasu Nori } 227ce38b98feb1e7c9c1799eb270c40798d833aa9aeVasu Nori } else if (state == LOCK_ACQUIRED) { 228ce38b98feb1e7c9c1799eb270c40798d833aa9aeVasu Nori mDatabase.unlock(); 229ce38b98feb1e7c9c1799eb270c40798d833aa9aeVasu Nori } 230ce38b98feb1e7c9c1799eb270c40798d833aa9aeVasu Nori if (mStatementType == DatabaseUtils.STATEMENT_COMMIT || 231ce38b98feb1e7c9c1799eb270c40798d833aa9aeVasu Nori mStatementType == DatabaseUtils.STATEMENT_ABORT) { 232ce38b98feb1e7c9c1799eb270c40798d833aa9aeVasu Nori mDatabase.resetTransactionUsingExecSqlFlag(); 233ce38b98feb1e7c9c1799eb270c40798d833aa9aeVasu Nori } 2342827d6d974beabb12344040a002dcb52dd7106b5Vasu Nori clearBindings(); 2352827d6d974beabb12344040a002dcb52dd7106b5Vasu Nori // release the compiled sql statement so that the caller's SQLiteStatement no longer 2362827d6d974beabb12344040a002dcb52dd7106b5Vasu Nori // has a hard reference to a database object that may get deallocated at any point. 2372827d6d974beabb12344040a002dcb52dd7106b5Vasu Nori releaseCompiledSqlIfNotInCache(); 238e25539fdfdf884eee55107efbcc893f44e82e00eVasu Nori // restore the database connection handle to the original value 239e25539fdfdf884eee55107efbcc893f44e82e00eVasu Nori mDatabase = mOrigDb; 240e25539fdfdf884eee55107efbcc893f44e82e00eVasu Nori nHandle = mDatabase.mNativeHandle; 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 243fb16cbd9b2e86d6878d4bff820422bc09c8938deVasu Nori private final native int native_execute(); 244fb16cbd9b2e86d6878d4bff820422bc09c8938deVasu Nori private final native long native_executeInsert(); 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final native long native_1x1_long(); 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final native String native_1x1_string(); 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 248