package com.sino.publicclass.base;

import java.io.InputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.sino.publicclass.util.StringTools;
public abstract class BaseBean {
	protected static final String SELECT = " SELECT ";
	protected static final String SELECT_ALL_FROM = " SELECT * FROM ";
	protected static final String DELETE_FROM = " DELETE FROM ";
	protected static final String UPDATE = " UPDATE ";
	protected static final String ALL = " * ";
	protected static final String FROM = " FROM ";
	protected static final String WHERE = " WHERE ";
	protected static final String ROWNUM = " ROWNUM ";
	protected static final String BETWEEN = " BETWEEN ";
	protected static final String SET = " SET ";
	protected static final String DISTINCT = " DISTINCT ";
	protected static final String EQ = " = ";
	protected static final String LT = " < ";
	protected static final String LE = " <= ";
	protected static final String GT = " > ";
	protected static final String GE = " >= ";
	protected static final String NE = " <> ";
	protected static final String LIKE = " LIKE ";
	protected static final String AND = " AND ";
	protected static final String OR = " OR ";
	protected static final String AS = " AS ";
	protected static final String IN = " IN ";
	protected static final String NOTIN = " NOT IN ";
	protected static final String ORDERSIBLINGSBY = " ORDER SIBLINGS BY ";
	protected static final String ORDERBY = " ORDER BY ";
	protected static final String STARTWITH = " START WITH ";
	protected static final String CONNECTBY = " CONNECT BY ";
	protected static final String PRIOR = " PRIOR ";
	protected static final String GROUPBY = " GROUP BY ";
	protected static final String DESC = " DESC ";
	protected static final String ASC = " ASC ";
	protected static final String C = " , ";
	protected static final String JOIN = "(+)";
	// public static String SEQUENCENAME = "";
	// public static String NEXTVAL = "";

	// protected PrivControl privControl = PrivControl.getInstance();

	protected ResultSet result = null;
	private Statement st = null;
	private Connection connection = null;
	protected List resultList = null;

	protected BaseBean(Connection curConn) {
		this.connection = curConn;
	}

	protected final Log log = LogFactory.getLog(getClass().getName());

	protected String getLocalString(String columnName) throws SQLException {
		String value = resultGet(columnName);
		if (value == null) {
			value = "";
		} else if (value.equals(null)) {
			value = "";
		}
		return value;
	}

	protected String getString(String columnName) throws SQLException {
		String value = resultGet(columnName);
		if (value == null) {
			value = "";
		} else if (value.equals(null)) {
			value = "";
		}
		return StringTools.convertForHtml(value);
	}

	protected int getInt(String columnName) throws SQLException {
		String value = resultGet(columnName);
		if (value == null) {
			return 0;
		} else if (value.equals(null)) {
			return 0;
		}
		return Integer.parseInt(value);
	}

	protected long getLong(String columnName) throws SQLException {
		String value = resultGet(columnName);
		if (value == null) {
			return 0;
		} else if (value.equals(null)) {
			return 0;
		}
		return Long.parseLong(value);
	}

	protected double getDouble(String columnName) throws SQLException {
		String value = resultGet(columnName);
		if (value == null) {
			return 0;
		} else if (value.equals(null)) {
			return 0;
		}
		return Double.parseDouble(value);
	}

	protected String getDate10(String columnName) throws SQLException {
		Date temp = this.result.getDate(columnName);
		if (temp == null) {
			return "";
		}
		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
		return formatter.format(temp);
	}

	protected String getDate16(String columnName) throws SQLException {
		Date temp = this.result.getTimestamp(columnName);
		if (temp == null) {
			return "";
		}
		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm");
		return formatter.format(temp);
	}

	protected String getStringFromTimestamp(String columnName)
			throws SQLException {
		Date temp = this.result.getTimestamp(columnName);
		if (temp == null) {
			return "";
		}
		SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss");
		return formatter.format(temp);
	}

	protected Date getDate(String columnName) throws SQLException {
		Date temp = this.result.getTimestamp(columnName);
		return temp;
	}

	private String resultGet(String columnName) throws SQLException {
		String value = "";
		try {
			value = this.result.getString(columnName);
		} catch (Exception ex) {
			String ems = "不存在columnName：" + columnName;
			log.error(ems);
			throw new SQLException(ems);
		}
		return value;
	}

