SQLite Android Bindings
Check-in [d03685fdba]
Not logged in

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Add modified version of DatabaseGeneralTest.java from the sqlite-android project.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:d03685fdba7530359f39c9921901d1989a3dad25
User & Date: dan 2017-11-23 19:13:13
Context
2017-11-27
14:14
Remove class org.sqlite.database.ExtraUtils. No longer required now that org.sqlite.database.DatabaseUtils works. check-in: 2332e2eecd user: dan tags: trunk
2017-11-23
19:13
Add modified version of DatabaseGeneralTest.java from the sqlite-android project. check-in: d03685fdba user: dan tags: trunk
16:21
Update the imported test cases so that they pass. check-in: f0e9c4d2ad user: dan tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Added sqlite3/src/androidTest/java/org/sqlite/database/sqlite_android/DatabaseGeneralTest.java.

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