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