11a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen/*
21a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen * Copyright (C) 2007 The Android Open Source Project
31a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen *
41a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen * Licensed under the Apache License, Version 2.0 (the "License");
51a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen * you may not use this file except in compliance with the License.
61a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen * You may obtain a copy of the License at
71a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen *
81a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen *      http://www.apache.org/licenses/LICENSE-2.0
91a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen *
101a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen * Unless required by applicable law or agreed to in writing, software
111a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen * distributed under the License is distributed on an "AS IS" BASIS,
121a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen * See the License for the specific language governing permissions and
141a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen * limitations under the License.
151a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen */
161a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen
171a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyenpackage android.database;
181a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen
191a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyenimport android.content.ContentValues;
201a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyenimport android.content.Context;
211a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyenimport android.database.Cursor;
221a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyenimport android.database.CursorIndexOutOfBoundsException;
231a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyenimport android.database.DataSetObserver;
241a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyenimport android.database.DatabaseUtils;
251a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyenimport android.database.sqlite.SQLiteCursor;
261a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyenimport android.database.sqlite.SQLiteCursorDriver;
271a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyenimport android.database.sqlite.SQLiteDatabase;
281a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyenimport android.database.sqlite.SQLiteQuery;
291a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyenimport android.os.Looper;
301a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyenimport android.test.AndroidTestCase;
311a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyenimport android.test.PerformanceTestCase;
321a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyenimport android.test.suitebuilder.annotation.LargeTest;
331a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyenimport android.test.suitebuilder.annotation.MediumTest;
341a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyenimport android.util.Log;
351a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen
361a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyenimport java.io.File;
376141e13f6e84846ae531358a8bcbf6d2102b1bd4Vasu Noriimport java.util.ArrayList;
381a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyenimport java.util.Arrays;
391a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyenimport java.util.Random;
401a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen
411a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyenpublic class DatabaseCursorTest extends AndroidTestCase implements PerformanceTestCase {
421a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen
431a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen    private static final String sString1 = "this is a test";
441a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen    private static final String sString2 = "and yet another test";
451a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen    private static final String sString3 = "this string is a little longer, but still a test";
461a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen
471a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen    private static final int CURRENT_DATABASE_VERSION = 42;
481a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen    private SQLiteDatabase mDatabase;
491a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen    private File mDatabaseFile;
501a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen
511a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen    @Override
521a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen    protected void setUp() throws Exception {
531a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        super.setUp();
548a985d24ce9a38f40ed88fecbdcd0e75e3a68f44John Spurlock        File dbDir = getContext().getDir("tests", Context.MODE_PRIVATE);
558a985d24ce9a38f40ed88fecbdcd0e75e3a68f44John Spurlock        mDatabaseFile = new File(dbDir, "database_test.db");
561a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen
571a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        if (mDatabaseFile.exists()) {
581a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen            mDatabaseFile.delete();
591a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        }
601a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        mDatabase = SQLiteDatabase.openOrCreateDatabase(mDatabaseFile.getPath(), null);
611a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        assertNotNull(mDatabase);
621a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        mDatabase.setVersion(CURRENT_DATABASE_VERSION);
631a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen    }
641a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen
651a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen    @Override
661a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen    protected void tearDown() throws Exception {
671a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        mDatabase.close();
681a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        mDatabaseFile.delete();
691a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        super.tearDown();
701a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen    }
711a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen
721a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen    public boolean isPerformanceOnly() {
731a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        return false;
741a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen    }
751a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen
761a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen    // These test can only be run once.
771a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen    public int startPerformance(Intermediates intermediates) {
781a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        return 1;
791a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen    }
801a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen
811a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen    private void populateDefaultTable() {
821a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        mDatabase.execSQL("CREATE TABLE test (_id INTEGER PRIMARY KEY, data TEXT);");
831a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen
841a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        mDatabase.execSQL("INSERT INTO test (data) VALUES ('" + sString1 + "');");
851a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        mDatabase.execSQL("INSERT INTO test (data) VALUES ('" + sString2 + "');");
861a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        mDatabase.execSQL("INSERT INTO test (data) VALUES ('" + sString3 + "');");
871a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen    }
881a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen
891a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen    @MediumTest
901a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen    public void testBlob() throws Exception {
911a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        // create table
921a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        mDatabase.execSQL(
931a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen            "CREATE TABLE test (_id INTEGER PRIMARY KEY, s TEXT, d REAL, l INTEGER, b BLOB);");
941a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        // insert blob
951a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        Object[] args = new Object[4];
961a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen
971a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        byte[] blob = new byte[1000];
981a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        byte value = 99;
991a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        Arrays.fill(blob, value);
1001a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        args[3] = blob;
1011a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen
1021a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        String s = new String("text");
1031a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        args[0] = s;
1041a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        Double d = 99.9;
1051a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        args[1] = d;
1061a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        Long l = (long)1000;
1071a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        args[2] = l;
1081a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen
1091a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        String sql = "INSERT INTO test (s, d, l, b) VALUES (?,?,?,?)";
1101a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        mDatabase.execSQL(sql, args);
1111a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        // use cursor to access blob
1121a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        Cursor c = mDatabase.query("test", null, null, null, null, null, null);
1131a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        c.moveToNext();
1141a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        ContentValues cv = new ContentValues();
1151a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        DatabaseUtils.cursorRowToContentValues(c, cv);
1161a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen
1171a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        int bCol = c.getColumnIndexOrThrow("b");
1181a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        int sCol = c.getColumnIndexOrThrow("s");
1191a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        int dCol = c.getColumnIndexOrThrow("d");
1201a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        int lCol = c.getColumnIndexOrThrow("l");
1211a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        byte[] cBlob =  c.getBlob(bCol);
1221a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        assertTrue(Arrays.equals(blob, cBlob));
1231a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        assertEquals(s, c.getString(sCol));
1241a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        assertEquals((double)d, c.getDouble(dCol));
1257cd51efcbd2d083bf577696591ef1769034f7e2fJeff Hamilton        assertEquals((long)l, c.getLong(lCol));
1261a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen    }
1271a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen
1281a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen    @MediumTest
1291a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen    public void testRealColumns() throws Exception {
1301a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        mDatabase.execSQL("CREATE TABLE test (_id INTEGER PRIMARY KEY, data REAL);");
1311a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        ContentValues values = new ContentValues();
1321a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        values.put("data", 42.11);
1331a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        long id = mDatabase.insert("test", "data", values);
1341a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        assertTrue(id > 0);
1351a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        Cursor c = mDatabase.rawQuery("SELECT data FROM test", null);
1361a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        assertNotNull(c);
1371a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        assertTrue(c.moveToFirst());
1381a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        assertEquals(42.11, c.getDouble(0));
1391a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        c.close();
1401a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen    }
1411a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen
1421a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen    @MediumTest
1431a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen    public void testCursor1() throws Exception {
1441a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        populateDefaultTable();
1451a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen
1461a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        Cursor c = mDatabase.query("test", null, null, null, null, null, null);
1471a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen
1481a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        int dataColumn = c.getColumnIndexOrThrow("data");
1491a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen
1501a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        // The cursor should ignore text before the last period when looking for a column. (This
1511a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        // is a temporary hack in all implementations of getColumnIndex.)
1521a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        int dataColumn2 = c.getColumnIndexOrThrow("junk.data");
1531a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        assertEquals(dataColumn, dataColumn2);
1541a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen
1551a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        assertSame(3, c.getCount());
1561a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen
1571a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        assertTrue(c.isBeforeFirst());
1581a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen
1591a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        try {
1601a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen            c.getInt(0);
1611a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen            fail("CursorIndexOutOfBoundsException expected");
1621a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        } catch (CursorIndexOutOfBoundsException ex) {
1631a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen            // expected
1641a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        }
1651a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen
1661a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        c.moveToNext();
1671a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        assertEquals(1, c.getInt(0));
1681a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen
1691a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        String s = c.getString(dataColumn);
1701a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        assertEquals(sString1, s);
1711a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen
1721a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        c.moveToNext();
1731a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        s = c.getString(dataColumn);
1741a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        assertEquals(sString2, s);
1751a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen
1761a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        c.moveToNext();
1771a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        s = c.getString(dataColumn);
1781a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        assertEquals(sString3, s);
1791a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen
1801a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        c.moveToPosition(-1);
1811a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        c.moveToNext();
1821a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        s = c.getString(dataColumn);
1831a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        assertEquals(sString1, s);
1841a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen
1851a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        c.moveToPosition(2);
1861a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        s = c.getString(dataColumn);
1871a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        assertEquals(sString3, s);
1881a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen
1891a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        int i;
1901a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen
1911a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        for (c.moveToFirst(), i = 0; !c.isAfterLast(); c.moveToNext(), i++) {
1921a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen            c.getInt(0);
1931a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        }
1941a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen
1951a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        assertEquals(3, i);
1961a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen
1971a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        try {
1981a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen            c.getInt(0);
1991a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen            fail("CursorIndexOutOfBoundsException expected");
2001a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        } catch (CursorIndexOutOfBoundsException ex) {
2011a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen            // expected
2021a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        }
2031a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        c.close();
2041a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen    }
2051a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen
2061a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen    @MediumTest
2071a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen    public void testCursor2() throws Exception {
2081a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        populateDefaultTable();
2091a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen
2101a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        Cursor c = mDatabase.query("test", null, "_id > 1000", null, null, null, null);
2111a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        assertEquals(0, c.getCount());
2121a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        assertTrue(c.isBeforeFirst());
2131a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen
2141a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        try {
2151a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen            c.getInt(0);
2161a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen            fail("CursorIndexOutOfBoundsException expected");
2171a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        } catch (CursorIndexOutOfBoundsException ex) {
2181a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen            // expected
2191a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        }
2201a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen
2211a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        int i;
2221a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        for (c.moveToFirst(), i = 0; !c.isAfterLast(); c.moveToNext(), i++) {
2231a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen            c.getInt(0);
2241a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        }
2251a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        assertEquals(0, i);
2261a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        try {
2271a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen            c.getInt(0);
2281a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen            fail("CursorIndexOutOfBoundsException expected");
2291a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        } catch (CursorIndexOutOfBoundsException ex) {
2301a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen            // expected
2311a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        }
2321a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        c.close();
2331a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen    }
2341a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen
2351a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen    @MediumTest
2361a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen    public void testLargeField() throws Exception {
2371a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        mDatabase.execSQL("CREATE TABLE test (_id INTEGER PRIMARY KEY, data TEXT);");
2381a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen
2391a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        StringBuilder sql = new StringBuilder(2100);
2401a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        sql.append("INSERT INTO test (data) VALUES ('");
2411a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        Random random = new Random(System.currentTimeMillis());
2421a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        StringBuilder randomString = new StringBuilder(1979);
2431a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        for (int i = 0; i < 1979; i++) {
2441a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen            randomString.append((random.nextInt() & 0xf) % 10);
2451a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        }
2461a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        sql.append(randomString);
2471a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        sql.append("');");
2481a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        mDatabase.execSQL(sql.toString());
2491a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen
2501a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        Cursor c = mDatabase.query("test", null, null, null, null, null, null);
2511a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        assertNotNull(c);
2521a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        assertEquals(1, c.getCount());
2531a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen
2541a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        assertTrue(c.moveToFirst());
2551a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        assertEquals(0, c.getPosition());
2561a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        String largeString = c.getString(c.getColumnIndexOrThrow("data"));
2571a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        assertNotNull(largeString);
2581a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        assertEquals(randomString.toString(), largeString);
2591a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        c.close();
2601a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen    }
2611a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen
2621a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen    class TestObserver extends DataSetObserver {
2631a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        int total;
2641a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        SQLiteCursor c;
2651a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        boolean quit = false;
2661a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        public TestObserver(int total_, SQLiteCursor cursor) {
2671a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen            c = cursor;
2681a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen            total = total_;
2691a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        }
2701a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen
2711a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        @Override
2721a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        public void onChanged() {
2731a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen            int count = c.getCount();
2741a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen            if (total == count) {
2751a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen                int i = 0;
2761a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen                while (c.moveToNext()) {
2771a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen                    assertEquals(i, c.getInt(1));
2781a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen                    i++;
2791a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen                }
2801a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen                assertEquals(count, i);
2811a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen                quit = true;
2821a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen                Looper.myLooper().quit();
2831a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen            }
2841a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        }
2851a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen
2861a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        @Override
2871a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        public void onInvalidated() {
2881a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        }
2891a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen    }
2901a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen
2911a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen    @LargeTest
2921a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen    public void testManyRowsLong() throws Exception {
2931a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        mDatabase.execSQL("CREATE TABLE test (_id INTEGER PRIMARY KEY, data INT);");
2941a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen
2951a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        final int count = 36799;
2965793a17366997060b34d1877380980683bacb965Vasu Nori        mDatabase.execSQL("BEGIN Transaction;");
2971a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        for (int i = 0; i < count; i++) {
2981a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen            mDatabase.execSQL("INSERT INTO test (data) VALUES (" + i + ");");
2991a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        }
3005793a17366997060b34d1877380980683bacb965Vasu Nori        mDatabase.execSQL("COMMIT;");
3011a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen
3021a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        Cursor c = mDatabase.query("test", new String[]{"data"}, null, null, null, null, null);
3031a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        assertNotNull(c);
3041a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen
3051a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        int i = 0;
3061a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        while (c.moveToNext()) {
3071a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen            assertEquals(i, c.getInt(0));
3081a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen            i++;
3091a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        }
3101a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        assertEquals(count, i);
3111a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        assertEquals(count, c.getCount());
3121a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen
3131a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        Log.d("testManyRows", "count " + Integer.toString(i));
3141a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        c.close();
3151a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen    }
3161a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen
3171a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen    @LargeTest
3181a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen    public void testManyRowsTxt() throws Exception {
3191a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        mDatabase.execSQL("CREATE TABLE test (_id INTEGER PRIMARY KEY, data TEXT);");
3201a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        StringBuilder sql = new StringBuilder(2100);
3211a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        sql.append("INSERT INTO test (data) VALUES ('");
3221a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        Random random = new Random(System.currentTimeMillis());
3231a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        StringBuilder randomString = new StringBuilder(1979);
3241a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        for (int i = 0; i < 1979; i++) {
3251a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen            randomString.append((random.nextInt() & 0xf) % 10);
3261a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        }
3271a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        sql.append(randomString);
3281a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        sql.append("');");
3291a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen
3301a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        // if cursor window size changed, adjust this value too
3311a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        final int count = 600; // more than two fillWindow needed
3325793a17366997060b34d1877380980683bacb965Vasu Nori        mDatabase.execSQL("BEGIN Transaction;");
3331a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        for (int i = 0; i < count; i++) {
3341a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen            mDatabase.execSQL(sql.toString());
3351a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        }
3365793a17366997060b34d1877380980683bacb965Vasu Nori        mDatabase.execSQL("COMMIT;");
3371a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen
3381a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        Cursor c = mDatabase.query("test", new String[]{"data"}, null, null, null, null, null);
3391a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        assertNotNull(c);
3401a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen
3411a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        int i = 0;
3421a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        while (c.moveToNext()) {
3431a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen            assertEquals(randomString.toString(), c.getString(0));
3441a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen            i++;
3451a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        }
3461a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        assertEquals(count, i);
3471a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        assertEquals(count, c.getCount());
3481a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        c.close();
3491a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen    }
3501a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen
3511a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen    @LargeTest
3521a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen    public void testManyRowsTxtLong() throws Exception {
3531a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        mDatabase.execSQL("CREATE TABLE test (_id INTEGER PRIMARY KEY, txt TEXT, data INT);");
3541a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen
3551a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        Random random = new Random(System.currentTimeMillis());
3561a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        StringBuilder randomString = new StringBuilder(1979);
3571a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        for (int i = 0; i < 1979; i++) {
3581a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen            randomString.append((random.nextInt() & 0xf) % 10);
3591a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        }
3601a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen
3611a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        // if cursor window size changed, adjust this value too
3621a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        final int count = 600;
3635793a17366997060b34d1877380980683bacb965Vasu Nori        mDatabase.execSQL("BEGIN Transaction;");
3641a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        for (int i = 0; i < count; i++) {
3651a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen            StringBuilder sql = new StringBuilder(2100);
3661a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen            sql.append("INSERT INTO test (txt, data) VALUES ('");
3671a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen            sql.append(randomString);
3681a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen            sql.append("','");
3691a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen            sql.append(i);
3701a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen            sql.append("');");
3711a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen            mDatabase.execSQL(sql.toString());
3721a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        }
3735793a17366997060b34d1877380980683bacb965Vasu Nori        mDatabase.execSQL("COMMIT;");
3741a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen
3751a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        Cursor c = mDatabase.query("test", new String[]{"txt", "data"}, null, null, null, null, null);
3761a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        assertNotNull(c);
3771a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen
3781a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        int i = 0;
3791a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        while (c.moveToNext()) {
3801a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen            assertEquals(randomString.toString(), c.getString(0));
3811a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen            assertEquals(i, c.getInt(1));
3821a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen            i++;
3831a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        }
3841a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        assertEquals(count, i);
3851a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        assertEquals(count, c.getCount());
3861a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        c.close();
3871a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen    }
3881a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen
3891a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen    @MediumTest
3901a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen    public void testRequery() throws Exception {
3911a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        populateDefaultTable();
3921a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen
3931a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        Cursor c = mDatabase.rawQuery("SELECT * FROM test", null);
3941a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        assertNotNull(c);
3951a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        assertEquals(3, c.getCount());
3961a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        c.deactivate();
3971a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        c.requery();
3981a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        assertEquals(3, c.getCount());
3991a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        c.close();
4001a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen    }
4011a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen
4021a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen    @MediumTest
4031a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen    public void testRequeryWithSelection() throws Exception {
4041a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        populateDefaultTable();
4051a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen
4061a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        Cursor c = mDatabase.rawQuery("SELECT data FROM test WHERE data = '" + sString1 + "'",
4071a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen                null);
4081a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        assertNotNull(c);
4091a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        assertEquals(1, c.getCount());
4101a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        assertTrue(c.moveToFirst());
4111a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        assertEquals(sString1, c.getString(0));
4121a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        c.deactivate();
4131a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        c.requery();
4141a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        assertEquals(1, c.getCount());
4151a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        assertTrue(c.moveToFirst());
4161a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        assertEquals(sString1, c.getString(0));
4171a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        c.close();
4181a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen    }
4191a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen
4201a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen    @MediumTest
4211a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen    public void testRequeryWithSelectionArgs() throws Exception {
4221a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        populateDefaultTable();
4231a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen
4241a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        Cursor c = mDatabase.rawQuery("SELECT data FROM test WHERE data = ?",
4251a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen                new String[]{sString1});
4261a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        assertNotNull(c);
4271a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        assertEquals(1, c.getCount());
4281a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        assertTrue(c.moveToFirst());
4291a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        assertEquals(sString1, c.getString(0));
4301a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        c.deactivate();
4311a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        c.requery();
4321a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        assertEquals(1, c.getCount());
4331a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        assertTrue(c.moveToFirst());
4341a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        assertEquals(sString1, c.getString(0));
4351a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        c.close();
4361a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen    }
4371a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen
4381a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen    @MediumTest
4391a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen    public void testRequeryWithAlteredSelectionArgs() throws Exception {
4401a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        /**
4411a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen         * Test the ability of a subclass of SQLiteCursor to change its query arguments.
4421a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen         */
4431a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        populateDefaultTable();
4441a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen
4451a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        SQLiteDatabase.CursorFactory factory = new SQLiteDatabase.CursorFactory() {
4461a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen            public Cursor newCursor(
4471a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen                    SQLiteDatabase db, SQLiteCursorDriver masterQuery, String editTable,
4481a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen                    SQLiteQuery query) {
4491a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen                return new SQLiteCursor(db, masterQuery, editTable, query) {
4501a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen                    @Override
4511a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen                    public boolean requery() {
4521a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen                        setSelectionArguments(new String[]{"2"});
4531a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen                        return super.requery();
4541a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen                    }
4551a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen                };
4561a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen            }
4571a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        };
4581a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        Cursor c = mDatabase.rawQueryWithFactory(
4591a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen                factory, "SELECT data FROM test WHERE _id <= ?", new String[]{"1"},
4601a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen                null);
4611a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        assertNotNull(c);
4621a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        assertEquals(1, c.getCount());
4631a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        assertTrue(c.moveToFirst());
4641a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        assertEquals(sString1, c.getString(0));
4651a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen
4661a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        // Our hacked requery() changes the query arguments in the cursor.
4671a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        c.requery();
4681a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen
4691a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        assertEquals(2, c.getCount());
4701a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        assertTrue(c.moveToFirst());
4711a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        assertEquals(sString1, c.getString(0));
4721a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        assertTrue(c.moveToNext());
4731a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        assertEquals(sString2, c.getString(0));
4741a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen
4751a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        // Test that setting query args on a deactivated cursor also works.
4761a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        c.deactivate();
4771a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen        c.requery();
4781a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen    }
4796141e13f6e84846ae531358a8bcbf6d2102b1bd4Vasu Nori    /**
4806141e13f6e84846ae531358a8bcbf6d2102b1bd4Vasu Nori     * sometimes CursorWindow creation fails due to non-availability of memory create
4816141e13f6e84846ae531358a8bcbf6d2102b1bd4Vasu Nori     * another CursorWindow object. One of the scenarios of its occurrence is when
4826141e13f6e84846ae531358a8bcbf6d2102b1bd4Vasu Nori     * there are too many CursorWindow objects already opened by the process.
4836141e13f6e84846ae531358a8bcbf6d2102b1bd4Vasu Nori     * This test is for that scenario.
4846141e13f6e84846ae531358a8bcbf6d2102b1bd4Vasu Nori     */
4856141e13f6e84846ae531358a8bcbf6d2102b1bd4Vasu Nori    @LargeTest
4866141e13f6e84846ae531358a8bcbf6d2102b1bd4Vasu Nori    public void testCursorWindowFailureWhenTooManyCursorWindowsLeftOpen() {
4876141e13f6e84846ae531358a8bcbf6d2102b1bd4Vasu Nori        mDatabase.execSQL("CREATE TABLE test (_id INTEGER PRIMARY KEY, data TEXT);");
4886141e13f6e84846ae531358a8bcbf6d2102b1bd4Vasu Nori        mDatabase.execSQL("INSERT INTO test values(1, 'test');");
4896141e13f6e84846ae531358a8bcbf6d2102b1bd4Vasu Nori        int N = 1024;
4906141e13f6e84846ae531358a8bcbf6d2102b1bd4Vasu Nori        ArrayList<Cursor> cursorList = new ArrayList<Cursor>();
4916141e13f6e84846ae531358a8bcbf6d2102b1bd4Vasu Nori        // open many cursors until a failure occurs
4926141e13f6e84846ae531358a8bcbf6d2102b1bd4Vasu Nori        for (int i = 0; i < N; i++) {
4936141e13f6e84846ae531358a8bcbf6d2102b1bd4Vasu Nori            try {
4946141e13f6e84846ae531358a8bcbf6d2102b1bd4Vasu Nori                Cursor cursor = mDatabase.rawQuery("select * from test", null);
4956141e13f6e84846ae531358a8bcbf6d2102b1bd4Vasu Nori                cursor.getCount();
4966141e13f6e84846ae531358a8bcbf6d2102b1bd4Vasu Nori                cursorList.add(cursor);
4976141e13f6e84846ae531358a8bcbf6d2102b1bd4Vasu Nori            } catch (CursorWindowAllocationException e) {
4986141e13f6e84846ae531358a8bcbf6d2102b1bd4Vasu Nori                // got the exception we wanted
4996141e13f6e84846ae531358a8bcbf6d2102b1bd4Vasu Nori                break;
5006141e13f6e84846ae531358a8bcbf6d2102b1bd4Vasu Nori            } catch (Exception e) {
5016141e13f6e84846ae531358a8bcbf6d2102b1bd4Vasu Nori                fail("unexpected exception: " + e.getMessage());
5026141e13f6e84846ae531358a8bcbf6d2102b1bd4Vasu Nori                e.printStackTrace();
5036141e13f6e84846ae531358a8bcbf6d2102b1bd4Vasu Nori                break;
5046141e13f6e84846ae531358a8bcbf6d2102b1bd4Vasu Nori            }
5056141e13f6e84846ae531358a8bcbf6d2102b1bd4Vasu Nori        }
5066141e13f6e84846ae531358a8bcbf6d2102b1bd4Vasu Nori        for (Cursor c : cursorList) {
5076141e13f6e84846ae531358a8bcbf6d2102b1bd4Vasu Nori            c.close();
5086141e13f6e84846ae531358a8bcbf6d2102b1bd4Vasu Nori        }
5096141e13f6e84846ae531358a8bcbf6d2102b1bd4Vasu Nori    }
5101a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen}
511