	protected int executeUpdate(String strSQL, boolean outprt)
			throws CException {
		int count = 0;
		try {
			st = createStatement();
			// if (outprt)
			// log.info(strSQL);
			st.executeUpdate(strSQL);
			count = st.getUpdateCount();
		} catch (Exception e) {
			// log.error("", e);
			if (e.getMessage().indexOf("ORA-02289") >= 0) {
			//	createSequence();
				executeUpdate(strSQL, outprt);
				return count;
			}
			if (!outprt)
				log.error(strSQL);
			throw new CException("数据库修改没有成功," + e.getMessage());
		} finally {
			close();
		}
		return count;
	}

	public long getSequence() throws CException {
		String sql = "SELECT " + getNextVal() + " FROM DUAL";
		return findCount(sql);
	}

	public long getSequence(String trigger) throws CException {
		String sql = "SELECT " + trigger + ".NEXTVAL" + " FROM DUAL";
		return findCount(sql);
	}

	/*public void createSequence() throws CException {
		if (getSequenceName().length() == 0)
			throw new CException(" SEQUENCENAME is no define");
		String sql = "CREATE SEQUENCE " + getSequenceName()
				+ " INCREMENT BY 1 START WITH 1 NOMAXVALUE NOCYCLE CACHE 10 ";
		executeUpdate(sql, false);
	}*/

	protected abstract String getTableName();

	protected String getSequenceName() {
		return "SEQ_" + getTableName();
	}

	protected String getNextVal() {
		return "SEQ_" + getTableName() + ".NEXTVAL";
	}

	protected int update(String strSQL) throws CException {
		log.info("==================插入供应商调度表"+strSQL);
		int count = executeUpdate(strSQL, true);
		return count;
	}

	protected void update(String strSQL, boolean outpr) throws CException {
		executeUpdate(strSQL, outpr);
	}

	protected void executeQuery(String strSQL) throws CException {
		try {
			st = createStatement();
			long start = System.currentTimeMillis();
			this.result = st.executeQuery(strSQL);
			// log.info(" query time=" + (System.currentTimeMillis() - start));
		} catch (Exception ex) {
			if (ex.getMessage().indexOf("ORA-02289") >= 0) {
			//	createSequence();
				executeQuery(strSQL);
				System.err.println("查询成功12323432132342");
				return;
			}
			// log.error("", ex);
			throw new CException("数据库查询没有成功" + ex.getMessage());
		}
	}
	
	protected void executeUpdate(String strSQL) throws CException {
		try {
			st = createStatement();
			int result1 = st.executeUpdate(strSQL);
			if (result1 > 0) {
				executeUpdate(strSQL);
				System.err.println("删除成功12323432132342");
				return;
			}
		} catch (Exception ex) {
			throw new CException("数据库删除没有成功" + ex.getMessage());
		}
	}

	protected List findAll(String sql) throws CException {
		resultList = new ArrayList();
		try {
			 /*log.info(sql);*/
			executeQuery(sql);
			resultList = listAdaptor();
		} catch (Exception ex) {
			throw new CException(ex.getMessage());
		} finally {
			close();
		}
		return resultList;
	}

	protected List findAll(String sql, String resultAdaptorMode)
			throws CException {
		resultList = new ArrayList();
		try {
			// log.info(sql);
			executeQuery(sql);
			resultList = listAdaptor(resultAdaptorMode);
		} catch (Exception ex) {
			throw new CException(ex.getMessage());
		} finally {
			close();
		}
		return resultList;
	}

	//删除（后添）
	protected boolean deleteOne(String sql) throws CException{
		log.info(sql+"删除语句是什么");
		executeUpdate(sql);
		return true;
	}
	
	protected Object findOne(String sql) throws CException {
		return findOne(sql, true);
	}

	protected Object findOne(String sql, boolean outpr) throws CException {
		Object obj = null;
		// if (outpr)
		 log.info(sql);
		executeQuery(sql);
		try {
			if (this.result.next()) {
				obj = resultAdaptor();
			}
		} catch (Exception ex) {
			throw new CException(ex.getMessage());
		}
		close();
		return obj;
	}

	protected Object findOne(String sql, String resultAdaptorMode)
			throws CException {
		Object obj = null;
		 log.info(sql);
		executeQuery(sql);
		try {
			if (this.result.next()) {
				obj = this.getClass().getMethod(resultAdaptorMode, null)
						.invoke(this, null);
			}
		} catch (Exception ex) {
			throw new CException(ex.getMessage());
		}
		close();
		return obj;
	}

	public long findCount(String sql) throws CException {
		return findCount(sql, true);
	}

