SQLite Android Bindings
Check-in [7820bf256b]
Not logged in

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

Overview
Comment:Add modified versions of the remainder of the Android CTS tests to this project.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | experimental
Files: files | file ages | folders
SHA1: 7820bf256b9bf6235d832930e59e550e153987b9
User & Date: dan 2017-11-15 10:56:58
Context
2017-11-15
18:12
Add other CTS tests that use SQLite objects. check-in: 796ba7d799 user: dan tags: experimental
10:56
Add modified versions of the remainder of the Android CTS tests to this project. check-in: 7820bf256b user: dan tags: experimental
2017-11-14
21:13
Add further cts tests to this project. check-in: 09d6816449 user: dan tags: experimental
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Added sqlite3/src/androidTest/java/org/sqlite/database/DatabaseStatementTest.java.

            1  +/*
            2  + * Copyright (C) 2007 The Android Open Source Project
            3  + *
            4  + * Licensed under the Apache License, Version 2.0 (the "License");
            5  + * you may not use this file except in compliance with the License.
            6  + * You may obtain a copy of the License at
            7  + *
            8  + *      http://www.apache.org/licenses/LICENSE-2.0
            9  + *
           10  + * Unless required by applicable law or agreed to in writing, software
           11  + * distributed under the License is distributed on an "AS IS" BASIS,
           12  + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
           13  + * See the License for the specific language governing permissions and
           14  + * limitations under the License.
           15  + */
           16  +
           17  +package org.sqlite.database;
           18  +
           19  +import android.content.Context;
           20  +import android.database.Cursor;
           21  +import org.sqlite.database.sqlite.SQLiteConstraintException;
           22  +import org.sqlite.database.sqlite.SQLiteDatabase;
           23  +import org.sqlite.database.sqlite.SQLiteDoneException;
           24  +import org.sqlite.database.sqlite.SQLiteStatement;
           25  +import android.test.AndroidTestCase;
           26  +import android.test.PerformanceTestCase;
           27  +import android.test.suitebuilder.annotation.MediumTest;
           28  +
           29  +import java.io.File;
           30  +
           31  +/*
           32  + * These tests were taken from
           33  + * frameworks/base/tests/AndroidTests/src/com/android/unit_tests/DatabaseStatementTest.java
           34  + * Modifications:
           35  + * - use Context to create and delete the DB to avoid hard-coded paths
           36  + */
           37  +public class DatabaseStatementTest extends AndroidTestCase implements PerformanceTestCase {
           38  +
           39  +    private static final String sString1 = "this is a test";
           40  +    private static final String sString2 = "and yet another test";
           41  +    private static final String sString3 = "this string is a little longer, but still a test";
           42  +
           43  +    private static final String DATABASE_NAME = "database_test.db";
           44  +
           45  +    private static final int CURRENT_DATABASE_VERSION = 42;
           46  +    private SQLiteDatabase mDatabase;
           47  +
           48  +    @Override
           49  +    protected void setUp() throws Exception {
           50  +        super.setUp();
           51  +        System.loadLibrary("sqliteX");
           52  +        File f = mContext.getDatabasePath(MyHelper.DATABASE_NAME);
           53  +        f.mkdirs();
           54  +        if (f.exists()) { f.delete(); }
           55  +        mDatabase = SQLiteDatabase.openOrCreateDatabase(f,null);
           56  +        assertNotNull(mDatabase);
           57  +        mDatabase.setVersion(CURRENT_DATABASE_VERSION);
           58  +    }
           59  +
           60  +    @Override
           61  +    protected void tearDown() throws Exception {
           62  +        mDatabase.close();
           63  +        getContext().deleteDatabase(DATABASE_NAME);
           64  +        super.tearDown();
           65  +    }
           66  +
           67  +    public boolean isPerformanceOnly() {
           68  +        return false;
           69  +    }
           70  +
           71  +    // These test can only be run once.
           72  +    public int startPerformance(Intermediates intermediates) {
           73  +        return 1;
           74  +    }
           75  +
           76  +    private void populateDefaultTable() {
           77  +        mDatabase.execSQL("CREATE TABLE test (_id INTEGER PRIMARY KEY, data TEXT);");
           78  +
           79  +        mDatabase.execSQL("INSERT INTO test (data) VALUES ('" + sString1 + "');");
           80  +        mDatabase.execSQL("INSERT INTO test (data) VALUES ('" + sString2 + "');");
           81  +        mDatabase.execSQL("INSERT INTO test (data) VALUES ('" + sString3 + "');");
           82  +    }
           83  +
           84  +    @MediumTest
           85  +    public void testExecuteStatement() throws Exception {
           86  +        populateDefaultTable();
           87  +        SQLiteStatement statement = mDatabase.compileStatement("DELETE FROM test");
           88  +        statement.execute();
           89  +
           90  +        Cursor c = mDatabase.query("test", null, null, null, null, null, null);
           91  +        assertEquals(0, c.getCount());
           92  +        c.deactivate();
           93  +        statement.close();
           94  +    }
           95  +
           96  +    @MediumTest
           97  +    public void testSimpleQuery() throws Exception {
           98  +        mDatabase.execSQL("CREATE TABLE test (num INTEGER NOT NULL, str TEXT NOT NULL);");
           99  +        mDatabase.execSQL("INSERT INTO test VALUES (1234, 'hello');");
          100  +        SQLiteStatement statement1 =
          101  +                mDatabase.compileStatement("SELECT num FROM test WHERE str = ?");
          102  +        SQLiteStatement statement2 =
          103  +                mDatabase.compileStatement("SELECT str FROM test WHERE num = ?");
          104  +
          105  +        try {
          106  +            statement1.bindString(1, "hello");
          107  +            long value = statement1.simpleQueryForLong();
          108  +            assertEquals(1234, value);
          109  +
          110  +            statement1.bindString(1, "world");
          111  +            statement1.simpleQueryForLong();
          112  +            fail("shouldn't get here");
          113  +        } catch (SQLiteDoneException e) {
          114  +            // expected
          115  +        }
          116  +
          117  +        try {
          118  +            statement2.bindLong(1, 1234);
          119  +            String value = statement1.simpleQueryForString();
          120  +            assertEquals("hello", value);
          121  +
          122  +            statement2.bindLong(1, 5678);
          123  +            statement1.simpleQueryForString();
          124  +            fail("shouldn't get here");
          125  +        } catch (SQLiteDoneException e) {
          126  +            // expected
          127  +        }
          128  +
          129  +        statement1.close();
          130  +        statement2.close();
          131  +    }
          132  +
          133  +    @MediumTest
          134  +    public void testStatementLongBinding() throws Exception {
          135  +        mDatabase.execSQL("CREATE TABLE test (num INTEGER);");
          136  +        SQLiteStatement statement = mDatabase.compileStatement("INSERT INTO test (num) VALUES (?)");
          137  +
          138  +        for (int i = 0; i < 10; i++) {
          139  +            statement.bindLong(1, i);
          140  +            statement.execute();
          141  +        }
          142  +        statement.close();
          143  +
          144  +        Cursor c = mDatabase.query("test", null, null, null, null, null, null);
          145  +        int numCol = c.getColumnIndexOrThrow("num");
          146  +        c.moveToFirst();
          147  +        for (long i = 0; i < 10; i++) {
          148  +            long num = c.getLong(numCol);
          149  +            assertEquals(i, num);
          150  +            c.moveToNext();
          151  +        }
          152  +        c.close();
          153  +    }
          154  +
          155  +    @MediumTest
          156  +    public void testStatementStringBinding() throws Exception {
          157  +        mDatabase.execSQL("CREATE TABLE test (num TEXT);");
          158  +        SQLiteStatement statement = mDatabase.compileStatement("INSERT INTO test (num) VALUES (?)");
          159  +
          160  +        for (long i = 0; i < 10; i++) {
          161  +            statement.bindString(1, Long.toHexString(i));
          162  +            statement.execute();
          163  +        }
          164  +        statement.close();
          165  +
          166  +        Cursor c = mDatabase.query("test", null, null, null, null, null, null);
          167  +        int numCol = c.getColumnIndexOrThrow("num");
          168  +        c.moveToFirst();
          169  +        for (long i = 0; i < 10; i++) {
          170  +            String num = c.getString(numCol);
          171  +            assertEquals(Long.toHexString(i), num);
          172  +            c.moveToNext();
          173  +        }
          174  +        c.close();
          175  +    }
          176  +
          177  +    @MediumTest
          178  +    public void testStatementClearBindings() throws Exception {
          179  +        mDatabase.execSQL("CREATE TABLE test (num INTEGER);");
          180  +        SQLiteStatement statement = mDatabase.compileStatement("INSERT INTO test (num) VALUES (?)");
          181  +
          182  +        for (long i = 0; i < 10; i++) {
          183  +            statement.bindLong(1, i);
          184  +            statement.clearBindings();
          185  +            statement.execute();
          186  +        }
          187  +        statement.close();
          188  +
          189  +        Cursor c = mDatabase.query("test", null, null, null, null, null, "ROWID");
          190  +        int numCol = c.getColumnIndexOrThrow("num");
          191  +        assertTrue(c.moveToFirst());
          192  +        for (long i = 0; i < 10; i++) {
          193  +            assertTrue(c.isNull(numCol));
          194  +            c.moveToNext();
          195  +        }
          196  +        c.close();
          197  +    }
          198  +
          199  +    @MediumTest
          200  +    public void testSimpleStringBinding() throws Exception {
          201  +        mDatabase.execSQL("CREATE TABLE test (num TEXT, value TEXT);");
          202  +        String statement = "INSERT INTO test (num, value) VALUES (?,?)";
          203  +
          204  +        String[] args = new String[2];
          205  +        for (int i = 0; i < 2; i++) {
          206  +            args[i] = Integer.toHexString(i);
          207  +        }
          208  +
          209  +        mDatabase.execSQL(statement, args);
          210  +
          211  +        Cursor c = mDatabase.query("test", null, null, null, null, null, null);
          212  +        int numCol = c.getColumnIndexOrThrow("num");
          213  +        int valCol = c.getColumnIndexOrThrow("value");
          214  +        c.moveToFirst();
          215  +        String num = c.getString(numCol);
          216  +        assertEquals(Integer.toHexString(0), num);
          217  +
          218  +        String val = c.getString(valCol);
          219  +        assertEquals(Integer.toHexString(1), val);
          220  +        c.close();
          221  +    }
          222  +
          223  +    @MediumTest
          224  +    public void testStatementMultipleBindings() throws Exception {
          225  +        mDatabase.execSQL("CREATE TABLE test (num INTEGER, str TEXT);");
          226  +        SQLiteStatement statement =
          227  +                mDatabase.compileStatement("INSERT INTO test (num, str) VALUES (?, ?)");
          228  +
          229  +        for (long i = 0; i < 10; i++) {
          230  +            statement.bindLong(1, i);
          231  +            statement.bindString(2, Long.toHexString(i));
          232  +            statement.execute();
          233  +        }
          234  +        statement.close();
          235  +
          236  +        Cursor c = mDatabase.query("test", null, null, null, null, null, "ROWID");
          237  +        int numCol = c.getColumnIndexOrThrow("num");
          238  +        int strCol = c.getColumnIndexOrThrow("str");
          239  +        assertTrue(c.moveToFirst());
          240  +        for (long i = 0; i < 10; i++) {
          241  +            long num = c.getLong(numCol);
          242  +            String str = c.getString(strCol);
          243  +            assertEquals(i, num);
          244  +            assertEquals(Long.toHexString(i), str);
          245  +            c.moveToNext();
          246  +        }
          247  +        c.close();
          248  +    }
          249  +
          250  +    private static class StatementTestThread extends Thread {
          251  +        private SQLiteDatabase mDatabase;
          252  +        private SQLiteStatement mStatement;
          253  +
          254  +        public StatementTestThread(SQLiteDatabase db, SQLiteStatement statement) {
          255  +            super();
          256  +            mDatabase = db;
          257  +            mStatement = statement;
          258  +        }
          259  +
          260  +        @Override
          261  +        public void run() {
          262  +            mDatabase.beginTransaction();
          263  +            for (long i = 0; i < 10; i++) {
          264  +                mStatement.bindLong(1, i);
          265  +                mStatement.bindString(2, Long.toHexString(i));
          266  +                mStatement.execute();
          267  +            }
          268  +            mDatabase.setTransactionSuccessful();
          269  +            mDatabase.endTransaction();
          270  +
          271  +            Cursor c = mDatabase.query("test", null, null, null, null, null, "ROWID");
          272  +            int numCol = c.getColumnIndexOrThrow("num");
          273  +            int strCol = c.getColumnIndexOrThrow("str");
          274  +            assertTrue(c.moveToFirst());
          275  +            for (long i = 0; i < 10; i++) {
          276  +                long num = c.getLong(numCol);
          277  +                String str = c.getString(strCol);
          278  +                assertEquals(i, num);
          279  +                assertEquals(Long.toHexString(i), str);
          280  +                c.moveToNext();
          281  +            }
          282  +            c.close();
          283  +        }
          284  +    }
          285  +
          286  +    @MediumTest
          287  +    public void testStatementMultiThreaded() throws Exception {
          288  +        mDatabase.execSQL("CREATE TABLE test (num INTEGER, str TEXT);");
          289  +        SQLiteStatement statement =
          290  +                mDatabase.compileStatement("INSERT INTO test (num, str) VALUES (?, ?)");
          291  +
          292  +        StatementTestThread thread = new StatementTestThread(mDatabase, statement);
          293  +        thread.start();
          294  +        try {
          295  +            thread.join();
          296  +        } finally {
          297  +            statement.close();
          298  +        }
          299  +    }
          300  +
          301  +    @MediumTest
          302  +    public void testStatementConstraint() throws Exception {
          303  +        mDatabase.execSQL("CREATE TABLE test (num INTEGER NOT NULL);");
          304  +        SQLiteStatement statement = mDatabase.compileStatement("INSERT INTO test (num) VALUES (?)");
          305  +
          306  +        // Try to insert NULL, which violates the constraint
          307  +        try {
          308  +            statement.clearBindings();
          309  +            statement.execute();
          310  +            fail("expected exception not thrown");
          311  +        } catch (SQLiteConstraintException e) {
          312  +            // expected
          313  +        }
          314  +
          315  +        // Make sure the statement can still be used
          316  +        statement.bindLong(1, 1);
          317  +        statement.execute();
          318  +        statement.close();
          319  +
          320  +        Cursor c = mDatabase.query("test", null, null, null, null, null, null);
          321  +        int numCol = c.getColumnIndexOrThrow("num");
          322  +        c.moveToFirst();
          323  +        long num = c.getLong(numCol);
          324  +        assertEquals(1, num);
          325  +        c.close();
          326  +    }
          327  +}

