package org.postgresforest.tool.tests;

import java.io.*;
import java.sql.*;
import junit.framework.*;

import org.postgresforest.tool.lib.Config;
import org.postgresforest.tool.lib.Database;
import org.postgresforest.tool.lib.Instance;
import org.postgresforest.tool.lib.Table;
import org.postgresforest.tool.lib.GSCdata;
import org.postgresforest.tool.lib.ForestToolException;

public class TestDatabase extends TestCase {
	String user = "snaga";
	String pass = "";

	public void setUp()
	{
	}

	public void tearDown()
	{
	}

	private boolean dropdb(String dbname, String portNumber)
	{
		boolean rc = false;

		try {
            Thread.sleep(2000);

			String url = "jdbc:postgresql://localhost:" + portNumber + "/postgres";
			System.out.println(url);

			Connection con = DriverManager.getConnection(url, user, pass);

			con.createStatement().executeUpdate("DROP DATABASE " + dbname);
			con.close();
			rc = true;

            Thread.sleep(2000);
		}
		catch (Exception e)
		{
			System.out.println(e.getMessage());
		}

		return rc;
	}

    private boolean executeDDL(String dbName, String portNumber, String sql)
    {
        boolean rc = false;

        try {
            String url = "jdbc:postgresql://localhost:" + portNumber + "/" + dbName;

            Connection con = DriverManager.getConnection(url, user, pass);
            con.createStatement().executeUpdate(sql);
            con.close();
        }
        catch (Exception e)
        {
            System.out.println(e.getMessage());
			return false;
        }

		return true;
    }


	public void testInitialize001()
	{
		GSCdata gsc = null;

		dropdb("gsctest", "9998");
		dropdb("testdb", "9998");
		dropdb("testdb", "9999");

		try {
			gsc = GSCdata.initialize("localhost", "9998", "gsctest",
									 user, pass);
			assertTrue(gsc!=null);

			gsc.registerInstance("localhost", "9999");

			Database d = gsc.createDatabase("testdb");

			gsc.close();
		}
		catch (ForestToolException e)
		{
			System.out.println(e.getMessage());
			fail();
		}
	}


	public void testGetDatabase001()
	{
		GSCdata gsc = null;
		String sql = "CREATE TABLE t1 ( uid INTEGER PRIMARY KEY, name TEXT NOT NULL )";

		try {
			gsc = new GSCdata("localhost", "9998", "gsctest",
							  user, pass);
			assertTrue(gsc!=null);

			Database d = gsc.getDatabase("testdb");

			d.createTable(sql);

			gsc.close();
		}
		catch (ForestToolException e)
		{
			System.out.println(e.getMessage());
			fail();
		}
	}

    public void testCreateTable002()
    {
        GSCdata gsc = null;
        String sql = "CREATE TABLE \"myschema\".t2 ( uid INTEGER PRIMARY KEY, name TEXT NOT NULL )"; 

        try {
			executeDDL("testdb", "9998", "create schema myschema");
			executeDDL("testdb", "9999", "create schema myschema");
			
			gsc = new GSCdata("localhost", "9998", "gsctest",
							  user, pass);
			assertTrue(gsc!=null);
			
			Database d = gsc.getDatabase("testdb");
			d.createTable(sql);
			gsc.close();
        }
        catch (ForestToolException e)
		{
			System.out.println(e.getMessage());
			fail();
		}
    }

	public void testCreateTable003()
    {
		GSCdata gsc = null;
        String sql = "CREATE TABLE \"myschema\".t3 ( uid INTEGER PRIMARY KEY, name TEXT NOT NULL )";

        try {
            gsc = new GSCdata("localhost", "9998", "gsctest",
                              user, pass);
            assertTrue(gsc!=null);

            Database d = gsc.getDatabase("testdb");
            d.createTable(sql);
            gsc.close();
        }
        catch (ForestToolException e)
        {
            System.out.println(e.getMessage());
            fail();
        }
    }


