package com.steering.pss.qcm;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;

import CoreFS.SA01.CoreIComponent;
import CoreFS.SA06.CorePageObject;
import CoreFS.SA06.CoreReturnObject;
import CoreFS.SA06.CoreSqlType.CoreOracleType;
import CoreFS.SA08.CoreXmlSqlParsersFactory;

/**
 * 平台的使用类都必须继承自平台的CoreIComponent类
 * 
 * @author wenqiao 2014/09/24
 * @version v1.0
 * @modify
 */
public class CoreProductionBase extends CoreIComponent {  
	/**
	 * 服务端的查询方法
	 * @param parm 姓名
	 * @return CoreReturnObject 必须返回CoreReturnObject
	 */
    public CoreReturnObject doQuery(ArrayList<Object> parm) {
    	CoreReturnObject cro = new CoreReturnObject();
        String sql = CoreXmlSqlParsersFactory.getSql("CoreProductionBase.QUERY");
        
        if(parm != null && parm.size() == 1){
            cro = this.getDao("KgDao").ExcuteQuery(sql, parm.toArray());
        }
        
        return cro;
    }

    public CoreReturnObject doDelete(ArrayList<Object> parms) {
        CoreReturnObject cro = new CoreReturnObject();

		String strSql = "delete from TPCOTEST where pline_code=?";

		try {
			cro = this.getDao("KgDao").ExcuteNonQuery(strSql, parms.toArray());
		} catch (Exception e) {
			// TODO: handle exception
			cro = cro.SetErrInfo(e.getMessage());
		}

		return cro;
	}

	public CoreReturnObject doAdd(ArrayList<Object> parms) {
		CoreReturnObject cro = new CoreReturnObject();
		String strSql = "insert into COM_BASE_PLINE"
				+ "(pline_code, pline_name, department_code, department_desc, "
				+ "create_name, create_time, update_name, update_time, "
				+ "delete_name, delete_time, validflag, memo)"
				+ "values(?,?,?,?,?,?,?,?,?,?,?,?)";

		try {
			cro = this.getDao("KgDao").ExcuteNonQuery(strSql, parms.toArray());
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			cro = cro.SetErrInfo(e.getMessage());
		}

		return cro;
	}

	public CoreReturnObject doModify(ArrayList<Object> parms) {
		CoreReturnObject cro = new CoreReturnObject();
		// insert into TPCOTEST (pline_code, pline_name, department_code,
		// department_desc, create_name, create_time, update_name, update_time,
		// delete_name, delete_time, validflag, memo)
		// values ('TPCO01', 'abc', 'abc', 'abc', 'abc', to_date('19-09-2014',
		// 'dd-mm-yyyy'), 'abc', to_date('19-09-2014', 'dd-mm-yyyy'), 'abc',
		// to_date('19-09-2014', 'dd-mm-yyyy'), '1', 'abc');
		String strSql = "update TPCOTEST set "
				+ "pline_name=?, department_code=?, department_desc=?, create_name=?, create_time=?, update_name=?, update_time=?,"
				+ " delete_name=?, delete_time=?, validflag=?, memo=? where pline_code=?";

		try {
			cro = this.getDao("KgDao").ExcuteNonQuery(strSql, parms.toArray());
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			cro = cro.SetErrInfo(e.getMessage());
		}

		return cro;
	}

	/*
	 * 数据查询方法，主要是在客户端DataTable没有提供相关的列结构例用该方式进行查询
	 */
	public CoreReturnObject doQueryBySort(ArrayList<Object> parm) {
		CoreReturnObject cro = new CoreReturnObject();
		// sql语句
		String strSql = "select USER_NAME,USER_ID from USER_TABLE where 1=1";
		String strWhere = ""; // 用来存放条件的字符串
		ArrayList<Object> al = new ArrayList<Object>(); // 存放处理后的参数
		if (!parm.get(0).equals("")) // 判断从客户端传来的姓名是不是为空，如果不为空则加上SQL的姓名查询条件，并将姓名添加到al这个集合中
		{
			strWhere += " And USER_NAME=?";
			al.add(parm.get(0));
		}
		strSql += strWhere; // 将strSql与strWhere字符串连接起来
		Object[] o = null; // 用来SQL的参数
		if (al.size() > 0) // 如果这值大于0则将这个al的arraylist转成Object数组并赋给定义的o数组
		{
			o = al.toArray();
		}
		// 调用平台的方法连数据库进行数据的查询
		// KgDao名字是从平台springjndiconfig.xml这个配置文件里面定义
		// ExcuteSortResultByQuery该方法可以固定查询字段的顺序
		cro = this.getDao("KgDao").ExcuteSortResultByQuery(strSql, o);

		return cro;
	}