Added sqlite3/src/androidTest/java/org/sqlite/database/SQLiteConstraintExceptionTest.java.

            1  +/*
            2  + * Copyright (C) 2009 The Android Open Source Project
            3  + *
            4  + * Licensed under the Apache License, Version 2.0 (the "License");
            5  + * you may not use this file except in compliance with the License.
            6  + * You may obtain a copy of the License at
            7  + *
            8  + *      http://www.apache.org/licenses/LICENSE-2.0
            9  + *
           10  + * Unless required by applicable law or agreed to in writing, software
           11  + * distributed under the License is distributed on an "AS IS" BASIS,
           12  + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
           13  + * See the License for the specific language governing permissions and
           14  + * limitations under the License.
           15  + */
           16  +
           17  +package org.sqlite.database;
           18  +
           19  +import org.sqlite.database.sqlite.SQLiteConstraintException;
           20  +import android.test.AndroidTestCase;
           21  +
           22  +public class SQLiteConstraintExceptionTest extends AndroidTestCase {
           23  +    public void testConstructor() {
           24  +        new SQLiteConstraintException();
           25  +
           26  +        new SQLiteConstraintException("error");
           27  +    }
           28  +}

Added sqlite3/src/androidTest/java/org/sqlite/database/SQLiteDatabaseCorruptExceptionTest.java.

            1  +/*
            2  + * Copyright (C) 2009 The Android Open Source Project
            3  + *
            4  + * Licensed under the Apache License, Version 2.0 (the "License");
            5  + * you may not use this file except in compliance with the License.
            6  + * You may obtain a copy of the License at
            7  + *
            8  + *      http://www.apache.org/licenses/LICENSE-2.0
            9  + *
           10  + * Unless required by applicable law or agreed to in writing, software
           11  + * distributed under the License is distributed on an "AS IS" BASIS,
           12  + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
           13  + * See the License for the specific language governing permissions and
           14  + * limitations under the License.
           15  + */
           16  +
           17  +package android.database.sqlite.cts;
           18  +
           19  +import android.database.sqlite.SQLiteDatabaseCorruptException;
           20  +import android.test.AndroidTestCase;
           21  +
           22  +public class SQLiteDatabaseCorruptExceptionTest extends AndroidTestCase {
           23  +    public void testConstructor() {
           24  +        new SQLiteDatabaseCorruptException();
           25  +
           26  +        new SQLiteDatabaseCorruptException("error");
           27  +    }
           28  +}

