<commit_before>package org.nutz.dao.sql;

import static java.lang.String.format;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.nutz.castor.Castors;
import org.nutz.dao.Condition;
import org.nutz.dao.DaoException;
import org.nutz.dao.Daos;
import org.nutz.dao.Sqls;
import org.nutz.dao.entity.Entity;
import org.nutz.dao.pager.Pager;

public class SqlImpl implements Sql, Cloneable {

	public SqlImpl(SqlLiteral sql, StatementAdapter adapter) {
		this.sql = sql;
		this.adapter = adapter;
		this.context = new SqlContext();
		updateCount = -1;
	}

	private SqlLiteral sql;
	private SqlContext context;
	private SqlCallback callback;
	private Condition condition;
	private StatementAdapter adapter;
	private Entity<?> entity;
	private int updateCount;

	public String toString() {
		mergeCondition();
		return sql.toString();
	}

	public void execute(Connection conn) throws DaoException {
		mergeCondition();
		updateCount = -1;
		boolean statIsClosed = false;
		try {
			// SELECT ...
			if (sql.isSELECT()) {
				// If without callback, the query do NOT make sense.
				if (null != callback) {
					// Create ResultSet type upon the page. default is
					// TYPE_FORWARD_ONLY
					Pager pager = context.getPager();
					int rsType = null == pager	? ResultSet.TYPE_FORWARD_ONLY
												: pager.getResultSetType();
					PreparedStatement stat = null;
					ResultSet rs = null;
					try {
						// Prepare statment for query
						String sqlStr = sql.toPreparedStatementString();
						stat = conn.prepareStatement(sqlStr, rsType, ResultSet.CONCUR_READ_ONLY);

						// Put all parameters to PreparedStatement and get
						// ResultSet
						adapter.process(stat, sql, entity);
						rs = stat.executeQuery();

						// Get result from ResultSet by callback
						context.setResult(callback.invoke(conn, rs, this));
					}
					// Closing...
					finally {
						Daos.safeClose(stat, rs);
					}
				}
			}
			// UPDATE | INSERT | DELETE | TRUNCATE ...
			else if (sql.isUPDATE() || sql.isINSERT() || sql.isDELETE() || sql.isTRUNCATE()) {
				PreparedStatement stat = null;
				try {
					String sqlStr = sql.toPreparedStatementString();
					stat = conn.prepareStatement(sqlStr);
					adapter.process(stat, sql, entity);
					stat.execute();
					updateCount = stat.getUpdateCount();
					stat.close();
					statIsClosed = true;
					if (null != callback)
						context.setResult(callback.invoke(conn, null, this));
				}
				// Closing...
				finally {
					if (!statIsClosed)
						Daos.safeClose(stat);
				}
			}
			// CREATE | DROP
			else {
				Statement stat = null;
				try {
					stat = conn.createStatement();
					stat.execute(sql.toString());
					stat.close();
					if (null != callback)
						context.setResult(callback.invoke(conn, null, this));
				}// Closing...
				finally {
					if (!statIsClosed)
						Daos.safeClose(stat);
				}
			}
		}
		// If any SQLException happend, throw out the SQL string
		catch (SQLException e) {
			throw new DaoException(format("!Nuz SQL Error: '%s'", sql.toString()), e);
		}

	}

	private void mergeCondition() {
		if (null != condition) {
			String cnd = Sqls.getConditionString(entity, condition);
			if (null != cnd)
				sql.getVars().set("condition", cnd);
		}
	}

	public int getUpdateCount() {
		return updateCount;
	}

	public Sql setAdapter(StatementAdapter adapter) {
		this.adapter = adapter;
		return this;
	}

	public Sql setEntity(Entity<?> entity) {
		this.entity = entity;
		return this;
	}