	public long findCount(String sql, boolean outpr) throws CException {
		int count = 0;
		// String countsql = "select count(*) as num " + sql;
		// if (outpr)
		 //log.info(sql);
		executeQuery(sql);
		try {
			if (result.next()) {
				count = result.getInt(1);
			}
			this.result.close();
		} catch (Exception ex) {
			throw new CException(ex.getMessage());
		}
		return count;
	}

	public long selectRowCount(String sql) throws CException {
		return selectRowCount(sql, true);
	}

	public long selectRowCount(String sql, boolean outpr) throws CException {
		return findCount("select count(*) from (" + sql + ")", outpr);
	}

	protected List listAdaptor() throws Exception {
		return listAdaptor("resultAdaptor");
	}

	/**
	 * 把结果集转成实体对象的ArrayList
	 * 
	 * @param methodName
	 *            String
	 * @throws CException
	 * @return ArrayList
	 */
	protected List listAdaptor(String methodName) throws Exception {
		List list = new ArrayList();
		Object entity = null;
		try {
			while (this.result.next()) {
				entity = this.getClass().getMethod(methodName, null)
						.invoke(this, null);
				list.add(entity);
			}
		} catch (Exception ex) {
			log.error("", ex);
			throw new Exception("结果集listAdaptor() Exception");
		}
		return list;
	}

	protected boolean resultNext() throws Exception {
		return this.result.next();
	}

	protected abstract Object resultAdaptor() throws Exception;

	protected boolean queryValidateByText(String value) {
		if (value != null) {
			if (!(value.equals("") || value.equals("&nbsp;") || value
					.equals("-1"))) {
				return true;
			}
		}
		return false;
	}

	protected boolean queryValidateByText(int value) {
		if (value != -1) {
			return true;
		}
		return false;
	}

	protected boolean queryValidateByText(long value) {
		if (value != -1) {
			return true;
		}
		return false;
	}

	protected void close() {
		try {
			if (this.result != null) {
				this.result.close();
				this.result = null;
			}
			if (this.st != null) {
				this.st.close();
				this.st = null;
			}
		} catch (Exception ex) {
			log.error(ex.getMessage());
		}
	}
	
	/**
	 * 关闭当前的statment和result(如果有的话),并设置相关变量为null
	 */
	public void closeCurrentStatementResultSet(){
		close();
	}

	protected Statement createStatement() throws Exception {
		if (this.connection != null) {
			return this.connection.createStatement();
		} else {
			throw new Exception("have not connection,can't createStatement!!!");
		}
	}

	protected PreparedStatement createPrepareStatement(String sql)
			throws Exception {
		if (this.connection != null) {

			return this.connection.prepareStatement(sql);
		} else {
			throw new Exception("have not connection,can't createStatement!!!");
		}
	}

	protected static String bracket(String sql) {
		return " (" + sql + ") ";
	}

	protected static String convert(String sql) {
		return StringTools.convertSqlStr(sql);
	}

	protected static long convert(long sql) {
		return sql;
	}

	protected static int convert(int sql) {
		return sql;
	}

	protected static String LIKE(String str) {
		return " LIKE " + StringTools.convertLikeStr(str) + " ";
	}

	protected static String COUNT(String str) {
		return " count(" + str + ")";
	}

	protected static String SUM(String str) {
		return " SUM(" + str + ")";
	}

	protected static String MAX(String str) {
		return " MAX(" + str + ")";
	}

	protected static String MIN(String str) {
		return " MIN(" + str + ")";
	}

	protected static String SUBSTR(String str, int beginPosi, int length) {
		return " SUBSTR(" + str + "," + beginPosi + "," + length + ")";
	}

	protected static String TODATE(String str, String format) {
		return " to_date ('" + str + "','" + format + "')";
	}

	protected static String TOTIMESTAMP(Date date) {
		String dateStr = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS")
				.format(date);
		return " to_timestamp ('" + dateStr + "','syyyy-mm-dd hh24:mi:ss.ff')";
	}

	protected Connection getConnection() {
		return connection;
	}

	protected void setConnection(Connection conn) {
		this.connection = conn;
	}

	protected String convertStr(String str) {
		return StringTools.convertSqlStr(str);
	}

	protected String convertLikeStr(String str) {
		return StringTools.convertLikeStr(str);
	}

	protected ResultSet getResult() {
		return result;
	}

	protected void setResult(ResultSet resultset) {
		this.result = resultset;
	}

	public List getResultList() {
		return resultList;
	}