Added sqlite3/src/androidTest/java/org/sqlite/database/SQLiteDiskIOExceptionTest.java.

            1  +/*
            2  + * Copyright (C) 2009 The Android Open Source Project
            3  + *
            4  + * Licensed under the Apache License, Version 2.0 (the "License");
            5  + * you may not use this file except in compliance with the License.
            6  + * You may obtain a copy of the License at
            7  + *
            8  + *      http://www.apache.org/licenses/LICENSE-2.0
            9  + *
           10  + * Unless required by applicable law or agreed to in writing, software
           11  + * distributed under the License is distributed on an "AS IS" BASIS,
           12  + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
           13  + * See the License for the specific language governing permissions and
           14  + * limitations under the License.
           15  + */
           16  +
           17  +package org.sqlite.database;
           18  +
           19  +import org.sqlite.database.sqlite.SQLiteDiskIOException;
           20  +import android.test.AndroidTestCase;
           21  +
           22  +public class SQLiteDiskIOExceptionTest extends AndroidTestCase {
           23  +    public void testConstructor() {
           24  +        new SQLiteDiskIOException();
           25  +
           26  +        new SQLiteDiskIOException("error");
           27  +    }
           28  +}

Added sqlite3/src/androidTest/java/org/sqlite/database/SQLiteDoneExceptionTest.java.

            1  +/*
            2  + * Copyright (C) 2009 The Android Open Source Project
            3  + *
            4  + * Licensed under the Apache License, Version 2.0 (the "License");
            5  + * you may not use this file except in compliance with the License.
            6  + * You may obtain a copy of the License at
            7  + *
            8  + *      http://www.apache.org/licenses/LICENSE-2.0
            9  + *
           10  + * Unless required by applicable law or agreed to in writing, software
           11  + * distributed under the License is distributed on an "AS IS" BASIS,
           12  + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
           13  + * See the License for the specific language governing permissions and
           14  + * limitations under the License.
           15  + */
           16  +
           17  +package org.sqlite.database;
           18  +
           19  +import org.sqlite.database.sqlite.SQLiteDoneException;
           20  +import android.test.AndroidTestCase;
           21  +
           22  +public class SQLiteDoneExceptionTest extends AndroidTestCase {
           23  +    public void testConstructor() {
           24  +        new SQLiteDoneException();
           25  +
           26  +        new SQLiteDoneException("error");
           27  +    }
           28  +}

Added sqlite3/src/androidTest/java/org/sqlite/database/SQLiteExceptionTest.java.

            1  +/*
            2  + * Copyright (C) 2009 The Android Open Source Project
            3  + *
            4  + * Licensed under the Apache License, Version 2.0 (the "License");
            5  + * you may not use this file except in compliance with the License.
            6  + * You may obtain a copy of the License at
            7  + *
            8  + *      http://www.apache.org/licenses/LICENSE-2.0
            9  + *
           10  + * Unless required by applicable law or agreed to in writing, software
           11  + * distributed under the License is distributed on an "AS IS" BASIS,
           12  + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
           13  + * See the License for the specific language governing permissions and
           14  + * limitations under the License.
           15  + */
           16  +
           17  +package org.sqlite.database;
           18  +
           19  +import org.sqlite.database.sqlite.SQLiteException;
           20  +import android.test.AndroidTestCase;
           21  +
           22  +public class SQLiteExceptionTest extends AndroidTestCase {
           23  +    public void testConstructor() {
           24  +        new SQLiteException();
           25  +
           26  +        new SQLiteException("error");
           27  +    }
           28  +}

Added sqlite3/src/androidTest/java/org/sqlite/database/SQLiteFullExceptionTest.java.

            1  +/*
            2  + * Copyright (C) 2009 The Android Open Source Project
            3  + *
            4  + * Licensed under the Apache License, Version 2.0 (the "License");
            5  + * you may not use this file except in compliance with the License.
            6  + * You may obtain a copy of the License at
            7  + *
            8  + *      http://www.apache.org/licenses/LICENSE-2.0
            9  + *
           10  + * Unless required by applicable law or agreed to in writing, software
           11  + * distributed under the License is distributed on an "AS IS" BASIS,
           12  + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
           13  + * See the License for the specific language governing permissions and
           14  + * limitations under the License.
           15  + */
           16  +
           17  +package org.sqlite.database;
           18  +
           19  +import org.sqlite.database.sqlite.SQLiteFullException;
           20  +import android.test.AndroidTestCase;
           21  +
           22  +public class SQLiteFullExceptionTest extends AndroidTestCase {
           23  +    public void testConstructor() {
           24  +        new SQLiteFullException();
           25  +
           26  +        new SQLiteFullException("error");
           27  +    }
           28  +}

Added sqlite3/src/androidTest/java/org/sqlite/database/SQLiteMisuseExceptionTest.java.

            1  +/*
            2  + * Copyright (C) 2009 The Android Open Source Project
            3  + *
            4  + * Licensed under the Apache License, Version 2.0 (the "License");
            5  + * you may not use this file except in compliance with the License.
            6  + * You may obtain a copy of the License at
            7  + *
            8  + *      http://www.apache.org/licenses/LICENSE-2.0
            9  + *
           10  + * Unless required by applicable law or agreed to in writing, software
           11  + * distributed under the License is distributed on an "AS IS" BASIS,
           12  + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
           13  + * See the License for the specific language governing permissions and
           14  + * limitations under the License.
           15  + */
           16  +
           17  +package org.sqlite.database;
           18  +
           19  +import org.sqlite.database.sqlite.SQLiteMisuseException;
           20  +import android.test.AndroidTestCase;
           21  +
           22  +public class SQLiteMisuseExceptionTest extends AndroidTestCase {
           23  +    public void testConstructor() {
           24  +        new SQLiteMisuseException();
           25  +
           26  +        new SQLiteMisuseException("error");
           27  +    }
           28  +}