	/*
	 * 该方法主要是确定这SQL存放在服务端query目录下，如何去取SQL语句
	 */
	public CoreReturnObject doQuerySqlInXML(ArrayList<Object> parm) {
		CoreReturnObject cro = new CoreReturnObject();
		// sql语句
		String strSql = CoreXmlSqlParsersFactory.getSql("query_userinfo_0001");// query_userinfo_0001在服务端的query目录下的CoreUSERInfo.xml中已经定义。
		String strWhere = ""; // 用来存放条件的字符串
		ArrayList<Object> al = new ArrayList<Object>(); // 存放处理后的参数
		if (!parm.get(0).equals("")) // 判断从客户端传来的姓名是不是为空，如果不为空则加上SQL的姓名查询条件，并将姓名添加到al这个集合中
		{
			strWhere += " And USER_NAME=?";
			al.add(parm.get(0));
		}
		strSql += strWhere; // 将strSql与strWhere字符串连接起来
		Object[] o = null; // 用来SQL的参数
		if (al.size() > 0) // 如果这值大于0则将这个al的arraylist转成Object数组并赋给定义的o数组
		{
			o = al.toArray();
		}
		// 调用平台的方法连数据库进行数据的查询
		// KgDao名字是从平台springjndiconfig.xml这个配置文件里面定义
		cro = this.getDao("KgDao").ExcuteQuery(strSql, o);

		return cro;
	}

	/**
	 * 数据新增的方法
	 * 
	 * @param parms
	 * @return
	 */
	// public CoreReturnObject doAdd(ArrayList parms)
	// {
	// CoreReturnObject cro=new CoreReturnObject();
	// String strSql="insert into USER_TABLE(USER_ID,USER_NAME)values(?,?)";
	// try {
	// //服务执行普通的添加、修改、删除使用方法为ExcuteNonQuery
	// cro=this.getDao("KgDao").ExcuteNonQuery(strSql,
	// parms.toArray());//将ArrayList的parms转成Object[]的数组
	// } catch (SQLException e) {
	// // TODO Auto-generated catch block
	// this.logAdapter.filelogger.logError(e.getMessage());//将服务端的错误信息写入日志文件
	// cro=cro.SetErrInfo(e.getMessage());//将服务端的错误返回到客户端，客户端通ccp.ReturnInfo来获取。
	// }
	//
	// return cro;
	// }

	/*
	 * 实现数据修改的通用方法
	 */
	// public CoreReturnObject doModify(ArrayList parms)
	// {
	// CoreReturnObject cro=new CoreReturnObject();
	// String strSql="update USER_TABLE set USER_NAME=? where USER_ID=?";
	//
	// try {
	// cro=this.getDao("KgDao").ExcuteNonQuery(strSql, parms.toArray());
	// } catch (SQLException e) {
	// // TODO Auto-generated catch block
	// this.logAdapter.filelogger.logError(e.getMessage());//将服务端的错误信息写入日志文件
	// cro=cro.SetErrInfo(e.getMessage());//将服务端的错误返回到客户端，客户端通ccp.ReturnInfo来获取。
	// }
	// //在cro.getResult() 可以获修改所影响行数
	//
	// return cro;
	// }

	/*
	 * 删除的方法
	 */
	// public CoreReturnObject doDelete(String userid)
	// {
	// CoreReturnObject cro=new CoreReturnObject();
	// String strSql="delete USER_TABLE where USER_ID=?";
	//
	// try {
	// cro=this.getDao("KgDao").ExcuteNonQuery(strSql,new Object[]{userid});
	// } catch (SQLException e) {
	// // TODO Auto-generated catch block
	// this.logAdapter.filelogger.logError(e.getMessage());//将服务端的错误信息写入日志文件
	// cro=cro.SetErrInfo(e.getMessage());//将服务端的错误返回到客户端，客户端通ccp.ReturnInfo来获取。
	// }
	// return cro;
	// }

