/*
 * Copyright (C) 2008 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package tests.SQLite;

import dalvik.annotation.AndroidOnly;
import dalvik.annotation.KnownFailure;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetClass;
import dalvik.annotation.TestTargetNew;
import dalvik.annotation.TestTargets;
import tests.support.DatabaseCreator;
import tests.support.MockFunction;
import tests.support.ThreadPool;
import tests.support.resource.Support_Resources;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import SQLite.Authorizer;
import SQLite.Blob;
import SQLite.BusyHandler;
import SQLite.Callback;
import SQLite.Constants;
import SQLite.Database;
import SQLite.Exception;
import SQLite.Function;
import SQLite.FunctionContext;
import SQLite.ProgressHandler;
import SQLite.Stmt;
import SQLite.TableResult;
import SQLite.Trace;
import SQLite.Vm;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.logging.Logger;

@TestTargetClass(Database.class)
public class DatabaseTest extends SQLiteTest {
    
    /**
     * The SQLite db file.
     */
//    protected final File dbFile = new File("sqliteTest.db");
//    
//    private final String connectionURL = "jdbc:sqlite:/" + dbFile.getPath();
//    
//    private final String classname = "SQLite.JDBCDriver";
//    
//    private static Connection conn = null;
    
    private static ErrorTracker tracker = null;
    
    private Statement statement;
    
    private Database db = null;
    
    private static final int numThreads = 10;
    
    private static final int numOfRecords = 30;
    
    public void setUp() throws java.lang.Exception {
        try {
            super.setUp();
            assertNotNull("Could not establish DB connection",conn);
            tracker = new ErrorTracker();
            
            statement = conn.createStatement();
            
          //Cleanup tables if necessary
            
            DatabaseMetaData meta = conn.getMetaData();
            assertNotNull(meta);
            if (meta != null) {
            ResultSet userTab = meta.getTables(null, null, null, null);
            while (userTab.next()) {
            String tableName = userTab.getString("TABLE_NAME");
               this.statement.execute("drop table "+tableName);
            }
            }
            
            // Create default test table
//            statement = conn.createStatement();
            statement.execute(DatabaseCreator.CREATE_TABLE_SIMPLE1);
            statement.close();
            
            try {
            db = new Database();
            db.open(dbFile.getPath(), 0);
            db.busy_handler(null);
            } catch (Exception e) {
                System.out.println("2: Error opening File: Dir "+dbFile.getPath()+" Name: "+dbFile.getPath());
            } catch (java.lang.Exception e) {
                System.err.println("Non SQLException "+e.getMessage());
            }
        } catch (Exception e) {
            System.out.println("Database setup fails: "+e.getMessage());
            e.printStackTrace();
        }

    }

    public void tearDown() {
       
        try {
            db.close();
        }catch (Exception e) {
            if (! (e.getMessage().equals("database already closed"))) {
                System.err.println("Error closing DB "+dbFile.getPath());
            }
        }
//        conn.close();
//        dbFile.delete();
        tracker.reset();
        super.tearDown();
    }
    
    /**
     * @tests Database#Database()
     */
    @TestTargetNew(
        level = TestLevel.COMPLETE,
        notes = "constructor test",
        method = "Database",
        args = {}
    )
    public void testDatabase() {
        // db closed
        Database db2 = new Database();
        try {
            db.close();
            db2 = new Database();
            db2.open(dbFile.getPath(), 0);
            db2.close();
            db.open(dbFile.getPath(), 0);
        } catch (Exception e) {
            fail("Database object could not be created "+e.getMessage());
            e.printStackTrace();
        }
        //db is open
        try {
            db2.open(dbFile.getPath(), 0);
            db2.close();          
        } catch (Exception e) {
            fail("Second Database object could not be created "+e.getMessage());
            e.printStackTrace();
        }
    }
    
    /**
     * @tests Database#finalize()
     */
    @TestTargetNew(
        level = TestLevel.NOT_FEASIBLE,
        notes = "method test",
        method = "finalize",
        args = {}
    )
    public void testFinalize() {
    }

    /**
     * @tests {@link Database#open(String, int)}.
     */
    @TestTargetNew(
        level = TestLevel.COMPLETE,
        notes = "method test. Test fails.",
        method = "open",
        args = {java.lang.String.class, int.class}
    )
    public void testOpen() {
        try {
            db.close();
            db.open(dbFile.getPath(), 0);
        } catch (Exception e) {
            fail("Database object could not be opened: " + e.getMessage());
            e.printStackTrace();
        }
        // open second db while db1 still open
        Database db2 = new Database();
        try {
            db2.open(dbFile.getPath(), 0);
            db2.open(dbFile.getPath(), 0);
            db2.close();
        } catch (Exception e) {
            fail("Database object could not be opened: " + e.getMessage());
            e.printStackTrace();
        }
        // open non db file
        File tempDir = Support_Resources.createTempFolder();
        final String resourceName = "blob.c";
        try {
            URL file = Class.forName(this.getClass().getName())
            .getResource("/blob.c");
            db2.open(file.getPath(), 0);
           fail("Should not be able to open non db file");
        } catch (Exception e) {
            assertEquals("unknown error in open", e.getMessage());
        } catch (java.lang.Exception e) {
            fail("Error in setup " + e.getMessage());
            e.printStackTrace();
        }

    }

    /**
     * @tests Database#open_aux_file(String)
     */
    @TestTargetNew(
        level = TestLevel.SUFFICIENT,
        notes = "not supported",
        method = "open_aux_file",
        args = {java.lang.String.class}
    )
    public void testOpen_aux_file() {
        File temp = null;
        try {
            db.open_aux_file("");
            fail("open should fail");
        } catch (Exception e) {
            assertEquals("unsupported", e.getMessage());
        }
        
     /*   
        try {
            temp = File.createTempFile("openAuxMethod", ".db");
            db.open_aux_file("");
            db.exec("create table AUX_TABLE", null);
            db.close();
        } catch (Exception e) {
            temp.delete();
            fail("Error handling temporary file "+e.getMessage());
            e.printStackTrace();
        } catch (IOException e) {
            temp.delete();
            fail("Could not create temporary File");
            e.printStackTrace();
        }
        try {
            db.open(dbFile.getPath(),0);
            db.exec("select * from AUX_TABLE", null);
            fail("Statement should fail");
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
       
        temp.delete();
        */
    }

    /**
     * @tests Database#close()
     */
    @TestTargetNew(
        level = TestLevel.COMPLETE,
        notes = "method test",
        method = "close",
        args = {}
    )
    public void testClose() {
        try {
            db.close();
            db.get_table("test");
        } catch (Exception e) {
            assertTrue(e.getMessage().equals("database already closed"));
            try {
                db.open(dbFile.getPath(), 0);
            } catch (Exception e1) {
                fail("Database object could not be reopened after 'close': "
                        + e.getMessage());
                e1.printStackTrace();
            }
        }
        
        try {
            db.close();
            db.close();
        } catch (Exception e) {
            assertTrue(e.getMessage().equals("database already closed"));
            try {
                db.open(dbFile.getPath(), 0);
            } catch (Exception e1) {
                fail("Database object could not be reopened after 'close': "
                        + e.getMessage());
                e1.printStackTrace();
            }
        }
    }

    /**
     * @tests Database#exec(String, Callback)
     */
    @TestTargetNew(
        level = TestLevel.COMPLETE,
        notes = "method test",
        method = "exec",
        args = {java.lang.String.class, Callback.class}
    )
    public void testExecStringCallback() {
        TableResult res = new TableResult();
        try {
            db.exec("insert into " + DatabaseCreator.SIMPLE_TABLE1
                    + " VALUES(1, 10, 20)", null);
            db.exec("select * from " + DatabaseCreator.SIMPLE_TABLE1, res);
            db
                    .exec("delete from " + DatabaseCreator.SIMPLE_TABLE1
                            + " where 1", null);
        } catch (Exception e) {
            fail("Database error");
            e.printStackTrace();
        }
        String row[] = (String[]) res.rows.elementAt(0);
        assertEquals(Integer.parseInt(row[0]), 1);
        assertEquals(Integer.parseInt(row[1]), 10);
        assertEquals(Integer.parseInt(row[2]), 20);
    }

    /**
     * @tests Database#exec(String, Callback, String[])
     */
    @TestTargetNew(
        level = TestLevel.COMPLETE,
        notes = "method test",
        method = "exec",
        args = {java.lang.String.class, Callback.class, java.lang.String[].class}
    )
    public void testExecStringCallbackStringArray() {
        TableResult res = new TableResult();
        String args[] = new String[1];
        args[0] = "table";
        try {
            db.exec("select name from sqlite_master where type = '%q';", res,
                    args);
            String[] s = (String[]) res.rows.elementAt(0);
            assertEquals(s[0], DatabaseCreator.SIMPLE_TABLE1);
        } catch (Exception e) {
            fail("DB Error occurred");
            e.printStackTrace();
        }

        try {
            db.exec("select name from sqlite_master where type = ", res, args);
            fail("Testmethod should fail");
        } catch (Exception e) {
            // Ok
        }
    }

    /**
     * @tests {@link Database#last_insert_rowid()}
     */
    @TestTargetNew(
        level = TestLevel.COMPLETE,
        notes = "method test",
        method = "last_insert_rowid",
        args = {}
    )
    public void testLast_insert_rowid() {
        assertEquals(0, db.last_insert_rowid());
        try {
            db
                    .exec(
                            "create table TEST5(id integer, firstname text, lastname text);",
                            null);
            db.exec("insert into TEST5 values (1,'James','Bond');", null);
            db.exec("insert into TEST5 values (2,'Fiona','Apple');", null);
        } catch (Exception e) {
            fail("Error in test setup: " + e.getMessage());
            e.printStackTrace();
        }
        assertEquals(2, db.last_insert_rowid());
        assertEquals(db.last_insert_rowid(), db.last_insert_rowid());

        try {
            db.exec("drop table TEST5;", null);
        } catch (Exception e) {
            fail("Error in test setup: " + e.getMessage());
            e.printStackTrace();
        }
        assertEquals(2, db.last_insert_rowid());
    }

    /**
     * @throws Exception 
     * @tests {@link Database#interrupt()}
     */
    @TestTargetNew(
        level = TestLevel.COMPLETE,
        notes = "",
        method = "interrupt",
        args = {}
    )
    @KnownFailure("Reason for failure unknown: Database should be locked. " +
                   "Specification of interrupt is scarce.")
    public void testInterrupt() throws Exception {
        ThreadPool threadPool = new ThreadPool(numThreads);

        // initialization
        ResultSet userTabs;
        try {
            userTabs = conn.getMetaData().getTables(null, null, null, null);
            while (userTabs.next()) {
                String tableName = userTabs.getString("TABLE_NAME");
                if (tableName.equals(DatabaseCreator.TEST_TABLE1)) {
                    statement.execute(DatabaseCreator.DROP_TABLE1);
                }
            }
            db.exec(DatabaseCreator.CREATE_TABLE3, null);
            db.exec(DatabaseCreator.CREATE_TABLE1, null);
        } catch (SQLException e1) {
            fail("Error initializing test " + e1.toString());
            e1.printStackTrace();
        } catch (Exception e) {
            fail("Error initializing test " + e.getMessage());
            e.printStackTrace();
        }

        int id1 = numOfRecords - 3;
        threadPool.runTask(createTask1(id1, dbFile.getPath(), tracker));
        // should not be able to do any other insertions since task 1 holds lock
        int id2 = numOfRecords + 3;
        threadPool
                .runTask(createTask2Interrupt(id2, dbFile.getPath(), tracker));

        threadPool.join();

        List<String> errors = tracker.getErrors();
        System.out.println("Last error: " + db.error_message());
        if (errors.size() > 0) {
            assertEquals(errors.get(0), db
                    .error_string(Constants.SQLITE_LOCKED));
            for (String s : errors) {
                Logger.global.info("INTERRUPT Error: " + s);
            }

        } else {
            fail("Should have one exception: database should be locked.");
        }

        // reset

        db
                .exec(
                        "delete from " + DatabaseCreator.TEST_TABLE1
                                + " where 1", null);
        db
                .exec(
                        "delete from " + DatabaseCreator.TEST_TABLE3
                                + " where 1", null);

    }

    /**
     * @tests {@link Database#changes()}
     */
    @TestTargetNew(
        level = TestLevel.COMPLETE,
        notes = "test fails",
        method = "changes",
        args = {}
    )
    @KnownFailure("Returns wrong number for updates: returns value > 1 for select.")
    public void testChanges() {
        TableResult res = new TableResult();
        try {
            assertTrue(db.changes() == 0);
            db.exec("INSERT INTO " + DatabaseCreator.SIMPLE_TABLE1
                    + " VALUES(2, 5, 7);", null);
            int rows = (int) db.changes();
            assertEquals(1,db.changes());
            db.exec("update " + DatabaseCreator.SIMPLE_TABLE1
                    + " set speed = 7, size= 5 where id = 2;", null);
            assertEquals(1,db.changes());
            db.exec("select * from " + DatabaseCreator.SIMPLE_TABLE1, res);
            assertEquals(0,db.changes());
            db.exec("INSERT INTO " + DatabaseCreator.SIMPLE_TABLE1
                    + " VALUES(8, 5, 7);", null);
            db.exec("Update "+DatabaseCreator.SIMPLE_TABLE1+" set speed = 10;",null);
           assertTrue(db.changes() > 2);
        } catch (Exception e) {
            fail("Could not get changes: " + e.getMessage());
            e.printStackTrace();
        }
    }

    /**
     * @throws SQLException 
     * @throws Exception 
     * @tests {@link Database#busy_handler(BusyHandler)}
     */
    @TestTargets({
    @TestTargetNew(
        level = TestLevel.NOT_FEASIBLE,
        notes = "method test fails once in a while. Cannot be sure that exception is thrown every time.",
        method = "busy_handler",
        args = {BusyHandler.class}
    ),
    @TestTargetNew(
            level = TestLevel.NOT_FEASIBLE,
            notes = "method test fails once in a while. Cannot be sure that exception is thrown every time.",
            method = "busy",
            clazz = BusyHandler.class,
            args = {java.lang.String.class, int.class}
        )
    })
    @KnownFailure("method test fails once in a while. "+
            "Cannot be sure that exception is thrown in every test execution.")
    public void testBusy_handler() throws SQLException, Exception {
        TestBusyHandler bh = new TestBusyHandler();
        db.busy_handler(bh);
        int counter = 0;
        ThreadPool threadPool = new ThreadPool(numThreads);

        // initialization
        ResultSet userTabs;
        try {
            userTabs = conn.getMetaData().getTables(null, null, null, null);
            while (userTabs.next()) {
                String tableName = userTabs.getString("TABLE_NAME");
                if (tableName.equals(DatabaseCreator.TEST_TABLE1)) {
                    statement.execute(DatabaseCreator.DROP_TABLE1);
                }
            }
            db.exec(DatabaseCreator.CREATE_TABLE3, null);
            db.exec(DatabaseCreator.CREATE_TABLE1, null);
        } catch (SQLException e1) {
            fail("Error initializing test " + e1.toString());
            e1.printStackTrace();
        } catch (Exception e) {
            fail("Error initializing test " + e.getMessage());
            e.printStackTrace();
        }

        
//        try {
//            DatabaseCreator.fillTestTable1(conn, numOfRecords);
            // set to fail immediately if table is locked.
//            db.busy_handler(bh);
//            db.busy_timeout(0);
        try {
            conn.setAutoCommit(false);
            int id1 = numOfRecords - 3;
            threadPool.runTask(createTask1(id1, dbFile.getPath(), tracker));
            int id2 = numOfRecords + 3;
            threadPool.runTask(createTask2(id2, dbFile.getPath(), tracker));
            int oldID = 5;
            int newID = 100;
            threadPool.runTask(createTask3(oldID, dbFile.getPath(), newID,
                    tracker));

            threadPool.join();

            List<String> errors = tracker.getErrors();
            if (errors.size() > 0) {
//                 assertEquals(errors.get(0),
//                 db.error_string(Constants.SQLITE_LOCKED));
                for (String s: errors) {
                  System.out.println("Round 2 Error: "+s);
              }
            } else {
                fail("No error happened");
            }
            
            // reset
            

            db.exec("delete from " + DatabaseCreator.TEST_TABLE1 + " where 1",
                    null);
            db.exec("delete from " + DatabaseCreator.TEST_TABLE3 + " where 1",
                            null);
//            
//            // increase timeout for retry
//            db.busy_timeout(1000);
//            db.busy_handler(bh);
//            tracker.reset();
           
//            threadPool = new ThreadPool(numThreads);
//            
//            threadPool.runTask(createTask1(id1, dbFile.getPath(), tracker));
//            threadPool.runTask(createTask2(id2, dbFile.getPath(), tracker));
//            
//            threadPool.join();
//            
//            errors = tracker.getErrors();
//            if (errors.size() > 0) {
//                // assertEquals(errors.get(0),
//                // db.error_string(Constants.SQLITE_LOCKED));
//                for (String s: errors) {
//                    System.out.println("Round 2 Error"+s);
//                }
//            } else {
//                // ok
//                System.out.println("BUSY: No Error!");
//            }
//            
//
        } catch (Exception e) {
            fail("Error in test setup " + e.getMessage());
            try {
                db.get_table("select * from " + DatabaseCreator.TEST_TABLE1,
                        null).toString();
            } catch (Exception e1) {

                e1.printStackTrace();
            }
            e.printStackTrace();
//             } catch (SQLException e2) {
//             System.out.println("Error in test setup "+e2.toString());
//             try {
//             db.get_table("select * from "+DatabaseCreator.TEST_TABLE1,null).
//             toString();
//             } catch (Exception e1) {
//             e2.printStackTrace();
//             }
        } finally {
            conn.setAutoCommit(true);
            db.exec(DatabaseCreator.DROP_TABLE1, null);
            db.exec(DatabaseCreator.DROP_TABLE3, null);
        }
    }
    
    /**
     * @throws Exception 
     * @throws SQLException 
     * @tests {@link Database#busy_timeout(int)}
     */
    @TestTargetNew(
        level = TestLevel.NOT_FEASIBLE,
        notes = "test fails. Cannot be sure that exception is thrown every time.",
        method = "busy_timeout",
        args = {int.class}
    )
    @KnownFailure("Database does not lock values")
    public void testBusy_timeout() throws Exception, SQLException {
        int counter = 0;
        ThreadPool threadPool = new ThreadPool(numThreads);
        
        // initialization
        ResultSet userTabs;
        try {
            userTabs = conn.getMetaData().getTables(null, null, null, null);
            while (userTabs.next()) {
                String tableName = userTabs.getString("TABLE_NAME");
                if (tableName.equals(DatabaseCreator.TEST_TABLE1)) {
                    statement.execute(DatabaseCreator.DROP_TABLE1);
                }
            }
            db.exec(DatabaseCreator.CREATE_TABLE3, null);
            db.exec(DatabaseCreator.CREATE_TABLE1, null);
        } catch (SQLException e1) {
            fail("Error initializing test " + e1.toString());
            e1.printStackTrace();
        } catch (Exception e) {
            fail("Error initializing test " + e.getMessage());
            e.printStackTrace();
        }
        
        
        // test run
        try {
            conn.setAutoCommit(false);
        
//            DatabaseCreator.fillTestTable1(conn, numOfRecords);
            // set to fail immediately if table is locked.
            db.busy_handler(null);
            db.busy_timeout(0);
            int id1 = numOfRecords - 3;
           
            threadPool.runTask(createTask2(id1, dbFile.getPath(), tracker));
            int id2 = numOfRecords + 3;
            threadPool.runTask(createTask1(id2, dbFile.getPath(), tracker));
            int oldID = 5;
            int newID = 100;
            threadPool.runTask(createTask3(oldID, dbFile.getPath(), newID,
                    tracker));

            threadPool.join();
            
            List<String> errors = tracker.getErrors();
            assertTrue("No error occurred on DB but should have",errors.size() > 0);
            
            assertEquals(errors.get(0),
            db.error_string(Constants.SQLITE_LOCKED));
            assertEquals(errors.get(0), "database is locked");
          
            // reset

            db.exec("delete from " + DatabaseCreator.TEST_TABLE1 + " where 1",
                    null);
            db.exec("delete from " + DatabaseCreator.TEST_TABLE3 + " where 1",
                            null);
            
            // increase timeout for retry
            db.busy_timeout(10000);
            db.busy_handler(null);
            tracker.reset();
            threadPool = new ThreadPool(numThreads);
            
            threadPool.runTask(createTask1(id1, dbFile.getPath(), tracker));
            threadPool.runTask(createTask2(id2, dbFile.getPath(), tracker));
            
            threadPool.join();
            
            errors = tracker.getErrors();
            if (errors.size() > 0) {
                fail("busy timeout should prevent from lock exception!");
                for (String s: errors) {
                    System.out.println("Round 2 Error"+s);
                }
            } else {
                // ok
            }
            

        } catch (Exception e) {
            fail("Error in test setup " + e.getMessage());
            try {
                db.get_table("select * from " + DatabaseCreator.TEST_TABLE1,
                        null).toString();
            } catch (Exception e1) {

                e1.printStackTrace();
            }
            e.printStackTrace();
        } finally {
            conn.setAutoCommit(true);
            // cleanup
            db.exec(DatabaseCreator.DROP_TABLE1, null);
            db.exec(DatabaseCreator.DROP_TABLE3, null);
        }
    }

    /**
     * @tests {@link Database#get_table(String)}
     */
    @TestTargetNew(
        level = TestLevel.COMPLETE,
        notes = "method test",
        method = "get_table",
        args = {java.lang.String.class}
    )
    public void testGet_tableString() {
        TableResult emptyTable = new TableResult();
        try {
            //select from empty table
            TableResult res = db.get_table("select * from "
                    + DatabaseCreator.SIMPLE_TABLE1);
            assertEquals(res.toString(), emptyTable.toString());
            //fill table-> t
//            DatabaseCreator.fillSimpleTable1(conn);
//            res = db.get_table("select * from "
//                    + DatabaseCreator.SIMPLE_TABLE1);
//            assertFalse(emptyTable.toString().equals(res.toString()));
            
            try {
                db.exec("insert into " + DatabaseCreator.SIMPLE_TABLE1
                        + " VALUES(1, 10, 20)", null);
                res = db.get_table("select * from " + DatabaseCreator.SIMPLE_TABLE1);
                db
                        .exec("delete from " + DatabaseCreator.SIMPLE_TABLE1
                                + " where 1", null);
            } catch (Exception e) {
                fail("Database error");
                e.printStackTrace();
            }
            String row[] = (String[]) res.rows.elementAt(0);
            assertEquals(Integer.parseInt(row[0]), 1);
            assertEquals(Integer.parseInt(row[1]), 10);
            assertEquals(Integer.parseInt(row[2]), 20);
        } catch (Exception e) {
            fail("Error getting table " + e.getMessage());
            e.printStackTrace();
//        } catch (SQLException e) {
//            fail("Error initialising table " + e.getMessage());
//            e.printStackTrace();
        }
    }

    /**
     * @tests {@link Database#get_table(String, String[])}
     */
    @TestTargetNew(
        level = TestLevel.COMPLETE,
        notes = "method test",
        method = "get_table",
        args = {java.lang.String.class, java.lang.String[].class}
    )
    public void testGet_tableStringStringArray() {
        String args[] = new String[1];
        args[0] = "table";
        String argsFail[] = new String[1];
        try {
            TableResult res = db.get_table(
                    "select name from sqlite_master where type = ", argsFail);
            fail("Testmethod should fail");
        } catch (Exception e) {
            try {
                TableResult res = db.get_table(
                        "select name from sqlite_master where type = '%q'",
                        args);
                String[] s = (String[]) res.rows.elementAt(0);
                assertEquals(s[0], DatabaseCreator.SIMPLE_TABLE1);
            } catch (Exception e2) {
                fail("Testmethod failed: " + e2.getMessage());
                e.printStackTrace();
            }
        }

    }

    /**
     * @tests {@link Database#get_table(String, String[], TableResult)}
     */
    @TestTargets({
        @TestTargetNew(
            level = TestLevel.COMPLETE,
            notes = "method test",
            method = "get_table",
            args = {java.lang.String.class, java.lang.String[].class, TableResult.class}
        ),
        @TestTargetNew(
                level = TestLevel.COMPLETE,
                notes = "method test",
                method = "toString",
                clazz = TableResult.class,
                args = {}
            ),
       @TestTargetNew(
                    level = TestLevel.COMPLETE,
                    notes = "method test",
                    method = "types",
                    clazz = TableResult.class,
                    args = {String[].class}
            ),
       @TestTargetNew(
                level = TestLevel.COMPLETE,
                notes = "method test",
                method = "TableResult",
                clazz = TableResult.class,
                args = {}
           ),
       @TestTargetNew(
               level = TestLevel.NOT_NECESSARY,
               notes = "method test",
               method = "columns",
               clazz = TableResult.class,
               args = {String[].class}
          ),
      @TestTargetNew(
              level = TestLevel.NOT_NECESSARY,
              notes = "method test",
              method = "newrow",
              clazz = TableResult.class,
              args = {String[].class}
         ),
     @TestTargetNew(
         level = TestLevel.NOT_NECESSARY,
         notes = "method test",
         method = "clear",
         clazz = TableResult.class,
         args = {}
        )
     
    })
    public void testGet_tableStringStringArrayTableResult() {
        String args[] = new String[1];
        String argsFail[] = new String[1];
        TableResult res = new TableResult();
        TableResult defaultTableRes = new TableResult();
        args[0] = "table";

        try {
            db.get_table("select name from sqlite_master where type = '%q'",
                    argsFail, res);
            assertEquals(defaultTableRes.toString(), res.toString());
        } catch (Exception e) {
            try {
                db.get_table(
                        "select name from sqlite_master where type = '%q'",
                        args, res);
                String[] s = (String[]) res.rows.elementAt(0);
                assertEquals(s[0], DatabaseCreator.SIMPLE_TABLE1);
                String[] types = res.types;
                System.out
                        .println("DatabaseTest.testGet_tableStringStringArrayTableResult() "+types.toString());
            } catch (Exception e2) {
                fail("Testmethod failed: " + e2.getMessage());
                e.printStackTrace();
            }
        }
    }

    
    /**
     * @tests {@link Database#complete(String)}
     */
    @TestTargetNew(
        level = TestLevel.COMPLETE,
        notes = "method test",
        method = "complete",
        args = {java.lang.String.class}
    )
    public void testComplete() {
        assertFalse(db.complete("create"));
        assertTrue(db.complete("create table TEST (res double);"));
    }

    /**
     * @tests {@link Database#version()}
     */
    @TestTargetNew(
        level = TestLevel.COMPLETE,
        notes = "method test",
        method = "version",
        args = {}
    )
    public void testVersion() {
        String version = db.version();
        if (version != null) {
        assertTrue(Integer.parseInt(db.version().substring(0,1)) > 0);
        assertEquals(db.version(), db.version());
        } else {
            fail("DB version info missing");
        }
        
    }

    /**
     * @tests {@link Database#dbversion()}
     */
    @TestTargetNew(
        level = TestLevel.COMPLETE,
        notes = "method test",
        method = "dbversion",
        args = {}
    )
    public void testDbversion() {
        String verNo = "";
        try {
            verNo = db.dbversion();
            db.close();
            assertEquals(db.dbversion(),"unknown");
            db.open(dbFile.getPath(), 0);
            assertEquals(verNo,db.dbversion());
        } catch (Exception e) {
            try {
                db.open(dbFile.getPath(), 0);
            } catch (Exception e1) {
                fail("error in db setup "+e.getMessage());
                e.printStackTrace();
            }
            fail("error in db setup "+e.getMessage());
            e.printStackTrace();
        }
        
        assertTrue(Integer.parseInt(verNo.substring(0, 1))>= 3 );
     
    }

    /**
     * @tests {@link Database#create_function(String, int, Function)}
     */
    @TestTargets({
    @TestTargetNew(
        level = TestLevel.COMPLETE,
        notes = "method test",
        method = "create_function",
        args = {java.lang.String.class, int.class, Function.class}
    ),
    @TestTargetNew(
        level = TestLevel.COMPLETE,
        notes = "method test",
        method = "create_function",
        args = {java.lang.String.class, int.class, Function.class}
        )
    })
    public void testCreate_function() {
        try {
            double input = 1.0;
            db.exec("create table TEST (res double)", null);
            db.exec("insert into TEST values (" + Double.toString(input) + ")",
                    null);
            TableResult res = new TableResult();
            Function sinFunc = (Function) new SinFunc();
            db.create_function("sin", 1, sinFunc);
            db.exec("select sin(res) from TEST WHERE res = "
                    + Double.toString(input), res);
            String row[] = (String[]) res.rows.elementAt(0);
            String val = row[0];
            double sinusVal = Double.parseDouble(val);
            double funcVal = Math.sin(input);

            assertTrue(Math.round(funcVal) == Math.round(sinusVal));
        } catch (Exception e) {
            fail("Error happened creating function:" + e.getMessage());
            e.printStackTrace();
        }
    }

    /**
     * @tests {@link Database#create_aggregate(String, int, Function)}
     */
    @TestTargets({
            
    @TestTargetNew(
        level = TestLevel.COMPLETE,
        notes = "method test",
        method = "create_aggregate",
        args = {java.lang.String.class, int.class, Function.class}
    ),
    @TestTargetNew(
        level = TestLevel.COMPLETE,
        notes = "method test",
        method = "step",
        clazz = Function.class,
        args = {FunctionContext.class, String[].class}
            ),
    @TestTargetNew(
        level = TestLevel.COMPLETE,
        notes = "method test",
        method = "last_step",
        clazz = Function.class,
        args = {FunctionContext.class}
                ),
    @TestTargetNew(
        level = TestLevel.COMPLETE,
        notes = "method test",
        method = "function",
        clazz = Function.class,
        args = {FunctionContext.class, String[].class}
                    )
    })
    @KnownFailure("Aggregation function not called")
    public void testCreate_aggregate() {
        TestTrace t = new TestTrace();
        
        MockFunction aggFunction = new MockFunction();
       
        try {
            db
                    .exec(
                            "create table TEST(id integer, firstname text, lastname text)",
                            null);
            db.exec("insert into TEST values(3, 'James', 'Bond'); ", null);
            db.exec("insert into TEST values(4, 'Fiona', 'Apple'); ", null);
            db.trace((Trace) t);
            db.create_aggregate("myaggfunc", 1, aggFunction);
            db.function_type("myaggfunc", Constants.SQLITE_TEXT);
            db.exec("PRAGMA show_datatypes = on", null);
            
            assertFalse(aggFunction.functionCalled);
            assertFalse(aggFunction.stepCalled);
            assertFalse(aggFunction.lastStepCalled);
            db.exec("select myaggfunc(TEST.firstname) from TEST", t);
            assertTrue(aggFunction.stepCalled);
            assertTrue(aggFunction.lastStepCalled);
            assertTrue(aggFunction.functionCalled);
            
            assertEquals("James Fiona ",aggFunction.getAggValue());
            db.exec("drop table TEST", null);
        } catch (Exception e) {
            System.out.println(t.getTrace());
            fail("Error in test setup: " + e.getMessage());
            e.printStackTrace();
        }
        
        try {
            db.create_aggregate("myaggfunc", 0, null);
        } catch (Throwable e) {
            assertEquals("null SQLite.Function not allowed",e.getMessage());
        }
            
          try {
            db.create_aggregate("myaggfunc", 0, aggFunction);
        } catch (Throwable e) {
            assertEquals("wrong number of arguments to function myaggfunc()",e.getMessage());
        }
        
    }

    /**
     * @throws Exception 
     * @tests {@link Database#function_type(String, int)}
     * This method does not make sense
     */
    @TestTargetNew(
        level = TestLevel.COMPLETE,
        notes = "Method does not make sense: for functions, return type is already set.",
        method = "function_type",
        args = {java.lang.String.class, int.class}
    )
    public void testFunction_type() throws Exception {
        
        double input = 1.0;
        TableResult res = new TableResult();
        Function sinFunc = (Function) new SinFunc();
        
        db.exec("PRAGMA show_datatypes = on", null);
        db.exec("create table TEST (res double)", null);
        db.exec("insert into TEST values (" + Double.toString(input) + ")",
                null);
        
        db.create_function("sin", 1, sinFunc);
        db.function_type("sin", Constants.SQLITE_NUMERIC);
        res = db.get_table("select sin(res) from TEST WHERE res = "
                + Double.toString(input));
         
        String row[] = (String[]) res.rows.elementAt(0);
        String val = row[0];
        assertTrue("double".equalsIgnoreCase(res.types[0]));
        assertSame(Math.round(Math.sin(input)), Math.round(Double.parseDouble(val)));
        
        // function determines return type: test that Double type is returned.
        db.function_type("sin", Constants.SQLITE_BLOB);
        Stmt s = db.prepare("select sin(res) from TEST WHERE res = ?");
        s.bind(1,input);
        s.step();
        
        res = db.get_table("select sin(res) from TEST WHERE res = "
                + Double.toString(input));
        assertTrue("double".equalsIgnoreCase(res.types[0]));
        row = (String[]) res.rows.elementAt(0);
        val = row[0]; 
        assertSame(Math.round(Math.sin(input)), Math.round(Double.parseDouble(val)));
        

        

    }

    /**
     * @tests {@link Database#last_error()}
     */
    @TestTargetNew(
        level = TestLevel.COMPLETE,
        notes = "method test",
        method = "last_error",
        args = {}
    )
    public void testLast_error() {
        assertEquals(db.last_error(), Constants.SQLITE_OK);
        try {
            db.exec("create table TEST (res double)",null);
            db.exec("create table TEST (res double)",null);
            fail("Error should have happened");
        } catch (Exception e) {
            assertEquals(db.last_error(),db.last_error());
            assertEquals(db.last_error(),Constants.SQLITE_ERROR);         
        }
       
    }

    /**
     * @tests {@link Database#set_last_error(int)}
     */
    @TestTargetNew(
        level = TestLevel.SUFFICIENT,
        notes = "don't now which other errors may occur from black-box approach.",
        method = "set_last_error",
        args = {int.class}
    )
    public void testSet_last_error() {
       assertEquals(db.last_error(), Constants.SQLITE_OK);
       
       try {
           db.exec("sel from test;", null);
       } catch (Exception e) {
           assertEquals(Constants.SQLITE_ERROR,db.last_error());
       }
    }

    /**
     * @tests {@link Database#error_message()}
     */
    @TestTargetNew(
        level = TestLevel.COMPLETE,
        notes = "method test",
        method = "error_message",
        args = {}
    )
    public void testError_message() {
        String statement = "create table TEST (res double)";
        try {
            db.exec(statement,null);
            db.exec(statement,null);
            fail("DB Error expected");
        } catch (Exception e) {
            String dbError = db.error_message();
            assertTrue(e.getMessage().equals(dbError)); 
            
        }
    }

    /**
     * @tests {@link Database#error_string(int)}
     */
    
    @TestTargetNew(
        level = TestLevel.COMPLETE,
        notes = "not supported",
        method = "error_string",
        args = {int.class}
    )
    public void testError_string() {
        TestTrace t = new TestTrace();
        assertEquals(db.last_error(), Constants.SQLITE_OK);
        String errorString = db.error_string(Constants.SQLITE_ERROR);
        try {
            db.trace((Trace) t);
            db.exec("create table TEST (res double)", t);
            db.exec("create table TEST (res double)", t);
        } catch (Exception e) {
            assertEquals(db.last_error(), Constants.SQLITE_ERROR);
            if (db.is3()) {
                assertEquals("Unsupported Method (sqlite 3): error_string", db
                        .error_string(db.last_error()), errorString);
            }
        }
    }

    /**
     * @throws UnsupportedEncodingException 
     * @tests {@link Database#set_encoding(String)}
     * Method unsupported? -> tests fail
     */
    @TestTargetNew(
        level = TestLevel.COMPLETE,
        notes = "method test fails.",
        method = "set_encoding",
        args = {java.lang.String.class}
    )
    @KnownFailure("ASCII encoding does not work: a UTF encoded val is returned. Spec is not sufficient. "
            + "Might be that test impl is wrong or String constructor for the ASCII encoding.")
    public void testSet_encoding() throws UnsupportedEncodingException {
        String input = "\u00bfMa\u00f1ana\u003f"; // ?Manana?
        TableResult res = new TableResult();
        String refOutput = null;
        Stmt stat = null;

        // DB setup
        try {
            db.exec("create table encodingTest (encoded text DEFAULT NULL);",
                    null);
            stat = db
                    .prepare("insert into encodingTest(encoded) values(:one);");
            stat.bind(1, input);
            stat.step();
            // stat.close();
            db.exec("select * from encodingTest;", res);
            String[] encInput = (String[]) res.rows.elementAt(0);
            String output = encInput[0];
            assertEquals(input, output);
            // db.exec("delete from encodingTest where 1", null);
        } catch (Exception e1) {
            fail("Error in test setup: " + e1.getMessage());
            e1.printStackTrace();
        }
        
     // tests for different encoding schemes
        String[] charsetNames = {"UTF-8", "UTF-16", "UTF-16BE", "UTF-16LE"};
        for (int i = 0; i < charsetNames.length; i++) {
            try {
                byte[] encInput = input.getBytes(charsetNames[i]);
                db.set_encoding(charsetNames[i]);
                db.exec("select * from encodingTest;", res);
                String[] encOutput = (String[]) res.rows.elementAt(0);
                String inputAsString = new String(encInput,charsetNames[i]);
                assertEquals(inputAsString, encOutput[0]);
            } catch (Exception e4) {
                fail("Error setting the encoding." + e4.getMessage());
                e4.printStackTrace();
            } catch (UnsupportedEncodingException e2) {
                fail(e2.getMessage());
                e2.printStackTrace();
            }
        }

        // Default tests
        try {
            db.set_encoding("UTF-16");
            db.exec("select * from encodingTest;", res);
            String[] encOutput1 = (String[]) res.rows.elementAt(0);
            assertEquals("Got "+encOutput1[0]+" as UTF-16",input,encOutput1[0]);

            db.set_encoding("US-ASCII");
            db.exec("select * from encodingTest;", res);
            String[] encOutput2 = (String[]) res.rows.elementAt(0);
            assertEquals(new String(input.getBytes(),"US-ASCII"),encOutput2[0]);
        } catch (Exception e) {
            fail("Error setting the encoding." + e.getMessage());
            e.printStackTrace();
        }
        
        
        // DB teardown
        try {
            stat.close();
            db.exec("delete from encodingTest", null);
            // reset encoding
        } catch (Exception e3) {
            fail("Error in teardown of encoding environment");
            e3.printStackTrace();
        }
        
        // Default tests
        try {
            db.set_encoding("");
            fail("invalid input should fail");
        } catch (Exception e) {
            //ok
        }

    }

    /**
     * Test fails -> implemented correctly?
     * @tests {@link Database#set_authorizer(Authorizer)}
     */
    @TestTargets({
    @TestTargetNew(
        level = TestLevel.COMPLETE,
        notes = "method test fails.",
        method = "set_authorizer",
        args = {Authorizer.class}
    ),
    @TestTargetNew(
            level = TestLevel.COMPLETE,
            notes = "method test fails.",
            method = "authorize",
            clazz = Authorizer.class,
            args = {int.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class}
        )
    })
    @KnownFailure("Callback never made for authorization. "+
            "Results of private table are returned withouth furhter checks.")
    public void testSet_authorizer() {
        
        TableResult resPriv = null;
        TableResult resPub = null;
        TableResult emptyTable = new TableResult();
        String insertPublic = "insert into public_table values(1,2)";
        String insertPrivate = "insert into private_table values(1,2)";
        try {
            // prepare, authorizer is not activated yet
            db.exec("create table public_table(c1 integer, c2 integer);", null); 
            db.exec("create table private_table(c1 integer, c2 integer);", null);
            // inserts
            db.exec(insertPublic, null);
            db.exec(insertPrivate, null);
            // selects
            resPriv = db.get_table("select * from private_table");
            resPub = db.get_table("select * from public_table");
            
//            db.exec("delete from public_table where 1", null);
//            TableResult emptyPubTable = db.exec("select * from public");
            
            // set Authorizer (positive case): denies private table
            AuthorizerCallback cb = new AuthorizerCallback();
            db.set_authorizer(cb);
            //select
            
            db.exec("select * from private_table", cb);
            assertTrue(cb.wasCalled());
            
           /*
            TableResult res = db.get_table("select * from private_table");
            assertEquals(emptyTable.toString(),res.toString());
            assertFalse(emptyTable.equals(resPriv));
            
            res = db.get_table("select * from public_table");
            assertEquals(resPub,res);
            */
        } catch (Exception e) {
            fail("Error testing authorization: "+e.getMessage());
        }
        
        // Try insert
        try {
            db.exec(insertPublic, null);
            fail("authorization failed");
        } catch (Exception e) {
            try {
                db.exec(insertPrivate, null);
                fail("authorization failed");
            } catch (Exception e1) {
                // ok
            }
        }
        
    }

    /**
     * @tests {@link Database#trace(Trace)}
     */

    @TestTargetNew(
        level = TestLevel.COMPLETE,
        notes = "method test",
        method = "trace",
        args = {Trace.class}
    )
    public void testTrace() {
        String stmt = "create table TEST (res double);";
        TestTrace t = new TestTrace();
        assertFalse(t.traceCalled);
        assertEquals(db.last_error(),Constants.SQLITE_OK);
        try {
            db.trace((Trace) t);
            db.exec(stmt,t);
            assertTrue(t.traceCalled);
            assertEquals(t.getTrace(),stmt);
        } catch (Exception e) {
            fail("Error testing traces: "+e.getMessage());
            e.printStackTrace();
        }
        
        try {
            db.close();
            db.exec(stmt,t);
            fail("Exception Expected");
        } catch (Exception e) {
            //ok
        }
        
        
    }

    /**
     * @tests {@link Database#compile(String)}
     */
    @TestTargetNew(
        level = TestLevel.COMPLETE,
        notes = "method test",
        method = "compile",
        args = {java.lang.String.class}
    )
    public void testCompileString() {
        try {
            db.compile("select name from sqlite_master;");
        } catch (Exception e) {
            fail("Error compiling sql statement " + e.getMessage());
            e.printStackTrace();
        }
        try {
            db.compile("test");
            fail("Compiling of inaccurate statement does not fail.");
        } catch (Exception e) {
            
        } 
    }

    /**
     * @tests {@link Database#compile(String, String[])}
     */
    @TestTargetNew(
        level = TestLevel.COMPLETE,
        notes = "method test",
        method = "compile",
        args = {java.lang.String.class, java.lang.String[].class}
    )
    public void testCompileStringStringArray() {
        String args[] = new String[1];
        args[0] = "table";
        try {
            db.compile("select name from sqlite_master where type = '%q';",args);
        } catch (Exception e) {
            fail("Error compiling sql statement " + e.getMessage());
            e.printStackTrace();
        }
        try {
            db.compile("test",null);
            fail("Compiling of inaccurate statement does not fail.");
        } catch (Exception e) {
            
        } 
    }

    /**
     * @tests {@link Database#prepare(String)}
     */
    @TestTargetNew(
        level = TestLevel.COMPLETE,
        notes = "method test",
        method = "prepare",
        args = {java.lang.String.class}
    )
    public void testPrepare() {
        Stmt st = null;
        Stmt st2 = null;
        // test empty statement
        try {
            st = db.prepare("");
            assertEquals(0, st.bind_parameter_count());
            st.step();
            fail("stmt should not be prepared");
        } catch (Exception e) {
            assertEquals("stmt already closed", e.getMessage());
        }

        // test statement with unbound arguments
        try {
            st2 = db.prepare("insert into " + DatabaseCreator.SIMPLE_TABLE1
                    + " values (:one,:two,:three)");
            assertEquals(3, st2.bind_parameter_count());
            assertEquals(3, st2.bind_parameter_index(":three"));
            assertEquals(":two", st2.bind_parameter_name(2));
        } catch (Exception e) {
            fail("error in prepare method: " + e.getMessage());
            e.printStackTrace();
        } finally {
            try {
                st2.close();
            } catch (Exception e) {
                fail("error in prepare method cleanup: " + e.getMessage());
                e.printStackTrace();
            }
        }

        try {
            db.prepare("insert into " + DatabaseCreator.SIMPLE_TABLE1
                    + " values(:one,:two,:three,:four);");
        } catch (Exception e) {
            assertEquals("table " + DatabaseCreator.SIMPLE_TABLE1
                    + " has 3 columns but 4 values were supplied", e
                    .getMessage());
        }

        try {
            db.prepare("insert into " + DatabaseCreator.SIMPLE_TABLE1
                    + " values(5, '10, 20);");
        } catch (Exception e) {
            assertEquals("unrecognized token: \"'10, 20);\"", e.getMessage());
        }

        try {
            db.prepare("insert into " + DatabaseCreator.SIMPLE_TABLE1
                    + " values(5, 10 20);");
        } catch (Exception e) {
            assertEquals("near \"20\": syntax error", e.getMessage());
        }

    }

    /**
     * @throws Exception 
     * @throws java.lang.Exception 
     * @tests {@link Database#open_blob(String, String, String, long, boolean)}
     * unsupported
     */
    @TestTargetNew(
        level = TestLevel.COMPLETE,
        notes = "not supported",
        method = "open_blob",
        args = {java.lang.String.class, java.lang.String.class, java.lang.String.class, long.class, boolean.class}
    )
    @KnownFailure("not supported")
    public void testOpen_blob() throws Exception, java.lang.Exception {
        Stmt statement2;
        Blob blobInput = new Blob();
       
        
        // Create test input Blob
        InputStream inStream = null;
        byte[] in = {(byte) 1, (byte) 2, (byte) 3, (byte) 4};
        
        // setup test input
        db.exec("create table TEST (res blob)",null);
        inStream = Class.forName(this.getClass().getName()).getResourceAsStream("/blob.c");
        assertNotNull(inStream);

        
        // insert byte array in db
        try {
            statement2 = db.prepare("insert into TEST(res) values (?)");
            statement2.bind(1, in);
            statement2.step();
            statement2.close();
        } catch (Exception e) {
            fail("Error happened inserting blob" + e.getMessage());
            e.printStackTrace();
        }
        
        // read from db
        byte[] output = null;
        Blob blob;
       
            blob = db.open_blob(dbFile.getPath(), "TEST", "res", 1, true);
            if (blob == null) {
                fail("Blob could not be retrieved");
            }
            //read from blob and compare values (positive case)
            InputStream is = blob.getInputStream();
            
            int i = 0;
            int outByte = 0;
            byte[] out = new byte[4];
            while ((outByte = is.read()) > -1) {
                out[i] = (byte) outByte;
                i++;
            }
            is.close();
            
            blob.close();
            
            assertTrue(Arrays.equals(in, out));
            
            //read from blob and compare values (default blob)
            db.exec("insert into TEST values(zeroblob(128))", null);
            Blob blob2 = db.open_blob(dbFile.getPath(), "TEST", "res", 2, true);
            is = blob2.getInputStream();
            for (i = 0; i < 128; i++)  {
               assertEquals(0, is.read());
            }
            is.close();
    }

    /**
     * @tests {@link Database#is3()}
     */
    @TestTargetNew(
        level = TestLevel.COMPLETE,
        notes = "method test",
        method = "is3",
        args = {}
    )
    public void testIs3() {
        int ver = Integer.parseInt(db.version().substring(0,1));
        if (db.is3()) {
            assertTrue( ver == 3);
        } else {
            assertTrue(ver != 3);
        }
    }

    /**
     * @tests {@link Database#progress_handler(int, ProgressHandler)}
     */
    @TestTargets ({
    @TestTargetNew(
        level = TestLevel.COMPLETE,
        notes = "method test",
        method = "progress_handler",
        args = {int.class, ProgressHandler.class}
    ),
    @TestTargetNew(
            level = TestLevel.COMPLETE,
            notes = "method test",
            method = "progress",
            clazz = ProgressHandler.class,
            args = {}
        )
    })
    public void testProgress_handler() {
        int inputVal = 3;
        TestProgressHandler prog = new TestProgressHandler();
        try {
            db.exec("create table TEST5(id integer, firstname text, lastname text)",null);
            Vm vm = db.compile("select * from TEST5; "
                    + "insert into TEST5 values(3, 'James', 'Bond'); "
                    + "delete from TEST5 where id = 3; "
                    + "select * from TEST5");
            int stmt = 0;
            do {
                ++stmt;
                if (stmt > inputVal) {
                    db.progress_handler(inputVal, prog);
                } else {
                    assertEquals(0, prog.getCounts());
                }
                while (vm.step(prog)) {
                }
            } while (vm.compile());
            assertEquals(inputVal,prog.getCounts());
        } catch (Exception e) {
            fail("Error in test setup: "+e.getMessage());
            e.printStackTrace();
        }
        
        // Boundary value test
        inputVal = 0;
        TestProgressHandler progBoundary = new TestProgressHandler();
        db.progress_handler(inputVal, progBoundary);
        try {
        Vm vm2 = db.compile("select * from TEST5; "
                + "insert into TEST5 values(3, 'James', 'Bond'); "
                + "delete from TEST5 where id = 3; "
                + "select * from TEST5");
        do {
            vm2.step(progBoundary);
        } while (vm2.compile());
        assertEquals(inputVal, progBoundary.getCounts());
        }catch (Exception e) {
            fail("Error in test setup: "+e.getMessage());
            e.printStackTrace();
        }
        
        try {
            db.exec("drop table TEST5",null);
        } catch (Exception e) {
            System.out.println(e.getMessage());
            e.printStackTrace();
        }
    }
    
    
    
    class SinFunc implements Function {
        
        
        public void function(FunctionContext fc, String args[]) {
            Double d = new Double(args[0]);
            fc.set_result(Math.sin(d.doubleValue()));
        }

        public void last_step(FunctionContext fc) {
            // TODO Auto-generated method stub

        }

        public void step(FunctionContext fc, String[] args) {
            // TODO Auto-generated method stub

        }
    }
    
   @TestTargetClass(Trace.class)
    class TestTrace implements Trace,Callback {
       
    private StringBuffer buf = new StringBuffer();
    
    public boolean traceCalled = false;
    
    public String getTrace() {
        return buf.toString();
    }
    
    public void trace(String stmt) {
        traceCalled = true;
        buf.append(stmt);
    }

    public void columns(String[] coldata) {
        // TODO Auto-generated method stub
        
    }

    public boolean newrow(String[] rowdata) {
        // TODO Auto-generated method stub
        return false;
    }

    public void types(String[] types) {
        // TODO Auto-generated method stub
        
    }
   }
   
   @TestTargetClass(Authorizer.class)
   class AuthorizerCallback implements Authorizer,Callback {
       private boolean isAuthorizing = false;
       
       public boolean wasCalled() {
           return isAuthorizing;
       }

    public int authorize(int action, String arg1, String arg2, String arg3,
            String arg4) {
        Logger.global.info("DB authorization callback "+action+" "+arg1+" "+arg2+" "+arg3+" "+arg4+" ");
        this.isAuthorizing = true;
        if (action != Constants.SQLITE_SELECT || arg1.contains("private_table")) {
        return Constants.SQLITE_DENY;
        } else {
        return Constants.SQLITE_OK;
        }
    }

    public void columns(String[] coldata) {
        // TODO Auto-generated method stub
        
    }

    public boolean newrow(String[] rowdata) {
        // TODO Auto-generated method stub
        return false;
    }

    public void types(String[] types) {
        // TODO Auto-generated method stub
        
    }
       
   }
   
   class TestBusyHandler implements BusyHandler, Callback {
    
    public boolean busy(String table, int count) {
        System.out.println("BUSY!");
        return true;
    }

    public void columns(String[] coldata) {
        // TODO Auto-generated method stub
        
    }

    public boolean newrow(String[] rowdata) {
        // TODO Auto-generated method stub
        return false;
    }

    public void types(String[] types) {
        // TODO Auto-generated method stub
        
    }
       
   }
   
   class TestProgressHandler implements ProgressHandler,Callback {
       
    private boolean progressed = false;
    
    private int counter = 0;
       
    public boolean isProgressed() {
        return progressed;
    }
    
    public int getCounts() {
        return counter;
    }

    public boolean progress() {
        this.progressed = true;
        counter++;
        return true;
    }

    public void columns(String[] coldata) {
        // TODO Auto-generated method stub
        
    }

    public boolean newrow(String[] rowdata) {
        // TODO Auto-generated method stub
        return false;
    }

    public void types(String[] types) {
        // TODO Auto-generated method stub
        
    }
       
   }
   
