Home | History | Annotate | Download | only in cts
      1 /*
      2  * Copyright (C) 2008 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.cts;
     18 
     19 
     20 import android.content.ContentValues;
     21 import android.content.Context;
     22 import android.database.Cursor;
     23 import android.database.DatabaseUtils;
     24 import android.database.DatabaseUtils.InsertHelper;
     25 import android.database.sqlite.SQLiteAbortException;
     26 import android.database.sqlite.SQLiteDatabase;
     27 import android.database.sqlite.SQLiteDoneException;
     28 import android.database.sqlite.SQLiteException;
     29 import android.database.sqlite.SQLiteStatement;
     30 import android.os.Parcel;
     31 import android.os.ParcelFileDescriptor;
     32 import android.test.AndroidTestCase;
     33 import android.test.MoreAsserts;
     34 
     35 import java.io.ByteArrayOutputStream;
     36 import java.io.File;
     37 import java.io.FileNotFoundException;
     38 import java.io.IOException;
     39 import java.io.InputStream;
     40 import java.io.PrintStream;
     41 
     42 public class DatabaseUtilsTest extends AndroidTestCase {
     43     private SQLiteDatabase mDatabase;
     44     private File mDatabaseFile;
     45     private static final String[] TEST_PROJECTION = new String[] {
     46         "_id",             // 0
     47         "name",            // 1
     48         "age",             // 2
     49         "address"          // 3
     50     };
     51     private static final String TABLE_NAME = "test";
     52 
     53     @Override
     54     protected void setUp() throws Exception {
     55         super.setUp();
     56         File dbDir = getContext().getDir("tests", Context.MODE_PRIVATE);
     57         mDatabaseFile = new File(dbDir, "database_test.db");
     58         if (mDatabaseFile.exists()) {
     59             mDatabaseFile.delete();
     60         }
     61         mDatabase = SQLiteDatabase.openOrCreateDatabase(mDatabaseFile.getPath(), null);
     62         assertNotNull(mDatabase);
     63         mDatabase.execSQL("CREATE TABLE " + TABLE_NAME + " (_id INTEGER PRIMARY KEY, " +
     64                 "name TEXT, age INTEGER, address TEXT);");
     65         mDatabase.execSQL(
     66                 "CREATE TABLE blob_test (_id INTEGER PRIMARY KEY, name TEXT, data BLOB)");
     67         mDatabase.execSQL(
     68                 "CREATE TABLE boolean_test (_id INTEGER PRIMARY KEY, value BOOLEAN)");
     69     }
     70 
     71     @Override
     72     protected void tearDown() throws Exception {
     73         mDatabase.close();
     74         mDatabaseFile.delete();
     75         super.tearDown();
     76     }
     77 
     78     public void testAppendEscapedSQLString() {
     79         String expected = "name='Mike'";
     80         StringBuilder sb = new StringBuilder("name=");
     81         DatabaseUtils.appendEscapedSQLString(sb, "Mike");
     82         assertEquals(expected, sb.toString());
     83 
     84         expected = "'name=''Mike'''";
     85         sb = new StringBuilder();
     86         DatabaseUtils.appendEscapedSQLString(sb, "name='Mike'");
     87         assertEquals(expected, sb.toString());
     88     }
     89 
     90     public void testSqlEscapeString() {
     91         String expected = "'Jack'";
     92         assertEquals(expected, DatabaseUtils.sqlEscapeString("Jack"));
     93     }
     94 
     95     public void testAppendValueToSql() {
     96         String expected = "address='LA'";
     97         StringBuilder sb = new StringBuilder("address=");
     98         DatabaseUtils.appendValueToSql(sb, "LA");
     99         assertEquals(expected, sb.toString());
    100 
    101         expected = "address=NULL";
    102         sb = new StringBuilder("address=");
    103         DatabaseUtils.appendValueToSql(sb, null);
    104         assertEquals(expected, sb.toString());
    105 
    106         expected = "flag=1";
    107         sb = new StringBuilder("flag=");
    108         DatabaseUtils.appendValueToSql(sb, true);
    109         assertEquals(expected, sb.toString());
    110     }
    111 
    112     public void testBindObjectToProgram() {
    113         String name = "Mike";
    114         int age = 21;
    115         String address = "LA";
    116 
    117         // at the beginning, there are no records in the database.
    118         Cursor cursor = mDatabase.query(TABLE_NAME, TEST_PROJECTION,
    119                 null, null, null, null, null);
    120         assertNotNull(cursor);
    121         assertEquals(0, cursor.getCount());
    122 
    123         String sql = "INSERT INTO " + TABLE_NAME + " (name, age, address) VALUES (?, ?, ?);";
    124         SQLiteStatement statement = mDatabase.compileStatement(sql);
    125         DatabaseUtils.bindObjectToProgram(statement, 1, name);
    126         DatabaseUtils.bindObjectToProgram(statement, 2, age);
    127         DatabaseUtils.bindObjectToProgram(statement, 3, address);
    128         statement.execute();
    129         statement.close();
    130 
    131         cursor = mDatabase.query(TABLE_NAME, TEST_PROJECTION, null, null, null, null, null);
    132         assertNotNull(cursor);
    133         assertEquals(1, cursor.getCount());
    134         cursor.moveToFirst();
    135         assertEquals(name, cursor.getString(1));
    136         assertEquals(age, cursor.getInt(2));
    137         assertEquals(address, cursor.getString(3));
    138     }
    139 
    140     public void testCreateDbFromSqlStatements() {
    141         String dbName = "ExampleName";
    142         String sqls = "CREATE TABLE " + TABLE_NAME + " (_id INTEGER PRIMARY KEY, name TEXT);\n"
    143                 + "INSERT INTO " + TABLE_NAME + " (name) VALUES ('Mike');\n";
    144         DatabaseUtils.createDbFromSqlStatements(getContext(), dbName, 1, sqls);
    145 
    146         SQLiteDatabase db = getContext().openOrCreateDatabase(dbName, 0, null);
    147         final String[] PROJECTION = new String[] {
    148             "_id",             // 0
    149             "name"             // 1
    150         };
    151         Cursor cursor = db.query(TABLE_NAME, PROJECTION, null, null, null, null, null);
    152         assertNotNull(cursor);
    153         assertEquals(1, cursor.getCount());
    154         cursor.moveToFirst();
    155         assertEquals("Mike", cursor.getString(1));
    156         getContext().deleteDatabase(dbName);
    157     }
    158 
    159     public void testCursorDoubleToContentValues() {
    160         mDatabase.execSQL("INSERT INTO " + TABLE_NAME + " (name, age, address)" +
    161                 " VALUES ('Mike', '20', 'LA');");
    162         Cursor cursor = mDatabase.query(TABLE_NAME, TEST_PROJECTION,
    163                 null, null, null, null, null);
    164         assertNotNull(cursor);
    165 
    166         ContentValues contentValues = new ContentValues();
    167         String key = "key";
    168         cursor.moveToFirst();
    169         DatabaseUtils.cursorDoubleToContentValues(cursor, "age", contentValues, key);
    170         assertEquals(20.0, contentValues.getAsDouble(key));
    171 
    172         DatabaseUtils.cursorDoubleToContentValues(cursor, "Error Field Name", contentValues, key);
    173         assertNull(contentValues.getAsDouble(key));
    174 
    175         DatabaseUtils.cursorDoubleToContentValues(cursor, "name", contentValues, key);
    176         assertEquals(0.0, contentValues.getAsDouble(key));
    177     }
    178 
    179     public void testCursorDoubleToCursorValues() {
    180         mDatabase.execSQL("INSERT INTO " + TABLE_NAME + " (name, age, address)" +
    181                 " VALUES ('Mike', '20', 'LA');");
    182         Cursor cursor = mDatabase.query(TABLE_NAME, TEST_PROJECTION,
    183                 null, null, null, null, null);
    184         assertNotNull(cursor);
    185 
    186         ContentValues contentValues = new ContentValues();
    187         cursor.moveToFirst();
    188         DatabaseUtils.cursorDoubleToCursorValues(cursor, "age", contentValues);
    189         assertEquals(20.0, contentValues.getAsDouble("age"));
    190 
    191         DatabaseUtils.cursorDoubleToCursorValues(cursor, "Error Field Name", contentValues);
    192         assertNull(contentValues.getAsDouble("Error Field Name"));
    193 
    194         DatabaseUtils.cursorDoubleToCursorValues(cursor, "name", contentValues);
    195         assertEquals(0.0, contentValues.getAsDouble("name"));
    196     }
    197 
    198     public void testCursorIntToContentValues() {
    199         mDatabase.execSQL("INSERT INTO " + TABLE_NAME + " (name, age, address)" +
    200                 " VALUES ('Mike', '20', 'LA');");
    201         Cursor cursor = mDatabase.query(TABLE_NAME, TEST_PROJECTION, null, null, null, null, null);
    202         assertNotNull(cursor);
    203 
    204         ContentValues contentValues = new ContentValues();
    205         String key = "key";
    206         cursor.moveToFirst();
    207         DatabaseUtils.cursorIntToContentValues(cursor, "age", contentValues, key);
    208         assertEquals(Integer.valueOf(20), contentValues.getAsInteger(key));
    209 
    210         DatabaseUtils.cursorIntToContentValues(cursor, "Error Field Name", contentValues, key);
    211         assertNull(contentValues.getAsInteger(key));
    212 
    213         DatabaseUtils.cursorIntToContentValues(cursor, "name", contentValues, key);
    214         assertEquals(Integer.valueOf(0), contentValues.getAsInteger(key));
    215 
    216         contentValues = new ContentValues();
    217         DatabaseUtils.cursorIntToContentValues(cursor, "age", contentValues);
    218         assertEquals(Integer.valueOf(20), contentValues.getAsInteger("age"));
    219 
    220         DatabaseUtils.cursorIntToContentValues(cursor, "Error Field Name", contentValues);
    221         assertNull(contentValues.getAsInteger("Error Field Name"));
    222 
    223         DatabaseUtils.cursorIntToContentValues(cursor, "name", contentValues);
    224         assertEquals(Integer.valueOf(0), contentValues.getAsInteger("name"));
    225     }
    226 
    227     public void testcursorLongToContentValues() {
    228         mDatabase.execSQL("INSERT INTO " + TABLE_NAME + " (name, age, address)" +
    229                 " VALUES ('Mike', '20', 'LA');");
    230         Cursor cursor = mDatabase.query(TABLE_NAME, TEST_PROJECTION, null, null, null, null, null);
    231         assertNotNull(cursor);
    232 
    233         ContentValues contentValues = new ContentValues();
    234         String key = "key";
    235         cursor.moveToNext();
    236         DatabaseUtils.cursorLongToContentValues(cursor, "age", contentValues, key);
    237         assertEquals(Long.valueOf(20), contentValues.getAsLong(key));
    238 
    239         DatabaseUtils.cursorLongToContentValues(cursor, "Error Field Name", contentValues, key);
    240         assertNull(contentValues.getAsLong(key));
    241 
    242         DatabaseUtils.cursorLongToContentValues(cursor, "name", contentValues, key);
    243         assertEquals(Long.valueOf(0), contentValues.getAsLong(key));
    244 
    245         contentValues = new ContentValues();
    246         DatabaseUtils.cursorLongToContentValues(cursor, "age", contentValues);
    247         assertEquals(Long.valueOf(20), contentValues.getAsLong("age"));
    248 
    249         DatabaseUtils.cursorLongToContentValues(cursor, "Error Field Name", contentValues);
    250         assertNull(contentValues.getAsLong("Error Field Name"));
    251 
    252         DatabaseUtils.cursorLongToContentValues(cursor, "name", contentValues);
    253         assertEquals(Long.valueOf(0), contentValues.getAsLong("name"));
    254     }
    255 
    256     public void testCursorRowToContentValues() {
    257         mDatabase.execSQL("INSERT INTO " + TABLE_NAME + " (name, age, address)" +
    258                 " VALUES ('Mike', '20', 'LA');");
    259         Cursor cursor = mDatabase.query(TABLE_NAME, TEST_PROJECTION,
    260                 null, null, null, null, null);
    261         assertNotNull(cursor);
    262 
    263         ContentValues contentValues = new ContentValues();
    264         cursor.moveToNext();
    265         DatabaseUtils.cursorRowToContentValues(cursor, contentValues);
    266         assertEquals("Mike", (String) contentValues.get("name"));
    267         assertEquals("20", (String) contentValues.get("age"));
    268         assertEquals("LA", (String) contentValues.get("address"));
    269 
    270         mDatabase.execSQL("INSERT INTO boolean_test (value)" +
    271                 " VALUES (0);");
    272         mDatabase.execSQL("INSERT INTO boolean_test (value)" +
    273                 " VALUES (1);");
    274         cursor = mDatabase.query("boolean_test", new String[] {"value"},
    275                 null, null, null, null, null);
    276         assertNotNull(cursor);
    277 
    278         contentValues = new ContentValues();
    279         cursor.moveToNext();
    280         DatabaseUtils.cursorRowToContentValues(cursor, contentValues);
    281         assertFalse(contentValues.getAsBoolean("value"));
    282         cursor.moveToNext();
    283         DatabaseUtils.cursorRowToContentValues(cursor, contentValues);
    284         assertTrue(contentValues.getAsBoolean("value"));
    285     }
    286 
    287     public void testCursorStringToContentValues() {
    288         mDatabase.execSQL("INSERT INTO " + TABLE_NAME + " (name, age, address)" +
    289                 " VALUES ('Mike', '20', 'LA');");
    290         Cursor cursor = mDatabase.query(TABLE_NAME, TEST_PROJECTION,
    291                 null, null, null, null, null);
    292         assertNotNull(cursor);
    293 
    294         ContentValues contentValues = new ContentValues();
    295         String key = "key";
    296         cursor.moveToNext();
    297         DatabaseUtils.cursorStringToContentValues(cursor, "age", contentValues, key);
    298         assertEquals("20", (String) contentValues.get(key));
    299 
    300         try {
    301             DatabaseUtils.cursorStringToContentValues(cursor, "Error Field Name",
    302                     contentValues, key);
    303             fail("should throw IllegalArgumentException.");
    304         } catch (IllegalArgumentException e) {
    305             // expected
    306         }
    307 
    308         DatabaseUtils.cursorStringToContentValues(cursor, "name", contentValues, key);
    309         assertEquals("Mike", contentValues.get(key));
    310 
    311         contentValues = new ContentValues();
    312         DatabaseUtils.cursorStringToContentValues(cursor, "age", contentValues);
    313         assertEquals("20", contentValues.get("age"));
    314 
    315         try {
    316             DatabaseUtils.cursorStringToContentValues(cursor, "Error Field Name", contentValues);
    317             fail("should throw IllegalArgumentException.");
    318         } catch (IllegalArgumentException e) {
    319             // expected
    320         }
    321 
    322         DatabaseUtils.cursorStringToContentValues(cursor, "name", contentValues);
    323         assertEquals("Mike", contentValues.get("name"));
    324     }
    325 
    326     public void testCursorStringToInsertHelper() {
    327         // create a new table.
    328         mDatabase.execSQL("CREATE TABLE test_copy (_id INTEGER PRIMARY KEY, " +
    329                 "name TEXT, age INTEGER, address TEXT);");
    330 
    331         mDatabase.execSQL("INSERT INTO " + TABLE_NAME + " (name, age, address)" +
    332                 " VALUES ('Mike', '20', 'LA');");
    333         Cursor cursor = mDatabase.query("test_copy", TEST_PROJECTION, null, null, null, null, null);
    334         assertEquals(0, cursor.getCount());
    335 
    336         InsertHelper insertHelper = new InsertHelper(mDatabase, "test_copy");
    337         int indexName = insertHelper.getColumnIndex("name");
    338         int indexAge = insertHelper.getColumnIndex("age");
    339         int indexAddress = insertHelper.getColumnIndex("address");
    340 
    341         cursor = mDatabase.query(TABLE_NAME, TEST_PROJECTION, null, null, null, null, null);
    342         cursor.moveToNext();
    343         insertHelper.prepareForInsert();
    344         DatabaseUtils.cursorStringToInsertHelper(cursor, "name", insertHelper, indexName);
    345         DatabaseUtils.cursorStringToInsertHelper(cursor, "age", insertHelper, indexAge);
    346         DatabaseUtils.cursorStringToInsertHelper(cursor, "address", insertHelper, indexAddress);
    347         insertHelper.execute();
    348 
    349         cursor = mDatabase.query("test_copy", TEST_PROJECTION, null, null, null, null, null);
    350         assertEquals(1, cursor.getCount());
    351         cursor.moveToNext();
    352         assertEquals("Mike", cursor.getString(1));
    353         assertEquals(20, cursor.getInt(2));
    354         assertEquals("LA", cursor.getString(3));
    355     }
    356 
    357     public void testDumpCurrentRow() {
    358         mDatabase.execSQL("INSERT INTO " + TABLE_NAME + " (name, age, address)" +
    359                 " VALUES ('Mike', '20', 'LA');");
    360         Cursor cursor = mDatabase.query(TABLE_NAME, TEST_PROJECTION,
    361                 null, null, null, null, null);
    362         assertNotNull(cursor);
    363         cursor.moveToNext();
    364         String expected = "0 {\n   _id=1\n   name=Mike\n   age=20\n   address=LA\n}\n";
    365 
    366         DatabaseUtils.dumpCurrentRow(cursor);
    367 
    368         ByteArrayOutputStream bos = new ByteArrayOutputStream();
    369         PrintStream os = new PrintStream(bos);
    370         DatabaseUtils.dumpCurrentRow(cursor, os);
    371         os.flush();
    372         os.close();
    373         assertEquals(expected, bos.toString());
    374 
    375         StringBuilder sb = new StringBuilder();
    376         DatabaseUtils.dumpCurrentRow(cursor, sb);
    377         assertEquals(expected, sb.toString());
    378 
    379         assertEquals(expected, DatabaseUtils.dumpCurrentRowToString(cursor));
    380     }
    381 
    382     public void testDumpCursor() {
    383         mDatabase.execSQL("INSERT INTO " + TABLE_NAME + " (name, age, address)" +
    384                 " VALUES ('Mike', '20', 'LA');");
    385         mDatabase.execSQL("INSERT INTO " + TABLE_NAME + " (name, age, address)" +
    386                 " VALUES ('Jack', '30', 'London');");
    387         Cursor cursor = mDatabase.query(TABLE_NAME, TEST_PROJECTION,
    388                 null, null, null, null, null);
    389         assertNotNull(cursor);
    390         int pos = cursor.getPosition();
    391         String expected = ">>>>> Dumping cursor " + cursor + "\n" +
    392                 "0 {\n" +
    393                 "   _id=1\n" +
    394                 "   name=Mike\n" +
    395                 "   age=20\n" +
    396                 "   address=LA\n" +
    397                 "}\n" +
    398                 "1 {\n" +
    399                 "   _id=2\n" +
    400                 "   name=Jack\n" +
    401                 "   age=30\n" +
    402                 "   address=London\n" +
    403                 "}\n" +
    404                 "<<<<<\n";
    405 
    406         DatabaseUtils.dumpCursor(cursor);
    407 
    408         ByteArrayOutputStream bos = new ByteArrayOutputStream();
    409         PrintStream os = new PrintStream(bos);
    410         DatabaseUtils.dumpCursor(cursor, os);
    411         os.flush();
    412         os.close();
    413         assertEquals(pos, cursor.getPosition()); // dumpCursor should not change status of cursor
    414         assertEquals(expected, bos.toString());
    415 
    416         StringBuilder sb = new StringBuilder();
    417         DatabaseUtils.dumpCursor(cursor, sb);
    418         assertEquals(pos, cursor.getPosition()); // dumpCursor should not change status of cursor
    419         assertEquals(expected, sb.toString());
    420 
    421         assertEquals(expected, DatabaseUtils.dumpCursorToString(cursor));
    422         assertEquals(pos, cursor.getPosition()); // dumpCursor should not change status of cursor
    423     }
    424 
    425     public void testCollationKey() {
    426         String key1 = DatabaseUtils.getCollationKey("abc");
    427         String key2 = DatabaseUtils.getCollationKey("ABC");
    428         String key3 = DatabaseUtils.getCollationKey("bcd");
    429 
    430         assertTrue(key1.equals(key2));
    431         assertFalse(key1.equals(key3));
    432 
    433         key1 = DatabaseUtils.getHexCollationKey("abc");
    434         key2 = DatabaseUtils.getHexCollationKey("ABC");
    435         key3 = DatabaseUtils.getHexCollationKey("bcd");
    436 
    437         assertTrue(key1.equals(key2));
    438         assertFalse(key1.equals(key3));
    439     }
    440 
    441     public void testLongForQuery() {
    442         mDatabase.execSQL("INSERT INTO " + TABLE_NAME + " (name, age, address)" +
    443                 " VALUES ('Mike', '20', 'LA');");
    444 
    445         String query = "SELECT age FROM " + TABLE_NAME;
    446         assertEquals(20, DatabaseUtils.longForQuery(mDatabase, query, null));
    447 
    448         mDatabase.execSQL("INSERT INTO " + TABLE_NAME + " (name, age, address)" +
    449                 " VALUES ('Jack', '35', 'London');");
    450         query = "SELECT age FROM " + TABLE_NAME + " WHERE name = ?";
    451         String[] args = new String[] { "Jack" };
    452         assertEquals(35, DatabaseUtils.longForQuery(mDatabase, query, args));
    453         args = new String[] { "No such name" };
    454         try {
    455             DatabaseUtils.longForQuery(mDatabase, query, args);
    456             fail("should throw SQLiteDoneException");
    457         } catch (SQLiteDoneException e) {
    458             // expected
    459         }
    460 
    461         query = "SELECT count(*) FROM " + TABLE_NAME + ";";
    462         SQLiteStatement statement = mDatabase.compileStatement(query);
    463         assertEquals(2, DatabaseUtils.longForQuery(statement, null));
    464 
    465         query = "SELECT age FROM " + TABLE_NAME + " WHERE address = ?;";
    466         statement = mDatabase.compileStatement(query);
    467         args = new String[] { "London" };
    468         assertEquals(35, DatabaseUtils.longForQuery(statement, args));
    469 
    470         args = new String[] { "No such address" };
    471         try {
    472             DatabaseUtils.longForQuery(statement, args);
    473             fail("should throw SQLiteDoneException");
    474         } catch (SQLiteDoneException e) {
    475             // expected
    476         }
    477         statement.close();
    478     }
    479 
    480     public void testQueryNumEntries() {
    481         assertEquals(0, DatabaseUtils.queryNumEntries(mDatabase, TABLE_NAME));
    482 
    483         mDatabase.execSQL(
    484                 "INSERT INTO " + TABLE_NAME + " (name, age, address)" +
    485                 " VALUES ('Mike', '20', 'LA');");
    486         assertEquals(1, DatabaseUtils.queryNumEntries(mDatabase, TABLE_NAME));
    487 
    488         mDatabase.execSQL(
    489                 "INSERT INTO " + TABLE_NAME + " (name, age, address)" +
    490                 " VALUES ('Susan', '20', 'AR');");
    491         assertEquals(2, DatabaseUtils.queryNumEntries(mDatabase, TABLE_NAME));
    492 
    493         mDatabase.execSQL(
    494                 "INSERT INTO " + TABLE_NAME + " (name, age, address)" +
    495                 " VALUES ('Christian', '25', 'AT');");
    496         assertEquals(3, DatabaseUtils.queryNumEntries(mDatabase, TABLE_NAME));
    497 
    498         assertEquals(2, DatabaseUtils.queryNumEntries(mDatabase, TABLE_NAME, "AGE = 20"));
    499 
    500         assertEquals(1, DatabaseUtils.queryNumEntries(mDatabase, TABLE_NAME, "AGE = ?",
    501                 new String[] { "25" }));
    502 
    503         try {
    504             DatabaseUtils.queryNumEntries(mDatabase, "NoSuchTable");
    505             fail("should throw SQLiteException.");
    506         } catch (SQLiteException e) {
    507             // expected
    508         }
    509     }
    510 
    511     public void testExceptionFromParcel() {
    512         Parcel parcel = Parcel.obtain();
    513         DatabaseUtils.writeExceptionToParcel(parcel, new IllegalArgumentException());
    514         parcel.setDataPosition(0);
    515         try {
    516             DatabaseUtils.readExceptionFromParcel(parcel);
    517             fail("should throw IllegalArgumentException.");
    518         } catch (IllegalArgumentException e) {
    519             // expected
    520         }
    521 
    522         parcel.recycle();
    523         parcel = Parcel.obtain();
    524         DatabaseUtils.writeExceptionToParcel(parcel, new SQLiteAbortException());
    525         parcel.setDataPosition(0);
    526         try {
    527             DatabaseUtils.readExceptionFromParcel(parcel);
    528             fail("should throw SQLiteAbortException.");
    529         } catch (SQLiteAbortException e) {
    530             // expected
    531         }
    532 
    533         parcel.recycle();
    534         parcel = Parcel.obtain();
    535         DatabaseUtils.writeExceptionToParcel(parcel, new FileNotFoundException());
    536         parcel.setDataPosition(0);
    537         try {
    538             DatabaseUtils.readExceptionFromParcel(parcel);
    539             fail("should throw RuntimeException.");
    540         } catch (RuntimeException e) {
    541             // expected
    542         }
    543 
    544         parcel.recycle();
    545         parcel = Parcel.obtain();
    546         DatabaseUtils.writeExceptionToParcel(parcel, new FileNotFoundException());
    547         parcel.setDataPosition(0);
    548         try {
    549             DatabaseUtils.readExceptionWithFileNotFoundExceptionFromParcel(parcel);
    550             fail("should throw FileNotFoundException.");
    551         } catch (FileNotFoundException e) {
    552             // expected
    553         }
    554     }
    555 
    556     public void testStringForQuery() {
    557         mDatabase.execSQL("INSERT INTO " + TABLE_NAME + " (name, age, address)" +
    558                 " VALUES ('Mike', '20', 'LA');");
    559 
    560         String query = "SELECT name FROM " + TABLE_NAME;
    561         assertEquals("Mike", DatabaseUtils.stringForQuery(mDatabase, query, null));
    562 
    563         mDatabase.execSQL("INSERT INTO " + TABLE_NAME + " (name, age, address)" +
    564                 " VALUES ('Jack', '35', 'London');");
    565         query = "SELECT name FROM " + TABLE_NAME + " WHERE address = ?";
    566         String[] args = new String[] { "London" };
    567         assertEquals("Jack", DatabaseUtils.stringForQuery(mDatabase, query, args));
    568         args = new String[] { "No such address" };
    569         try {
    570             DatabaseUtils.stringForQuery(mDatabase, query, args);
    571             fail("should throw SQLiteDoneException");
    572         } catch (SQLiteDoneException e) {
    573             // expected
    574         }
    575 
    576         query = "SELECT name FROM " + TABLE_NAME + " WHERE age = ?;";
    577         SQLiteStatement statement = mDatabase.compileStatement(query);
    578         args = new String[] { "20" };
    579         assertEquals("Mike", DatabaseUtils.stringForQuery(statement, args));
    580 
    581         args = new String[] { "1000" }; // NO people can be older than this.
    582         try {
    583             DatabaseUtils.blobFileDescriptorForQuery(statement, args);
    584             fail("should throw SQLiteDoneException");
    585         } catch (SQLiteDoneException e) {
    586             // expected
    587         }
    588         statement.close();
    589     }
    590 
    591     public void testBlobFileDescriptorForQuery() throws Exception {
    592         String data1 = "5300FEFF";
    593         String data2 = "DECAFBAD";
    594         mDatabase.execSQL("INSERT INTO blob_test (name, data) VALUES ('Mike', X'" + data1 + "')");
    595 
    596         String query = "SELECT data FROM blob_test";
    597         assertFileDescriptorContent(parseBlob(data1),
    598                         DatabaseUtils.blobFileDescriptorForQuery(mDatabase, query, null));
    599 
    600         mDatabase.execSQL("INSERT INTO blob_test (name, data) VALUES ('Jack', X'" + data2 + "');");
    601         query = "SELECT data FROM blob_test WHERE name = ?";
    602         String[] args = new String[] { "Jack" };
    603         assertFileDescriptorContent(parseBlob(data2),
    604                 DatabaseUtils.blobFileDescriptorForQuery(mDatabase, query, args));
    605 
    606         args = new String[] { "No such name" };
    607         try {
    608             DatabaseUtils.stringForQuery(mDatabase, query, args);
    609             fail("should throw SQLiteDoneException");
    610         } catch (SQLiteDoneException e) {
    611             // expected
    612         }
    613 
    614         query = "SELECT data FROM blob_test WHERE name = ?;";
    615         SQLiteStatement statement = mDatabase.compileStatement(query);
    616         args = new String[] { "Mike" };
    617         assertFileDescriptorContent(parseBlob(data1),
    618                 DatabaseUtils.blobFileDescriptorForQuery(statement, args));
    619 
    620         args = new String[] { "No such name" };
    621         try {
    622             DatabaseUtils.blobFileDescriptorForQuery(statement, args);
    623             fail("should throw SQLiteDoneException");
    624         } catch (SQLiteDoneException e) {
    625             // expected
    626         }
    627         statement.close();
    628     }
    629 
    630     private static byte[] parseBlob(String src) {
    631         int len = src.length();
    632         byte[] result = new byte[len / 2];
    633 
    634         for (int i = 0; i < len/2; i++) {
    635             int val;
    636             char c1 = src.charAt(i*2);
    637             char c2 = src.charAt(i*2+1);
    638             int val1 = Character.digit(c1, 16);
    639             int val2 = Character.digit(c2, 16);
    640             val = (val1 << 4) | val2;
    641             result[i] = (byte)val;
    642         }
    643         return result;
    644     }
    645 
    646     private static void assertFileDescriptorContent(byte[] expected, ParcelFileDescriptor fd)
    647             throws IOException {
    648         assertInputStreamContent(expected, new ParcelFileDescriptor.AutoCloseInputStream(fd));
    649     }
    650 
    651     private static void assertInputStreamContent(byte[] expected, InputStream is)
    652             throws IOException {
    653         try {
    654             byte[] observed = new byte[expected.length];
    655             int count = is.read(observed);
    656             assertEquals(expected.length, count);
    657             assertEquals(-1, is.read());
    658             MoreAsserts.assertEquals(expected, observed);
    659         } finally {
    660             is.close();
    661         }
    662     }
    663 
    664 }
    665