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