package xyz.wbsite.wsqlite;

import java.io.File;
import java.sql.*;

/**
 * xyz.wbsite.wsqlite.Client
 *
 * @author wangbing
 */
public class Client {

    Connection connection;
    ResultSet resultSet;
    String dbFilePath;

    /**
     * 构造函数
     *
     * @param dbFile 文件
     * @throws ClassNotFoundException
     * @throws SQLException
     */
    public Client(File dbFile) throws ClassNotFoundException, SQLException {
        this.dbFilePath = dbFile.getAbsolutePath();
        if (!dbFile.exists()) {
            connection = getConnection();
        }
    }

    /**
     * 执行sql语句
     *
     * @param sql
     * @throws SQLException
     * @throws ClassNotFoundException
     */
    public void execute(String sql) throws SQLException, ClassNotFoundException {
        try {
            executeUpdate(sql);
        } finally {
            destroyed();
        }
    }

    /**
     * 执行sql查询语句
     *
     * @param sql
     * @throws SQLException
     * @throws ClassNotFoundException
     */
    public ResultSet executeQuery(String sql, Object... args) throws SQLException, ClassNotFoundException {
        PreparedStatement preparedStatement = getConnection().prepareStatement(sql);
        setArg(preparedStatement, args);
        return preparedStatement.executeQuery();
    }

    /**
     * 执行sql语句
     *
     * @param sql
     * @throws SQLException
     * @throws ClassNotFoundException
     */
    public int executeUpdate(String sql, Object... args) throws SQLException, ClassNotFoundException {
        try {
            PreparedStatement preparedStatement = getConnection().prepareStatement(sql);
            setArg(preparedStatement, args);
            return preparedStatement.executeUpdate();
        } finally {
            destroyed();
        }
    }

    private void setArg(PreparedStatement ps, Object... args) throws SQLException {
        for (int i = 0; i < args.length; i++) {
            Object arg = args[i];

            if (arg == null) {
                ps.setNull(i + 1, Types.NULL);
            } else if (arg instanceof String) {
                ps.setString(i + 1, (String) arg);
            } else if (arg instanceof Date) {
                ps.setDate(i + 1, (Date) arg);
            } else if (arg instanceof Time) {
                ps.setTime(i + 1, (Time) arg);
            } else if (arg instanceof java.util.Date) {
                ps.setLong(i + 1, ((java.util.Date) arg).getTime());
            } else if (arg instanceof Boolean) {
                ps.setBoolean(i + 1, (Boolean) arg);
            } else if (arg instanceof Byte) {
                ps.setByte(i + 1, (Byte) arg);
            } else if (arg instanceof Short) {
                ps.setShort(i + 1, (Short) arg);
            } else if (arg instanceof Integer) {
                ps.setInt(i + 1, (int) arg);
            } else if (arg instanceof Long) {
                ps.setLong(i + 1, (long) arg);
            } else if (arg instanceof Float) {
                ps.setFloat(i + 1, (float) arg);
            } else if (arg instanceof Double) {
                ps.setDouble(i + 1, (double) arg);
            } else if (arg instanceof byte[]) {
                ps.setBytes(i + 1, (byte[]) arg);
            }
        }
    }

    /**
     * 获取数据库连接
     *
     * @return 数据库连接
     * @throws ClassNotFoundException
     * @throws SQLException
     */
    Connection getConnection() throws ClassNotFoundException, SQLException {
        if (null == connection) {
            Class.forName("org.sqlite.JDBC");
            connection = DriverManager.getConnection("jdbc:sqlite:" + dbFilePath);
        }
        return connection;
    }

    /**
     * 数据库资源关闭和释放
     */
    public void destroyed() {
//        try {
//            if (null != resultSet) {
//                resultSet.close();
//                resultSet = null;
//            }
//
//            if (null != connection) {
//                connection.close();
//                connection = null;
//            }
//
//        } catch (SQLException e) {
//            e.printStackTrace();
//        }
    }
}