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