//   class dbBusyThread implements Runnable {
//       
//       String dbName = "sqliteTest.db";
//
//       Thread runner;
//       public dbBusyThread() {
//       }
//       public dbBusyThread(String threadName) {
//           runner = new Thread(this, threadName); // (1) Create a new thread.
//           System.out.println(runner.getName());
//           runner.start(); // (2) Start the thread.
//       }
//       public void run() {
//            insert(3000);
//        }
//       
//       public void runNoDelay() {
//           insert(0);
//       }
//       
//       synchronized private void insert(long delay) {
//           Database db2 = new Database();
//           try {
//               db2.open(dbName, 0);
//               db2.exec("insert into TEST5 values (4,'Anglina','Jolie');",
//                       null);
//               wait(delay);
//           } catch (Exception e) {
//               System.out.println("Error in Thread " + e.getMessage());
//               e.printStackTrace();
//           } catch (InterruptedException e2) {
//               System.out.println("Error in Thread " + e2.getMessage());
//               e2.printStackTrace();
//           } finally {
//              try {
//               db2.close();
//           } catch (Exception e) {
//               // We do not handle this case
//           }
//           }
//       }
//   }
   
   /**
    * This method creates a Runnable that executes insert operation for the
    * first table
    */
   private static Runnable createTask2Interrupt(final int id,
            final String dbName, final ErrorTracker errorTracker) {
        return new Runnable() {
            public void run() {
                Database db = new Database();
                try {
                    String value = DatabaseCreator.defaultString + id;

                    db.open(dbName, 0);
                    String insertQuery = "INSERT INTO "
                            + DatabaseCreator.TEST_TABLE1
                            + " (id, field1, field2, field3) VALUES(" + id
                            + ", '" + value + "', " + id + ", " + id + ")";
                    db.exec(insertQuery, null);
                } catch (Exception e) {
                    errorTracker.registerException(this, e);
                    try {
                        db.interrupt();
                        db.exec("DELETE FROM " + DatabaseCreator.SIMPLE_TABLE1
                                + " WHERE id=" + id, null);
                    } catch (Exception e1) {
                        errorTracker.registerException(this, e1);
                    }
                }
            }
        };
   }
   
   /**
    * This method creates a Runnable that executes delete operation for the
    * first table
    */
   private static Runnable createTask1(final int id,final String dbName, final ErrorTracker errorTracker) {
       return new Runnable() {
           public void run() {
               try {
                   Database db = new Database();
                   db.open(dbName, 0);
                   db.exec("DELETE FROM "
                           + DatabaseCreator.SIMPLE_TABLE1 + " WHERE id=" + id,null);
               } catch (Exception e) {
                   errorTracker.registerException(this, e);
               }
           }
       };
   }
   
   /**
    * This method creates a Runnable that executes insert operation for the
    * first table
    */
   private static Runnable createTask2(final int id, final String dbName, final ErrorTracker errorTracker ) {
       return new Runnable() {
           public void run() {
               try {
                   String value = DatabaseCreator.defaultString + id;
                   Database db = new Database();
                   db.open(dbName, 0);
                   String insertQuery = "INSERT INTO "
                           + DatabaseCreator.TEST_TABLE1
                           + " (id, field1, field2, field3) VALUES(" + id
                           + ", '" + value + "', " + id + ", " + id + ")";
                   db.exec(insertQuery,null);
               } catch (Exception e) {  
                   errorTracker.registerException(this, e);
                   
               }
           }
       };
   }
   
   /**
    * This method creates a Runnable that executes update operation for the one
    * record of the first table
    */
   private static Runnable createTask3(final int oldID, final String dbName,
            final int newID, final ErrorTracker errorTracker) {
        return new Runnable() {
            public void run() {
                Database db = new Database();
                try {
                    db.open(dbName, 0);
                    String value = DatabaseCreator.defaultString + newID;
                    String updateQuery = "UPDATE "
                            + DatabaseCreator.TEST_TABLE1 + " SET id=" + newID
                            + ", field1='" + value + "', field2=" + newID
                            + ", field3=" + newID + " WHERE id=" + oldID;
                    db.exec(updateQuery, null);
                } catch (Exception e) {
                    errorTracker.registerException(this, e);
                }
            }
        };
    }
   
   private class ErrorTracker {
        private List<String> errors = new ArrayList<String>();

        public void registerException(Runnable runnable, Exception e) {
            System.out.println("Registered: "+e.getMessage());
            errors.add(e.getMessage());
        }

        public List<String> getErrors() {
            return errors;
        }
        
        public void reset() {
            errors.clear();
        }
    }
   
}

