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