SQLiteStatement.java revision f3ca9a5c7e87319c934b5815566054d2e5c2085f
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
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.SystemClock;
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log;
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * A pre-compiled statement against a {@link SQLiteDatabase} that can be reused.
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The statement cannot return multiple rows, but 1x1 result sets are allowed.
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Don't use SQLiteStatement constructor directly, please use
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link SQLiteDatabase#compileStatement(String)}
27f3ca9a5c7e87319c934b5815566054d2e5c2085fJeff Hamilton *
28f3ca9a5c7e87319c934b5815566054d2e5c2085fJeff Hamilton * SQLiteStatement is not internally synchronized so code using a SQLiteStatement from multiple
29f3ca9a5c7e87319c934b5815566054d2e5c2085fJeff Hamilton * threads should perform its own synchronization when using the SQLiteStatement.
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class SQLiteStatement extends SQLiteProgram
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final String TAG = "SQLiteStatement";
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private final String mSql;
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Don't use SQLiteStatement constructor directly, please use
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link SQLiteDatabase#compileStatement(String)}
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param db
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param sql
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /* package */ SQLiteStatement(SQLiteDatabase db, String sql) {
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super(db, sql);
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (SQLiteDebug.DEBUG_SQL_STATEMENTS) {
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mSql = sql;
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mSql = null;
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Execute this SQL statement, if it is not a query. For example,
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * CREATE TABLE, DELTE, INSERT, etc.
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @throws android.database.SQLException If the SQL string is invalid for
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         some reason
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void execute() {
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mDatabase.lock();
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean logStats = mDatabase.mLogStats;
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        long startTime = logStats ? SystemClock.elapsedRealtime() : 0;
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        acquireReference();
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (SQLiteDebug.DEBUG_SQL_STATEMENTS) {
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Log.v(TAG, "execute() for [" + mSql + "]");
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            native_execute();
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (logStats) {
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mDatabase.logTimeStat(false /* write */, startTime, SystemClock.elapsedRealtime());
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } finally {
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            releaseReference();
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mDatabase.unlock();
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Execute this SQL statement and return the ID of the most
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * recently inserted row.  The SQL statement should probably be an
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * INSERT for this to be a useful call.
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return the row ID of the last row inserted.
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @throws android.database.SQLException If the SQL string is invalid for
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         some reason
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public long executeInsert() {
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mDatabase.lock();
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean logStats = mDatabase.mLogStats;
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        long startTime = logStats ? SystemClock.elapsedRealtime() : 0;
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        acquireReference();
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (SQLiteDebug.DEBUG_SQL_STATEMENTS) {
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Log.v(TAG, "executeInsert() for [" + mSql + "]");
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            native_execute();
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (logStats) {
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mDatabase.logTimeStat(false /* write */, startTime, SystemClock.elapsedRealtime());
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mDatabase.lastInsertRow();
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } finally {
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            releaseReference();
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mDatabase.unlock();
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() {
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mDatabase.lock();
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean logStats = mDatabase.mLogStats;
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        long startTime = logStats ? SystemClock.elapsedRealtime() : 0;
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        acquireReference();
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (SQLiteDebug.DEBUG_SQL_STATEMENTS) {
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Log.v(TAG, "simpleQueryForLong() for [" + mSql + "]");
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            long retValue = native_1x1_long();
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (logStats) {
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mDatabase.logTimeStat(false /* write */, startTime, SystemClock.elapsedRealtime());
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return retValue;
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } finally {
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            releaseReference();
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mDatabase.unlock();
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Execute a statement that returns a 1 by 1 table with a text value.
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * For example, SELECT COUNT(*) FROM table;
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The result of the query.
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @throws android.database.sqlite.SQLiteDoneException if the query returns zero rows
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public String simpleQueryForString() {
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mDatabase.lock();
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean logStats = mDatabase.mLogStats;
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        long startTime = logStats ? SystemClock.elapsedRealtime() : 0;
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        acquireReference();
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (SQLiteDebug.DEBUG_SQL_STATEMENTS) {
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Log.v(TAG, "simpleQueryForString() for [" + mSql + "]");
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String retValue = native_1x1_string();
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (logStats) {
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mDatabase.logTimeStat(false /* write */, startTime, SystemClock.elapsedRealtime());
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return retValue;
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } finally {
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            releaseReference();
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mDatabase.unlock();
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private final native void native_execute();
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private final native long native_1x1_long();
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private final native String native_1x1_string();
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
172