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