DatabaseGeneralTest.java revision fb16cbd9b2e86d6878d4bff820422bc09c8938de
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; 18 19import static android.database.DatabaseUtils.InsertHelper.TABLE_INFO_PRAGMA_COLUMNNAME_INDEX; 20import static android.database.DatabaseUtils.InsertHelper.TABLE_INFO_PRAGMA_DEFAULT_INDEX; 21import android.content.ContentValues; 22import android.content.Context; 23import android.database.sqlite.SQLiteDatabase; 24import android.database.sqlite.SQLiteException; 25import android.os.Handler; 26import android.os.Parcel; 27import android.test.AndroidTestCase; 28import android.test.PerformanceTestCase; 29import android.test.suitebuilder.annotation.LargeTest; 30import android.test.suitebuilder.annotation.MediumTest; 31import android.test.suitebuilder.annotation.SmallTest; 32import android.util.Log; 33import android.util.Pair; 34 35import junit.framework.Assert; 36 37import java.io.File; 38import java.util.ArrayList; 39import java.util.Arrays; 40import java.util.Locale; 41 42public class DatabaseGeneralTest extends AndroidTestCase implements PerformanceTestCase { 43 private static final String TAG = "DatabaseGeneralTest"; 44 45 private static final String sString1 = "this is a test"; 46 private static final String sString2 = "and yet another test"; 47 private static final String sString3 = "this string is a little longer, but still a test"; 48 private static final String PHONE_NUMBER = "16175551212"; 49 50 private static final int CURRENT_DATABASE_VERSION = 42; 51 private SQLiteDatabase mDatabase; 52 private File mDatabaseFile; 53 54 @Override 55 protected void setUp() throws Exception { 56 super.setUp(); 57 File dbDir = getContext().getDir(this.getClass().getName(), Context.MODE_PRIVATE); 58 mDatabaseFile = new File(dbDir, "database_test.db"); 59 if (mDatabaseFile.exists()) { 60 mDatabaseFile.delete(); 61 } 62 mDatabase = SQLiteDatabase.openOrCreateDatabase(mDatabaseFile.getPath(), null); 63 assertNotNull(mDatabase); 64 mDatabase.setVersion(CURRENT_DATABASE_VERSION); 65 } 66 67 @Override 68 protected void tearDown() throws Exception { 69 mDatabase.close(); 70 mDatabaseFile.delete(); 71 super.tearDown(); 72 } 73 74 public boolean isPerformanceOnly() { 75 return false; 76 } 77 78 // These test can only be run once. 79 public int startPerformance(Intermediates intermediates) { 80 return 1; 81 } 82 83 private void populateDefaultTable() { 84 mDatabase.execSQL("CREATE TABLE test (_id INTEGER PRIMARY KEY, data TEXT);"); 85 86 mDatabase.execSQL("INSERT INTO test (data) VALUES ('" + sString1 + "');"); 87 mDatabase.execSQL("INSERT INTO test (data) VALUES ('" + sString2 + "');"); 88 mDatabase.execSQL("INSERT INTO test (data) VALUES ('" + sString3 + "');"); 89 } 90 91 @MediumTest 92 public void testVersion() throws Exception { 93 assertEquals(CURRENT_DATABASE_VERSION, mDatabase.getVersion()); 94 mDatabase.setVersion(11); 95 assertEquals(11, mDatabase.getVersion()); 96 } 97 98 @MediumTest 99 public void testUpdate() throws Exception { 100 populateDefaultTable(); 101 102 ContentValues values = new ContentValues(1); 103 values.put("data", "this is an updated test"); 104 assertEquals(1, mDatabase.update("test", values, "_id=1", null)); 105 Cursor c = mDatabase.query("test", null, "_id=1", null, null, null, null); 106 assertNotNull(c); 107 assertEquals(1, c.getCount()); 108 c.moveToFirst(); 109 String value = c.getString(c.getColumnIndexOrThrow("data")); 110 assertEquals("this is an updated test", value); 111 } 112 113 @MediumTest 114 public void testPhoneNumbersEqual() throws Exception { 115 mDatabase.execSQL("CREATE TABLE phones (num TEXT);"); 116 mDatabase.execSQL("INSERT INTO phones (num) VALUES ('911');"); 117 mDatabase.execSQL("INSERT INTO phones (num) VALUES ('5555');"); 118 mDatabase.execSQL("INSERT INTO phones (num) VALUES ('+" + PHONE_NUMBER + "');"); 119 120 String number; 121 Cursor c; 122 123 c = mDatabase.query("phones", null, 124 "PHONE_NUMBERS_EQUAL(num, '504-555-7683')", null, null, null, null); 125 assertTrue(c == null || c.getCount() == 0); 126 c.close(); 127 128 c = mDatabase.query("phones", null, 129 "PHONE_NUMBERS_EQUAL(num, '911')", null, null, null, null); 130 assertNotNull(c); 131 assertEquals(1, c.getCount()); 132 c.moveToFirst(); 133 number = c.getString(c.getColumnIndexOrThrow("num")); 134 assertEquals("911", number); 135 c.close(); 136 137 c = mDatabase.query("phones", null, 138 "PHONE_NUMBERS_EQUAL(num, '5555')", null, null, null, null); 139 assertNotNull(c); 140 assertEquals(1, c.getCount()); 141 c.moveToFirst(); 142 number = c.getString(c.getColumnIndexOrThrow("num")); 143 assertEquals("5555", number); 144 c.close(); 145 146 c = mDatabase.query("phones", null, 147 "PHONE_NUMBERS_EQUAL(num, '180055555555')", null, null, null, null); 148 assertTrue(c == null || c.getCount() == 0); 149 c.close(); 150 151 c = mDatabase.query("phones", null, 152 "PHONE_NUMBERS_EQUAL(num, '+" + PHONE_NUMBER + "')", null, null, null, null); 153 assertNotNull(c); 154 assertEquals(1, c.getCount()); 155 c.moveToFirst(); 156 number = c.getString(c.getColumnIndexOrThrow("num")); 157 assertEquals("+" + PHONE_NUMBER, number); 158 c.close(); 159 160 c = mDatabase.query("phones", null, 161 "PHONE_NUMBERS_EQUAL(num, '+1 (617).555-1212')", null, null, null, null); 162 assertNotNull(c); 163 assertEquals(1, c.getCount()); 164 c.moveToFirst(); 165 number = c.getString(c.getColumnIndexOrThrow("num")); 166 assertEquals("+" + PHONE_NUMBER, number); 167 c.close(); 168 169 c = mDatabase.query("phones", null, 170 "PHONE_NUMBERS_EQUAL(num, '" + PHONE_NUMBER + "')", null, null, null, null); 171 assertNotNull(c); 172 assertEquals(1, c.getCount()); 173 c.moveToFirst(); 174 number = c.getString(c.getColumnIndexOrThrow("num")); 175 assertEquals("+" + PHONE_NUMBER, number); 176 c.close(); 177 178 /* 179 c = mDatabase.query("phones", null, 180 "PHONE_NUMBERS_EQUAL(num, '5551212')", null, null, null, null); 181 assertNotNull(c); 182 assertEquals(1, c.getCount()); 183 c.moveToFirst(); 184 number = c.getString(c.getColumnIndexOrThrow("num")); 185 assertEquals("+" + PHONE_NUMBER, number); 186 c.close(); 187 */ 188 189 c = mDatabase.query("phones", null, 190 "PHONE_NUMBERS_EQUAL(num, '011" + PHONE_NUMBER + "')", null, null, null, null); 191 assertNotNull(c); 192 assertEquals(1, c.getCount()); 193 c.moveToFirst(); 194 number = c.getString(c.getColumnIndexOrThrow("num")); 195 assertEquals("+" + PHONE_NUMBER, number); 196 c.close(); 197 198 c = mDatabase.query("phones", null, 199 "PHONE_NUMBERS_EQUAL(num, '00" + PHONE_NUMBER + "')", null, null, null, null); 200 assertNotNull(c); 201 assertEquals(1, c.getCount()); 202 c.moveToFirst(); 203 number = c.getString(c.getColumnIndexOrThrow("num")); 204 assertEquals("+" + PHONE_NUMBER, number); 205 c.close(); 206 } 207 208 private void phoneNumberCompare(String phone1, String phone2, boolean equal, 209 boolean useStrictComparation) { 210 String[] temporalPhoneNumbers = new String[2]; 211 temporalPhoneNumbers[0] = phone1; 212 temporalPhoneNumbers[1] = phone2; 213 214 Cursor cursor = mDatabase.rawQuery( 215 String.format( 216 "SELECT CASE WHEN PHONE_NUMBERS_EQUAL(?, ?, %d) " + 217 "THEN 'equal' ELSE 'not equal' END", 218 (useStrictComparation ? 1 : 0)), 219 temporalPhoneNumbers); 220 try { 221 assertNotNull(cursor); 222 assertTrue(cursor.moveToFirst()); 223 if (equal) { 224 assertEquals(String.format("Unexpectedly, \"%s != %s\".", phone1, phone2), 225 "equal", cursor.getString(0)); 226 } else { 227 assertEquals(String.format("Unexpectedly, \"%s\" == \"%s\".", phone1, phone2), 228 "not equal", cursor.getString(0)); 229 } 230 } finally { 231 if (cursor != null) { 232 cursor.close(); 233 } 234 } 235 } 236 237 private void assertPhoneNumberEqual(String phone1, String phone2) throws Exception { 238 assertPhoneNumberEqual(phone1, phone2, true); 239 assertPhoneNumberEqual(phone1, phone2, false); 240 } 241 242 private void assertPhoneNumberEqual(String phone1, String phone2, boolean useStrict) 243 throws Exception { 244 phoneNumberCompare(phone1, phone2, true, useStrict); 245 } 246 247 private void assertPhoneNumberNotEqual(String phone1, String phone2) throws Exception { 248 assertPhoneNumberNotEqual(phone1, phone2, true); 249 assertPhoneNumberNotEqual(phone1, phone2, false); 250 } 251 252 private void assertPhoneNumberNotEqual(String phone1, String phone2, boolean useStrict) 253 throws Exception { 254 phoneNumberCompare(phone1, phone2, false, useStrict); 255 } 256 257 /** 258 * Tests international matching issues for the PHONE_NUMBERS_EQUAL function. 259 * 260 * @throws Exception 261 */ 262 @SmallTest 263 public void testPhoneNumbersEqualInternationl() throws Exception { 264 assertPhoneNumberEqual("1", "1"); 265 assertPhoneNumberEqual("123123", "123123"); 266 assertPhoneNumberNotEqual("123123", "923123"); 267 assertPhoneNumberNotEqual("123123", "123129"); 268 assertPhoneNumberNotEqual("123123", "1231234"); 269 assertPhoneNumberNotEqual("123123", "0123123", false); 270 assertPhoneNumberNotEqual("123123", "0123123", true); 271 assertPhoneNumberEqual("650-253-0000", "6502530000"); 272 assertPhoneNumberEqual("650-253-0000", "650 253 0000"); 273 assertPhoneNumberEqual("650 253 0000", "6502530000"); 274 assertPhoneNumberEqual("+1 650-253-0000", "6502530000"); 275 assertPhoneNumberEqual("001 650-253-0000", "6502530000"); 276 assertPhoneNumberEqual("0111 650-253-0000", "6502530000"); 277 278 // Russian trunk digit 279 assertPhoneNumberEqual("+79161234567", "89161234567"); 280 281 // French trunk digit 282 assertPhoneNumberEqual("+33123456789", "0123456789"); 283 284 // Trunk digit for city codes in the Netherlands 285 assertPhoneNumberEqual("+31771234567", "0771234567"); 286 287 // Test broken caller ID seen on call from Thailand to the US 288 assertPhoneNumberEqual("+66811234567", "166811234567"); 289 290 // Test the same in-country number with different country codes 291 assertPhoneNumberNotEqual("+33123456789", "+1123456789"); 292 293 // Test one number with country code and the other without 294 assertPhoneNumberEqual("5125551212", "+15125551212"); 295 296 // Test two NANP numbers that only differ in the area code 297 assertPhoneNumberNotEqual("5125551212", "6505551212"); 298 299 // Japanese phone numbers 300 assertPhoneNumberEqual("090-1234-5678", "+819012345678"); 301 assertPhoneNumberEqual("090(1234)5678", "+819012345678"); 302 assertPhoneNumberEqual("090-1234-5678", "+81-90-1234-5678"); 303 304 // Equador 305 assertPhoneNumberEqual("+593(800)123-1234", "8001231234"); 306 assertPhoneNumberEqual("+593-2-1234-123", "21234123"); 307 308 // Two continuous 0 at the beginning of the phone string should not be 309 // treated as trunk prefix in the strict comparation. 310 assertPhoneNumberEqual("008001231234", "8001231234", false); 311 assertPhoneNumberNotEqual("008001231234", "8001231234", true); 312 313 // Confirm that the bug found before does not re-appear in the strict compalation 314 assertPhoneNumberEqual("080-1234-5678", "+819012345678", false); 315 assertPhoneNumberNotEqual("080-1234-5678", "+819012345678", true); 316 } 317 318 @MediumTest 319 public void testCopyString() throws Exception { 320 mDatabase.execSQL("CREATE TABLE guess (numi INTEGER, numf FLOAT, str TEXT);"); 321 mDatabase.execSQL( 322 "INSERT INTO guess (numi,numf,str) VALUES (0,0.0,'ZoomZoomZoomZoom');"); 323 mDatabase.execSQL("INSERT INTO guess (numi,numf,str) VALUES (2000000000,3.1415926535,'');"); 324 String chinese = "\u4eac\u4ec5 \u5c3d\u5f84\u60ca"; 325 String[] arr = new String[1]; 326 arr[0] = chinese; 327 mDatabase.execSQL("INSERT INTO guess (numi,numf,str) VALUES (-32768,-1.0,?)", arr); 328 329 Cursor c; 330 331 c = mDatabase.rawQuery("SELECT * FROM guess", null); 332 333 c.moveToFirst(); 334 335 CharArrayBuffer buf = new CharArrayBuffer(14); 336 337 String compareTo = c.getString(c.getColumnIndexOrThrow("numi")); 338 int numiIdx = c.getColumnIndexOrThrow("numi"); 339 int numfIdx = c.getColumnIndexOrThrow("numf"); 340 int strIdx = c.getColumnIndexOrThrow("str"); 341 342 c.copyStringToBuffer(numiIdx, buf); 343 assertEquals(1, buf.sizeCopied); 344 assertEquals(compareTo, new String(buf.data, 0, buf.sizeCopied)); 345 346 c.copyStringToBuffer(strIdx, buf); 347 assertEquals("ZoomZoomZoomZoom", new String(buf.data, 0, buf.sizeCopied)); 348 349 c.moveToNext(); 350 compareTo = c.getString(numfIdx); 351 352 c.copyStringToBuffer(numfIdx, buf); 353 assertEquals(compareTo, new String(buf.data, 0, buf.sizeCopied)); 354 c.copyStringToBuffer(strIdx, buf); 355 assertEquals(0, buf.sizeCopied); 356 357 c.moveToNext(); 358 c.copyStringToBuffer(numfIdx, buf); 359 assertEquals(-1.0, Double.valueOf( 360 new String(buf.data, 0, buf.sizeCopied)).doubleValue()); 361 362 c.copyStringToBuffer(strIdx, buf); 363 compareTo = c.getString(strIdx); 364 assertEquals(chinese, compareTo); 365 366 assertEquals(chinese, new String(buf.data, 0, buf.sizeCopied)); 367 c.close(); 368 } 369 370 @MediumTest 371 public void testSchemaChange1() throws Exception { 372 SQLiteDatabase db1 = mDatabase; 373 Cursor cursor; 374 375 db1.execSQL("CREATE TABLE db1 (_id INTEGER PRIMARY KEY, data TEXT);"); 376 377 cursor = db1.query("db1", null, null, null, null, null, null); 378 assertNotNull("Cursor is null", cursor); 379 380 db1.execSQL("CREATE TABLE db2 (_id INTEGER PRIMARY KEY, data TEXT);"); 381 382 assertEquals(0, cursor.getCount()); 383 cursor.deactivate(); 384 } 385 386 @MediumTest 387 public void testSchemaChange2() throws Exception { 388 mDatabase.execSQL("CREATE TABLE db1 (_id INTEGER PRIMARY KEY, data TEXT);"); 389 Cursor cursor = mDatabase.query("db1", null, null, null, null, null, null); 390 assertNotNull(cursor); 391 assertEquals(0, cursor.getCount()); 392 cursor.close(); 393 } 394 395 @MediumTest 396 public void testSchemaChange3() throws Exception { 397 mDatabase.execSQL("CREATE TABLE db1 (_id INTEGER PRIMARY KEY, data TEXT);"); 398 mDatabase.execSQL("INSERT INTO db1 (data) VALUES ('test');"); 399 mDatabase.execSQL("ALTER TABLE db1 ADD COLUMN blah int;"); 400 Cursor c = null; 401 try { 402 c = mDatabase.rawQuery("select blah from db1", null); 403 } catch (SQLiteException e) { 404 fail("unexpected exception: " + e.getMessage()); 405 } finally { 406 if (c != null) { 407 c.close(); 408 } 409 } 410 } 411 412 private class ChangeObserver extends ContentObserver { 413 private int mCursorNotificationCount = 0; 414 private int mNotificationCount = 0; 415 416 public int getCursorNotificationCount() { 417 return mCursorNotificationCount; 418 } 419 420 public int getNotificationCount() { 421 return mNotificationCount; 422 } 423 424 public ChangeObserver(boolean cursor) { 425 super(new Handler()); 426 mCursor = cursor; 427 } 428 429 @Override 430 public boolean deliverSelfNotifications() { 431 return true; 432 } 433 434 @Override 435 public void onChange(boolean selfChange) { 436 if (mCursor) { 437 mCursorNotificationCount++; 438 } else { 439 mNotificationCount++; 440 } 441 } 442 443 boolean mCursor; 444 } 445 446 @MediumTest 447 public void testSelectionArgs() throws Exception { 448 mDatabase.execSQL("CREATE TABLE test (_id INTEGER PRIMARY KEY, data TEXT);"); 449 ContentValues values = new ContentValues(1); 450 values.put("data", "don't forget to handled 's"); 451 mDatabase.insert("test", "data", values); 452 values.clear(); 453 values.put("data", "no apostrophes here"); 454 mDatabase.insert("test", "data", values); 455 Cursor c = mDatabase.query( 456 "test", null, "data GLOB ?", new String[]{"*'*"}, null, null, null); 457 assertEquals(1, c.getCount()); 458 assertTrue(c.moveToFirst()); 459 assertEquals("don't forget to handled 's", c.getString(1)); 460 c.deactivate(); 461 462 // make sure code should checking null string properly so that 463 // it won't crash 464 try { 465 mDatabase.query("test", new String[]{"_id"}, 466 "_id=?", new String[]{null}, null, null, null); 467 fail("expected exception not thrown"); 468 } catch (IllegalArgumentException e) { 469 // expected 470 } 471 } 472 473 @MediumTest 474 public void testTokenize() throws Exception { 475 Cursor c; 476 mDatabase.execSQL("CREATE TABLE tokens (" + 477 "token TEXT COLLATE unicode," + 478 "source INTEGER," + 479 "token_index INTEGER," + 480 "tag TEXT" + 481 ");"); 482 mDatabase.execSQL("CREATE TABLE tokens_no_index (" + 483 "token TEXT COLLATE unicode," + 484 "source INTEGER" + 485 ");"); 486 487 Assert.assertEquals(0, DatabaseUtils.longForQuery(mDatabase, 488 "SELECT _TOKENIZE(NULL, NULL, NULL, NULL)", null)); 489 Assert.assertEquals(0, DatabaseUtils.longForQuery(mDatabase, 490 "SELECT _TOKENIZE('tokens', NULL, NULL, NULL)", null)); 491 Assert.assertEquals(0, DatabaseUtils.longForQuery(mDatabase, 492 "SELECT _TOKENIZE('tokens', 10, NULL, NULL)", null)); 493 Assert.assertEquals(0, DatabaseUtils.longForQuery(mDatabase, 494 "SELECT _TOKENIZE('tokens', 10, 'some string', NULL)", null)); 495 496 Assert.assertEquals(3, DatabaseUtils.longForQuery(mDatabase, 497 "SELECT _TOKENIZE('tokens', 11, 'some string ok', ' ', 1, 'foo')", null)); 498 Assert.assertEquals(2, DatabaseUtils.longForQuery(mDatabase, 499 "SELECT _TOKENIZE('tokens', 11, 'second field', ' ', 1, 'bar')", null)); 500 501 Assert.assertEquals(3, DatabaseUtils.longForQuery(mDatabase, 502 "SELECT _TOKENIZE('tokens_no_index', 20, 'some string ok', ' ')", null)); 503 Assert.assertEquals(3, DatabaseUtils.longForQuery(mDatabase, 504 "SELECT _TOKENIZE('tokens_no_index', 21, 'foo bar baz', ' ', 0)", null)); 505 506 // test Chinese 507 String chinese = new String("\u4eac\u4ec5 \u5c3d\u5f84\u60ca"); 508 Assert.assertEquals(2, DatabaseUtils.longForQuery(mDatabase, 509 "SELECT _TOKENIZE('tokens', 12,'" + chinese + "', ' ', 1)", null)); 510 511 String icustr = new String("Fr\u00e9d\u00e9ric Hj\u00f8nnev\u00e5g"); 512 513 Assert.assertEquals(2, DatabaseUtils.longForQuery(mDatabase, 514 "SELECT _TOKENIZE('tokens', 13, '" + icustr + "', ' ', 1)", null)); 515 516 Assert.assertEquals(9, DatabaseUtils.longForQuery(mDatabase, 517 "SELECT count(*) from tokens;", null)); 518 519 String key = DatabaseUtils.getHexCollationKey("Frederic Hjonneva"); 520 Assert.assertEquals(1, DatabaseUtils.longForQuery(mDatabase, 521 "SELECT count(*) from tokens where token GLOB '" + key + "*'", null)); 522 Assert.assertEquals(13, DatabaseUtils.longForQuery(mDatabase, 523 "SELECT source from tokens where token GLOB '" + key + "*'", null)); 524 Assert.assertEquals(0, DatabaseUtils.longForQuery(mDatabase, 525 "SELECT token_index from tokens where token GLOB '" + key + "*'", null)); 526 key = DatabaseUtils.getHexCollationKey("Hjonneva"); 527 Assert.assertEquals(1, DatabaseUtils.longForQuery(mDatabase, 528 "SELECT count(*) from tokens where token GLOB '" + key + "*'", null)); 529 Assert.assertEquals(13, DatabaseUtils.longForQuery(mDatabase, 530 "SELECT source from tokens where token GLOB '" + key + "*'", null)); 531 Assert.assertEquals(1, DatabaseUtils.longForQuery(mDatabase, 532 "SELECT token_index from tokens where token GLOB '" + key + "*'", null)); 533 534 key = DatabaseUtils.getHexCollationKey("some string ok"); 535 Assert.assertEquals(1, DatabaseUtils.longForQuery(mDatabase, 536 "SELECT count(*) from tokens where token GLOB '" + key + "*'", null)); 537 Assert.assertEquals(11, DatabaseUtils.longForQuery(mDatabase, 538 "SELECT source from tokens where token GLOB '" + key + "*'", null)); 539 Assert.assertEquals(0, DatabaseUtils.longForQuery(mDatabase, 540 "SELECT token_index from tokens where token GLOB '" + key + "*'", null)); 541 Assert.assertEquals("foo", DatabaseUtils.stringForQuery(mDatabase, 542 "SELECT tag from tokens where token GLOB '" + key + "*'", null)); 543 key = DatabaseUtils.getHexCollationKey("string"); 544 Assert.assertEquals(1, DatabaseUtils.longForQuery(mDatabase, 545 "SELECT count(*) from tokens where token GLOB '" + key + "*'", null)); 546 Assert.assertEquals(11, DatabaseUtils.longForQuery(mDatabase, 547 "SELECT source from tokens where token GLOB '" + key + "*'", null)); 548 Assert.assertEquals(1, DatabaseUtils.longForQuery(mDatabase, 549 "SELECT token_index from tokens where token GLOB '" + key + "*'", null)); 550 Assert.assertEquals("foo", DatabaseUtils.stringForQuery(mDatabase, 551 "SELECT tag from tokens where token GLOB '" + key + "*'", null)); 552 key = DatabaseUtils.getHexCollationKey("ok"); 553 Assert.assertEquals(1, DatabaseUtils.longForQuery(mDatabase, 554 "SELECT count(*) from tokens where token GLOB '" + key + "*'", null)); 555 Assert.assertEquals(11, DatabaseUtils.longForQuery(mDatabase, 556 "SELECT source from tokens where token GLOB '" + key + "*'", null)); 557 Assert.assertEquals(2, DatabaseUtils.longForQuery(mDatabase, 558 "SELECT token_index from tokens where token GLOB '" + key + "*'", null)); 559 Assert.assertEquals("foo", DatabaseUtils.stringForQuery(mDatabase, 560 "SELECT tag from tokens where token GLOB '" + key + "*'", null)); 561 562 key = DatabaseUtils.getHexCollationKey("second field"); 563 Assert.assertEquals(1, DatabaseUtils.longForQuery(mDatabase, 564 "SELECT count(*) from tokens where token GLOB '" + key + "*'", null)); 565 Assert.assertEquals(11, DatabaseUtils.longForQuery(mDatabase, 566 "SELECT source from tokens where token GLOB '" + key + "*'", null)); 567 Assert.assertEquals(0, DatabaseUtils.longForQuery(mDatabase, 568 "SELECT token_index from tokens where token GLOB '" + key + "*'", null)); 569 Assert.assertEquals("bar", DatabaseUtils.stringForQuery(mDatabase, 570 "SELECT tag from tokens where token GLOB '" + key + "*'", null)); 571 key = DatabaseUtils.getHexCollationKey("field"); 572 Assert.assertEquals(1, DatabaseUtils.longForQuery(mDatabase, 573 "SELECT count(*) from tokens where token GLOB '" + key + "*'", null)); 574 Assert.assertEquals(11, DatabaseUtils.longForQuery(mDatabase, 575 "SELECT source from tokens where token GLOB '" + key + "*'", null)); 576 Assert.assertEquals(1, DatabaseUtils.longForQuery(mDatabase, 577 "SELECT token_index from tokens where token GLOB '" + key + "*'", null)); 578 Assert.assertEquals("bar", DatabaseUtils.stringForQuery(mDatabase, 579 "SELECT tag from tokens where token GLOB '" + key + "*'", null)); 580 581 key = DatabaseUtils.getHexCollationKey(chinese); 582 String[] a = new String[1]; 583 a[0] = key; 584 Assert.assertEquals(1, DatabaseUtils.longForQuery(mDatabase, 585 "SELECT count(*) from tokens where token= ?", a)); 586 Assert.assertEquals(12, DatabaseUtils.longForQuery(mDatabase, 587 "SELECT source from tokens where token= ?", a)); 588 Assert.assertEquals(0, DatabaseUtils.longForQuery(mDatabase, 589 "SELECT token_index from tokens where token= ?", a)); 590 a[0] += "*"; 591 Assert.assertEquals(1, DatabaseUtils.longForQuery(mDatabase, 592 "SELECT count(*) from tokens where token GLOB ?", a)); 593 Assert.assertEquals(12, DatabaseUtils.longForQuery(mDatabase, 594 "SELECT source from tokens where token GLOB ?", a)); 595 Assert.assertEquals(0, DatabaseUtils.longForQuery(mDatabase, 596 "SELECT token_index from tokens where token GLOB ?", a)); 597 598 Assert.assertEquals(1, DatabaseUtils.longForQuery(mDatabase, 599 "SELECT count(*) from tokens where token= '" + key + "'", null)); 600 Assert.assertEquals(12, DatabaseUtils.longForQuery(mDatabase, 601 "SELECT source from tokens where token= '" + key + "'", null)); 602 Assert.assertEquals(0, DatabaseUtils.longForQuery(mDatabase, 603 "SELECT token_index from tokens where token= '" + key + "'", null)); 604 605 Assert.assertEquals(1, DatabaseUtils.longForQuery(mDatabase, 606 "SELECT count(*) from tokens where token GLOB '" + key + "*'", null)); 607 Assert.assertEquals(12, DatabaseUtils.longForQuery(mDatabase, 608 "SELECT source from tokens where token GLOB '" + key + "*'", null)); 609 Assert.assertEquals(0, DatabaseUtils.longForQuery(mDatabase, 610 "SELECT token_index from tokens where token GLOB '" + key + "*'", null)); 611 612 key = DatabaseUtils.getHexCollationKey("\u4eac\u4ec5"); 613 Assert.assertEquals(1, DatabaseUtils.longForQuery(mDatabase, 614 "SELECT count(*) from tokens where token GLOB '" + key + "*'", null)); 615 Assert.assertEquals(12, DatabaseUtils.longForQuery(mDatabase, 616 "SELECT source from tokens where token GLOB '" + key + "*'", null)); 617 Assert.assertEquals(0, DatabaseUtils.longForQuery(mDatabase, 618 "SELECT token_index from tokens where token GLOB '" + key + "*'", null)); 619 620 key = DatabaseUtils.getHexCollationKey("\u5c3d\u5f84\u60ca"); 621 Log.d("DatabaseGeneralTest", "key = " + key); 622 Assert.assertEquals(1, DatabaseUtils.longForQuery(mDatabase, 623 "SELECT count(*) from tokens where token GLOB '" + key + "*'", null)); 624 Assert.assertEquals(12, DatabaseUtils.longForQuery(mDatabase, 625 "SELECT source from tokens where token GLOB '" + key + "*'", null)); 626 Assert.assertEquals(1, DatabaseUtils.longForQuery(mDatabase, 627 "SELECT token_index from tokens where token GLOB '" + key + "*'", null)); 628 629 Assert.assertEquals(0, DatabaseUtils.longForQuery(mDatabase, 630 "SELECT count(*) from tokens where token GLOB 'ab*'", null)); 631 632 key = DatabaseUtils.getHexCollationKey("some string ok"); 633 Assert.assertEquals(1, DatabaseUtils.longForQuery(mDatabase, 634 "SELECT count(*) from tokens_no_index where token GLOB '" + key + "*'", null)); 635 Assert.assertEquals(20, DatabaseUtils.longForQuery(mDatabase, 636 "SELECT source from tokens_no_index where token GLOB '" + key + "*'", null)); 637 638 key = DatabaseUtils.getHexCollationKey("bar"); 639 Assert.assertEquals(1, DatabaseUtils.longForQuery(mDatabase, 640 "SELECT count(*) from tokens_no_index where token GLOB '" + key + "*'", null)); 641 Assert.assertEquals(21, DatabaseUtils.longForQuery(mDatabase, 642 "SELECT source from tokens_no_index where token GLOB '" + key + "*'", null)); 643 } 644 645 @MediumTest 646 public void testTransactions() throws Exception { 647 mDatabase.execSQL("CREATE TABLE test (num INTEGER);"); 648 mDatabase.execSQL("INSERT INTO test (num) VALUES (0)"); 649 650 // Make sure that things work outside an explicit transaction. 651 setNum(1); 652 checkNum(1); 653 654 // Test a single-level transaction. 655 setNum(0); 656 mDatabase.beginTransaction(); 657 setNum(1); 658 mDatabase.setTransactionSuccessful(); 659 mDatabase.endTransaction(); 660 checkNum(1); 661 Assert.assertFalse(mDatabase.isDbLockedByCurrentThread()); 662 663 // Test a rolled-back transaction. 664 setNum(0); 665 mDatabase.beginTransaction(); 666 setNum(1); 667 mDatabase.endTransaction(); 668 checkNum(0); 669 Assert.assertFalse(mDatabase.isDbLockedByCurrentThread()); 670 671 // We should get an error if we end a non-existent transaction. 672 assertThrowsIllegalState(new Runnable() { public void run() { 673 mDatabase.endTransaction(); 674 }}); 675 676 // We should get an error if a set a non-existent transaction as clean. 677 assertThrowsIllegalState(new Runnable() { public void run() { 678 mDatabase.setTransactionSuccessful(); 679 }}); 680 681 mDatabase.beginTransaction(); 682 mDatabase.setTransactionSuccessful(); 683 // We should get an error if we mark a transaction as clean twice. 684 assertThrowsIllegalState(new Runnable() { public void run() { 685 mDatabase.setTransactionSuccessful(); 686 }}); 687 // We should get an error if we begin a transaction after marking the parent as clean. 688 assertThrowsIllegalState(new Runnable() { public void run() { 689 mDatabase.beginTransaction(); 690 }}); 691 mDatabase.endTransaction(); 692 Assert.assertFalse(mDatabase.isDbLockedByCurrentThread()); 693 694 // Test a two-level transaction. 695 setNum(0); 696 mDatabase.beginTransaction(); 697 mDatabase.beginTransaction(); 698 setNum(1); 699 mDatabase.setTransactionSuccessful(); 700 mDatabase.endTransaction(); 701 mDatabase.setTransactionSuccessful(); 702 mDatabase.endTransaction(); 703 checkNum(1); 704 Assert.assertFalse(mDatabase.isDbLockedByCurrentThread()); 705 706 // Test rolling back an inner transaction. 707 setNum(0); 708 mDatabase.beginTransaction(); 709 mDatabase.beginTransaction(); 710 setNum(1); 711 mDatabase.endTransaction(); 712 mDatabase.setTransactionSuccessful(); 713 mDatabase.endTransaction(); 714 checkNum(0); 715 Assert.assertFalse(mDatabase.isDbLockedByCurrentThread()); 716 717 // Test rolling back an outer transaction. 718 setNum(0); 719 mDatabase.beginTransaction(); 720 mDatabase.beginTransaction(); 721 setNum(1); 722 mDatabase.setTransactionSuccessful(); 723 mDatabase.endTransaction(); 724 mDatabase.endTransaction(); 725 checkNum(0); 726 Assert.assertFalse(mDatabase.isDbLockedByCurrentThread()); 727 } 728 729 private void setNum(int num) { 730 mDatabase.execSQL("UPDATE test SET num = " + num); 731 } 732 733 private void checkNum(int num) { 734 Assert.assertEquals( 735 num, DatabaseUtils.longForQuery(mDatabase, "SELECT num FROM test", null)); 736 } 737 738 private void assertThrowsIllegalState(Runnable r) { 739 boolean ok = false; 740 try { 741 r.run(); 742 } catch (IllegalStateException e) { 743 ok = true; 744 } 745 Assert.assertTrue(ok); 746 } 747 748 // Disable these until we can explicitly mark them as stress tests 749 public void xxtestMem1() throws Exception { 750 populateDefaultTable(); 751 752 for (int i = 0; i < 50000; i++) { 753 Cursor cursor = mDatabase.query("test", null, null, null, null, null, null); 754 cursor.moveToFirst(); 755 cursor.close(); 756// Log.i("~~~~", "Finished round " + i); 757 } 758 } 759 760 // Disable these until we can explicitly mark them as stress tests 761 public void xxtestMem2() throws Exception { 762 populateDefaultTable(); 763 764 for (int i = 0; i < 50000; i++) { 765 Cursor cursor = mDatabase.query("test", null, null, null, null, null, null); 766 cursor.close(); 767// Log.i("~~~~", "Finished round " + i); 768 } 769 } 770 771 // Disable these until we can explicitly mark them as stress tests 772 public void xxtestMem3() throws Exception { 773 populateDefaultTable(); 774 775 for (int i = 0; i < 50000; i++) { 776 Cursor cursor = mDatabase.query("test", null, null, null, null, null, null); 777 cursor.deactivate(); 778// Log.i("~~~~", "Finished round " + i); 779 } 780 } 781 782 @MediumTest 783 public void testContentValues() throws Exception { 784 ContentValues values = new ContentValues(); 785 values.put("string", "value"); 786 assertEquals("value", values.getAsString("string")); 787 byte[] bytes = new byte[42]; 788 Arrays.fill(bytes, (byte) 0x28); 789 values.put("byteArray", bytes); 790 assertTrue(Arrays.equals(bytes, values.getAsByteArray("byteArray"))); 791 792 // Write the ContentValues to a Parcel and then read them out 793 Parcel p = Parcel.obtain(); 794 values.writeToParcel(p, 0); 795 p.setDataPosition(0); 796 values = ContentValues.CREATOR.createFromParcel(p); 797 798 // Read the values out again and make sure they're the same 799 assertTrue(Arrays.equals(bytes, values.getAsByteArray("byteArray"))); 800 assertEquals("value", values.get("string")); 801 } 802 803 @MediumTest 804 public void testTableInfoPragma() throws Exception { 805 mDatabase.execSQL("CREATE TABLE pragma_test (" + 806 "i INTEGER DEFAULT 1234, " + 807 "j INTEGER, " + 808 "s TEXT DEFAULT 'hello', " + 809 "t TEXT, " + 810 "'select' TEXT DEFAULT \"hello\")"); 811 try { 812 Cursor cur = mDatabase.rawQuery("PRAGMA table_info(pragma_test)", null); 813 Assert.assertEquals(5, cur.getCount()); 814 815 Assert.assertTrue(cur.moveToNext()); 816 Assert.assertEquals("i", 817 cur.getString(TABLE_INFO_PRAGMA_COLUMNNAME_INDEX)); 818 Assert.assertEquals("1234", 819 cur.getString(TABLE_INFO_PRAGMA_DEFAULT_INDEX)); 820 821 Assert.assertTrue(cur.moveToNext()); 822 Assert.assertEquals("j", 823 cur.getString(TABLE_INFO_PRAGMA_COLUMNNAME_INDEX)); 824 Assert.assertNull(cur.getString(TABLE_INFO_PRAGMA_DEFAULT_INDEX)); 825 826 Assert.assertTrue(cur.moveToNext()); 827 Assert.assertEquals("s", 828 cur.getString(TABLE_INFO_PRAGMA_COLUMNNAME_INDEX)); 829 Assert.assertEquals("'hello'", 830 cur.getString(TABLE_INFO_PRAGMA_DEFAULT_INDEX)); 831 832 Assert.assertTrue(cur.moveToNext()); 833 Assert.assertEquals("t", 834 cur.getString(TABLE_INFO_PRAGMA_COLUMNNAME_INDEX)); 835 Assert.assertNull(cur.getString(TABLE_INFO_PRAGMA_DEFAULT_INDEX)); 836 837 Assert.assertTrue(cur.moveToNext()); 838 Assert.assertEquals("select", 839 cur.getString(TABLE_INFO_PRAGMA_COLUMNNAME_INDEX)); 840 Assert.assertEquals("\"hello\"", 841 cur.getString(TABLE_INFO_PRAGMA_DEFAULT_INDEX)); 842 843 cur.close(); 844 } catch (Throwable t) { 845 throw new RuntimeException( 846 "If you see this test fail, it's likely that something about " + 847 "sqlite's PRAGMA table_info(...) command has changed.", t); 848 } 849 } 850 851 @MediumTest 852 public void testInsertHelper() throws Exception { 853 Cursor cur; 854 ContentValues cv; 855 long row; 856 857 mDatabase.execSQL("CREATE TABLE insert_test (" + 858 "_id INTEGER PRIMARY KEY, " + 859 "s TEXT NOT NULL UNIQUE, " + 860 "t TEXT NOT NULL DEFAULT 'hello world', " + 861 "i INTEGER, " + 862 "j INTEGER NOT NULL DEFAULT 1234, " + 863 "'select' TEXT)"); 864 865 DatabaseUtils.InsertHelper ih = 866 new DatabaseUtils.InsertHelper(mDatabase, "insert_test"); 867 868 cv = new ContentValues(); 869 cv.put("s", "one"); 870 row = ih.insert(cv); 871 cur = mDatabase.rawQuery("SELECT * FROM insert_test WHERE _id == " + row, null); 872 Assert.assertTrue(cur.moveToFirst()); 873 Assert.assertEquals("one", cur.getString(1)); 874 Assert.assertEquals("hello world", cur.getString(2)); 875 Assert.assertNull(cur.getString(3)); 876 Assert.assertEquals(1234, cur.getLong(4)); 877 Assert.assertNull(cur.getString(5)); 878 cur.close(); 879 880 cv = new ContentValues(); 881 cv.put("s", "two"); 882 cv.put("t", "goodbye world"); 883 row = ih.insert(cv); 884 cur = mDatabase.rawQuery("SELECT * FROM insert_test WHERE _id == " + row, null); 885 Assert.assertTrue(cur.moveToFirst()); 886 Assert.assertEquals("two", cur.getString(1)); 887 Assert.assertEquals("goodbye world", cur.getString(2)); 888 Assert.assertNull(cur.getString(3)); 889 Assert.assertEquals(1234, cur.getLong(4)); 890 Assert.assertNull(cur.getString(5)); 891 cur.close(); 892 893 cv = new ContentValues(); 894 cv.put("t", "goodbye world"); 895 row = ih.insert(cv); 896 Assert.assertEquals(-1, row); 897 898 cv = new ContentValues(); 899 cv.put("s", "three"); 900 cv.put("i", 2345); 901 cv.put("j", 3456); 902 cv.put("select", "tricky"); 903 row = ih.insert(cv); 904 cur = mDatabase.rawQuery("SELECT * FROM insert_test WHERE _id == " + row, null); 905 Assert.assertTrue(cur.moveToFirst()); 906 Assert.assertEquals("three", cur.getString(1)); 907 Assert.assertEquals("hello world", cur.getString(2)); 908 Assert.assertEquals(2345, cur.getLong(3)); 909 Assert.assertEquals(3456, cur.getLong(4)); 910 Assert.assertEquals("tricky", cur.getString(5)); 911 cur.close(); 912 913 cv = new ContentValues(); 914 cv.put("s", "three"); 915 cv.put("i", 6789); 916 row = ih.insert(cv); 917 Assert.assertEquals(-1, row); 918 row = ih.replace(cv); 919 cur = mDatabase.rawQuery("SELECT * FROM insert_test WHERE _id == " + row, null); 920 Assert.assertTrue(cur.moveToFirst()); 921 Assert.assertEquals("three", cur.getString(1)); 922 Assert.assertEquals("hello world", cur.getString(2)); 923 Assert.assertEquals(6789, cur.getLong(3)); 924 cur.close(); 925 926 ih.close(); 927 } 928 929 @MediumTest 930 public void testSemicolonsInStatements() throws Exception { 931 mDatabase.execSQL("CREATE TABLE pragma_test (" + 932 "i INTEGER DEFAULT 1234, " + 933 "j INTEGER, " + 934 "s TEXT DEFAULT 'hello', " + 935 "t TEXT, " + 936 "'select' TEXT DEFAULT \"hello\")"); 937 try { 938 // ending the sql statement with semicolons shouldn't be a problem. 939 Cursor cur = mDatabase.rawQuery("PRAGMA database_list;", null); 940 cur.close(); 941 // two semicolons in the statement shouldn't be a problem. 942 cur = mDatabase.rawQuery("PRAGMA database_list;;", null); 943 cur.close(); 944 } catch (Throwable t) { 945 fail("unexpected, of course"); 946 } 947 } 948 949 @MediumTest 950 public void testUnionsWithBindArgs() { 951 /* make sure unions with bindargs work http://b/issue?id=1061291 */ 952 mDatabase.execSQL("CREATE TABLE A (i int);"); 953 mDatabase.execSQL("create table B (k int);"); 954 mDatabase.execSQL("create table C (n int);"); 955 mDatabase.execSQL("insert into A values(1);"); 956 mDatabase.execSQL("insert into A values(2);"); 957 mDatabase.execSQL("insert into A values(3);"); 958 mDatabase.execSQL("insert into B values(201);"); 959 mDatabase.execSQL("insert into B values(202);"); 960 mDatabase.execSQL("insert into B values(203);"); 961 mDatabase.execSQL("insert into C values(901);"); 962 mDatabase.execSQL("insert into C values(902);"); 963 String s = "select i from A where i > 2 " + 964 "UNION select k from B where k > 201 " + 965 "UNION select n from C where n !=900;"; 966 Cursor c = mDatabase.rawQuery(s, null); 967 int n = c.getCount(); 968 c.close(); 969 String s1 = "select i from A where i > ? " + 970 "UNION select k from B where k > ? " + 971 "UNION select n from C where n != ?;"; 972 Cursor c1 = mDatabase.rawQuery(s1, new String[]{"2", "201", "900"}); 973 assertEquals(n, c1.getCount()); 974 c1.close(); 975 } 976 977 /** 978 * This test is available only when the platform has a locale with the language "ja". 979 * It finishes without failure when it is not available. 980 */ 981 @MediumTest 982 public void testCollateLocalizedForJapanese() throws Exception { 983 final String testName = "DatabaseGeneralTest#testCollateLocalizedForJapanese()"; 984 final Locale[] localeArray = Locale.getAvailableLocales(); 985 final String japanese = Locale.JAPANESE.getLanguage(); 986 final String english = Locale.ENGLISH.getLanguage(); 987 Locale japaneseLocale = null; 988 Locale englishLocale = null; 989 for (Locale locale : localeArray) { 990 if (locale != null) { 991 final String language = locale.getLanguage(); 992 if (language == null) { 993 continue; 994 } else if (language.equals(japanese)) { 995 japaneseLocale = locale; 996 } else if (language.equals(english)) { 997 englishLocale = locale; 998 } 999 } 1000 1001 if (japaneseLocale != null && englishLocale != null) { 1002 break; 1003 } 1004 } 1005 1006 if (japaneseLocale == null || englishLocale == null) { 1007 Log.d(TAG, testName + "n is silently skipped since " + 1008 (englishLocale == null ? 1009 (japaneseLocale == null ? 1010 "Both English and Japanese locales do not exist." : 1011 "English locale does not exist.") : 1012 (japaneseLocale == null ? 1013 "Japanese locale does not exist." : 1014 "...why?"))); 1015 return; 1016 } 1017 1018 Locale originalLocale = Locale.getDefault(); 1019 try { 1020 1021 final String dbName = "collate_localized_test"; 1022 mDatabase.execSQL("CREATE TABLE " + dbName + " (" + 1023 "_id INTEGER PRIMARY KEY, " + 1024 "s TEXT COLLATE LOCALIZED) "); 1025 DatabaseUtils.InsertHelper ih = 1026 new DatabaseUtils.InsertHelper(mDatabase, dbName); 1027 ContentValues cv = new ContentValues(); 1028 1029 cv = new ContentValues(); // 1030 cv.put("s", "\uFF75\uFF77\uFF85\uFF9C"); // O-ki-na-wa in half-width Katakana 1031 ih.insert(cv); 1032 1033 cv = new ContentValues(); // 1034 cv.put("s", "\u306B\u307B\u3093"); // Ni-ho-n in Hiragana 1035 ih.insert(cv); 1036 1037 cv = new ContentValues(); // 1038 cv.put("s", "\u30A2\u30E1\u30EA\u30AB"); // A-me-ri-ca in hull-width Katakana 1039 ih.insert(cv); 1040 1041 // Assume setLocale() does REINDEX and an English locale does not consider 1042 // Japanese-specific LOCALIZED order. 1043 Locale.setDefault(englishLocale); 1044 Locale.setDefault(japaneseLocale); 1045 1046 Cursor cur = mDatabase.rawQuery( 1047 "SELECT * FROM " + dbName + " ORDER BY s", null); 1048 assertTrue(cur.moveToFirst()); 1049 assertEquals("\u30A2\u30E1\u30EA\u30AB", cur.getString(1)); 1050 assertTrue(cur.moveToNext()); 1051 assertEquals("\uFF75\uFF77\uFF85\uFF9C", cur.getString(1)); 1052 assertTrue(cur.moveToNext()); 1053 assertEquals("\u306B\u307B\u3093", cur.getString(1)); 1054 } finally { 1055 if (originalLocale != null) { 1056 try { 1057 Locale.setDefault(originalLocale); 1058 } catch (Exception e) { 1059 } 1060 } 1061 } 1062 } 1063 1064 @SmallTest 1065 public void testSetMaxCahesize() { 1066 mDatabase.execSQL("CREATE TABLE test (i int, j int);"); 1067 mDatabase.execSQL("insert into test values(1,1);"); 1068 // set cache size 1069 int N = SQLiteDatabase.MAX_SQL_CACHE_SIZE; 1070 mDatabase.setMaxSqlCacheSize(N); 1071 1072 // try reduce cachesize 1073 try { 1074 mDatabase.setMaxSqlCacheSize(1); 1075 } catch (IllegalStateException e) { 1076 assertTrue(e.getMessage().contains("cannot set cacheSize to a value less than")); 1077 } 1078 } 1079 1080 @LargeTest 1081 public void testDefaultDatabaseErrorHandler() { 1082 DefaultDatabaseErrorHandler errorHandler = new DefaultDatabaseErrorHandler(); 1083 1084 // close the database. and call corruption handler. 1085 // it should delete the database file. 1086 File dbfile = new File(mDatabase.getPath()); 1087 mDatabase.close(); 1088 assertFalse(mDatabase.isOpen()); 1089 assertTrue(dbfile.exists()); 1090 try { 1091 errorHandler.onCorruption(mDatabase); 1092 assertFalse(dbfile.exists()); 1093 } catch (Exception e) { 1094 fail("unexpected"); 1095 } 1096 1097 // create an in-memory database. and corruption handler shouldn't try to delete it 1098 SQLiteDatabase memoryDb = SQLiteDatabase.openOrCreateDatabase(":memory:", null); 1099 assertNotNull(memoryDb); 1100 memoryDb.close(); 1101 assertFalse(memoryDb.isOpen()); 1102 try { 1103 errorHandler.onCorruption(memoryDb); 1104 } catch (Exception e) { 1105 fail("unexpected"); 1106 } 1107 1108 // create a database, keep it open, call corruption handler. database file should be deleted 1109 SQLiteDatabase dbObj = SQLiteDatabase.openOrCreateDatabase(mDatabase.getPath(), null); 1110 assertTrue(dbfile.exists()); 1111 assertNotNull(dbObj); 1112 assertTrue(dbObj.isOpen()); 1113 try { 1114 errorHandler.onCorruption(dbObj); 1115 assertFalse(dbfile.exists()); 1116 } catch (Exception e) { 1117 fail("unexpected"); 1118 } 1119 1120 // create a database, attach 2 more databases to it 1121 // attached database # 1: ":memory:" 1122 // attached database # 2: mDatabase.getPath() + "1"; 1123 // call corruption handler. database files including the one for attached database # 2 1124 // should be deleted 1125 String attachedDb1File = mDatabase.getPath() + "1"; 1126 dbObj = SQLiteDatabase.openOrCreateDatabase(mDatabase.getPath(), null); 1127 dbObj.execSQL("ATTACH DATABASE ':memory:' as memoryDb"); 1128 dbObj.execSQL("ATTACH DATABASE '" + attachedDb1File + "' as attachedDb1"); 1129 assertTrue(dbfile.exists()); 1130 assertTrue(new File(attachedDb1File).exists()); 1131 assertNotNull(dbObj); 1132 assertTrue(dbObj.isOpen()); 1133 ArrayList<Pair<String, String>> attachedDbs = dbObj.getAttachedDbs(); 1134 try { 1135 errorHandler.onCorruption(dbObj); 1136 assertFalse(dbfile.exists()); 1137 assertFalse(new File(attachedDb1File).exists()); 1138 } catch (Exception e) { 1139 fail("unexpected"); 1140 } 1141 1142 // same as above, except this is a bit of stress testing. attach 5 database files 1143 // and make sure they are all removed. 1144 int N = 5; 1145 ArrayList<String> attachedDbFiles = new ArrayList<String>(N); 1146 for (int i = 0; i < N; i++) { 1147 attachedDbFiles.add(mDatabase.getPath() + i); 1148 } 1149 dbObj = SQLiteDatabase.openOrCreateDatabase(mDatabase.getPath(), null); 1150 dbObj.execSQL("ATTACH DATABASE ':memory:' as memoryDb"); 1151 for (int i = 0; i < N; i++) { 1152 dbObj.execSQL("ATTACH DATABASE '" + attachedDbFiles.get(i) + "' as attachedDb" + i); 1153 } 1154 assertTrue(dbfile.exists()); 1155 for (int i = 0; i < N; i++) { 1156 assertTrue(new File(attachedDbFiles.get(i)).exists()); 1157 } 1158 assertNotNull(dbObj); 1159 assertTrue(dbObj.isOpen()); 1160 attachedDbs = dbObj.getAttachedDbs(); 1161 try { 1162 errorHandler.onCorruption(dbObj); 1163 assertFalse(dbfile.exists()); 1164 for (int i = 0; i < N; i++) { 1165 assertFalse(new File(attachedDbFiles.get(i)).exists()); 1166 } 1167 } catch (Exception e) { 1168 fail("unexpected"); 1169 } 1170 } 1171} 1172