package test.org.seasar.dao.impl;

import java.util.ArrayList;
import java.util.List;

import org.seasar.dao.DaoMetaData;
import org.seasar.dao.IllegalSignatureRuntimeException;
import org.seasar.dao.SqlCommand;
import org.seasar.dao.dbms.Oracle;
import org.seasar.dao.impl.BeanArrayMetaDataResultSetHandler;
import org.seasar.dao.impl.BeanListMetaDataResultSetHandler;
import org.seasar.dao.impl.BeanMetaDataResultSetHandler;
import org.seasar.dao.impl.DaoMetaDataImpl;
import org.seasar.dao.impl.DeleteBatchAutoStaticCommand;
import org.seasar.dao.impl.InsertAutoStaticCommand;
import org.seasar.dao.impl.InsertBatchAutoStaticCommand;
import org.seasar.dao.impl.SelectDynamicCommand;
import org.seasar.dao.impl.UpdateBatchAutoStaticCommand;
import org.seasar.dao.impl.UpdateDynamicCommand;
import org.seasar.extension.jdbc.impl.BasicCallableStatementFactory;
import org.seasar.extension.jdbc.impl.BasicResultSetFactory;
import org.seasar.extension.jdbc.impl.ObjectResultSetHandler;
import org.seasar.extension.unit.S2TestCase;

/**
 * @author higa
 *  
 */
public class DaoMetaDataImplTest extends S2TestCase {

	/**
	 * Constructor for InvocationImplTest.
	 * 
	 * @param arg0
	 */
	public DaoMetaDataImplTest(String arg0) {
		super(arg0);
	}

	public static void main(String[] args) {
		junit.textui.TestRunner.run(DaoMetaDataImplTest.class);
	}

	public void setUp() {
		include("j2ee.dicon");
	}

	public void testSelectBeanList() throws Exception {
		DaoMetaData dmd = new DaoMetaDataImpl(EmployeeDao.class,
				getDataSource(), BasicCallableStatementFactory.INSTANCE,
				BasicResultSetFactory.INSTANCE);
		SelectDynamicCommand cmd = (SelectDynamicCommand) dmd
				.getSqlCommand("getAllEmployees");
		assertNotNull("1", cmd);
		assertEquals("2", "SELECT * FROM emp", cmd.getSql());
		BeanListMetaDataResultSetHandler rsh = (BeanListMetaDataResultSetHandler) cmd
				.getResultSetHandler();
		assertEquals("3", Employee.class, rsh.getBeanMetaData().getBeanClass());
	}

	public void testSelectBeanArray() throws Exception {
		DaoMetaData dmd = new DaoMetaDataImpl(EmployeeDao.class,
				getDataSource(), BasicCallableStatementFactory.INSTANCE,
				BasicResultSetFactory.INSTANCE);
		SelectDynamicCommand cmd = (SelectDynamicCommand) dmd
				.getSqlCommand("getAllEmployeeArray");
		assertNotNull("1", cmd);
		BeanArrayMetaDataResultSetHandler rsh = (BeanArrayMetaDataResultSetHandler) cmd
				.getResultSetHandler();
		assertEquals("2", Employee.class, rsh.getBeanMetaData().getBeanClass());
	}

	public void testSelectBean() throws Exception {
		DaoMetaData dmd = new DaoMetaDataImpl(EmployeeDao.class,
				getDataSource(), BasicCallableStatementFactory.INSTANCE,
				BasicResultSetFactory.INSTANCE);
		SelectDynamicCommand cmd = (SelectDynamicCommand) dmd
				.getSqlCommand("getEmployee");
		assertNotNull("1", cmd);
		assertEquals("2", BeanMetaDataResultSetHandler.class, cmd
				.getResultSetHandler().getClass());
		assertEquals("3", "empno", cmd.getArgNames()[0]);
	}

