199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson/*
299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson * Copyright (C) 2008 The Android Open Source Project
399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson *
499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson * Licensed under the Apache License, Version 2.0 (the "License");
599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson * you may not use this file except in compliance with the License.
699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson * You may obtain a copy of the License at
799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson *
899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson *      http://www.apache.org/licenses/LICENSE-2.0
999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson *
1099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson * Unless required by applicable law or agreed to in writing, software
1199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson * distributed under the License is distributed on an "AS IS" BASIS,
1299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson * See the License for the specific language governing permissions and
1499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson * limitations under the License.
1599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson */
1699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
1799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilsonpackage libcore.sqlite;
1899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
1999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilsonimport SQLite.Authorizer;
2099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilsonimport SQLite.Blob;
2199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilsonimport SQLite.BusyHandler;
2299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilsonimport SQLite.Callback;
2399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilsonimport SQLite.Constants;
2499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilsonimport SQLite.Database;
2599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilsonimport SQLite.Exception;
2699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilsonimport SQLite.Function;
2799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilsonimport SQLite.FunctionContext;
2899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilsonimport SQLite.ProgressHandler;
2999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilsonimport SQLite.Stmt;
3099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilsonimport SQLite.TableResult;
3199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilsonimport SQLite.Trace;
3299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilsonimport SQLite.Vm;
3399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilsonimport java.io.File;
3499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilsonimport java.io.InputStream;
3599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilsonimport java.io.UnsupportedEncodingException;
3699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilsonimport java.net.URL;
3799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilsonimport java.sql.DatabaseMetaData;
3899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilsonimport java.sql.ResultSet;
3999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilsonimport java.sql.SQLException;
4099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilsonimport java.sql.Statement;
4199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilsonimport java.util.ArrayList;
4299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilsonimport java.util.Arrays;
4399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilsonimport java.util.List;
4499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilsonimport java.util.logging.Logger;
4599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilsonimport tests.support.DatabaseCreator;
4699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilsonimport tests.support.MockFunction;
4799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilsonimport tests.support.ThreadPool;
4899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
4999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilsonpublic final class OldDatabaseTest extends OldSQLiteTest {
5099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
5199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    private static ErrorTracker tracker = null;
5299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
5399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    private Statement statement;
5499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
5599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    private Database db = null;
5699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
5799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    private static final int numThreads = 10;
5899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
5999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    private static final int numOfRecords = 30;
6099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
6199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    @Override public void setUp() throws java.lang.Exception {
6299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        super.setUp();
6399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        assertNotNull("Could not establish DB connection",conn);
6499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        tracker = new ErrorTracker();
6599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
6699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        statement = conn.createStatement();
6799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
6899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        // Cleanup tables if necessary
6999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
7099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        DatabaseMetaData meta = conn.getMetaData();
7199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        assertNotNull(meta);
7299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        ResultSet userTab = meta.getTables(null, null, null, null);
7399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        while (userTab.next()) {
7499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            String tableName = userTab.getString("TABLE_NAME");
7599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            this.statement.execute("drop table " + tableName);
7699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        }
7799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
7899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        // Create default test table
7999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        statement.execute(DatabaseCreator.CREATE_TABLE_SIMPLE1);
8099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        statement.close();
8199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
8299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        db = new Database();
8399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        db.open(dbFile.getPath(), 0);
8499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        db.busy_handler(null);
8599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    }
8699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
8799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    public void tearDown() throws java.lang.Exception {
8899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        try {
8999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            db.close();
9099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        } catch (Exception e) {
9199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            if (!(e.getMessage().equals("database already closed"))) {
9299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                System.err.println("Error closing DB " + dbFile.getPath());
9399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            }
9499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        }
9599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        tracker.reset();
9699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        super.tearDown();
9799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    }
9899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
9999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    public void testDatabase() throws Exception {
10099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        // db closed
10199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        Database db2 = new Database();
10299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        db.close();
10399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        db2 = new Database();
10499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        db2.open(dbFile.getPath(), 0);
10599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        db2.close();
10699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        db.open(dbFile.getPath(), 0);
10799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        //db is open
10899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        db2.open(dbFile.getPath(), 0);
10999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        db2.close();
11099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    }
11199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
11299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    public void testOpen() throws Exception {
11399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        db.close();
11499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        db.open(dbFile.getPath(), 0);
11599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        // open second db while db1 still open
11699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        Database db2 = new Database();
11799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        db2.open(dbFile.getPath(), 0);
11899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        db2.open(dbFile.getPath(), 0);
11999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        db2.close();
12099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        // open non db file
12199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        try {
12299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            URL file = OldDatabaseTest.class.getResource("/blob.c");
12399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            db2.open(file.getPath(), 0);
12499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            fail("Should not be able to open non db file");
12599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        } catch (SQLite.Exception e) {
12699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            assertEquals("unknown error in open", e.getMessage());
12799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        }
12899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    }
12999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
13099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    public void testOpen_aux_file() {
13199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        File temp = null;
13299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        try {
13399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            db.open_aux_file("");
13499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            fail("open should fail");
13599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        } catch (Exception e) {
13699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            assertEquals("unsupported", e.getMessage());
13799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        }
13899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
13999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson     /*
14099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        try {
14199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            temp = File.createTempFile("openAuxMethod", ".db");
14299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            db.open_aux_file("");
14399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            db.exec("create table AUX_TABLE", null);
14499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            db.close();
14599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        } catch (Exception e) {
14699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            temp.delete();
14799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            fail("Error handling temporary file "+e.getMessage());
14899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            e.printStackTrace();
14999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        } catch (IOException e) {
15099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            temp.delete();
15199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            fail("Could not create temporary File");
15299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            e.printStackTrace();
15399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        }
15499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        try {
15599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            db.open(dbFile.getPath(),0);
15699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            db.exec("select * from AUX_TABLE", null);
15799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            fail("Statement should fail");
15899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        } catch (Exception e) {
15999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            // TODO Auto-generated catch block
16099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            e.printStackTrace();
16199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        }
16299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
16399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        temp.delete();
16499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        */
16599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    }
16699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
16799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    public void testClose() throws Exception {
16899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        try {
16999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            db.close();
17099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            db.get_table("test");
17199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            fail();
17299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        } catch (Exception e) {
17399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            assertTrue(e.getMessage().equals("database already closed"));
17499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            try {
17599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                db.open(dbFile.getPath(), 0);
17699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            } catch (Exception e1) {
17799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                fail("Database object could not be reopened after 'close': "
17899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                        + e.getMessage());
17999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                e1.printStackTrace();
18099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            }
18199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        }
18299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
18399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        try {
18499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            db.close();
18599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            db.close();
18699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            fail();
18799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        } catch (Exception e) {
18899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            assertTrue(e.getMessage().equals("database already closed"));
18999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            db.open(dbFile.getPath(), 0);
19099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        }
19199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    }
19299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
19399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    public void testExecStringCallback() throws Exception {
19499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        TableResult res = new TableResult();
19599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        db.exec("insert into " + DatabaseCreator.SIMPLE_TABLE1
19699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                + " VALUES(1, 10, 20)", null);
19799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        db.exec("select * from " + DatabaseCreator.SIMPLE_TABLE1, res);
19899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        db.exec("delete from " + DatabaseCreator.SIMPLE_TABLE1 + " where 1", null);
19999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        String row[] = (String[]) res.rows.elementAt(0);
20099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        assertEquals(Integer.parseInt(row[0]), 1);
20199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        assertEquals(Integer.parseInt(row[1]), 10);
20299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        assertEquals(Integer.parseInt(row[2]), 20);
20399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    }
20499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
20599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    public void testExecStringCallbackStringArray() throws Exception {
20699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        TableResult res = new TableResult();
20799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        String args[] = new String[1];
20899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        args[0] = "table";
20999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        db.exec("select name from sqlite_master where type = '%q';", res, args);
21099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        String[] s = (String[]) res.rows.elementAt(0);
21199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        assertEquals(s[0], DatabaseCreator.SIMPLE_TABLE1);
21299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
21399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        try {
21499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            db.exec("select name from sqlite_master where type = ", res, args);
21599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            fail("Testmethod should fail");
21699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        } catch (Exception e) {
21799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            // Ok
21899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        }
21999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    }
22099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
22199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    public void testLast_insert_rowid() throws Exception {
22299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        assertEquals(0, db.last_insert_rowid());
22399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        db.exec("create table TEST5(id integer, firstname text, lastname text);", null);
22499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        db.exec("insert into TEST5 values (1,'James','Bond');", null);
22599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        db.exec("insert into TEST5 values (2,'Fiona','Apple');", null);
22699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        assertEquals(2, db.last_insert_rowid());
22799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        assertEquals(db.last_insert_rowid(), db.last_insert_rowid());
22899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
22999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        db.exec("drop table TEST5;", null);
23099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        assertEquals(2, db.last_insert_rowid());
23199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    }
23299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
23399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    /**
23499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson     * Reason for failure unknown: Database should be locked. Specification
23599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson     * of interrupt is scarce.
23699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson     */
23799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    public void testInterrupt() throws Exception, SQLException {
23899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        ThreadPool threadPool = new ThreadPool(numThreads);
23999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
24099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        // initialization
24199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        ResultSet userTabs;
24299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        userTabs = conn.getMetaData().getTables(null, null, null, null);
24399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        while (userTabs.next()) {
24499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            String tableName = userTabs.getString("TABLE_NAME");
24599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            if (tableName.equals(DatabaseCreator.TEST_TABLE1)) {
24699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                statement.execute(DatabaseCreator.DROP_TABLE1);
24799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            }
24899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        }
24999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        db.exec(DatabaseCreator.CREATE_TABLE3, null);
25099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        db.exec(DatabaseCreator.CREATE_TABLE1, null);
25199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
25299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        int id1 = numOfRecords - 3;
25399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        threadPool.runTask(createTask1(id1, dbFile.getPath(), tracker));
25499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        // should not be able to do any other insertions since task 1 holds lock
25599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        int id2 = numOfRecords + 3;
25699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        threadPool
25799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                .runTask(createTask2Interrupt(id2, dbFile.getPath(), tracker));
25899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
25999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        threadPool.join();
26099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
26199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        List<String> errors = tracker.getErrors();
26299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        System.out.println("Last error: " + db.error_message());
26399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        if (errors.size() > 0) {
26499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            assertEquals(errors.get(0), db.error_string(Constants.SQLITE_LOCKED));
26599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            for (String s : errors) {
26699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                Logger.global.info("INTERRUPT Error: " + s);
26799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            }
26899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
26999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        } else {
27099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            fail("Should have one exception: database should be locked.");
27199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        }
27299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
27399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        // reset
27499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        db.exec("delete from " + DatabaseCreator.TEST_TABLE1 + " where 1", null);
27599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        db.exec("delete from " + DatabaseCreator.TEST_TABLE3 + " where 1", null);
27699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    }
27799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
27899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    /**
27999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson     * Returns wrong number for updates: returns value > 1 for select.
28099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson     */
28199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    public void testChanges() throws Exception {
28299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        TableResult res = new TableResult();
28399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        assertTrue(db.changes() == 0);
28499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        db.exec("INSERT INTO " + DatabaseCreator.SIMPLE_TABLE1
28599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                + " VALUES(2, 5, 7);", null);
28699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        int rows = (int) db.changes();
28799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        assertEquals(1,db.changes());
28899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        db.exec("update " + DatabaseCreator.SIMPLE_TABLE1
28999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                + " set speed = 7, size= 5 where id = 2;", null);
29099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        assertEquals(1,db.changes());
29199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        db.exec("select * from " + DatabaseCreator.SIMPLE_TABLE1, res);
29299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        assertEquals(0,db.changes());
29399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        db.exec("INSERT INTO " + DatabaseCreator.SIMPLE_TABLE1
29499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                + " VALUES(8, 5, 7);", null);
29599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        db.exec("Update "+DatabaseCreator.SIMPLE_TABLE1+" set speed = 10;",null);
29699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        assertTrue(db.changes() > 2);
29799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    }
29899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
29999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    /**
30099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson     * method test fails once in a while. Cannot be sure that exception is
30199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson     * thrown in every test execution.
30299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson     */
30399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    public void testBusy_handler() throws SQLException, Exception {
30499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        TestBusyHandler bh = new TestBusyHandler();
30599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        db.busy_handler(bh);
30699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        int counter = 0;
30799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        ThreadPool threadPool = new ThreadPool(numThreads);
30899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
30999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        // initialization
31099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        ResultSet userTabs;
31199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        userTabs = conn.getMetaData().getTables(null, null, null, null);
31299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        while (userTabs.next()) {
31399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            String tableName = userTabs.getString("TABLE_NAME");
31499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            if (tableName.equals(DatabaseCreator.TEST_TABLE1)) {
31599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                statement.execute(DatabaseCreator.DROP_TABLE1);
31699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            }
31799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        }
31899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        db.exec(DatabaseCreator.CREATE_TABLE3, null);
31999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        db.exec(DatabaseCreator.CREATE_TABLE1, null);
32099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
32199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
32299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        try {
32399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            conn.setAutoCommit(false);
32499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            int id1 = numOfRecords - 3;
32599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            threadPool.runTask(createTask1(id1, dbFile.getPath(), tracker));
32699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            int id2 = numOfRecords + 3;
32799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            threadPool.runTask(createTask2(id2, dbFile.getPath(), tracker));
32899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            int oldID = 5;
32999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            int newID = 100;
33099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            threadPool.runTask(createTask3(oldID, dbFile.getPath(), newID,
33199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                    tracker));
33299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
33399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            threadPool.join();
33499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
33599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            List<String> errors = tracker.getErrors();
33699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            if (errors.size() > 0) {
33799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson//                 assertEquals(errors.get(0),
33899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson//                 db.error_string(Constants.SQLITE_LOCKED));
33999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                for (String s: errors) {
34099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                  System.out.println("Round 2 Error: "+s);
34199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson              }
34299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            } else {
34399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                fail("No error happened");
34499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            }
34599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
34699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            // reset
34799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
34899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
34999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            db.exec("delete from " + DatabaseCreator.TEST_TABLE1 + " where 1",
35099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                    null);
35199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            db.exec("delete from " + DatabaseCreator.TEST_TABLE3 + " where 1",
35299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                            null);
35399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson//
35499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson//            // increase timeout for retry
35599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson//            db.busy_timeout(1000);
35699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson//            db.busy_handler(bh);
35799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson//            tracker.reset();
35899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
35999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson//            threadPool = new ThreadPool(numThreads);
36099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson//
36199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson//            threadPool.runTask(createTask1(id1, dbFile.getPath(), tracker));
36299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson//            threadPool.runTask(createTask2(id2, dbFile.getPath(), tracker));
36399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson//
36499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson//            threadPool.join();
36599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson//
36699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson//            errors = tracker.getErrors();
36799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson//            if (errors.size() > 0) {
36899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson//                // assertEquals(errors.get(0),
36999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson//                // db.error_string(Constants.SQLITE_LOCKED));
37099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson//                for (String s: errors) {
37199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson//                    System.out.println("Round 2 Error"+s);
37299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson//                }
37399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson//            } else {
37499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson//                // ok
37599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson//                System.out.println("BUSY: No Error!");
37699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson//            }
37799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson//
37899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson//
37999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        } finally {
38099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            conn.setAutoCommit(true);
38199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            db.exec(DatabaseCreator.DROP_TABLE1, null);
38299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            db.exec(DatabaseCreator.DROP_TABLE3, null);
38399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        }
38499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    }
38599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
38699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    /**
38799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson     * test fails. Cannot be sure that exception is thrown every time.
38899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson     * Database does not lock values.
38999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson     */
39099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    public void testBusy_timeout() throws Exception, SQLException {
39199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        int counter = 0;
39299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        ThreadPool threadPool = new ThreadPool(numThreads);
39399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
39499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        // initialization
39599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        ResultSet userTabs = conn.getMetaData().getTables(null, null, null, null);
39699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        while (userTabs.next()) {
39799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            String tableName = userTabs.getString("TABLE_NAME");
39899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            if (tableName.equals(DatabaseCreator.TEST_TABLE1)) {
39999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                statement.execute(DatabaseCreator.DROP_TABLE1);
40099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            }
40199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        }
40299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        db.exec(DatabaseCreator.CREATE_TABLE3, null);
40399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        db.exec(DatabaseCreator.CREATE_TABLE1, null);
40499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
40599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        // test run
40699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        try {
40799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            conn.setAutoCommit(false);
40899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
40999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson//            DatabaseCreator.fillTestTable1(conn, numOfRecords);
41099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            // set to fail immediately if table is locked.
41199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            db.busy_handler(null);
41299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            db.busy_timeout(0);
41399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            int id1 = numOfRecords - 3;
41499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
41599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            threadPool.runTask(createTask2(id1, dbFile.getPath(), tracker));
41699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            int id2 = numOfRecords + 3;
41799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            threadPool.runTask(createTask1(id2, dbFile.getPath(), tracker));
41899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            int oldID = 5;
41999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            int newID = 100;
42099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            threadPool.runTask(createTask3(oldID, dbFile.getPath(), newID,
42199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                    tracker));
42299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
42399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            threadPool.join();
42499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
42599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            List<String> errors = tracker.getErrors();
42699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            assertTrue("No error occurred on DB but should have",errors.size() > 0);
42799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
42899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            assertEquals(errors.get(0),
42999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            db.error_string(Constants.SQLITE_LOCKED));
43099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            assertEquals(errors.get(0), "database is locked");
43199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
43299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            // reset
43399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
43499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            db.exec("delete from " + DatabaseCreator.TEST_TABLE1 + " where 1",
43599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                    null);
43699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            db.exec("delete from " + DatabaseCreator.TEST_TABLE3 + " where 1",
43799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                            null);
43899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
43999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            // increase timeout for retry
44099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            db.busy_timeout(10000);
44199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            db.busy_handler(null);
44299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            tracker.reset();
44399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            threadPool = new ThreadPool(numThreads);
44499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
44599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            threadPool.runTask(createTask1(id1, dbFile.getPath(), tracker));
44699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            threadPool.runTask(createTask2(id2, dbFile.getPath(), tracker));
44799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
44899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            threadPool.join();
44999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
45099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            errors = tracker.getErrors();
45199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            if (errors.size() > 0) {
45299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                fail("busy timeout should prevent from lock exception!");
45399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                for (String s: errors) {
45499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                    System.out.println("Round 2 Error"+s);
45599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                }
45699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            } else {
45799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                // ok
45899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            }
45999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        } finally {
46099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            conn.setAutoCommit(true);
46199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            // cleanup
46299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            db.exec(DatabaseCreator.DROP_TABLE1, null);
46399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            db.exec(DatabaseCreator.DROP_TABLE3, null);
46499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        }
46599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    }
46699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
46799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    public void testGet_tableString() throws Exception {
46899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        TableResult emptyTable = new TableResult();
46999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        //select from empty table
47099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        TableResult res = db.get_table("select * from " + DatabaseCreator.SIMPLE_TABLE1);
47199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        assertEquals(res.toString(), emptyTable.toString());
47299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        //fill table-> t
47399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson//        DatabaseCreator.fillSimpleTable1(conn);
47499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson//        res = db.get_table("select * from "
47599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson//                + DatabaseCreator.SIMPLE_TABLE1);
47699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson//        assertFalse(emptyTable.toString().equals(res.toString()));
47799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
47899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        db.exec("insert into " + DatabaseCreator.SIMPLE_TABLE1 + " VALUES(1, 10, 20)", null);
47999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        res = db.get_table("select * from " + DatabaseCreator.SIMPLE_TABLE1);
48099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        db.exec("delete from " + DatabaseCreator.SIMPLE_TABLE1
48199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                + " where 1", null);
48299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        String row[] = (String[]) res.rows.elementAt(0);
48399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        assertEquals(Integer.parseInt(row[0]), 1);
48499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        assertEquals(Integer.parseInt(row[1]), 10);
48599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        assertEquals(Integer.parseInt(row[2]), 20);
48699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    }
48799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
48899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    public void testGet_tableStringStringArray() throws Exception {
48999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        String args[] = new String[1];
49099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        args[0] = "table";
49199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        String argsFail[] = new String[1];
49299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        try {
49399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            db.get_table("select name from sqlite_master where type = ", argsFail);
49499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            fail("Testmethod should fail");
49599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        } catch (Exception e) {
49699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        }
49799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
49899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        TableResult res = db.get_table(
49999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                "select name from sqlite_master where type = '%q'",
50099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                args);
50199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        String[] s = (String[]) res.rows.elementAt(0);
50299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        assertEquals(s[0], DatabaseCreator.SIMPLE_TABLE1);
50399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    }
50499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
50599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    public void testGet_tableStringStringArrayTableResult() throws Exception {
50699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        String args[] = new String[1];
50799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        String argsFail[] = new String[1];
50899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        TableResult res = new TableResult();
50999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        TableResult defaultTableRes = new TableResult();
51099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        args[0] = "table";
51199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
51299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        try {
51399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            db.get_table("select name from sqlite_master where type = '%q'", argsFail, res);
51499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            assertEquals(defaultTableRes.toString(), res.toString());
51599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        } catch (Exception e) {
51699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            db.get_table("select name from sqlite_master where type = '%q'", args, res);
51799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            String[] s = (String[]) res.rows.elementAt(0);
51899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            assertEquals(s[0], DatabaseCreator.SIMPLE_TABLE1);
51999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            System.out.println("DatabaseTest.testGet_tableStringStringArrayTableResult() "
52099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                    + Arrays.toString(res.types));
52199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        }
52299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    }
52399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
52499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    public void testComplete() {
52599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        assertFalse(db.complete("create"));
52699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        assertTrue(db.complete("create table TEST (res double);"));
52799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    }
52899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
52999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    public void testVersion() {
53099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        String version = db.version();
53199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        if (version != null) {
53299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            assertTrue(Integer.parseInt(db.version().substring(0, 1)) > 0);
53399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            assertEquals(db.version(), db.version());
53499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        } else {
53599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            fail("DB version info missing");
53699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        }
53799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    }
53899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
53999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    public void testDbversion() throws Exception {
54099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        String verNo = "";
54199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        try {
54299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            verNo = db.dbversion();
54399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            db.close();
54499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            assertEquals(db.dbversion(),"unknown");
54599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            db.open(dbFile.getPath(), 0);
54699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            assertEquals(verNo, db.dbversion());
54799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        } catch (Exception e) {
54899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            db.open(dbFile.getPath(), 0);
54999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        }
55099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
55199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        assertTrue(Integer.parseInt(verNo.substring(0, 1))>= 3 );
55299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
55399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    }
55499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
55599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    public void testCreate_function() throws Exception {
55699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        double input = 1.0;
55799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        db.exec("create table TEST (res double)", null);
55899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        db.exec("insert into TEST values (" + Double.toString(input) + ")",
55999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                null);
56099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        TableResult res = new TableResult();
56199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        Function sinFunc = (Function) new SinFunc();
56299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        db.create_function("sin", 1, sinFunc);
56399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        db.exec("select sin(res) from TEST WHERE res = "
56499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                + Double.toString(input), res);
56599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        String row[] = (String[]) res.rows.elementAt(0);
56699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        String val = row[0];
56799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        double sinusVal = Double.parseDouble(val);
56899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        double funcVal = Math.sin(input);
56999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
57099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        assertTrue(Math.round(funcVal) == Math.round(sinusVal));
57199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    }
57299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
57399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    /**
57499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson     * Aggregation function not called.
57599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson     */
57699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    public void testCreate_aggregate() throws Exception {
57799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        TestTrace t = new TestTrace();
57899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        MockFunction aggFunction = new MockFunction();
57999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        db.exec("create table TEST(id integer, firstname text, lastname text)", null);
58099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        db.exec("insert into TEST values(3, 'James', 'Bond'); ", null);
58199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        db.exec("insert into TEST values(4, 'Fiona', 'Apple'); ", null);
58299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        db.trace((Trace) t);
58399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        db.create_aggregate("myaggfunc", 1, aggFunction);
58499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        db.function_type("myaggfunc", Constants.SQLITE3_TEXT);
58599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        db.exec("PRAGMA show_datatypes = on", null);
58699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
58799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        assertFalse(aggFunction.functionCalled);
58899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        assertFalse(aggFunction.stepCalled);
58999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        assertFalse(aggFunction.lastStepCalled);
59099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        db.exec("select myaggfunc(TEST.firstname) from TEST", t);
59199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        assertTrue(aggFunction.stepCalled);
59299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        assertTrue(aggFunction.lastStepCalled);
59399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        assertTrue(aggFunction.functionCalled);
59499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
59599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        assertEquals("James Fiona ",aggFunction.getAggValue());
59699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        db.exec("drop table TEST", null);
59799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
59899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        try {
59999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            db.create_aggregate("myaggfunc", 0, null);
60099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        } catch (Throwable e) {
60199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            assertEquals("null SQLite.Function not allowed",e.getMessage());
60299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        }
60399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
60499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson          try {
60599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            db.create_aggregate("myaggfunc", 0, aggFunction);
60699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        } catch (Throwable e) {
60799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            assertEquals("wrong number of arguments to function myaggfunc()",e.getMessage());
60899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        }
60999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    }
61099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
61199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    public void testFunction_type() throws Exception {
61299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        double input = 1.0;
61399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        TableResult res = new TableResult();
61499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        Function sinFunc = (Function) new SinFunc();
61599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
61699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        db.exec("PRAGMA show_datatypes = on", null);
61799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        db.exec("create table TEST (res double)", null);
61899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        db.exec("insert into TEST values (" + Double.toString(input) + ")",
61999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                null);
62099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
62199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        db.create_function("sin", 1, sinFunc);
62299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        db.function_type("sin", Constants.SQLITE_FLOAT);
62399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        res = db.get_table("select sin(res) from TEST WHERE res = "
62499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                + Double.toString(input));
62599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
62699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        String row[] = (String[]) res.rows.elementAt(0);
62799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        String val = row[0];
62899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        assertTrue("double".equalsIgnoreCase(res.types[0]));
62999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        assertSame(Math.round(Math.sin(input)), Math.round(Double.parseDouble(val)));
63099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
63199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        // function determines return type: test that Double type is returned.
63299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        db.function_type("sin", Constants.SQLITE_BLOB);
63399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        Stmt s = db.prepare("select sin(res) from TEST WHERE res = ?");
63499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        s.bind(1, input);
63599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        s.step();
63699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
63799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        res = db.get_table("select sin(res) from TEST WHERE res = "
63899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                + Double.toString(input));
63999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        assertTrue("double".equalsIgnoreCase(res.types[0]));
64099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        row = (String[]) res.rows.elementAt(0);
64199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        val = row[0];
64299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        assertSame(Math.round(Math.sin(input)), Math.round(Double.parseDouble(val)));
64399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    }
64499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
64599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    public void testLast_error() {
64699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        assertEquals(db.last_error(), Constants.SQLITE_OK);
64799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        try {
64899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            db.exec("create table TEST (res double)",null);
64999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            db.exec("create table TEST (res double)",null);
65099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            fail("Error should have happened");
65199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        } catch (Exception e) {
65299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            assertEquals(db.last_error(),db.last_error());
65399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            assertEquals(db.last_error(),Constants.SQLITE_ERROR);
65499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        }
65599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    }
65699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
65799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    public void testSet_last_error() {
65899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson       assertEquals(db.last_error(), Constants.SQLITE_OK);
65999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson       try {
66099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson           db.exec("sel from test;", null);
66199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson       } catch (Exception e) {
66299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson           assertEquals(Constants.SQLITE_ERROR,db.last_error());
66399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson       }
66499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    }
66599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
66699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    public void testError_message() {
66799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        String statement = "create table TEST (res double)";
66899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        try {
66999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            db.exec(statement,null);
67099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            db.exec(statement,null);
67199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            fail("DB Error expected");
67299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        } catch (Exception e) {
67399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            String dbError = db.error_message();
67499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            assertTrue(e.getMessage().equals(dbError));
67599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
67699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        }
67799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    }
67899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
67999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    public void testError_string() {
68099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        TestTrace t = new TestTrace();
68199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        assertEquals(db.last_error(), Constants.SQLITE_OK);
68299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        String errorString = db.error_string(Constants.SQLITE_ERROR);
68399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        try {
68499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            db.trace((Trace) t);
68599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            db.exec("create table TEST (res double)", t);
68699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            db.exec("create table TEST (res double)", t);
68799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        } catch (Exception e) {
68899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            assertEquals(db.last_error(), Constants.SQLITE_ERROR);
68999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            if (db.is3()) {
69099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                assertEquals("Unsupported Method (sqlite 3): error_string", db
69199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                        .error_string(db.last_error()), errorString);
69299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            }
69399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        }
69499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    }
69599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
69699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    /**
69799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson     * ASCII encoding does not work: a UTF encoded val is returned. Spec is not
69899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson     * sufficient. Might be that test impl is wrong or String constructor for
69999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson     * the ASCII encoding.
70099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson     */
70199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    public void testSet_encoding() throws UnsupportedEncodingException, Exception {
70299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        String input = "\u00bfMa\u00f1ana\u003f"; // ?Manana?
70399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        TableResult res = new TableResult();
70499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        String refOutput = null;
70599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        Stmt stat = null;
70699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
70799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        // DB setup
70899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        db.exec("create table encodingTest (encoded text DEFAULT NULL);",
70999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                null);
71099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        stat = db
71199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                .prepare("insert into encodingTest(encoded) values(:one);");
71299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        stat.bind(1, input);
71399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        stat.step();
71499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        // stat.close();
71599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        db.exec("select * from encodingTest;", res);
71699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        String[] encInput = (String[]) res.rows.elementAt(0);
71799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        String output = encInput[0];
71899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        assertEquals(input, output);
71999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        // db.exec("delete from encodingTest where 1", null);
72099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
72199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson     // tests for different encoding schemes
72299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        String[] charsetNames = {"UTF-8", "UTF-16", "UTF-16BE", "UTF-16LE"};
72399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        for (int i = 0; i < charsetNames.length; i++) {
72499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            byte[] encInputBytes = input.getBytes(charsetNames[i]);
72599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            db.set_encoding(charsetNames[i]);
72699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            db.exec("select * from encodingTest;", res);
72799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            String[] encOutput = (String[]) res.rows.elementAt(0);
72899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            String inputAsString = new String(encInputBytes,charsetNames[i]);
72999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            assertEquals(inputAsString, encOutput[0]);
73099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        }
73199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
73299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        // Default tests
73399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        db.set_encoding("UTF-16");
73499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        db.exec("select * from encodingTest;", res);
73599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        String[] encOutput1 = (String[]) res.rows.elementAt(0);
73699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        assertEquals("Got "+encOutput1[0]+" as UTF-16",input,encOutput1[0]);
73799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
73899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        db.set_encoding("US-ASCII");
73999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        db.exec("select * from encodingTest;", res);
74099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        String[] encOutput2 = (String[]) res.rows.elementAt(0);
74199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        assertEquals(new String(input.getBytes(),"US-ASCII"),encOutput2[0]);
74299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
74399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        // DB teardown
74499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        stat.close();
74599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        db.exec("delete from encodingTest", null);
74699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
74799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        // Default tests
74899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        try {
74999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            db.set_encoding("");
75099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            fail("invalid input should fail");
75199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        } catch (Exception e) {
75299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            //ok
75399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        }
75499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    }
75599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
75699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    /**
75799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson     * Callback never made for authorization. Results of private table are
75899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson     * returned withouth furhter checks.
75999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson     *
76099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson     * Test fails -> implemented correctly?
76199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson     */
76299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    public void testSet_authorizer() throws Exception {
76399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        TableResult resPriv = null;
76499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        TableResult resPub = null;
76599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        TableResult emptyTable = new TableResult();
76699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        String insertPublic = "insert into public_table values(1,2)";
76799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        String insertPrivate = "insert into private_table values(1,2)";
76899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        // prepare, authorizer is not activated yet
76999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        db.exec("create table public_table(c1 integer, c2 integer);", null);
77099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        db.exec("create table private_table(c1 integer, c2 integer);", null);
77199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        // inserts
77299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        db.exec(insertPublic, null);
77399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        db.exec(insertPrivate, null);
77499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        // selects
77599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        resPriv = db.get_table("select * from private_table");
77699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        resPub = db.get_table("select * from public_table");
77799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
77899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson//        db.exec("delete from public_table where 1", null);
77999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson//        TableResult emptyPubTable = db.exec("select * from public");
78099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
78199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        // set Authorizer (positive case): denies private table
78299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        AuthorizerCallback cb = new AuthorizerCallback();
78399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        db.set_authorizer(cb);
78499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        //select
78599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
78699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        db.exec("select * from private_table", cb);
78799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        assertTrue(cb.wasCalled());
78899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
78999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson       /*
79099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        TableResult res = db.get_table("select * from private_table");
79199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        assertEquals(emptyTable.toString(),res.toString());
79299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        assertFalse(emptyTable.equals(resPriv));
79399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
79499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        res = db.get_table("select * from public_table");
79599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        assertEquals(resPub,res);
79699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        */
79799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
79899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        // Try insert
79999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        try {
80099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            db.exec(insertPublic, null);
80199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            fail("authorization failed");
80299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        } catch (Exception e) {
80399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        }
80499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
80599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        try {
80699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            db.exec(insertPrivate, null);
80799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            fail("authorization failed");
80899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        } catch (Exception e1) {
80999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            // ok
81099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        }
81199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    }
81299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
81399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    public void testTrace() throws Exception {
81499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        String stmt = "create table TEST (res double);";
81599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        TestTrace t = new TestTrace();
81699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        assertFalse(t.traceCalled);
81799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        assertEquals(db.last_error(),Constants.SQLITE_OK);
81899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        db.trace((Trace) t);
81999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        db.exec(stmt,t);
82099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        assertTrue(t.traceCalled);
82199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        assertEquals(t.getTrace(),stmt);
82299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
82399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        try {
82499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            db.close();
82599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            db.exec(stmt,t);
82699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            fail("Exception Expected");
82799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        } catch (Exception e) {
82899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            //ok
82999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        }
83099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    }
83199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
83299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    public void testCompileString() throws Exception {
83399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        db.compile("select name from sqlite_master;");
83499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        try {
83599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            db.compile("test");
83699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            fail("Compiling of inaccurate statement does not fail.");
83799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        } catch (Exception e) {
83899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        }
83999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    }
84099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
84199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    public void testCompileStringStringArray() throws Exception {
84299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        String args[] = new String[1];
84399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        args[0] = "table";
84499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        db.compile("select name from sqlite_master where type = '%q';",args);
84599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
84699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        try {
84799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            db.compile("test",null);
84899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            fail("Compiling of inaccurate statement does not fail.");
84999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        } catch (Exception e) {
85099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        }
85199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    }
85299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
85399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    public void testPrepare() throws Exception {
85499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        Stmt st = null;
85599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        Stmt st2 = null;
85699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        // test empty statement
85799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        try {
85899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            st = db.prepare("");
85999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            assertEquals(0, st.bind_parameter_count());
86099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            st.step();
86199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            fail("stmt should not be prepared");
86299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        } catch (Exception e) {
86399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            assertEquals("stmt already closed", e.getMessage());
86499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        }
86599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
86699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        // test statement with unbound arguments
86799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        try {
86899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            st2 = db.prepare("insert into " + DatabaseCreator.SIMPLE_TABLE1
86999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                    + " values (:one,:two,:three)");
87099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            assertEquals(3, st2.bind_parameter_count());
87199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            assertEquals(3, st2.bind_parameter_index(":three"));
87299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            assertEquals(":two", st2.bind_parameter_name(2));
87399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        } finally {
87499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            st2.close();
87599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        }
87699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
87799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        try {
87899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            db.prepare("insert into " + DatabaseCreator.SIMPLE_TABLE1
87999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                    + " values(:one,:two,:three,:four);");
88099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        } catch (Exception e) {
88199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            assertEquals("table " + DatabaseCreator.SIMPLE_TABLE1
88299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                    + " has 3 columns but 4 values were supplied", e
88399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                    .getMessage());
88499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        }
88599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
88699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        try {
88799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            db.prepare("insert into " + DatabaseCreator.SIMPLE_TABLE1
88899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                    + " values(5, '10, 20);");
88999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        } catch (Exception e) {
89099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            assertEquals("unrecognized token: \"'10, 20);\"", e.getMessage());
89199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        }
89299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
89399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        try {
89499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            db.prepare("insert into " + DatabaseCreator.SIMPLE_TABLE1
89599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                    + " values(5, 10 20);");
89699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        } catch (Exception e) {
89799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            assertEquals("near \"20\": syntax error", e.getMessage());
89899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        }
89999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
90099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    }
90199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
90299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    /**
90399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson     * Not supported.
90499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson     */
90599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    public void testOpen_blob() throws Exception, java.lang.Exception {
90699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        Stmt statement2;
90799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        Blob blobInput = new Blob();
90899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
90999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        // Create test input Blob
91099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        InputStream inStream = null;
91199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        byte[] in = {(byte) 1, (byte) 2, (byte) 3, (byte) 4};
91299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
91399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        // setup test input
91499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        db.exec("create table TEST (res blob)",null);
91599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        inStream = Class.forName(this.getClass().getName()).getResourceAsStream("/blob.c");
91699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        assertNotNull(inStream);
91799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
91899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        // insert byte array in db
91999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        statement2 = db.prepare("insert into TEST(res) values (?)");
92099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        statement2.bind(1, in);
92199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        statement2.step();
92299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        statement2.close();
92399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
92499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        // read from db
92599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        Blob blob = db.open_blob(dbFile.getPath(), "TEST", "res", 1, true);
92699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        if (blob == null) {
92799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            fail("Blob could not be retrieved");
92899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        }
92999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        //read from blob and compare values (positive case)
93099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        InputStream is = blob.getInputStream();
93199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
93299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        int i = 0;
93399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        int outByte = 0;
93499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        byte[] out = new byte[4];
93599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        while ((outByte = is.read()) > -1) {
93699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            out[i] = (byte) outByte;
93799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            i++;
93899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        }
93999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        is.close();
94099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
94199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        blob.close();
94299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
94399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        assertTrue(Arrays.equals(in, out));
94499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
94599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        //read from blob and compare values (default blob)
94699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        db.exec("insert into TEST values(zeroblob(128))", null);
94799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        Blob blob2 = db.open_blob(dbFile.getPath(), "TEST", "res", 2, true);
94899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        is = blob2.getInputStream();
94999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        for (i = 0; i < 128; i++)  {
95099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson           assertEquals(0, is.read());
95199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        }
95299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        is.close();
95399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    }
95499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
95599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    public void testIs3() {
95699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        int ver = Integer.parseInt(db.version().substring(0,1));
95799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        if (db.is3()) {
95899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            assertTrue( ver == 3);
95999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        } else {
96099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            assertTrue(ver != 3);
96199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        }
96299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    }
96399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
96499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    public void testProgress_handler() throws Exception {
96599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        int inputVal = 3;
96699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        TestProgressHandler prog = new TestProgressHandler();
96799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        db.exec("create table TEST5(id integer, firstname text, lastname text)",null);
96899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        Vm vm = db.compile("select * from TEST5; "
96999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                + "insert into TEST5 values(3, 'James', 'Bond'); "
97099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                + "delete from TEST5 where id = 3; "
97199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                + "select * from TEST5");
97299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        int stmt = 0;
97399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        do {
97499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            ++stmt;
97599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            if (stmt > inputVal) {
97699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                db.progress_handler(inputVal, prog);
97799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            } else {
97899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                assertEquals(0, prog.getCounts());
97999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            }
98099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            while (vm.step(prog)) {
98199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            }
98299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        } while (vm.compile());
98399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        assertEquals(inputVal,prog.getCounts());
98499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
98599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        // Boundary value test
98699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        inputVal = 0;
98799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        TestProgressHandler progBoundary = new TestProgressHandler();
98899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        db.progress_handler(inputVal, progBoundary);
98999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        Vm vm2 = db.compile("select * from TEST5; "
99099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                + "insert into TEST5 values(3, 'James', 'Bond'); "
99199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                + "delete from TEST5 where id = 3; "
99299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                + "select * from TEST5");
99399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        do {
99499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            vm2.step(progBoundary);
99599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        } while (vm2.compile());
99699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        assertEquals(inputVal, progBoundary.getCounts());
99799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
99899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        try {
99999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            db.exec("drop table TEST5",null);
100099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        } catch (Exception e) {
100199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            System.out.println(e.getMessage());
100299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            e.printStackTrace();
100399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        }
100499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    }
100599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
100699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    class SinFunc implements Function {
100799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        public void function(FunctionContext fc, String args[]) {
100899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            Double d = new Double(args[0]);
100999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            fc.set_result(Math.sin(d.doubleValue()));
101099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        }
101199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        public void last_step(FunctionContext fc) {}
101299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        public void step(FunctionContext fc, String[] args) {}
101399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    }
101499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
101599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    class TestTrace implements Trace,Callback {
101699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
101799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        private StringBuffer buf = new StringBuffer();
101899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
101999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        public boolean traceCalled = false;
102099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
102199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        public String getTrace() {
102299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            return buf.toString();
102399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        }
102499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
102599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        public void trace(String stmt) {
102699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            traceCalled = true;
102799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            buf.append(stmt);
102899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        }
102999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
103099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        public void columns(String[] coldata) {}
103199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
103299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        public boolean newrow(String[] rowdata) {
103399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            return false;
103499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        }
103599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
103699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        public void types(String[] types) {}
103799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    }
103899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
103999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    class AuthorizerCallback implements Authorizer, Callback {
104099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
104199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        private boolean isAuthorizing = false;
104299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
104399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        public boolean wasCalled() {
104499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            return isAuthorizing;
104599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        }
104699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
104799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        public int authorize(int action, String arg1, String arg2, String arg3,
104899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                String arg4) {
104999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            Logger.global.info("DB authorization callback " + action + " " + arg1 + " " + arg2 + " "
105099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                    + arg3 + " " + arg4 + " ");
105199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            this.isAuthorizing = true;
105299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            if (action != Constants.SQLITE_SELECT || arg1.contains("private_table")) {
105399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                return Constants.SQLITE_DENY;
105499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            } else {
105599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                return Constants.SQLITE_OK;
105699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            }
105799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        }
105899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
105999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        public void columns(String[] coldata) {}
106099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
106199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        public boolean newrow(String[] rowdata) {
106299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            return false;
106399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        }
106499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
106599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        public void types(String[] types) {}
106699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
106799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    }
106899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
106999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    class TestBusyHandler implements BusyHandler, Callback {
107099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
107199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        public boolean busy(String table, int count) {
107299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            return true;
107399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        }
107499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
107599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        public void columns(String[] coldata) {}
107699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
107799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        public boolean newrow(String[] rowdata) {
107899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            return false;
107999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        }
108099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
108199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        public void types(String[] types) {}
108299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    }
108399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
108499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    class TestProgressHandler implements ProgressHandler, Callback {
108599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
108699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        private boolean progressed = false;
108799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
108899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        private int counter = 0;
108999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
109099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        public int getCounts() {
109199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            return counter;
109299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        }
109399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
109499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        public boolean progress() {
109599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            this.progressed = true;
109699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            counter++;
109799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            return true;
109899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        }
109999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
110099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        public void columns(String[] coldata) {}
110199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
110299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        public boolean newrow(String[] rowdata) {
110399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            return false;
110499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        }
110599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
110699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        public void types(String[] types) {}
110799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    }
110899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
110999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    /**
111099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson     * This method creates a Runnable that executes insert operation for the first table
111199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson     */
111299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    private static Runnable createTask2Interrupt(final int id,
111399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            final String dbName, final ErrorTracker errorTracker) {
111499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        return new Runnable() {
111599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            public void run() {
111699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                Database db = new Database();
111799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                try {
111899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                    String value = DatabaseCreator.defaultString + id;
111999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
112099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                    db.open(dbName, 0);
112199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                    String insertQuery = "INSERT INTO "
112299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                            + DatabaseCreator.TEST_TABLE1
112399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                            + " (id, field1, field2, field3) VALUES(" + id
112499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                            + ", '" + value + "', " + id + ", " + id + ")";
112599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                    db.exec(insertQuery, null);
112699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                } catch (Exception e) {
112799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                    errorTracker.registerException(this, e);
112899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                    try {
112999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                        db.interrupt();
113099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                        db.exec("DELETE FROM " + DatabaseCreator.SIMPLE_TABLE1
113199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                                + " WHERE id=" + id, null);
113299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                    } catch (Exception e1) {
113399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                        errorTracker.registerException(this, e1);
113499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                    }
113599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                }
113699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            }
113799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        };
113899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    }
113999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
114099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    /**
114199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson     * This method creates a Runnable that executes delete operation for the first table
114299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson     */
114399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    private static Runnable createTask1(final int id, final String dbName,
114499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            final ErrorTracker errorTracker) {
114599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        return new Runnable() {
114699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            public void run() {
114799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                try {
114899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                    Database db = new Database();
114999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                    db.open(dbName, 0);
115099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                    db.exec("DELETE FROM "
115199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                            + DatabaseCreator.SIMPLE_TABLE1 + " WHERE id=" + id, null);
115299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                } catch (Exception e) {
115399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                    errorTracker.registerException(this, e);
115499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                }
115599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            }
115699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        };
115799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    }
115899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
115999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    /**
116099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson     * This method creates a Runnable that executes insert operation for the first table
116199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson     */
116299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    private static Runnable createTask2(final int id, final String dbName,
116399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            final ErrorTracker errorTracker) {
116499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        return new Runnable() {
116599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            public void run() {
116699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                try {
116799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                    String value = DatabaseCreator.defaultString + id;
116899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                    Database db = new Database();
116999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                    db.open(dbName, 0);
117099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                    String insertQuery = "INSERT INTO "
117199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                            + DatabaseCreator.TEST_TABLE1
117299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                            + " (id, field1, field2, field3) VALUES(" + id
117399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                            + ", '" + value + "', " + id + ", " + id + ")";
117499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                    db.exec(insertQuery, null);
117599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                } catch (Exception e) {
117699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                    errorTracker.registerException(this, e);
117799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
117899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                }
117999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            }
118099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        };
118199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    }
118299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
118399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    /**
118499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson     * This method creates a Runnable that executes update operation for the one record of the first
118599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson     * table
118699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson     */
118799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    private static Runnable createTask3(final int oldID, final String dbName,
118899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            final int newID, final ErrorTracker errorTracker) {
118999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        return new Runnable() {
119099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            public void run() {
119199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                Database db = new Database();
119299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                try {
119399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                    db.open(dbName, 0);
119499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                    String value = DatabaseCreator.defaultString + newID;
119599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                    String updateQuery = "UPDATE "
119699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                            + DatabaseCreator.TEST_TABLE1 + " SET id=" + newID
119799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                            + ", field1='" + value + "', field2=" + newID
119899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                            + ", field3=" + newID + " WHERE id=" + oldID;
119999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                    db.exec(updateQuery, null);
120099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                } catch (Exception e) {
120199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                    errorTracker.registerException(this, e);
120299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson                }
120399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            }
120499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        };
120599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    }
120699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
120799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    private class ErrorTracker {
120899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
120999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        private List<String> errors = new ArrayList<String>();
121099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
121199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        public void registerException(Runnable runnable, Exception e) {
121299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            System.out.println("Registered: " + e.getMessage());
121399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            errors.add(e.getMessage());
121499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        }
121599aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
121699aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        public List<String> getErrors() {
121799aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            return errors;
121899aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        }
121999aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson
122099aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        public void reset() {
122199aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson            errors.clear();
122299aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson        }
122399aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson    }
122499aa85175f733e896d6cc01e968933a02e997bc2Jesse Wilson}
1225