	public void testCreateTable004()
    {
		GSCdata gsc = null;
        String sql = "CREATE TABLE accounts (\n" +
			"    aid integer NOT NULL,\n" +
			"    bid integer,\n" +
			"    abalance integer,\n" +
			"    filler character(84)\n" +
			");";

        try {
            gsc = new GSCdata("localhost", "9998", "gsctest",
                              user, pass);
            assertTrue(gsc!=null);

            Database d = gsc.getDatabase("testdb");
            d.createTable(sql);
            gsc.close();
        }
        catch (ForestToolException e)
        {
            System.out.println(e.getMessage());
            fail();
        }
    }

    public void testCreateTable005()
    {
        GSCdata gsc = null;
        String sql = "CREATE TABLE history (\n" +
			"    tid integer,\n" +
			"    bid integer,\n" +
			"    aid integer,\n" +
			"    delta integer,\n" +
			"    mtime timestamp without time zone,\n" +
			"    filler character(22)\n" +
			");";

        try {
			gsc = new GSCdata("localhost", "9998", "gsctest",
                              user, pass);
            assertTrue(gsc!=null);

            Database d = gsc.getDatabase("testdb");
            d.createTable(sql);
            gsc.close();
        }
		catch (ForestToolException e)
        {
            System.out.println(e.getMessage());
            fail();
        }
    }

    public void testGetTableNames001()
    {
        GSCdata gsc = null;

        try {
            gsc = new GSCdata("localhost", "9998", "gsctest",
                              user, pass);
            assertTrue(gsc!=null);

            Database d = gsc.getDatabase("testdb");
            String[] tableNames = d.getTableNames();

			assertTrue( tableNames[0].equals("accounts") );
			assertTrue( tableNames[1].equals("history") );
			assertTrue( tableNames[2].equals("myschema.t2") );
			assertTrue( tableNames[3].equals("myschema.t3") );
			assertTrue( tableNames[4].equals("t1") );

			gsc.close();
        }
        catch (ForestToolException e)
        {
            System.out.println(e.getMessage());
            fail();
        }
    } 


    public void testGetColumnNames001()
    {
        GSCdata gsc = null;

        try {
            gsc = new GSCdata("localhost", "9998", "gsctest",
                              user, pass);
            assertTrue(gsc!=null);

            Database d = gsc.getDatabase("testdb");

			Table t = d.getTable("accounts");
			
			String[] c = t.getColumnNames();

			assertTrue( c[0].equals("aid") );
			assertTrue( c[1].equals("bid") );
			assertTrue( c[2].equals("abalance") );
			assertTrue( c[3].equals("filler") );

			gsc.close();
        }
        catch (ForestToolException e)
        {
            System.out.println(e.getMessage());
            fail();
        }
    } 


	/*
	 * データベース削除（テーブルがあったら失敗）
	 */
    public void testDropDatabase001()
    {
        GSCdata gsc = null;

        try {
            gsc = new GSCdata("localhost", "9998", "gsctest",
                              user, pass);
            assertTrue(gsc!=null);

            boolean rc = gsc.dropDatabase("testdb", false);

			assertTrue( rc==false );

			gsc.close();
        }
        catch (ForestToolException e)
        {
            System.out.println(e.getMessage());
            fail();
        }
    } 

	/*
	 * データベース削除（テーブルがあったら強制削除）
	 */
    public void testDropDatabase002()
    {
        GSCdata gsc = null;

        try {
            gsc = new GSCdata("localhost", "9998", "gsctest",
                              user, pass);
            assertTrue(gsc!=null);

            boolean rc = gsc.dropDatabase("testdb", true);

			assertTrue( rc==true );

			gsc.close();
        }
        catch (ForestToolException e)
        {
            System.out.println(e.getMessage());
            fail();
        }
    } 


	public static void main(String[] args)
	{
		try {
			Class.forName("org.postgresql.Driver");
		}
		catch (Exception e)
		{
			System.out.println(e.getMessage());
			System.exit(-1);
		}

		junit.textui.TestRunner.run(TestDatabase.class);
	}
}