	public void testSelectObject() throws Exception {
		DaoMetaData dmd = new DaoMetaDataImpl(EmployeeDao.class,
				getDataSource(), BasicCallableStatementFactory.INSTANCE,
				BasicResultSetFactory.INSTANCE);
		SelectDynamicCommand cmd = (SelectDynamicCommand) dmd
				.getSqlCommand("getCount");
		assertNotNull("1", cmd);
		assertEquals("2", ObjectResultSetHandler.class, cmd
				.getResultSetHandler().getClass());
		assertEquals("3", "SELECT COUNT(*) FROM emp", cmd.getSql());
	}

	public void testUpdate() throws Exception {
		DaoMetaData dmd = new DaoMetaDataImpl(EmployeeDao.class,
				getDataSource(), BasicCallableStatementFactory.INSTANCE,
				BasicResultSetFactory.INSTANCE);
		UpdateDynamicCommand cmd = (UpdateDynamicCommand) dmd
				.getSqlCommand("update");
		assertNotNull("1", cmd);
		assertEquals("2", "employee", cmd.getArgNames()[0]);
	}

	public void testInsertAutoTx() throws Exception {
		DaoMetaData dmd = new DaoMetaDataImpl(EmployeeAutoDao.class,
				getDataSource(), BasicCallableStatementFactory.INSTANCE,
				BasicResultSetFactory.INSTANCE);
		InsertAutoStaticCommand cmd = (InsertAutoStaticCommand) dmd
				.getSqlCommand("insert");
		assertNotNull("1", cmd);
		Employee emp = new Employee();
		emp.setEmpno(99);
		emp.setEname("hoge");
		cmd.execute(new Object[] { emp });
	}

	public void testInsertAuto() throws Exception {
		DaoMetaData dmd = new DaoMetaDataImpl(FormUseHistoryDao.class,
				getDataSource(), BasicCallableStatementFactory.INSTANCE,
				BasicResultSetFactory.INSTANCE);
		InsertAutoStaticCommand cmd = (InsertAutoStaticCommand) dmd
				.getSqlCommand("insert");
		assertNotNull("1", cmd);
	}

	public void testUpdateAutoTx() throws Exception {
		DaoMetaData dmd = new DaoMetaDataImpl(EmployeeAutoDao.class,
				getDataSource(), BasicCallableStatementFactory.INSTANCE,
				BasicResultSetFactory.INSTANCE);
		SqlCommand cmd = dmd.getSqlCommand("update");
		assertNotNull("1", cmd);
		SelectDynamicCommand cmd2 = (SelectDynamicCommand) dmd
				.getSqlCommand("getEmployee");
		Employee emp = (Employee) cmd2
				.execute(new Object[] { new Integer(7788) });
		emp.setEname("hoge2");
		cmd.execute(new Object[] { emp });
	}

	public void testDeleteAutoTx() throws Exception {
		DaoMetaData dmd = new DaoMetaDataImpl(EmployeeAutoDao.class,
				getDataSource(), BasicCallableStatementFactory.INSTANCE,
				BasicResultSetFactory.INSTANCE);
		SqlCommand cmd = dmd.getSqlCommand("delete");
		assertNotNull("1", cmd);
		SelectDynamicCommand cmd2 = (SelectDynamicCommand) dmd
				.getSqlCommand("getEmployee");
		Employee emp = (Employee) cmd2
				.execute(new Object[] { new Integer(7788) });
		cmd.execute(new Object[] { emp });
	}

	public void testIllegalAutoUpdateMethod() throws Exception {
		try {
			new DaoMetaDataImpl(IllegalEmployeeAutoDao.class, getDataSource(),
					BasicCallableStatementFactory.INSTANCE,
					BasicResultSetFactory.INSTANCE);
			fail("1");
		} catch (IllegalSignatureRuntimeException ex) {
			System.out.println(ex.getSignature());
			System.out.println(ex);
		}
	}

	public void testSelectAuto() throws Exception {
		DaoMetaData dmd = new DaoMetaDataImpl(EmployeeAutoDao.class,
				getDataSource(), BasicCallableStatementFactory.INSTANCE,
				BasicResultSetFactory.INSTANCE);
		SelectDynamicCommand cmd = (SelectDynamicCommand) dmd
				.getSqlCommand("getEmployeeByDeptno");
		System.out.println(cmd.getSql());
	}

