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