	/**
	 * 从Blob中获取字节数据
	 * 
	 * @param columnName
	 * @return
	 * @throws SQLException
	 */
	protected byte[] getBlobToBytes(String columnName) throws SQLException {
		oracle.sql.BLOB blob = null;
		try {
			blob = (oracle.sql.BLOB) this.result.getBlob(columnName);
			if (null == blob) {
				return null;
			}
		} catch (Exception ex) {
			String ems = "不存在columnName：" + columnName;
			log.error(ems);
			throw new SQLException(ems);
		}

		ArrayList<byte[]> al = new ArrayList<byte[]>();

		InputStream blobStream = null;
		int totalSize = 0;
		try {
			blobStream = blob.getBinaryStream();
			int bufferSize = 10 * 1024;
			byte[] buffer = new byte[bufferSize];
			int nbytes = 0; // Number of bytes read
			while ((nbytes = blobStream.read(buffer)) != -1) {// Read from Blob
																// stream
				totalSize += nbytes;
				if (nbytes == bufferSize) {
					al.add(buffer);
					buffer = new byte[bufferSize];
				} else {
					byte[] temp = new byte[nbytes];
					System.arraycopy(buffer, 0, temp, 0, nbytes);
					al.add(temp);
				}
			}
		} catch (Exception e) {
			throw new SQLException(e);
		} finally {
			if (null != blobStream) {
				try {
					blobStream.close();
				} catch (Exception e) {

				}
			}
		}

		if (totalSize <= 0) {
			return null;
		}

		if (al.size() == 1) {
			return al.get(0);
		}

		byte[] result = new byte[totalSize];
		byte[] temp;
		for (int destPos = 0, i = 0, n = al.size(); i < n; i++) {
			temp = al.get(i);
			System.arraycopy(temp, 0, result, destPos, temp.length);
			destPos += temp.length;
		}

		return result;
	}

	/**
	 * 从字节数组转换为字符串
	 * 
	 * @param bytes
	 *            字节数组
	 * @return
	 * @throws Exception
	 */
	protected String getStringFromBytes(byte[] bytes) throws Exception {
		if (null == bytes || bytes.length <= 0) {
			return "";
		}

		return new String(bytes);
	}

	/**
	 * 从字节数组转换为字符串
	 * 
	 * @param bytes
	 * @param charsetName
	 * @return
	 * @throws Exception
	 */
	protected String getStringFromBytes(byte[] bytes, String charsetName)
			throws Exception {
		if (null == bytes || bytes.length <= 0) {
			return "";
		}

		return new String(bytes, charsetName);
	}

	public Date findTime() throws CException {
		String sql = "SELECT SYSTIMESTAMP FROM DUAL";
		Date time = null;
		executeQuery(sql);
		try {
			if (result.next()) {
				time = result.getTimestamp(1);
			}
			this.result.close();
		} catch (Exception ex) {
			throw new CException(ex.getMessage());
		}
		return time;
	}
	
	/**
	 * 关闭connection
	 * @param conn
	 */
	public static void close(Connection conn){
		if (null != conn){
			try {
				conn.close();
			} catch (Exception ee){
				
			}
		}
	}
	

	

	
	/**
	 * 获取数据权限sql
	 * @param loginUserId 登陆用户的ID, null代表不启用数据权限,系统会返回 (1=1) 
	 * @param permissionFlag 是否启用数据权限(lUserPO.getPermission_flag方法得到),如果是不启用数据权限则系统会返回 (1=1) 
	 * @param contractCompanyFieldName 合同字段(包含别名),如：C.CODE; null代表没有这个条件
	 * @param rescueCompanyFieldName 服务商字段(包含别名),如：RC.CODE; null代表没有这个条件
	 * @return 权限过滤sql，有最外层括弧(); 第一个字符、最后一个字符是空格; 
	 * 			如果两个条件都需要则这两个条件是or关系,对外用括弧括起来作为一个条件；
	 *			如果两个字段都为null，系统认为不启用数据权限过滤，返回返回 (1=1) 
	 */
	public static String getDataPermissionSql(String loginUserId, int permissionFlag , String contractCompanyFieldName){
		StringBuilder sb = new StringBuilder(256);
		sb.append(" (");
		
		if (permissionFlag == 1 && null != loginUserId && Integer.parseInt(loginUserId) >= 0 ){//启用权限
			if (null != contractCompanyFieldName && contractCompanyFieldName.length() > 0){//合同条件
				sb.append("(exists (select * from involve_contracting_company icc_123 where icc_123.system_user_id = ")
				  .append(loginUserId)
				  .append(" and icc_123.contracting_company_code = ").append(contractCompanyFieldName)
				  .append("))");
			}
		} else {//不启用权限
			sb.append("1=1");
		}
		
		sb.append(") ");
		return sb.toString();
	}
	

}