Added sqlite3/src/androidTest/java/org/sqlite/database/SQLiteOpenHelperTest.java.

            1  +/*
            2  + * Copyright (C) 2009 The Android Open Source Project
            3  + *
            4  + * Licensed under the Apache License, Version 2.0 (the "License");
            5  + * you may not use this file except in compliance with the License.
            6  + * You may obtain a copy of the License at
            7  + *
            8  + *      http://www.apache.org/licenses/LICENSE-2.0
            9  + *
           10  + * Unless required by applicable law or agreed to in writing, software
           11  + * distributed under the License is distributed on an "AS IS" BASIS,
           12  + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
           13  + * See the License for the specific language governing permissions and
           14  + * limitations under the License.
           15  + */
           16  +
           17  +package org.sqlite.database;
           18  +
           19  +import android.content.Context;
           20  +import android.database.Cursor;
           21  +import org.sqlite.database.sqlite.SQLiteCursor;
           22  +import org.sqlite.database.sqlite.SQLiteCursorDriver;
           23  +import org.sqlite.database.sqlite.SQLiteDatabase;
           24  +import org.sqlite.database.sqlite.SQLiteOpenHelper;
           25  +import org.sqlite.database.sqlite.SQLiteQuery;
           26  +import org.sqlite.database.sqlite.SQLiteDatabase.CursorFactory;
           27  +import android.test.AndroidTestCase;
           28  +
           29  +import java.io.File;
           30  +
           31  +/**
           32  + * Test {@link SQLiteOpenHelper}.
           33  + */
           34  +public class SQLiteOpenHelperTest extends AndroidTestCase {
           35  +    private static final String TEST_DATABASE_NAME = "database_test.db";
           36  +    static String DATABASE_PATH;
           37  +    private static final int TEST_VERSION = 1;
           38  +    private static final int TEST_ILLEGAL_VERSION = 0;
           39  +    private MockOpenHelper mOpenHelper;
           40  +    private SQLiteDatabase.CursorFactory mFactory = new SQLiteDatabase.CursorFactory() {
           41  +        public Cursor newCursor(SQLiteDatabase db, SQLiteCursorDriver masterQuery,
           42  +                String editTable, SQLiteQuery query) {
           43  +            return new MockCursor(db, masterQuery, editTable, query);
           44  +        }
           45  +    };
           46  +
           47  +    @Override
           48  +    protected void setUp() throws Exception {
           49  +        super.setUp();
           50  +        System.loadLibrary("sqliteX");
           51  +        DATABASE_PATH = mContext.getDatabasePath(TEST_DATABASE_NAME).toString();
           52  +        mOpenHelper = getOpenHelper();
           53  +    }
           54  +
           55  +    public void testConstructor() {
           56  +        new MockOpenHelper(mContext, DATABASE_PATH, mFactory, TEST_VERSION);
           57  +
           58  +        // Test with illegal version number.
           59  +        try {
           60  +            new MockOpenHelper(mContext, DATABASE_PATH, mFactory, TEST_ILLEGAL_VERSION);
           61  +            fail("Constructor of SQLiteOpenHelp should throws a IllegalArgumentException here.");
           62  +        } catch (IllegalArgumentException e) {
           63  +        }
           64  +
           65  +        // Test with null factory
           66  +        new MockOpenHelper(mContext, DATABASE_PATH, null, TEST_VERSION);
           67  +    }
           68  +
           69  +    public void testGetDatabase() {
           70  +        SQLiteDatabase database = null;
           71  +        assertFalse(mOpenHelper.hasCalledOnOpen());
           72  +        // Test getReadableDatabase.
           73  +        database = mOpenHelper.getReadableDatabase();
           74  +        assertNotNull(database);
           75  +        assertTrue(database.isOpen());
           76  +        assertTrue(mOpenHelper.hasCalledOnOpen());
           77  +
           78  +        // Database has been opened, so onOpen can not be invoked.
           79  +        mOpenHelper.resetStatus();
           80  +        assertFalse(mOpenHelper.hasCalledOnOpen());
           81  +        // Test getWritableDatabase.
           82  +        SQLiteDatabase database2 = mOpenHelper.getWritableDatabase();
           83  +        assertSame(database, database2);
           84  +        assertTrue(database.isOpen());
           85  +        assertFalse(mOpenHelper.hasCalledOnOpen());
           86  +
           87  +        mOpenHelper.close();
           88  +        assertFalse(database.isOpen());
           89  +
           90  +        // After close(), onOpen() will be invoked by getWritableDatabase.
           91  +        mOpenHelper.resetStatus();
           92  +        assertFalse(mOpenHelper.hasCalledOnOpen());
           93  +        SQLiteDatabase database3 = mOpenHelper.getWritableDatabase();
           94  +        assertNotNull(database);
           95  +        assertNotSame(database, database3);
           96  +        assertTrue(mOpenHelper.hasCalledOnOpen());
           97  +        assertTrue(database3.isOpen());
           98  +        mOpenHelper.close();
           99  +        assertFalse(database3.isOpen());
          100  +    }
          101  +
          102  +    private MockOpenHelper getOpenHelper() {
          103  +        return new MockOpenHelper(mContext, DATABASE_PATH, mFactory, TEST_VERSION);
          104  +    }
          105  +
          106  +    private class MockOpenHelper extends SQLiteOpenHelper {
          107  +        private boolean mHasCalledOnOpen = false;
          108  +
          109  +        public MockOpenHelper(Context context, String name, CursorFactory factory, int version) {
          110  +            super(context, name, factory, version);
          111  +        }
          112  +
          113  +        @Override
          114  +        public void onCreate(SQLiteDatabase db) {
          115  +        }
          116  +
          117  +        @Override
          118  +        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
          119  +        }
          120  +
          121  +        @Override
          122  +        public void onOpen(SQLiteDatabase db) {
          123  +            mHasCalledOnOpen = true;
          124  +        }
          125  +
          126  +        public boolean hasCalledOnOpen() {
          127  +            return mHasCalledOnOpen;
          128  +        }
          129  +
          130  +        public void resetStatus() {
          131  +            mHasCalledOnOpen = false;
          132  +        }
          133  +    }
          134  +
          135  +    private class MockCursor extends SQLiteCursor {
          136  +        public MockCursor(SQLiteDatabase db, SQLiteCursorDriver driver, String editTable,
          137  +                SQLiteQuery query) {
          138  +            super(db, driver, editTable, query);
          139  +        }
          140  +    }
          141  +}