	/*
	 * 分页查询的自定义方法
	 * 
	 * 如果有相关业务处理不调平台在服务端提供的分页方法即 CoreBpm.Authentication
	 * commonQueryForPage这个方法，则可以自己实一个分页方法自定义的分页方法的参数必须是CorePageObject
	 * 在这个CorePageObject的实例中可以修改相关的属性值
	 */
	public CoreReturnObject doQueryByPage(CorePageObject cpo) {
		// 以下每个get方法都有一个对应set方法
		/*
		 * cpo.getColIdx();//获取列索引 cpo.getCurrentPage();//当前页
		 * cpo.getNMax();//总记录行数 cpo.getPageSize();//每页记录行数 cpo.getResult();//结果
		 * cpo.getSql();//Sql语句，也可以存SqlID cpo.getSqlparamter();//Sql的参数
		 * cpo.getTotalPage();//总页数
		 */
		CoreReturnObject cro = new CoreReturnObject();
		// ExcutePageQuery为进行分页查询的方法。
		cro = this.getDao("KgDao").ExcutePageQuery(cpo);

		return cro;
	}

	/*
	 * 在查询的数据如果有Blob\Clob大数据类型，那么服务端的实现如下
	 */
	public CoreReturnObject doQueryBlob() {
		CoreReturnObject cro = new CoreReturnObject();
		String strSql = "xx";
		try {
			// 服务端往数据库查询Blob/Clob主要使用ExceuteQueryForBlobList
			cro = this.getDao("KgDao").ExceuteQueryForBlobList(strSql,
					new Object[] {});
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			CoreIComponent.logAdapter.filelogger.logError(e.getMessage());// 将服务端的错误信息写入日志文件
			cro = cro.SetErrInfo(e.getMessage());// 将服务端的错误返回到客户端，客户端通ccp.ReturnInfo来获取。
		}
		return cro;
	}

	/*
	 * 服务端执行修改、添加如果存在Blob/Clob按如下方法处理
	 */
	public CoreReturnObject doNonQuery() {
		CoreReturnObject cro = new CoreReturnObject();
		String strSql = "xx";
		try {
			// 如果服务端往数据库修改、添加的字段含有Blob/Clob类型的数据使方法为：ExceuteNonQueryForBlobList
			cro = this.getDao("KgDao").ExceuteNonQueryForBlobList(strSql,
					new Object[] {});
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			CoreIComponent.logAdapter.filelogger.logError(e.getMessage());// 将服务端的错误信息写入日志文件
			cro = cro.SetErrInfo(e.getMessage());// 将服务端的错误返回到客户端，客户端通ccp.ReturnInfo来获取。
		}

		return cro;
	}

	/*
	 * 执行数据库的存储使用如下方式
	 */
	public CoreReturnObject doProcedure() {
		CoreReturnObject cro = new CoreReturnObject();
		/*
		 * procedure testprocedure(userid in varchar2,userName in varchar2,
		 * error out varchar2)
		 */
		String pName = "testprocedure";// 存储过程的名字

		// inParmType用来存放存储过程输入参数的数据类型
		ArrayList<Object> inParmType = new ArrayList<Object>();
		inParmType.add(CoreOracleType.STRING_TYPE.ordinal());// 获取userid数据类型为varchar2
																// 在这个集合添加String的类型索引
		inParmType.add(CoreOracleType.STRING_TYPE.ordinal());

		// inValue用来存放存储过程输入参数的值
		ArrayList<Object> inValue = new ArrayList<Object>();
		inValue.add("1");
		inValue.add("张三");

		// outResultType用来存入存储过程输出结果的数据类型
		ArrayList<Object> outResultType = new ArrayList<Object>();
		outResultType.add(CoreOracleType.STRING_TYPE.ordinal());

		// outResulte用来存放输出的结果值
		ArrayList<Object> outResult = new ArrayList<Object>();

		try {
			cro = this.getDao("KgDao").ExcuteProcedure(pName, inParmType,
					inValue, outResultType, outResult);
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			CoreIComponent.logAdapter.filelogger.logError(e.getMessage());// 将服务端的错误信息写入日志文件
			cro = cro.SetErrInfo(e.getMessage());// 将服务端的错误返回到客户端，客户端通ccp.ReturnInfo来获取。
		}

		return cro;
	}

