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