Added sqlite3/src/androidTest/java/org/sqlite/database/SQLiteProgramTest.java.

            1  +/*
            2  + * Copyright (C) 2009 The Android Open Source Project
            3  + *
            4  + * Licensed under the Apache License, Version 2.0 (the "License");
            5  + * you may not use this file except in compliance with the License.
            6  + * You may obtain a copy of the License at
            7  + *
            8  + *      http://www.apache.org/licenses/LICENSE-2.0
            9  + *
           10  + * Unless required by applicable law or agreed to in writing, software
           11  + * distributed under the License is distributed on an "AS IS" BASIS,
           12  + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
           13  + * See the License for the specific language governing permissions and
           14  + * limitations under the License.
           15  + */
           16  +
           17  +package org.sqlite.database;
           18  +
           19  +
           20  +import android.content.Context;
           21  +import android.database.Cursor;
           22  +import org.sqlite.database.sqlite.SQLiteDatabase;
           23  +import org.sqlite.database.sqlite.SQLiteDoneException;
           24  +import org.sqlite.database.sqlite.SQLiteException;
           25  +import org.sqlite.database.sqlite.SQLiteQuery;
           26  +import org.sqlite.database.sqlite.SQLiteStatement;
           27  +import android.test.AndroidTestCase;
           28  +import android.test.MoreAsserts;
           29  +
           30  +import java.io.File;
           31  +
           32  +public class SQLiteProgramTest extends AndroidTestCase {
           33  +    private static final String DATABASE_NAME = "database_test.db";
           34  +
           35  +    private SQLiteDatabase mDatabase;
           36  +
           37  +    @Override
           38  +    protected void setUp() throws Exception {
           39  +        super.setUp();
           40  +        System.loadLibrary("sqliteX");
           41  +        File f = mContext.getDatabasePath(DATABASE_NAME);
           42  +        f.mkdirs();
           43  +        if (f.exists()) { f.delete(); }
           44  +        mDatabase = SQLiteDatabase.openOrCreateDatabase(f,null);
           45  +        assertNotNull(mDatabase);
           46  +    }
           47  +
           48  +    @Override
           49  +    protected void tearDown() throws Exception {
           50  +        mDatabase.close();
           51  +        getContext().deleteDatabase(DATABASE_NAME);
           52  +
           53  +        super.tearDown();
           54  +    }
           55  +
           56  +    public void testBind() {
           57  +        mDatabase.execSQL("CREATE TABLE test (_id INTEGER PRIMARY KEY, text1 TEXT, text2 TEXT, " +
           58  +                "num1 INTEGER, num2 INTEGER, image BLOB);");
           59  +        mDatabase.execSQL("INSERT INTO test (text1, text2, num1, num2, image) " +
           60  +                "VALUES ('Mike', 'Jack', 12, 30, 'abcdefg');");
           61  +        mDatabase.execSQL("INSERT INTO test (text1, text2, num1, num2, image) " +
           62  +                "VALUES ('test1', 'test2', 213, 589, '123456789');");
           63  +        SQLiteStatement statement;
           64  +
           65  +        statement = mDatabase.compileStatement("SELECT num1 FROM test WHERE num2 = ?;");
           66  +        statement.bindLong(1, 30);
           67  +        assertEquals(12, statement.simpleQueryForLong());
           68  +
           69  +        // re-bind without clearing
           70  +        statement.bindDouble(1, 589.0);
           71  +        assertEquals(213, statement.simpleQueryForLong());
           72  +        statement.close();
           73  +
           74  +        statement = mDatabase.compileStatement("SELECT text1 FROM test WHERE text2 = ?;");
           75  +
           76  +        statement.bindDouble(1, 589.0); // Wrong binding
           77  +        try {
           78  +            statement.simpleQueryForString();
           79  +            fail("Should throw exception (no rows found)");
           80  +        } catch (SQLiteDoneException expected) {
           81  +            // expected
           82  +        }
           83  +        statement.bindString(1, "test2");
           84  +        assertEquals("test1", statement.simpleQueryForString());
           85  +        statement.clearBindings();
           86  +        try {
           87  +            statement.simpleQueryForString();
           88  +            fail("Should throw exception (unbound value)");
           89  +        } catch (SQLiteDoneException expected) {
           90  +            // expected
           91  +        }
           92  +        statement.close();
           93  +
           94  +        Cursor cursor = null;
           95  +        try {
           96  +            cursor = mDatabase.query("test", new String[]{"text1"}, "where text1='a'",
           97  +                    new String[]{"foo"}, null, null, null);
           98  +            fail("Should throw exception (no value to bind)");
           99  +        } catch (SQLiteException expected) {
          100  +            // expected
          101  +        } finally {
          102  +            if (cursor != null) {
          103  +                cursor.close();
          104  +            }
          105  +        }
          106  +        try {
          107  +            cursor = mDatabase.query("test", new String[]{"text1"}, "where text1='a'",
          108  +                    new String[]{"foo", "bar"}, null, null, null);
          109  +            fail("Should throw exception (index too large)");
          110  +        } catch (SQLiteException expected) {
          111  +            // expected
          112  +        } finally {
          113  +            if (cursor != null) {
          114  +                cursor.close();
          115  +            }
          116  +        }
          117  +        // test positive case
          118  +        statement = mDatabase.compileStatement(
          119  +                "SELECT text1 FROM test WHERE text2 = ? AND num2 = ?;");
          120  +        statement.bindString(1, "Jack");
          121  +        statement.bindLong(2, 30);
          122  +        assertEquals("Mike", statement.simpleQueryForString());
          123  +        statement.close();
          124  +    }
          125  +
          126  +    public void testBindNull() {
          127  +        mDatabase.execSQL("CREATE TABLE test (_id INTEGER PRIMARY KEY, text1 TEXT, text2 TEXT, " +
          128  +                "num1 INTEGER, num2 INTEGER, image BLOB);");
          129  +
          130  +        SQLiteStatement statement = mDatabase.compileStatement("INSERT INTO test " +
          131  +                "(text1,text2,num1,image) VALUES (?,?,?,?)");
          132  +        statement.bindString(1, "string1");
          133  +        statement.bindString(2, "string2");
          134  +        statement.bindLong(3, 100);
          135  +        statement.bindNull(4);
          136  +        statement.execute();
          137  +        statement.close();
          138  +
          139  +        final int COLUMN_TEXT1_INDEX = 0;
          140  +        final int COLUMN_TEXT2_INDEX = 1;
          141  +        final int COLUMN_NUM1_INDEX = 2;
          142  +        final int COLUMN_IMAGE_INDEX = 3;
          143  +
          144  +        Cursor cursor = mDatabase.query("test", new String[] { "text1", "text2", "num1", "image" },
          145  +                null, null, null, null, null);
          146  +        assertNotNull(cursor);
          147  +        assertEquals(1, cursor.getCount());
          148  +        cursor.moveToFirst();
          149  +        assertEquals("string1", cursor.getString(COLUMN_TEXT1_INDEX));
          150  +        assertEquals("string2", cursor.getString(COLUMN_TEXT2_INDEX));
          151  +        assertEquals(100, cursor.getInt(COLUMN_NUM1_INDEX));
          152  +        assertNull(cursor.getString(COLUMN_IMAGE_INDEX));
          153  +        cursor.close();
          154  +    }
          155  +
          156  +    public void testBindBlob() {
          157  +        mDatabase.execSQL("CREATE TABLE test (_id INTEGER PRIMARY KEY, text1 TEXT, text2 TEXT, " +
          158  +                "num1 INTEGER, num2 INTEGER, image BLOB);");
          159  +
          160  +        SQLiteStatement statement = mDatabase.compileStatement("INSERT INTO test " +
          161  +                "(text1,text2,num1,image) VALUES (?,?,?,?)");
          162  +        statement.bindString(1, "string1");
          163  +        statement.bindString(2, "string2");
          164  +        statement.bindLong(3, 100);
          165  +        byte[] blob = new byte[] { '1', '2', '3' };
          166  +        statement.bindBlob(4, blob);
          167  +        statement.execute();
          168  +        statement.close();
          169  +
          170  +        final int COLUMN_TEXT1_INDEX = 0;
          171  +        final int COLUMN_TEXT2_INDEX = 1;
          172  +        final int COLUMN_NUM1_INDEX = 2;
          173  +        final int COLUMN_IMAGE_INDEX = 3;
          174  +
          175  +        Cursor cursor = mDatabase.query("test", new String[] { "text1", "text2", "num1", "image" },
          176  +                null, null, null, null, null);
          177  +        assertNotNull(cursor);
          178  +        assertEquals(1, cursor.getCount());
          179  +        cursor.moveToFirst();
          180  +        assertEquals("string1", cursor.getString(COLUMN_TEXT1_INDEX));
          181  +        assertEquals("string2", cursor.getString(COLUMN_TEXT2_INDEX));
          182  +        assertEquals(100, cursor.getInt(COLUMN_NUM1_INDEX));
          183  +        byte[] value = cursor.getBlob(COLUMN_IMAGE_INDEX);
          184  +        MoreAsserts.assertEquals(blob, value);
          185  +        cursor.close();
          186  +    }
          187  +}