	/*
	 * 执行数据库的存储过程，且存储过程带有自定义参
	 */
	public CoreReturnObject doProcedureSelfType(String userid, String username) {
		CoreReturnObject cro = new CoreReturnObject();
		/*
		 * procedure testprocedure(arr in str_ary_type, error out varchar2)
		 * procedure testprocedure(arr in str_ary_type, error out str_ary_type)
		 */

		String pName = "testprocedure";// 存储过程的名字

		// 将客户端传来值存放到ArrayList，方便转为存储过程能够识别的数组类型
		ArrayList<Object> pValue = new ArrayList<Object>();
		pValue.add(userid);
		pValue.add(username);

		// inParmType用来存放存储过程输入参数的数据类型
		ArrayList<Object> inParmType = new ArrayList<Object>();
		inParmType.add(CoreOracleType.ARRAY_TYPE.ordinal());// 获取userid数据类型为varchar2
															// 在这个集合添加String的类型索引

		// inValue用来存放存储过程输入参数的值
		ArrayList<Object> inValue = new ArrayList<Object>();
		// 将ArrayList的pValue通过getArray转换成存储过程能识别的数组形式，
		// getArray的参数str_ary_type为在数据库定义的自定义数据类型
		try {
			inValue.add(this.getDao("KgDao").getArray("str_ary_type", pValue));
		} catch (SQLException e1) {
			// TODO Auto-generated catch block
			CoreIComponent.logAdapter.filelogger.logError(e1.getMessage());
		}

		// outResultType用来存入存储过程输出结果的数据类型
		ArrayList<Object> outResultType = new ArrayList<Object>();
		outResultType.add(CoreOracleType.STRING_TYPE.ordinal());

		// outResulte用来存放输出的结果值
		ArrayList<Object> outResult = new ArrayList<Object>();

		// 如果存储过程的输出有自定义的数据类型，那么先将这个自义类型的名字存放在ArrayList中
		ArrayList<Object> cusType = new ArrayList<Object>();
		cusType.add("str_ary_type");

		try {
			cro = this.getDao("KgDao").ExcuteProcedure(pName, inParmType,
					inValue, outResultType, outResult);
			// 下面的方式为当存储过程的输出有自定义的数据类型时调用平台方法
			// cro=this.getDao("KgDao").ExcuteProcedure(pName, inParmType,
			// inValue,outResultType,outResult,cusType);
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			CoreIComponent.logAdapter.filelogger.logError(e.getMessage());// 将服务端的错误信息写入日志文件
			cro = cro.SetErrInfo(e.getMessage());// 将服务端的错误返回到客户端，客户端通ccp.ReturnInfo来获取。
		}

		return cro;
	}

	// 事务处理
	/*
	 * 如果执的操作只有修改，删除，添加这种简单的操作，可以使如下方式做事务处理
	 */
	public CoreReturnObject doTrancation1() {
		CoreReturnObject cro = new CoreReturnObject();
		// sqllist是用来存放要处理的SqL语句
		ArrayList<Object> sqllist = new ArrayList<Object>();
		sqllist.add("insert into usertable(userid,username)value(?,?)");
		sqllist.add("update usertable set username=? where userid=?");
		sqllist.add("delete usertable where userid=?");
		// parmlist用来存放要处理SqL语句的参数，这个参数的存必须与sql在sqllist的存放顺序保持一致
		ArrayList<Object[]> parmlist = new ArrayList<Object[]>();
		parmlist.add(new Object[] { "1", "张三" });
		parmlist.add(new Object[] { "李三", "2" });
		parmlist.add(new Object[] { "3" });
		// 执行ExcuteTransction的时候，只有这三条语句都执成功则成功，否则将会被回滚
		cro = this.getDao("KgDao").ExcuteTransction(sqllist, parmlist);

		return cro;
	}

	/*
	 * 执行比较复杂的事务处理，如包含有查询、修改、删除、新增以及存储过程
	 */
	public CoreReturnObject doTraction2() {
		CoreReturnObject cro = new CoreReturnObject();
		// 获取要操作的数据库的连接对象
		Connection conn = this.getDao("KgDao").getConnection();
		try {
			// 执行添加、修改、删除事务的方法
			this.getDao("KgDao").ExceuteNonQueryTranscation("sql语句",
					new Object[] {}, conn);
			// 执行查询的事务
			this.getDao("KgDao").ExceuteQueryTranscation("sql语句",
					new Object[] {}, conn);
			// 执行存储过程的事务，如果存储会做为事务的一部，那么，在存储过程的实现当中，不应当使commit去提交数据
			this.getDao("KgDao").executeSPTranscation("存储过程的名字",
					new ArrayList<Object>(), new ArrayList<Object>(), new ArrayList<Object>(),
					new ArrayList<Object>(), new ArrayList<Object>(), conn);
			conn.commit();// 提交事务
		} catch (Exception e) {
			// TODO Auto-generated catch block
			try {
				conn.rollback();// 回滚事务
			} catch (SQLException e1) {
				// TODO Auto-generated catch block
				CoreIComponent.logAdapter.filelogger.logError(e1.getMessage());
			}
			CoreIComponent.logAdapter.filelogger.logError(e.getMessage());
		} finally // 如果使用这种方式处理事务，那么打开的连接conn要最后释放
		{
			this.getDao("KgDao").close(conn, null, null);
		}
		return cro;
	}
}
