• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2007 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 
17 package com.android.unit_tests;
18 
19 import android.database.Cursor;
20 import android.database.sqlite.SQLiteConstraintException;
21 import android.database.sqlite.SQLiteDatabase;
22 import android.database.sqlite.SQLiteDoneException;
23 import android.database.sqlite.SQLiteStatement;
24 import android.test.PerformanceTestCase;
25 import android.test.suitebuilder.annotation.MediumTest;
26 import android.test.suitebuilder.annotation.SmallTest;
27 import junit.framework.TestCase;
28 
29 import java.io.File;
30 
31 public class DatabaseStatementTest extends TestCase implements PerformanceTestCase {
32 
33     private static final String sString1 = "this is a test";
34     private static final String sString2 = "and yet another test";
35     private static final String sString3 = "this string is a little longer, but still a test";
36 
37     private static final int CURRENT_DATABASE_VERSION = 42;
38     private SQLiteDatabase mDatabase;
39     private File mDatabaseFile;
40 
41     @Override
setUp()42     protected void setUp() throws Exception {
43         super.setUp();
44         mDatabaseFile = new File("/sqlite_stmt_journals", "database_test.db");
45         if (mDatabaseFile.exists()) {
46             mDatabaseFile.delete();
47         }
48         mDatabase = SQLiteDatabase.openOrCreateDatabase(mDatabaseFile.getPath(), null);
49         assertNotNull(mDatabase);
50         mDatabase.setVersion(CURRENT_DATABASE_VERSION);
51     }
52 
53     @Override
tearDown()54     protected void tearDown() throws Exception {
55         mDatabase.close();
56         mDatabaseFile.delete();
57         super.tearDown();
58     }
59 
isPerformanceOnly()60     public boolean isPerformanceOnly() {
61         return false;
62     }
63 
64     // These test can only be run once.
startPerformance(Intermediates intermediates)65     public int startPerformance(Intermediates intermediates) {
66         return 1;
67     }
68 
populateDefaultTable()69     private void populateDefaultTable() {
70         mDatabase.execSQL("CREATE TABLE test (_id INTEGER PRIMARY KEY, data TEXT);");
71 
72         mDatabase.execSQL("INSERT INTO test (data) VALUES ('" + sString1 + "');");
73         mDatabase.execSQL("INSERT INTO test (data) VALUES ('" + sString2 + "');");
74         mDatabase.execSQL("INSERT INTO test (data) VALUES ('" + sString3 + "');");
75     }
76 
77     @MediumTest
testExecuteStatement()78     public void testExecuteStatement() throws Exception {
79         populateDefaultTable();
80         SQLiteStatement statement = mDatabase.compileStatement("DELETE FROM test");
81         statement.execute();
82 
83         Cursor c = mDatabase.query("test", null, null, null, null, null, null);
84         assertEquals(0, c.getCount());
85         c.deactivate();
86         statement.close();
87     }
88 
89     @MediumTest
testSimpleQuery()90     public void testSimpleQuery() throws Exception {
91         mDatabase.execSQL("CREATE TABLE test (num INTEGER NOT NULL, str TEXT NOT NULL);");
92         mDatabase.execSQL("INSERT INTO test VALUES (1234, 'hello');");
93         SQLiteStatement statement1 =
94                 mDatabase.compileStatement("SELECT num FROM test WHERE str = ?");
95         SQLiteStatement statement2 =
96                 mDatabase.compileStatement("SELECT str FROM test WHERE num = ?");
97 
98         try {
99             statement1.bindString(1, "hello");
100             long value = statement1.simpleQueryForLong();
101             assertEquals(1234, value);
102 
103             statement1.bindString(1, "world");
104             statement1.simpleQueryForLong();
105             fail("shouldn't get here");
106         } catch (SQLiteDoneException e) {
107             // expected
108         }
109 
110         try {
111             statement2.bindLong(1, 1234);
112             String value = statement1.simpleQueryForString();
113             assertEquals("hello", value);
114 
115             statement2.bindLong(1, 5678);
116             statement1.simpleQueryForString();
117             fail("shouldn't get here");
118         } catch (SQLiteDoneException e) {
119             // expected
120         }
121 
122         statement1.close();
123         statement2.close();
124     }
125 
126     @MediumTest
testStatementLongBinding()127     public void testStatementLongBinding() throws Exception {
128         mDatabase.execSQL("CREATE TABLE test (num INTEGER);");
129         SQLiteStatement statement = mDatabase.compileStatement("INSERT INTO test (num) VALUES (?)");
130 
131         for (int i = 0; i < 10; i++) {
132             statement.bindLong(1, i);
133             statement.execute();
134         }
135         statement.close();
136 
137         Cursor c = mDatabase.query("test", null, null, null, null, null, null);
138         int numCol = c.getColumnIndexOrThrow("num");
139         c.moveToFirst();
140         for (long i = 0; i < 10; i++) {
141             long num = c.getLong(numCol);
142             assertEquals(i, num);
143             c.moveToNext();
144         }
145         c.close();
146     }
147 
148     @MediumTest
testStatementStringBinding()149     public void testStatementStringBinding() throws Exception {
150         mDatabase.execSQL("CREATE TABLE test (num TEXT);");
151         SQLiteStatement statement = mDatabase.compileStatement("INSERT INTO test (num) VALUES (?)");
152 
153         for (long i = 0; i < 10; i++) {
154             statement.bindString(1, Long.toHexString(i));
155             statement.execute();
156         }
157         statement.close();
158 
159         Cursor c = mDatabase.query("test", null, null, null, null, null, null);
160         int numCol = c.getColumnIndexOrThrow("num");
161         c.moveToFirst();
162         for (long i = 0; i < 10; i++) {
163             String num = c.getString(numCol);
164             assertEquals(Long.toHexString(i), num);
165             c.moveToNext();
166         }
167         c.close();
168     }
169 
170     @MediumTest
testStatementClearBindings()171     public void testStatementClearBindings() throws Exception {
172         mDatabase.execSQL("CREATE TABLE test (num INTEGER);");
173         SQLiteStatement statement = mDatabase.compileStatement("INSERT INTO test (num) VALUES (?)");
174 
175         for (long i = 0; i < 10; i++) {
176             statement.bindLong(1, i);
177             statement.clearBindings();
178             statement.execute();
179         }
180         statement.close();
181 
182         Cursor c = mDatabase.query("test", null, null, null, null, null, "ROWID");
183         int numCol = c.getColumnIndexOrThrow("num");
184         assertTrue(c.moveToFirst());
185         for (long i = 0; i < 10; i++) {
186             assertTrue(c.isNull(numCol));
187             c.moveToNext();
188         }
189         c.close();
190     }
191 
192     @MediumTest
testSimpleStringBinding()193     public void testSimpleStringBinding() throws Exception {
194         mDatabase.execSQL("CREATE TABLE test (num TEXT, value TEXT);");
195         String statement = "INSERT INTO test (num, value) VALUES (?,?)";
196 
197         String[] args = new String[2];
198         for (int i = 0; i < 2; i++) {
199             args[i] = Integer.toHexString(i);
200         }
201 
202         mDatabase.execSQL(statement, args);
203 
204         Cursor c = mDatabase.query("test", null, null, null, null, null, null);
205         int numCol = c.getColumnIndexOrThrow("num");
206         int valCol = c.getColumnIndexOrThrow("value");
207         c.moveToFirst();
208         String num = c.getString(numCol);
209         assertEquals(Integer.toHexString(0), num);
210 
211         String val = c.getString(valCol);
212         assertEquals(Integer.toHexString(1), val);
213         c.close();
214     }
215 
216     @MediumTest
testStatementMultipleBindings()217     public void testStatementMultipleBindings() throws Exception {
218         mDatabase.execSQL("CREATE TABLE test (num INTEGER, str TEXT);");
219         SQLiteStatement statement =
220                 mDatabase.compileStatement("INSERT INTO test (num, str) VALUES (?, ?)");
221 
222         for (long i = 0; i < 10; i++) {
223             statement.bindLong(1, i);
224             statement.bindString(2, Long.toHexString(i));
225             statement.execute();
226         }
227         statement.close();
228 
229         Cursor c = mDatabase.query("test", null, null, null, null, null, "ROWID");
230         int numCol = c.getColumnIndexOrThrow("num");
231         int strCol = c.getColumnIndexOrThrow("str");
232         assertTrue(c.moveToFirst());
233         for (long i = 0; i < 10; i++) {
234             long num = c.getLong(numCol);
235             String str = c.getString(strCol);
236             assertEquals(i, num);
237             assertEquals(Long.toHexString(i), str);
238             c.moveToNext();
239         }
240         c.close();
241     }
242 
243     private static class StatementTestThread extends Thread {
244         private SQLiteDatabase mDatabase;
245         private SQLiteStatement mStatement;
246 
StatementTestThread(SQLiteDatabase db, SQLiteStatement statement)247         public StatementTestThread(SQLiteDatabase db, SQLiteStatement statement) {
248             super();
249             mDatabase = db;
250             mStatement = statement;
251         }
252 
253         @Override
run()254         public void run() {
255             mDatabase.beginTransaction();
256             for (long i = 0; i < 10; i++) {
257                 mStatement.bindLong(1, i);
258                 mStatement.bindString(2, Long.toHexString(i));
259                 mStatement.execute();
260             }
261             mDatabase.setTransactionSuccessful();
262             mDatabase.endTransaction();
263 
264             Cursor c = mDatabase.query("test", null, null, null, null, null, "ROWID");
265             int numCol = c.getColumnIndexOrThrow("num");
266             int strCol = c.getColumnIndexOrThrow("str");
267             assertTrue(c.moveToFirst());
268             for (long i = 0; i < 10; i++) {
269                 long num = c.getLong(numCol);
270                 String str = c.getString(strCol);
271                 assertEquals(i, num);
272                 assertEquals(Long.toHexString(i), str);
273                 c.moveToNext();
274             }
275             c.close();
276         }
277     }
278 
279     @MediumTest
testStatementMultiThreaded()280     public void testStatementMultiThreaded() throws Exception {
281         mDatabase.execSQL("CREATE TABLE test (num INTEGER, str TEXT);");
282         SQLiteStatement statement =
283                 mDatabase.compileStatement("INSERT INTO test (num, str) VALUES (?, ?)");
284 
285         StatementTestThread thread = new StatementTestThread(mDatabase, statement);
286         thread.start();
287         try {
288             thread.join();
289         } finally {
290             statement.close();
291         }
292     }
293 
294     @MediumTest
testStatementConstraint()295     public void testStatementConstraint() throws Exception {
296         mDatabase.execSQL("CREATE TABLE test (num INTEGER NOT NULL);");
297         SQLiteStatement statement = mDatabase.compileStatement("INSERT INTO test (num) VALUES (?)");
298 
299         // Try to insert NULL, which violates the constraint
300         try {
301             statement.clearBindings();
302             statement.execute();
303             fail("expected exception not thrown");
304         } catch (SQLiteConstraintException e) {
305             // expected
306         }
307 
308         // Make sure the statement can still be used
309         statement.bindLong(1, 1);
310         statement.execute();
311         statement.close();
312 
313         Cursor c = mDatabase.query("test", null, null, null, null, null, null);
314         int numCol = c.getColumnIndexOrThrow("num");
315         c.moveToFirst();
316         long num = c.getLong(numCol);
317         assertEquals(1, num);
318         c.close();
319     }
320 }
321