/**
 * Company Name : 中贸促信息技术有限责任公司
 * Project Name:memberManageSys
 * File Name:JdbcDaoHelper.java
 * Package Name:ccpit.base.dao
 * Date:2016年2月26日下午4:35:34
 * Copyright (c) 2016, dingwei@ccpit.org All Rights Reserved.
 *
 */

package org.ccpit.base.dao;

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

import org.ccpit.base.controller.Page;
import org.ccpit.base.controller.PageRequest;
import org.ccpit.base.utils.AssertUtil;
import org.ccpit.base.utils.ReadConfigUtil;
import org.ccpit.base.utils.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;

/**
 * ClassName:JdbcDaoHelper <br/>
 * Function: TODO ADD FUNCTION. <br/>
 * Reason: TODO ADD REASON. <br/>
 * Date: 2016年2月26日 下午4:35:34 <br/>
 * 
 * @author dingwei
 * @version
 * @since JDK 1.6
 * @see
 */
@Repository
public class JdbcDaoHelper<T> implements IJdbcDao<T> {

	@Autowired
	private JdbcTemplate jdbcTemplate;

	public Boolean hasExist(String sql, Object[] args) {
		int count = jdbcTemplate.queryForInt(sql, args);
		if (count > 0) {
			return Boolean.valueOf(true);
		}
		return Boolean.valueOf(false);
	}

	public int save(String sql, Object[] args) {
		int result = jdbcTemplate.update(sql, args);
		return result;
	}

	public int update(String sql, Object[] args) {
		int result = jdbcTemplate.update(sql, args);
		return result;
	}

	public int updateColumn(String tableName, String columnName,
			Object columnValue, String whereFilter) {
		StringBuffer sqlSb = new StringBuffer("update " + tableName + " set ");
		try {
			if (StringUtil.hasText(columnName)) {
				sqlSb.append(columnName);
				sqlSb.append(" = ? ");
			} else {
				return 0;
			}

			if (StringUtil.hasText(whereFilter)) {
				sqlSb.append(" where " + whereFilter + " ");
			}

			String sql = sqlSb.toString();

			Object[] args = new Object[1];
			args[0] = columnValue;

			return jdbcTemplate.update(sql, args);
		} catch (Exception ex) {
			throw new RuntimeException("orm-jdbc-001:修改列 执行错误, sql is:"
					+ sqlSb.toString(), ex);
		}
	}

	public int updateColumn(String tableName, String[] columnNames,
			Object[] columnValues, String whereFilter) {
		String sql = "";
		try {
			StringBuffer sqlSb = new StringBuffer("update " + tableName
					+ " set ");

			if ((columnNames.length != columnValues.length)
					&& (columnNames.length > 0)) {
				throw new Exception("属性名及值个数不相等");
			}
			for (int i = 0; i < columnNames.length - 1; i++) {
				sqlSb.append(columnNames[i]);
				sqlSb.append(" = ? , ");
			}

			sqlSb.append(columnNames[(columnNames.length - 1)]);
			sqlSb.append(" = ? ");

			if ((whereFilter != null) && (!whereFilter.equals(""))) {
				sqlSb.append(" where " + whereFilter + " ");
			}

			sql = sqlSb.toString();

			return jdbcTemplate.update(sql, columnValues);
		} catch (Exception ex) {
			throw new RuntimeException("orm-jdbc-001:修改列 执行错误, sql is:" + sql,
					ex);
		}
	}

	public int delete(String sql, Object[] args) {
		int result = jdbcTemplate.update(sql, args);
		return result;
	}

	public int delete(String tableName, String columnName, String columnValues) {
		StringBuffer sqlSb = new StringBuffer("delete from " + tableName + " ");
		try {
			if ((StringUtil.hasText(columnName))
					&& (StringUtil.hasText(columnValues))) {
				if (columnValues.startsWith("'")) {
					sqlSb.append(" where " + columnName + " in (");
					sqlSb.append(columnValues);
					sqlSb.append(")");
				} else {
					sqlSb.append(" where " + columnName + " in ('");
					sqlSb.append(columnValues.replaceAll(",", "','"));
					sqlSb.append("')");
				}
			} else {
				return 0;
			}
			return jdbcTemplate.update(sqlSb.toString());
		} catch (Exception ex) {
			throw new RuntimeException("orm-jdbc-002:删除数据错误, sql is:"
					+ sqlSb.toString(), ex);
		}
	}

	public int delete(String tableName, String columnName, String columnValues,
			String deleteColumnTag, String deleteColumnValue) {
		AssertUtil.hasText(columnName, "orm-jdbc-002:假删除数据错误,主键标识字段为空 ");
		AssertUtil.hasText(columnValues, "orm-jdbc-002:假删除数据错误,主键标识字段值为空 ");
		AssertUtil.hasText(deleteColumnTag, "orm-jdbc-002:假删除数据错误,删除标识字段为空 ");
		AssertUtil
				.hasText(deleteColumnValue, "orm-jdbc-002:假删除数据错误,删除标识字段值为空 ");

		StringBuffer sqlSb = new StringBuffer("update ");
		sqlSb.append(tableName);
		sqlSb.append("  set ");
		sqlSb.append(deleteColumnTag);
		sqlSb.append(" = ");
		sqlSb.append(deleteColumnValue);
		try {
			if ((StringUtil.hasText(columnName))
					&& (StringUtil.hasText(columnValues))) {
				if (columnValues.startsWith("'")) {
					sqlSb.append(" where " + columnName + " in (");
					sqlSb.append(columnValues);
					sqlSb.append(")");
				} else {
					sqlSb.append(" where " + columnName + " in ('");
					sqlSb.append(columnValues.replaceAll(",", "','"));
					sqlSb.append("')");
				}
			} else {
				return 0;
			}
			return jdbcTemplate.update(sqlSb.toString());
		} catch (Exception ex) {
			throw new RuntimeException("orm-jdbc-002:删除数据错误, sql is:"
					+ sqlSb.toString(), ex);
		}
	}