	public void testInsertBatchAuto() throws Exception {
		DaoMetaData dmd = new DaoMetaDataImpl(EmployeeAutoDao.class,
				getDataSource(), BasicCallableStatementFactory.INSTANCE,
				BasicResultSetFactory.INSTANCE);
		InsertBatchAutoStaticCommand cmd = (InsertBatchAutoStaticCommand) dmd
				.getSqlCommand("insertBatch");
		assertNotNull("1", cmd);
	}

	public void testUpdateBatchAuto() throws Exception {
		DaoMetaData dmd = new DaoMetaDataImpl(EmployeeAutoDao.class,
				getDataSource(), BasicCallableStatementFactory.INSTANCE,
				BasicResultSetFactory.INSTANCE);
		UpdateBatchAutoStaticCommand cmd = (UpdateBatchAutoStaticCommand) dmd
				.getSqlCommand("updateBatch");
		assertNotNull("1", cmd);
	}

	public void testDeleteBatchAuto() throws Exception {
		DaoMetaData dmd = new DaoMetaDataImpl(EmployeeAutoDao.class,
				getDataSource(), BasicCallableStatementFactory.INSTANCE,
				BasicResultSetFactory.INSTANCE);
		DeleteBatchAutoStaticCommand cmd = (DeleteBatchAutoStaticCommand) dmd
				.getSqlCommand("deleteBatch");
		assertNotNull("1", cmd);
	}

	public void testCreateFindCommand() throws Exception {
		DaoMetaData dmd = new DaoMetaDataImpl(EmployeeAutoDao.class,
				getDataSource(), BasicCallableStatementFactory.INSTANCE,
				BasicResultSetFactory.INSTANCE);

		SqlCommand cmd = dmd.createFindCommand(null);
		List employees = (List) cmd.execute(null);
		System.out.println(employees);
		assertTrue("1", employees.size() > 0);
	}

	public void testCreateFindCommand2() throws Exception {
		DaoMetaData dmd = new DaoMetaDataImpl(EmployeeAutoDao.class,
				getDataSource(), BasicCallableStatementFactory.INSTANCE,
				BasicResultSetFactory.INSTANCE);
		SqlCommand cmd = dmd.createFindCommand(null);
		List employees = (List) cmd.execute(null);
		System.out.println(employees);
		assertTrue("1", employees.size() > 0);
	}

	public void testCreateFindCommand3() throws Exception {
		DaoMetaData dmd = new DaoMetaDataImpl(EmployeeAutoDao.class,
				getDataSource(), BasicCallableStatementFactory.INSTANCE,
				BasicResultSetFactory.INSTANCE);

		SqlCommand cmd = dmd.createFindCommand("select * from emp");
		List employees = (List) cmd.execute(null);
		System.out.println(employees);
		assertTrue("1", employees.size() > 0);
	}

	public void testCreateFindCommand4() throws Exception {
		DaoMetaData dmd = new DaoMetaDataImpl(EmployeeAutoDao.class,
				getDataSource(), BasicCallableStatementFactory.INSTANCE,
				BasicResultSetFactory.INSTANCE);

		SqlCommand cmd = dmd.createFindCommand("order by empno");
		List employees = (List) cmd.execute(null);
		System.out.println(employees);
		assertTrue("1", employees.size() > 0);
	}

	public void testCreateFindCommand5() throws Exception {
		DaoMetaDataImpl dmd = new DaoMetaDataImpl(EmployeeAutoDao.class,
				getDataSource(), BasicCallableStatementFactory.INSTANCE,
				BasicResultSetFactory.INSTANCE);

		dmd.setDbms(new Oracle());
		SelectDynamicCommand cmd = (SelectDynamicCommand) dmd
				.createFindCommand("empno = ?");
		System.out.println(cmd.getSql());
		assertTrue("1", cmd.getSql().endsWith(" AND empno = ?"));
	}