	public VarSet params() {
		return sql.getParams();<commit_msg>add more information to SQL Exception<commit_after>package org.nutz.dao.sql;

import static java.lang.String.format;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.nutz.castor.Castors;
import org.nutz.dao.Condition;
import org.nutz.dao.DaoException;
import org.nutz.dao.Daos;
import org.nutz.dao.Sqls;
import org.nutz.dao.entity.Entity;
import org.nutz.dao.pager.Pager;

public class SqlImpl implements Sql, Cloneable {

	public SqlImpl(SqlLiteral sql, StatementAdapter adapter) {
		this.sql = sql;
		this.adapter = adapter;
		this.context = new SqlContext();
		updateCount = -1;
	}

	private SqlLiteral sql;
	private SqlContext context;
	private SqlCallback callback;
	private Condition condition;
	private StatementAdapter adapter;
	private Entity<?> entity;
	private int updateCount;

	public String toString() {
		mergeCondition();
		return sql.toString();
	}

	public void execute(Connection conn) throws DaoException {
		mergeCondition();
		updateCount = -1;
		boolean statIsClosed = false;
		try {
			// SELECT ...
			if (sql.isSELECT()) {
				// If without callback, the query do NOT make sense.
				if (null != callback) {
					// Create ResultSet type upon the page. default is
					// TYPE_FORWARD_ONLY
					Pager pager = context.getPager();
					int rsType = null == pager	? ResultSet.TYPE_FORWARD_ONLY
												: pager.getResultSetType();
					PreparedStatement stat = null;
					ResultSet rs = null;
					try {
						// Prepare statment for query
						String sqlStr = sql.toPreparedStatementString();
						stat = conn.prepareStatement(sqlStr, rsType, ResultSet.CONCUR_READ_ONLY);

						// Put all parameters to PreparedStatement and get
						// ResultSet
						adapter.process(stat, sql, entity);
						rs = stat.executeQuery();

						// Get result from ResultSet by callback
						context.setResult(callback.invoke(conn, rs, this));
					}
					// Closing...
					finally {
						Daos.safeClose(stat, rs);
					}
				}
			}
			// UPDATE | INSERT | DELETE | TRUNCATE ...
			else if (sql.isUPDATE() || sql.isINSERT() || sql.isDELETE() || sql.isTRUNCATE()) {
				PreparedStatement stat = null;
				try {
					String sqlStr = sql.toPreparedStatementString();
					stat = conn.prepareStatement(sqlStr);
					adapter.process(stat, sql, entity);
					stat.execute();
					updateCount = stat.getUpdateCount();
					stat.close();
					statIsClosed = true;
					if (null != callback)
						context.setResult(callback.invoke(conn, null, this));
				}
				// Closing...
				finally {
					if (!statIsClosed)
						Daos.safeClose(stat);
				}
			}
			// CREATE | DROP
			else {
				Statement stat = null;
				try {
					stat = conn.createStatement();
					stat.execute(sql.toString());
					stat.close();
					if (null != callback)
						context.setResult(callback.invoke(conn, null, this));
				}// Closing...
				finally {
					if (!statIsClosed)
						Daos.safeClose(stat);
				}
			}
		}
		// If any SQLException happend, throw out the SQL string
		catch (SQLException e) {
			throw new DaoException(format(	"!Nuz SQL Error: '%s'\nPreparedStatement: \n'%s'",
											sql.toString(),
											sql.toPreparedStatementString()), e);
		}

	}

	private void mergeCondition() {
		if (null != condition) {
			String cnd = Sqls.getConditionString(entity, condition);
			if (null != cnd)
				sql.getVars().set("condition", cnd);
		}
	}

	public int getUpdateCount() {
		return updateCount;
	}

	public Sql setAdapter(StatementAdapter adapter) {
		this.adapter = adapter;
		return this;
	}

	public Sql setEntity(Entity<?> entity) {
		this.entity = entity;
		return this;
	}

	public VarSet params() {
		return sql.getParams();
{'fraction_non_alphanumeric': 0.12084271896117663, 'fraction_numerical': 0.0005300119252683185, 'mean_word_length': 3.0191693290734825, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4020456', 'n_tokens_mistral': 2941, 'n_tokens_neox': 2362, 'n_words': 595}