Added sqlite3/src/androidTest/java/org/sqlite/database/SQLiteQueryBuilderTest.java.

            1  +/*
            2  + * Copyright (C) 2009 The Android Open Source Project
            3  + *
            4  + * Licensed under the Apache License, Version 2.0 (the "License");
            5  + * you may not use this file except in compliance with the License.
            6  + * You may obtain a copy of the License at
            7  + *
            8  + *      http://www.apache.org/licenses/LICENSE-2.0
            9  + *
           10  + * Unless required by applicable law or agreed to in writing, software
           11  + * distributed under the License is distributed on an "AS IS" BASIS,
           12  + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
           13  + * See the License for the specific language governing permissions and
           14  + * limitations under the License.
           15  + */
           16  +
           17  +package org.sqlite.database;
           18  +
           19  +
           20  +import android.content.Context;
           21  +import android.database.Cursor;
           22  +import org.sqlite.database.sqlite.SQLiteCursor;
           23  +import org.sqlite.database.sqlite.SQLiteCursorDriver;
           24  +import org.sqlite.database.sqlite.SQLiteDatabase;
           25  +import org.sqlite.database.sqlite.SQLiteQuery;
           26  +import org.sqlite.database.sqlite.SQLiteQueryBuilder;
           27  +import android.os.CancellationSignal;
           28  +import android.os.OperationCanceledException;
           29  +import android.test.AndroidTestCase;
           30  +
           31  +import java.util.HashMap;
           32  +import java.util.Map;
           33  +import java.util.concurrent.Semaphore;
           34  +import java.io.File;
           35  +
           36  +public class SQLiteQueryBuilderTest extends AndroidTestCase {
           37  +    private SQLiteDatabase mDatabase;
           38  +    private final String TEST_TABLE_NAME = "test";
           39  +    private final String EMPLOYEE_TABLE_NAME = "employee";
           40  +    private static final String DATABASE_FILE = "database_test.db";
           41  +
           42  +    @Override
           43  +    protected void setUp() throws Exception {
           44  +        super.setUp();
           45  +        System.loadLibrary("sqliteX");
           46  +        File f = mContext.getDatabasePath(MyHelper.DATABASE_NAME);
           47  +        f.mkdirs();
           48  +        if (f.exists()) { f.delete(); }
           49  +        mDatabase = SQLiteDatabase.openOrCreateDatabase(f,null);
           50  +        assertNotNull(mDatabase);
           51  +    }
           52  +
           53  +    @Override
           54  +    protected void tearDown() throws Exception {
           55  +        mDatabase.close();
           56  +        getContext().deleteDatabase(DATABASE_FILE);
           57  +        super.tearDown();
           58  +    }
           59  +
           60  +    public void testConstructor() {
           61  +        new SQLiteQueryBuilder();
           62  +    }
           63  +
           64  +    public void testSetDistinct() {
           65  +        String expected;
           66  +        SQLiteQueryBuilder sqliteQueryBuilder = new SQLiteQueryBuilder();
           67  +        sqliteQueryBuilder.setTables(TEST_TABLE_NAME);
           68  +        sqliteQueryBuilder.setDistinct(false);
           69  +        sqliteQueryBuilder.appendWhere("age=20");
           70  +        String sql = sqliteQueryBuilder.buildQuery(new String[] { "age", "address" },
           71  +                null, null, null, null, null, null);
           72  +        assertEquals(TEST_TABLE_NAME, sqliteQueryBuilder.getTables());
           73  +        expected = "SELECT age, address FROM " + TEST_TABLE_NAME + " WHERE (age=20)";
           74  +        assertEquals(expected, sql);
           75  +
           76  +        sqliteQueryBuilder = new SQLiteQueryBuilder();
           77  +        sqliteQueryBuilder.setTables(EMPLOYEE_TABLE_NAME);
           78  +        sqliteQueryBuilder.setDistinct(true);
           79  +        sqliteQueryBuilder.appendWhere("age>32");
           80  +        sql = sqliteQueryBuilder.buildQuery(new String[] { "age", "address" },
           81  +                null, null, null, null, null, null);
           82  +        assertEquals(EMPLOYEE_TABLE_NAME, sqliteQueryBuilder.getTables());
           83  +        expected = "SELECT DISTINCT age, address FROM " + EMPLOYEE_TABLE_NAME + " WHERE (age>32)";
           84  +        assertEquals(expected, sql);
           85  +
           86  +        sqliteQueryBuilder = new SQLiteQueryBuilder();
           87  +        sqliteQueryBuilder.setTables(EMPLOYEE_TABLE_NAME);
           88  +        sqliteQueryBuilder.setDistinct(true);
           89  +        sqliteQueryBuilder.appendWhereEscapeString("age>32");
           90  +        sql = sqliteQueryBuilder.buildQuery(new String[] { "age", "address" },
           91  +                null, null, null, null, null, null);
           92  +        assertEquals(EMPLOYEE_TABLE_NAME, sqliteQueryBuilder.getTables());
           93  +        expected = "SELECT DISTINCT age, address FROM " + EMPLOYEE_TABLE_NAME
           94  +                + " WHERE ('age>32')";
           95  +        assertEquals(expected, sql);
           96  +    }
           97  +
           98  +    public void testSetProjectionMap() {
           99  +        String expected;
          100  +        Map<String, String> projectMap = new HashMap<String, String>();
          101  +        projectMap.put("EmployeeName", "name");
          102  +        projectMap.put("EmployeeAge", "age");
          103  +        projectMap.put("EmployeeAddress", "address");
          104  +        SQLiteQueryBuilder sqliteQueryBuilder = new SQLiteQueryBuilder();
          105  +        sqliteQueryBuilder.setTables(TEST_TABLE_NAME);
          106  +        sqliteQueryBuilder.setDistinct(false);
          107  +        sqliteQueryBuilder.setProjectionMap(projectMap);
          108  +        String sql = sqliteQueryBuilder.buildQuery(new String[] { "EmployeeName", "EmployeeAge" },
          109  +                null, null, null, null, null, null);
          110  +        expected = "SELECT name, age FROM " + TEST_TABLE_NAME;
          111  +        assertEquals(expected, sql);
          112  +
          113  +        sql = sqliteQueryBuilder.buildQuery(null, // projectionIn is null
          114  +                null, null, null, null, null, null);
          115  +        assertTrue(sql.matches("SELECT (age|name|address), (age|name|address), (age|name|address) "
          116  +                + "FROM " + TEST_TABLE_NAME));
          117  +        assertTrue(sql.contains("age"));
          118  +        assertTrue(sql.contains("name"));
          119  +        assertTrue(sql.contains("address"));
          120  +
          121  +        sqliteQueryBuilder.setProjectionMap(null);
          122  +        sql = sqliteQueryBuilder.buildQuery(new String[] { "name", "address" },
          123  +                null, null, null, null, null, null);
          124  +        assertTrue(sql.matches("SELECT (name|address), (name|address) "
          125  +                + "FROM " + TEST_TABLE_NAME));
          126  +        assertTrue(sql.contains("name"));
          127  +        assertTrue(sql.contains("address"));
          128  +    }
          129  +
          130  +    public void testSetCursorFactory() {
          131  +        mDatabase.execSQL("CREATE TABLE test (_id INTEGER PRIMARY KEY, " +
          132  +                "name TEXT, age INTEGER, address TEXT);");
          133  +        mDatabase.execSQL("INSERT INTO test (name, age, address) VALUES ('Mike', '20', 'LA');");
          134  +        mDatabase.execSQL("INSERT INTO test (name, age, address) VALUES ('jack', '40', 'LA');");
          135  +
          136  +        SQLiteQueryBuilder sqliteQueryBuilder = new SQLiteQueryBuilder();
          137  +        sqliteQueryBuilder.setTables(TEST_TABLE_NAME);
          138  +        Cursor cursor = sqliteQueryBuilder.query(mDatabase, new String[] { "name", "age" },
          139  +                null, null, null, null, null);
          140  +        assertNotNull(cursor);
          141  +        assertTrue(cursor instanceof SQLiteCursor);
          142  +
          143  +        SQLiteDatabase.CursorFactory factory = new SQLiteDatabase.CursorFactory() {
          144  +            public Cursor newCursor(SQLiteDatabase db, SQLiteCursorDriver masterQuery,
          145  +                    String editTable, SQLiteQuery query) {
          146  +                return new MockCursor(db, masterQuery, editTable, query);
          147  +            }
          148  +        };
          149  +
          150  +        sqliteQueryBuilder.setCursorFactory(factory);
          151  +        cursor = sqliteQueryBuilder.query(mDatabase, new String[] { "name", "age" },
          152  +                null, null, null, null, null);
          153  +        assertNotNull(cursor);
          154  +        assertTrue(cursor instanceof MockCursor);
          155  +    }
          156  +
          157  +    private static class MockCursor extends SQLiteCursor {
          158  +        public MockCursor(SQLiteDatabase db, SQLiteCursorDriver driver,
          159  +                String editTable, SQLiteQuery query) {
          160  +            super(db, driver, editTable, query);
          161  +        }
          162  +    }
          163  +
          164  +    public void testBuildQueryString() {
          165  +        String expected;
          166  +        final String[] DEFAULT_TEST_PROJECTION = new String [] { "name", "age", "sum(salary)" };
          167  +        final String DEFAULT_TEST_WHERE = "age > 25";
          168  +        final String DEFAULT_HAVING = "sum(salary) > 3000";
          169  +
          170  +        String sql = SQLiteQueryBuilder.buildQueryString(false, "Employee",
          171  +                DEFAULT_TEST_PROJECTION,
          172  +                DEFAULT_TEST_WHERE, "name", DEFAULT_HAVING, "name", "100");
          173  +
          174  +        expected = "SELECT name, age, sum(salary) FROM Employee WHERE " + DEFAULT_TEST_WHERE +
          175  +                " GROUP BY name " +
          176  +                "HAVING " + DEFAULT_HAVING + " " +
          177  +                "ORDER BY name " +
          178  +                "LIMIT 100";
          179  +        assertEquals(expected, sql);
          180  +    }
          181  +
          182  +    public void testBuildQuery() {
          183  +        final String[] DEFAULT_TEST_PROJECTION = new String[] { "name", "sum(salary)" };
          184  +        final String DEFAULT_TEST_WHERE = "age > 25";
          185  +        final String DEFAULT_HAVING = "sum(salary) > 2000";
          186  +
          187  +        SQLiteQueryBuilder sqliteQueryBuilder = new SQLiteQueryBuilder();
          188  +        sqliteQueryBuilder.setTables(TEST_TABLE_NAME);
          189  +        sqliteQueryBuilder.setDistinct(false);
          190  +        String sql = sqliteQueryBuilder.buildQuery(DEFAULT_TEST_PROJECTION,
          191  +                DEFAULT_TEST_WHERE, null, "name", DEFAULT_HAVING, "name", "2");
          192  +        String expected = "SELECT name, sum(salary) FROM " + TEST_TABLE_NAME
          193  +                + " WHERE (" + DEFAULT_TEST_WHERE + ") " +
          194  +                "GROUP BY name HAVING " + DEFAULT_HAVING + " ORDER BY name LIMIT 2";
          195  +        assertEquals(expected, sql);
          196  +    }
          197  +
          198  +    public void testAppendColumns() {
          199  +        StringBuilder sb = new StringBuilder();
          200  +        String[] columns = new String[] { "name", "age" };
          201  +
          202  +        assertEquals("", sb.toString());
          203  +        SQLiteQueryBuilder.appendColumns(sb, columns);
          204  +        assertEquals("name, age ", sb.toString());
          205  +    }
          206  +
          207  +    public void testQuery() {
          208  +        createEmployeeTable();
          209  +
          210  +        SQLiteQueryBuilder sqliteQueryBuilder = new SQLiteQueryBuilder();
          211  +        sqliteQueryBuilder.setTables("Employee");
          212  +        Cursor cursor = sqliteQueryBuilder.query(mDatabase,
          213  +                new String[] { "name", "sum(salary)" }, null, null,
          214  +                "name", "sum(salary)>1000", "name");
          215  +        assertNotNull(cursor);
          216  +        assertEquals(3, cursor.getCount());
          217  +
          218  +        final int COLUMN_NAME_INDEX = 0;
          219  +        final int COLUMN_SALARY_INDEX = 1;
          220  +        cursor.moveToFirst();
          221  +        assertEquals("Jim", cursor.getString(COLUMN_NAME_INDEX));
          222  +        assertEquals(4500, cursor.getInt(COLUMN_SALARY_INDEX));
          223  +        cursor.moveToNext();
          224  +        assertEquals("Mike", cursor.getString(COLUMN_NAME_INDEX));
          225  +        assertEquals(4000, cursor.getInt(COLUMN_SALARY_INDEX));
          226  +        cursor.moveToNext();
          227  +        assertEquals("jack", cursor.getString(COLUMN_NAME_INDEX));
          228  +        assertEquals(3500, cursor.getInt(COLUMN_SALARY_INDEX));
          229  +
          230  +        sqliteQueryBuilder = new SQLiteQueryBuilder();
          231  +        sqliteQueryBuilder.setTables(EMPLOYEE_TABLE_NAME);
          232  +        cursor = sqliteQueryBuilder.query(mDatabase,
          233  +                new String[] { "name", "sum(salary)" }, null, null,
          234  +                "name", "sum(salary)>1000", "name", "2" // limit is 2
          235  +                );
          236  +        assertNotNull(cursor);
          237  +        assertEquals(2, cursor.getCount());
          238  +        cursor.moveToFirst();
          239  +        assertEquals("Jim", cursor.getString(COLUMN_NAME_INDEX));
          240  +        assertEquals(4500, cursor.getInt(COLUMN_SALARY_INDEX));
          241  +        cursor.moveToNext();
          242  +        assertEquals("Mike", cursor.getString(COLUMN_NAME_INDEX));
          243  +        assertEquals(4000, cursor.getInt(COLUMN_SALARY_INDEX));
          244  +    }
          245  +
          246  +    public void testUnionQuery() {
          247  +        String expected;
          248  +        String[] innerProjection = new String[] {"name", "age", "location"};
          249  +        SQLiteQueryBuilder employeeQueryBuilder = new SQLiteQueryBuilder();
          250  +        SQLiteQueryBuilder peopleQueryBuilder = new SQLiteQueryBuilder();
          251  +
          252  +        employeeQueryBuilder.setTables("employee");
          253  +        peopleQueryBuilder.setTables("people");
          254  +
          255  +        String employeeSubQuery = employeeQueryBuilder.buildUnionSubQuery(
          256  +                "_id", innerProjection,
          257  +                null, 2, "employee",
          258  +                "age=25",
          259  +                null, null, null);
          260  +        String peopleSubQuery = peopleQueryBuilder.buildUnionSubQuery(
          261  +                "_id", innerProjection,
          262  +                null, 2, "people",
          263  +                "location=LA",
          264  +                null, null, null);
          265  +        expected = "SELECT name, age, location FROM employee WHERE (age=25)";
          266  +        assertEquals(expected, employeeSubQuery);
          267  +        expected = "SELECT name, age, location FROM people WHERE (location=LA)";
          268  +        assertEquals(expected, peopleSubQuery);
          269  +
          270  +        SQLiteQueryBuilder unionQueryBuilder = new SQLiteQueryBuilder();
          271  +
          272  +        unionQueryBuilder.setDistinct(true);
          273  +
          274  +        String unionQuery = unionQueryBuilder.buildUnionQuery(
          275  +                new String[] { employeeSubQuery, peopleSubQuery }, null, null);
          276  +        expected = "SELECT name, age, location FROM employee WHERE (age=25) " +
          277  +                "UNION SELECT name, age, location FROM people WHERE (location=LA)";
          278  +        assertEquals(expected, unionQuery);
          279  +    }
          280  +
          281  +    public void testCancelableQuery_WhenNotCanceled_ReturnsResultSet() {
          282  +        createEmployeeTable();
          283  +
          284  +        CancellationSignal cancellationSignal = new CancellationSignal();
          285  +        SQLiteQueryBuilder sqliteQueryBuilder = new SQLiteQueryBuilder();
          286  +        sqliteQueryBuilder.setTables("Employee");
          287  +        Cursor cursor = sqliteQueryBuilder.query(mDatabase,
          288  +                new String[] { "name", "sum(salary)" }, null, null,
          289  +                "name", "sum(salary)>1000", "name", null, cancellationSignal);
          290  +
          291  +        assertEquals(3, cursor.getCount());
          292  +    }
          293  +
          294  +    public void testCancelableQuery_WhenCanceledBeforeQuery_ThrowsImmediately() {
          295  +        createEmployeeTable();
          296  +
          297  +        CancellationSignal cancellationSignal = new CancellationSignal();
          298  +        SQLiteQueryBuilder sqliteQueryBuilder = new SQLiteQueryBuilder();
          299  +        sqliteQueryBuilder.setTables("Employee");
          300  +
          301  +        cancellationSignal.cancel();
          302  +        try {
          303  +            sqliteQueryBuilder.query(mDatabase,
          304  +                    new String[] { "name", "sum(salary)" }, null, null,
          305  +                    "name", "sum(salary)>1000", "name", null, cancellationSignal);
          306  +            fail("Expected OperationCanceledException");
          307  +        } catch (OperationCanceledException ex) {
          308  +            // expected
          309  +        }
          310  +    }
          311  +
          312  +    public void testCancelableQuery_WhenCanceledAfterQuery_ThrowsWhenExecuted() {
          313  +        createEmployeeTable();
          314  +
          315  +        CancellationSignal cancellationSignal = new CancellationSignal();
          316  +        SQLiteQueryBuilder sqliteQueryBuilder = new SQLiteQueryBuilder();
          317  +        sqliteQueryBuilder.setTables("Employee");
          318  +
          319  +        Cursor cursor = sqliteQueryBuilder.query(mDatabase,
          320  +                new String[] { "name", "sum(salary)" }, null, null,
          321  +                "name", "sum(salary)>1000", "name", null, cancellationSignal);
          322  +
          323  +        cancellationSignal.cancel();
          324  +        try {
          325  +            cursor.getCount(); // force execution
          326  +            fail("Expected OperationCanceledException");
          327  +        } catch (OperationCanceledException ex) {
          328  +            // expected
          329  +        }
          330  +    }
          331  +
          332  +    public void testCancelableQuery_WhenCanceledDueToContention_StopsWaitingAndThrows() {
          333  +        createEmployeeTable();
          334  +
          335  +        for (int i = 0; i < 5; i++) {
          336  +            final CancellationSignal cancellationSignal = new CancellationSignal();
          337  +            final Semaphore barrier1 = new Semaphore(0);
          338  +            final Semaphore barrier2 = new Semaphore(0);
          339  +            Thread contentionThread = new Thread() {
          340  +                @Override
          341  +                public void run() {
          342  +                    mDatabase.beginTransaction(); // acquire the only available connection
          343  +                    barrier1.release(); // release query to start running
          344  +                    try {
          345  +                        barrier2.acquire(); // wait for test to end
          346  +                    } catch (InterruptedException e) {
          347  +                    }
          348  +                    mDatabase.endTransaction(); // release the connection
          349  +                }
          350  +            };
          351  +            Thread cancellationThread = new Thread() {
          352  +                @Override
          353  +                public void run() {
          354  +                    try {
          355  +                        Thread.sleep(300);
          356  +                    } catch (InterruptedException ex) {
          357  +                    }
          358  +                    cancellationSignal.cancel();
          359  +                }
          360  +            };
          361  +            try {
          362  +                SQLiteQueryBuilder sqliteQueryBuilder = new SQLiteQueryBuilder();
          363  +                sqliteQueryBuilder.setTables("Employee");
          364  +
          365  +                contentionThread.start();
          366  +                cancellationThread.start();
          367  +
          368  +                try {
          369  +                    barrier1.acquire(); // wait for contention thread to start transaction
          370  +                } catch (InterruptedException e) {
          371  +                }
          372  +
          373  +                final long startTime = System.nanoTime();
          374  +                try {
          375  +                    Cursor cursor = sqliteQueryBuilder.query(mDatabase,
          376  +                            new String[] { "name", "sum(salary)" }, null, null,
          377  +                            "name", "sum(salary)>1000", "name", null, cancellationSignal);
          378  +                    cursor.getCount(); // force execution
          379  +                    fail("Expected OperationCanceledException");
          380  +                } catch (OperationCanceledException ex) {
          381  +                    // expected
          382  +                }
          383  +
          384  +                // We want to confirm that the query really was blocked trying to acquire a
          385  +                // connection for a certain amount of time before it was freed by cancel.
          386  +                final long waitTime = System.nanoTime() - startTime;
          387  +                if (waitTime > 150 * 1000000L) {
          388  +                    return; // success!
          389  +                }
          390  +            } finally {
          391  +                barrier1.release();
          392  +                barrier2.release();
          393  +                try {
          394  +                    contentionThread.join();
          395  +                    cancellationThread.join();
          396  +                } catch (InterruptedException e) {
          397  +                }
          398  +            }
          399  +        }
          400  +
          401  +        // Occasionally we might miss the timing deadline due to factors in the
          402  +        // environment, but if after several trials we still couldn't demonstrate
          403  +        // that the query was blocked, then the test must be broken.
          404  +        fail("Could not prove that the query actually blocked before cancel() was called.");
          405  +    }
          406  +
          407  +    public void testCancelableQuery_WhenCanceledDuringLongRunningQuery_CancelsQueryAndThrows() {
          408  +        // Populate a table with a bunch of integers.
          409  +        mDatabase.execSQL("CREATE TABLE x (v INTEGER);");
          410  +        for (int i = 0; i < 100; i++) {
          411  +            mDatabase.execSQL("INSERT INTO x VALUES (?)", new Object[] { i });
          412  +        }
          413  +
          414  +        for (int i = 0; i < 5; i++) {
          415  +            final CancellationSignal cancellationSignal = new CancellationSignal();
          416  +            Thread cancellationThread = new Thread() {
          417  +                @Override
          418  +                public void run() {
          419  +                    try {
          420  +                        Thread.sleep(300);
          421  +                    } catch (InterruptedException ex) {
          422  +                    }
          423  +                    cancellationSignal.cancel();
          424  +                }
          425  +            };
          426  +            try {
          427  +                // Build an unsatisfiable 5-way cross-product query over 100 values but
          428  +                // produces no output.  This should force SQLite to loop for a long time
          429  +                // as it tests 10^10 combinations.
          430  +                SQLiteQueryBuilder sqliteQueryBuilder = new SQLiteQueryBuilder();
          431  +                sqliteQueryBuilder.setTables("x AS a, x AS b, x AS c, x AS d, x AS e");
          432  +
          433  +                cancellationThread.start();
          434  +
          435  +                final long startTime = System.nanoTime();
          436  +                try {
          437  +                    Cursor cursor = sqliteQueryBuilder.query(mDatabase, null,
          438  +                            "a.v + b.v + c.v + d.v + e.v > 1000000",
          439  +                            null, null, null, null, null, cancellationSignal);
          440  +                    cursor.getCount(); // force execution
          441  +                    fail("Expected OperationCanceledException");
          442  +                } catch (OperationCanceledException ex) {
          443  +                    // expected
          444  +                }
          445  +
          446  +                // We want to confirm that the query really was running and then got
          447  +                // canceled midway.
          448  +                final long waitTime = System.nanoTime() - startTime;
          449  +                if (waitTime > 150 * 1000000L && waitTime < 600 * 1000000L) {
          450  +                    return; // success!
          451  +                }
          452  +            } finally {
          453  +                try {
          454  +                    cancellationThread.join();
          455  +                } catch (InterruptedException e) {
          456  +                }
          457  +            }
          458  +        }
          459  +
          460  +        // Occasionally we might miss the timing deadline due to factors in the
          461  +        // environment, but if after several trials we still couldn't demonstrate
          462  +        // that the query was canceled, then the test must be broken.
          463  +        fail("Could not prove that the query actually canceled midway during execution.");
          464  +    }
          465  +
          466  +    private void createEmployeeTable() {
          467  +        mDatabase.execSQL("CREATE TABLE employee (_id INTEGER PRIMARY KEY, " +
          468  +                "name TEXT, month INTEGER, salary INTEGER);");
          469  +        mDatabase.execSQL("INSERT INTO employee (name, month, salary) " +
          470  +                "VALUES ('Mike', '1', '1000');");
          471  +        mDatabase.execSQL("INSERT INTO employee (name, month, salary) " +
          472  +                "VALUES ('Mike', '2', '3000');");
          473  +        mDatabase.execSQL("INSERT INTO employee (name, month, salary) " +
          474  +                "VALUES ('jack', '1', '2000');");
          475  +        mDatabase.execSQL("INSERT INTO employee (name, month, salary) " +
          476  +                "VALUES ('jack', '3', '1500');");
          477  +        mDatabase.execSQL("INSERT INTO employee (name, month, salary) " +
          478  +                "VALUES ('Jim', '1', '1000');");
          479  +        mDatabase.execSQL("INSERT INTO employee (name, month, salary) " +
          480  +                "VALUES ('Jim', '3', '3500');");
          481  +    }
          482  +}

Added sqlite3/src/androidTest/java/org/sqlite/database/SQLiteQueryTest.java.

            1  +/*
            2  + * Copyright (C) 2009 The Android Open Source Project
            3  + *
            4  + * Licensed under the Apache License, Version 2.0 (the "License");
            5  + * you may not use this file except in compliance with the License.
            6  + * You may obtain a copy of the License at
            7  + *
            8  + *      http://www.apache.org/licenses/LICENSE-2.0
            9  + *
           10  + * Unless required by applicable law or agreed to in writing, software
           11  + * distributed under the License is distributed on an "AS IS" BASIS,
           12  + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
           13  + * See the License for the specific language governing permissions and
           14  + * limitations under the License.
           15  + */
           16  +
           17  +package org.sqlite.database;
           18  +
           19  +import junit.framework.TestCase;
           20  +
           21  +public class SQLiteQueryTest extends TestCase {
           22  +    public void testMethods() {
           23  +        // cannot obtain an instance of SQLiteQuery
           24  +    }
           25  +}