	public void testCreateFindBeanCommand() throws Exception {
		DaoMetaData dmd = new DaoMetaDataImpl(EmployeeAutoDao.class,
				getDataSource(), BasicCallableStatementFactory.INSTANCE,
				BasicResultSetFactory.INSTANCE);

		SqlCommand cmd = dmd.createFindBeanCommand("empno = ?");
		Employee employee = (Employee) cmd.execute(new Object[] { new Integer(
				7788) });
		System.out.println(employee);
		assertNotNull("1", employee);
	}

	public void testCreateObjectBeanCommand() throws Exception {
		DaoMetaData dmd = new DaoMetaDataImpl(EmployeeAutoDao.class,
				getDataSource(), BasicCallableStatementFactory.INSTANCE,
				BasicResultSetFactory.INSTANCE);

		SqlCommand cmd = dmd
				.createFindObjectCommand("select count(*) from emp");
		Integer count = (Integer) cmd.execute(null);
		assertEquals("1", 14, count.intValue());
	}

	public void testSelectAutoByQuery() throws Exception {
		DaoMetaData dmd = new DaoMetaDataImpl(EmployeeAutoDao.class,
				getDataSource(), BasicCallableStatementFactory.INSTANCE,
				BasicResultSetFactory.INSTANCE);
		SqlCommand cmd = dmd.getSqlCommand("getEmployeesBySal");
		List employees = (List) cmd.execute(new Object[] { new Integer(0),
				new Integer(1000) });
		System.out.println(employees);
		assertEquals("1", 2, employees.size());
	}

	public void testSelectAutoByQueryMultiIn() throws Exception {
		DaoMetaData dmd = new DaoMetaDataImpl(EmployeeAutoDao.class,
				getDataSource(), BasicCallableStatementFactory.INSTANCE,
				BasicResultSetFactory.INSTANCE);
		SelectDynamicCommand cmd = (SelectDynamicCommand) dmd
				.getSqlCommand("getEmployeesByEnameJob");
		System.out.println(cmd.getSql());
		List enames = new ArrayList();
		enames.add("SCOTT");
		enames.add("MARY");
		List jobs = new ArrayList();
		jobs.add("ANALYST");
		jobs.add("FREE");
		List employees = (List) cmd.execute(new Object[] { enames, jobs });
		System.out.println(employees);
		//assertEquals("1", 2, employees.size());
	}

	public void testRelation() throws Exception {
		DaoMetaData dmd = new DaoMetaDataImpl(Employee2Dao.class,
				getDataSource(), BasicCallableStatementFactory.INSTANCE,
				BasicResultSetFactory.INSTANCE);

		SqlCommand cmd = dmd.getSqlCommand("getAllEmployees");
		List emps = (List) cmd.execute(null);
		System.out.println(emps);
		assertTrue("1", emps.size() > 0);
	}

	public void testGetDaoInterface() throws Exception {
		assertEquals("1", EmployeeDao.class, DaoMetaDataImpl
				.getDaoInterface(EmployeeDao.class));
		assertEquals("2", EmployeeDao.class, DaoMetaDataImpl
				.getDaoInterface(EmployeeDaoImpl.class));
	}

	public void testAutoSelectSqlByDto() throws Exception {
		DaoMetaData dmd = new DaoMetaDataImpl(EmployeeAutoDao.class,
				getDataSource(), BasicCallableStatementFactory.INSTANCE,
				BasicResultSetFactory.INSTANCE);
		SelectDynamicCommand cmd = (SelectDynamicCommand) dmd
				.getSqlCommand("getEmployeesBySearchCondition");
		assertNotNull("1", cmd);
		System.out.println(cmd.getSql());
		EmployeeSearchCondition dto = new EmployeeSearchCondition();
		dto.setDname("RESEARCH");
		List employees = (List) cmd.execute(new Object[] { dto });
		assertTrue("2", employees.size() > 0);
	}