	public List queryForList(String sql, Object[] args) {
		List list = jdbcTemplate.queryForList(sql, args);
		return list;
	}

	public List queryForList(String sql, Object[] args, Class elementType) {
		RowMapper rowMapper = new BeanPropertyRowMapper(elementType);
		List list = jdbcTemplate.query(sql, args, rowMapper);
		return list;
	}

	public int queryForInt(String sql, Object[] args) {
		try {
			return jdbcTemplate.queryForInt(sql, args);
		} catch (Exception e) {
		}
		return -1;
	}

	public long queryForLong(String sql, Object[] args) {
		try {
			return jdbcTemplate.queryForLong(sql, args);
		} catch (Exception e) {
		}
		return -1L;
	}

	public Map queryForMap(String sql, Object[] args) {
		try {
			return jdbcTemplate.queryForMap(sql, args);
		} catch (Exception e) {
		}
		return null;
	}

	public Object queryForObject(String sql, Object[] args) {
		try {
			return jdbcTemplate.queryForObject(sql, args,
					Object.class);
		} catch (Exception e) {
		}
		return null;
	}

	public Object queryForObject(String sql, Object[] args, Class requiredType) {
		try {
			RowMapper rowMapper = new BeanPropertyRowMapper(requiredType);
			return jdbcTemplate.queryForObject(sql, args, rowMapper);
		} catch (Exception e) {
		}
		return null;
	}

	public List batchQuery(String[] sql, Class[] elementTypes) {
		List resultList = new ArrayList();
		for (int i = 0; i < sql.length; i++) {
			RowMapper rowMapper = new BeanPropertyRowMapper(elementTypes[i]);
			List list = jdbcTemplate.query(sql[i], rowMapper);
			resultList.add(list);
		}
		return resultList;
	}

	public void batchExecute(String[] sql) {
		for (int i = 0; i < sql.length; i++)
			jdbcTemplate.execute(sql[i]);
	}

	public int[] batchUpdate(String[] sql) {
		int[] result = jdbcTemplate.batchUpdate(sql);
		return result;
	}

	public void execute(String sql) {
		jdbcTemplate.update(sql);
	}
	/**
	 * 
	 * TODO 查询结果分页显示，查询语句为sql
	 * @see IJdbcDao#queryPage(PageRequest, String, Object[], Class)
	 */
	public Page queryPage(PageRequest pageRequest, String sql, Object[] args, Class elementType) {
		AssertUtil.notNull(pageRequest, "pageRequest不能为空");

		Page page = new Page(pageRequest);
		if (pageRequest.isCountTotal()) {
			long totalCount = countSqlResult(sql, args);
			page.setTotal(totalCount);
		}
		if (pageRequest.isOrderBySetted()) {
			sql = setOrderParameterToSql(sql, pageRequest);
		}

		String pageSql = getPageSql(pageRequest, sql);

		List list = null;

		if (elementType != null) {
			RowMapper rowMapper = new BeanPropertyRowMapper(elementType);
			list = jdbcTemplate.query(pageSql, args, rowMapper);
		} else {
			list = jdbcTemplate.queryForList(pageSql, args);
		}
		page.setRows(list);
		return page;
	}

	protected long countSqlResult(String sql, Object[] params) {
		String countSql = prepareCountSql(sql);
		try {
			Long count = Long.valueOf(jdbcTemplate.queryForLong(countSql,
					params));
			return count.longValue();
		} catch (Exception e) {
			throw new RuntimeException("orm-jdbc-003:无法计算记录总数, sql is:"
					+ countSql, e);
		}
	}

	private String prepareCountSql(String sql) {
		String countSql = "select count(*) " + removeSelect(removeOrders(sql));
		return countSql;
	}

	private String removeSelect(String sql) {
		int beginPos = sql.toLowerCase().indexOf("from");
		return sql.substring(beginPos);
	}

	private String removeOrders(String sql) {
		return sql;
	}

	protected String setOrderParameterToSql(String sql, PageRequest pageRequest) {
		StringBuilder builder = new StringBuilder(sql);
		builder.append(" order by ");
		builder.append(pageRequest.getOrderBy());
		return builder.toString();
	}

	public String getPageSql(PageRequest pageRequest, String sqlStr) {
		int start = (pageRequest.getPageNo() - 1) * pageRequest.getPageSize();
		int end = start + pageRequest.getPageSize();
		String databank = ReadConfigUtil.getPlatformConfig("database");
		String sql = "";
		if ("oracle".equalsIgnoreCase(databank))
			sql = "select * from ( select row_.*, rownum rownum_ from ( "
					+ sqlStr + ") row_ where rownum <=" + end
					+ " ) where rownum_ > " + start;
		else if ("mysql".equalsIgnoreCase(databank))
			sql = sqlStr + " limit " + start + "," + pageRequest.getPageSize();
		else {
			sql = "select * from ( select row_.*, rownum rownum_ from ( "
					+ sqlStr + ") row_ where rownum <=" + end
					+ " ) where rownum_ > " + start;
		}
		return sql;
	}

	public void clearCache(Class entityClass) {
	}
}
