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.ParcelFileDescriptor;
20
21/**
22 * Represents a statement that can be executed against a database.  The statement
23 * cannot return multiple rows or columns, but single value (1 x 1) result sets
24 * are supported.
25 * <p>
26 * This class is not thread-safe.
27 * </p>
28 */
29public final class SQLiteStatement extends SQLiteProgram {
30    SQLiteStatement(SQLiteDatabase db, String sql, Object[] bindArgs) {
31        super(db, sql, bindArgs, null);
32    }
33
34    /**
35     * Execute this SQL statement, if it is not a SELECT / INSERT / DELETE / UPDATE, for example
36     * CREATE / DROP table, view, trigger, index etc.
37     *
38     * @throws android.database.SQLException If the SQL string is invalid for
39     *         some reason
40     */
41    public void execute() {
42        acquireReference();
43        try {
44            getSession().execute(getSql(), getBindArgs(), getConnectionFlags(), null);
45        } catch (SQLiteDatabaseCorruptException ex) {
46            onCorruption();
47            throw ex;
48        } finally {
49            releaseReference();
50        }
51    }
52
53    /**
54     * Execute this SQL statement, if the the number of rows affected by execution of this SQL
55     * statement is of any importance to the caller - for example, UPDATE / DELETE SQL statements.
56     *
57     * @return the number of rows affected by this SQL statement execution.
58     * @throws android.database.SQLException If the SQL string is invalid for
59     *         some reason
60     */
61    public int executeUpdateDelete() {
62        acquireReference();
63        try {
64            return getSession().executeForChangedRowCount(
65                    getSql(), getBindArgs(), getConnectionFlags(), null);
66        } catch (SQLiteDatabaseCorruptException ex) {
67            onCorruption();
68            throw ex;
69        } finally {
70            releaseReference();
71        }
72    }
73
74    /**
75     * Execute this SQL statement and return the ID of the row inserted due to this call.
76     * The SQL statement should be an INSERT for this to be a useful call.
77     *
78     * @return the row ID of the last row inserted, if this insert is successful. -1 otherwise.
79     *
80     * @throws android.database.SQLException If the SQL string is invalid for
81     *         some reason
82     */
83    public long executeInsert() {
84        acquireReference();
85        try {
86            return getSession().executeForLastInsertedRowId(
87                    getSql(), getBindArgs(), getConnectionFlags(), null);
88        } catch (SQLiteDatabaseCorruptException ex) {
89            onCorruption();
90            throw ex;
91        } finally {
92            releaseReference();
93        }
94    }
95
96    /**
97     * Execute a statement that returns a 1 by 1 table with a numeric value.
98     * For example, SELECT COUNT(*) FROM table;
99     *
100     * @return The result of the query.
101     *
102     * @throws android.database.sqlite.SQLiteDoneException if the query returns zero rows
103     */
104    public long simpleQueryForLong() {
105        acquireReference();
106        try {
107            return getSession().executeForLong(
108                    getSql(), getBindArgs(), getConnectionFlags(), null);
109        } catch (SQLiteDatabaseCorruptException ex) {
110            onCorruption();
111            throw ex;
112        } finally {
113            releaseReference();
114        }
115    }
116
117    /**
118     * Execute a statement that returns a 1 by 1 table with a text value.
119     * For example, SELECT COUNT(*) FROM table;
120     *
121     * @return The result of the query.
122     *
123     * @throws android.database.sqlite.SQLiteDoneException if the query returns zero rows
124     */
125    public String simpleQueryForString() {
126        acquireReference();
127        try {
128            return getSession().executeForString(
129                    getSql(), getBindArgs(), getConnectionFlags(), null);
130        } catch (SQLiteDatabaseCorruptException ex) {
131            onCorruption();
132            throw ex;
133        } finally {
134            releaseReference();
135        }
136    }
137
138    /**
139     * Executes a statement that returns a 1 by 1 table with a blob value.
140     *
141     * @return A read-only file descriptor for a copy of the blob value, or {@code null}
142     *         if the value is null or could not be read for some reason.
143     *
144     * @throws android.database.sqlite.SQLiteDoneException if the query returns zero rows
145     */
146    public ParcelFileDescriptor simpleQueryForBlobFileDescriptor() {
147        acquireReference();
148        try {
149            return getSession().executeForBlobFileDescriptor(
150                    getSql(), getBindArgs(), getConnectionFlags(), null);
151        } catch (SQLiteDatabaseCorruptException ex) {
152            onCorruption();
153            throw ex;
154        } finally {
155            releaseReference();
156        }
157    }
158
159    @Override
160    public String toString() {
161        return "SQLiteProgram: " + getSql();
162    }
163}
164