	public void testAutoSelectSqlByDto2() throws Exception {
		DaoMetaData dmd = new DaoMetaDataImpl(EmployeeAutoDao.class,
				getDataSource(), BasicCallableStatementFactory.INSTANCE,
				BasicResultSetFactory.INSTANCE);
		SelectDynamicCommand cmd = (SelectDynamicCommand) dmd
				.getSqlCommand("getEmployeesByEmployee");
		assertNotNull("1", cmd);
		System.out.println(cmd.getSql());
		Employee dto = new Employee();
		dto.setJob("MANAGER");
		List employees = (List) cmd.execute(new Object[] { dto });
		System.out.println(employees);
		//assertTrue("2", employees.size() > 0);
	}

	public void testAutoSelectSqlByDto3() throws Exception {
		DaoMetaData dmd = new DaoMetaDataImpl(Employee3Dao.class,
				getDataSource(), BasicCallableStatementFactory.INSTANCE,
				BasicResultSetFactory.INSTANCE);
		SelectDynamicCommand cmd = (SelectDynamicCommand) dmd
				.getSqlCommand("getEmployees");
		assertNotNull("1", cmd);
		System.out.println(cmd.getSql());
		Employee3 dto = new Employee3();
		dto.setManager(new Short((short) 7902));
		List employees = (List) cmd.execute(new Object[] { dto });
		System.out.println(employees);
		assertTrue("2", employees.size() > 0);
	}

	public void testAutoSelectSqlByDto4() throws Exception {
		DaoMetaData dmd = new DaoMetaDataImpl(Employee3Dao.class,
				getDataSource(), BasicCallableStatementFactory.INSTANCE,
				BasicResultSetFactory.INSTANCE);
		SelectDynamicCommand cmd = (SelectDynamicCommand) dmd
				.getSqlCommand("getEmployees2");
		assertNotNull("1", cmd);
		System.out.println(cmd.getSql());
		assertTrue("2", cmd.getSql().endsWith(" ORDER BY empno"));
	}

	public void testSelfReference() throws Exception {
		DaoMetaData dmd = new DaoMetaDataImpl(Employee4Dao.class,
				getDataSource(), BasicCallableStatementFactory.INSTANCE,
				BasicResultSetFactory.INSTANCE);
		SelectDynamicCommand cmd = (SelectDynamicCommand) dmd
				.getSqlCommand("getEmployee");
		assertNotNull("1", cmd);
		System.out.println(cmd.getSql());
		Employee4 employee = (Employee4) cmd
				.execute(new Object[] { new Integer(7788) });
		System.out.println(employee);
		assertEquals("2", new Long(7566), employee.getParent().getEmpno());
	}

	public void testSelfMultiPk() throws Exception {
		DaoMetaData dmd = new DaoMetaDataImpl(Employee5Dao.class,
				getDataSource(), BasicCallableStatementFactory.INSTANCE,
				BasicResultSetFactory.INSTANCE);
		SelectDynamicCommand cmd = (SelectDynamicCommand) dmd
				.getSqlCommand("getEmployee");
		assertNotNull("1", cmd);
		System.out.println(cmd.getSql());
	}

	public void testNotHavePrimaryKey() throws Exception {
		DaoMetaData dmd = new DaoMetaDataImpl(DepartmentTotalSalaryDao.class,
				getDataSource(), BasicCallableStatementFactory.INSTANCE,
				BasicResultSetFactory.INSTANCE);
		SelectDynamicCommand cmd = (SelectDynamicCommand) dmd
				.getSqlCommand("getTotalSalaries");
		assertNotNull("1", cmd);
		System.out.println(cmd.getSql());
		List result = (List) cmd.execute(null);
		System.out.println(result);
	}

	public void testSelectAutoFullColumnName() throws Exception {
		DaoMetaData dmd = new DaoMetaDataImpl(EmployeeAutoDao.class,
				getDataSource(), BasicCallableStatementFactory.INSTANCE,
				BasicResultSetFactory.INSTANCE);
		SelectDynamicCommand cmd = (SelectDynamicCommand) dmd
				.getSqlCommand("getEmployee");
		System.out.println(cmd.getSql());
	}
}