SQLiteStatement.java revision 3dec7d563a2f3e1eb967ce2054a00b6620e3558c
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.os.SystemClock;
20import android.util.Log;
21
22/**
23 * A pre-compiled statement against a {@link SQLiteDatabase} that can be reused.
24 * The statement cannot return multiple rows, but 1x1 result sets are allowed.
25 * Don't use SQLiteStatement constructor directly, please use
26 * {@link SQLiteDatabase#compileStatement(String)}
27 */
28public class SQLiteStatement extends SQLiteProgram
29{
30    private static final String TAG = "SQLiteStatement";
31
32    private final String mSql;
33
34    /**
35     * Don't use SQLiteStatement constructor directly, please use
36     * {@link SQLiteDatabase#compileStatement(String)}
37     * @param db
38     * @param sql
39     */
40    /* package */ SQLiteStatement(SQLiteDatabase db, String sql) {
41        super(db, sql);
42        if (SQLiteDebug.DEBUG_SQL_STATEMENTS) {
43            mSql = sql;
44        } else {
45            mSql = null;
46        }
47    }
48
49    /**
50     * Execute this SQL statement, if it is not a query. For example,
51     * CREATE TABLE, DELTE, INSERT, etc.
52     *
53     * @throws android.database.SQLException If the SQL string is invalid for
54     *         some reason
55     */
56    public void execute() {
57        mDatabase.lock();
58        boolean logStats = mDatabase.mLogStats;
59        long startTime = logStats ? SystemClock.elapsedRealtime() : 0;
60
61        acquireReference();
62        try {
63            if (SQLiteDebug.DEBUG_SQL_STATEMENTS) {
64                Log.v(TAG, "execute() for [" + mSql + "]");
65            }
66            native_execute();
67            if (logStats) {
68                mDatabase.logTimeStat(false /* write */, startTime, SystemClock.elapsedRealtime());
69            }
70        } finally {
71            releaseReference();
72            mDatabase.unlock();
73        }
74    }
75
76    /**
77     * Execute this SQL statement and return the ID of the most
78     * recently inserted row.  The SQL statement should probably be an
79     * INSERT for this to be a useful call.
80     *
81     * @return the row ID of the last row inserted.
82     *
83     * @throws android.database.SQLException If the SQL string is invalid for
84     *         some reason
85     */
86    public long executeInsert() {
87        mDatabase.lock();
88        boolean logStats = mDatabase.mLogStats;
89        long startTime = logStats ? SystemClock.elapsedRealtime() : 0;
90
91        acquireReference();
92        try {
93            if (SQLiteDebug.DEBUG_SQL_STATEMENTS) {
94                Log.v(TAG, "executeInsert() for [" + mSql + "]");
95            }
96            native_execute();
97            if (logStats) {
98                mDatabase.logTimeStat(false /* write */, startTime, SystemClock.elapsedRealtime());
99            }
100            return mDatabase.lastInsertRow();
101        } finally {
102            releaseReference();
103            mDatabase.unlock();
104        }
105    }
106
107    /**
108     * Execute a statement that returns a 1 by 1 table with a numeric value.
109     * For example, SELECT COUNT(*) FROM table;
110     *
111     * @return The result of the query.
112     *
113     * @throws android.database.sqlite.SQLiteDoneException if the query returns zero rows
114     */
115    public long simpleQueryForLong() {
116        mDatabase.lock();
117        boolean logStats = mDatabase.mLogStats;
118        long startTime = logStats ? SystemClock.elapsedRealtime() : 0;
119
120        acquireReference();
121        try {
122            if (SQLiteDebug.DEBUG_SQL_STATEMENTS) {
123                Log.v(TAG, "simpleQueryForLong() for [" + mSql + "]");
124            }
125            long retValue = native_1x1_long();
126            if (logStats) {
127                mDatabase.logTimeStat(false /* write */, startTime, SystemClock.elapsedRealtime());
128            }
129            return retValue;
130        } finally {
131            releaseReference();
132            mDatabase.unlock();
133        }
134    }
135
136    /**
137     * Execute a statement that returns a 1 by 1 table with a text value.
138     * For example, SELECT COUNT(*) FROM table;
139     *
140     * @return The result of the query.
141     *
142     * @throws android.database.sqlite.SQLiteDoneException if the query returns zero rows
143     */
144    public String simpleQueryForString() {
145        mDatabase.lock();
146        boolean logStats = mDatabase.mLogStats;
147        long startTime = logStats ? SystemClock.elapsedRealtime() : 0;
148
149        acquireReference();
150        try {
151            if (SQLiteDebug.DEBUG_SQL_STATEMENTS) {
152                Log.v(TAG, "simpleQueryForString() for [" + mSql + "]");
153            }
154            String retValue = native_1x1_string();
155            if (logStats) {
156                mDatabase.logTimeStat(false /* write */, startTime, SystemClock.elapsedRealtime());
157            }
158            return retValue;
159        } finally {
160            releaseReference();
161            mDatabase.unlock();
162        }
163    }
164
165    private final native void native_execute();
166    private final native long native_1x1_long();
167    private final native String native_1x1_string();
168}
169