SQLiteStatement.java revision 1a3b3d48413d9134738c9b457292fb2b71a5dfe4
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;
20
21/**
22 * A pre-compiled statement against a {@link SQLiteDatabase} that can be reused.
23 * The statement cannot return multiple rows, but 1x1 result sets are allowed.
24 * Don't use SQLiteStatement constructor directly, please use
25 * {@link SQLiteDatabase#compileStatement(String)}
26 *
27 * SQLiteStatement is not internally synchronized so code using a SQLiteStatement from multiple
28 * threads should perform its own synchronization when using the SQLiteStatement.
29 */
30public class SQLiteStatement extends SQLiteProgram
31{
32    /**
33     * Don't use SQLiteStatement constructor directly, please use
34     * {@link SQLiteDatabase#compileStatement(String)}
35     * @param db
36     * @param sql
37     */
38    /* package */ SQLiteStatement(SQLiteDatabase db, String sql) {
39        super(db, sql);
40    }
41
42    /**
43     * Execute this SQL statement, if it is not a query. For example,
44     * CREATE TABLE, DELTE, INSERT, etc.
45     *
46     * @throws android.database.SQLException If the SQL string is invalid for
47     *         some reason
48     */
49    public void execute() {
50        if (!mDatabase.isOpen()) {
51            throw new IllegalStateException("database " + mDatabase.getPath() + " already closed");
52        }
53        long timeStart = SystemClock.uptimeMillis();
54        mDatabase.lock();
55
56        acquireReference();
57        try {
58            native_execute();
59            mDatabase.logTimeStat(mSql, timeStart);
60        } finally {
61            releaseReference();
62            mDatabase.unlock();
63        }
64    }
65
66    /**
67     * Execute this SQL statement and return the ID of the row inserted due to this call.
68     * The SQL statement should be an INSERT for this to be a useful call.
69     *
70     * @return the row ID of the last row inserted, if this insert is successful. -1 otherwise.
71     *
72     * @throws android.database.SQLException If the SQL string is invalid for
73     *         some reason
74     */
75    public long executeInsert() {
76        if (!mDatabase.isOpen()) {
77            throw new IllegalStateException("database " + mDatabase.getPath() + " already closed");
78        }
79        long timeStart = SystemClock.uptimeMillis();
80        mDatabase.lock();
81
82        acquireReference();
83        try {
84            native_execute();
85            mDatabase.logTimeStat(mSql, timeStart);
86            return (mDatabase.lastChangeCount() > 0) ? mDatabase.lastInsertRow() : -1;
87        } finally {
88            releaseReference();
89            mDatabase.unlock();
90        }
91    }
92
93    /**
94     * Execute a statement that returns a 1 by 1 table with a numeric value.
95     * For example, SELECT COUNT(*) FROM table;
96     *
97     * @return The result of the query.
98     *
99     * @throws android.database.sqlite.SQLiteDoneException if the query returns zero rows
100     */
101    public long simpleQueryForLong() {
102        if (!mDatabase.isOpen()) {
103            throw new IllegalStateException("database " + mDatabase.getPath() + " already closed");
104        }
105        long timeStart = SystemClock.uptimeMillis();
106        mDatabase.lock();
107
108        acquireReference();
109        try {
110            long retValue = native_1x1_long();
111            mDatabase.logTimeStat(mSql, timeStart);
112            return retValue;
113        } finally {
114            releaseReference();
115            mDatabase.unlock();
116        }
117    }
118
119    /**
120     * Execute a statement that returns a 1 by 1 table with a text value.
121     * For example, SELECT COUNT(*) FROM table;
122     *
123     * @return The result of the query.
124     *
125     * @throws android.database.sqlite.SQLiteDoneException if the query returns zero rows
126     */
127    public String simpleQueryForString() {
128        if (!mDatabase.isOpen()) {
129            throw new IllegalStateException("database " + mDatabase.getPath() + " already closed");
130        }
131        long timeStart = SystemClock.uptimeMillis();
132        mDatabase.lock();
133
134        acquireReference();
135        try {
136            String retValue = native_1x1_string();
137            mDatabase.logTimeStat(mSql, timeStart);
138            return retValue;
139        } finally {
140            releaseReference();
141            mDatabase.unlock();
142        }
143    }
144
145    private final native void native_execute();
146    private final native long native_1x1_long();
147    private final native String native_1x1_string();
148}
149