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