/**
 *
 */
package common;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Map;

public class DBAccessWrapper {

	private String driver;
	private String url;
	private String user;
	private String pass;

	DBAccessWrapper(String driver, String url, String user, String pass) {
		this.driver = driver;
		this.url = url;
		this.user = user;
		this.pass = pass;
	}

	private Connection connect() throws ClassNotFoundException, SQLException {
		Class.forName(driver);
		return DriverManager.getConnection(url, user, pass);
	}

	public ArrayList<ArrayList<String>> select(ArrayList<String> params, String table, String condition) {
		Connection conn = null;
		Statement stmt = null;
		ResultSet rs = null;

		ArrayList<ArrayList<String>> results = new ArrayList<ArrayList<String>>();

		try {
			StringBuilder sql = new StringBuilder();
			sql.append("SELECT ");
			for ( int ii = 0; ii < params.size(); ++ii ) {
				if ( ii > 0 ) {
					sql.append(", ");
				}
				sql.append(params.get(ii));
			}
			sql.append(" FROM ");
			sql.append(table);

			if ( !condition.isEmpty() ) {
				sql.append(" WHERE ");
				sql.append(condition);
			}

			conn = connect();
			stmt = conn.createStatement();
			rs = stmt.executeQuery(sql.toString());
			while (rs.next()) {
				ArrayList<String> result = new ArrayList<String>();
				for ( int ii = 0; ii < params.size(); ++ii ) {
					String value = "";
					value = rs.getString(params.get(ii));
					result.add(value);
				}
				results.add(result);
			}
		} catch (SQLException e) {
			// TODO 自動生成された catch ブロック
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO 自動生成された catch ブロック
			e.printStackTrace();
		} finally {
			try {
				if (rs != null) {
					rs.close();
				}
				if (stmt != null) {
					stmt.close();
				}
				if (conn != null) {
					conn.close();
				}
			} catch (SQLException e) {
				// TODO 自動生成された catch ブロック
				e.printStackTrace();
			}
		}
		return results;
	}

	public String insert(Map<String, String> params, String table) {
		Connection conn = null;
		Statement stmt = null;
		ResultSet rs = null;

		String result = "";

		try {

			StringBuilder sql = new StringBuilder();
			sql.append("INSERT INTO ");
			sql.append(table);
			sql.append("( ");

			Iterator<String> itr = params.keySet().iterator();
			while (itr.hasNext()) {
				String key = (String)itr.next();
				sql.append(key);
				if (itr.hasNext()) {
					sql.append(", ");
				}
			}
			sql.append(" ) VALUES ( ");
			itr = params.keySet().iterator();
			while (itr.hasNext()) {
				String key = (String)itr.next();
				String value = (String)params.get(key);
				sql.append("'");
				sql.append(value);
				sql.append("'");
				if (itr.hasNext()) {
					sql.append(", ");
				}
			}
			sql.append(")");
			sql.append(" RETURNING identification");

			conn = connect();
			stmt = conn.createStatement();
			rs = stmt.executeQuery(sql.toString());
			while (rs.next()) {
				result = rs.getString("identification");
			}
		} catch (SQLException e) {
			// TODO 自動生成された catch ブロック
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO 自動生成された catch ブロック
			e.printStackTrace();
		} finally {
			try {
				if (rs != null) {
					rs.close();
				}
				if (stmt != null) {
					stmt.close();
				}
				if (conn != null) {
					conn.close();
				}
			} catch (SQLException e) {
				// TODO 自動生成された catch ブロック
				e.printStackTrace();
			}
		}
		return result;
	}

	public int update(Map<String, String> params, String table, String condition) {
		Connection conn = null;
		Statement stmt = null;

		int result = 0;

		try {
			if ( condition.isEmpty() ) {
				return 0;
			}

			StringBuilder sql = new StringBuilder();
			sql.append("UPDATE ");
			sql.append(table);
			sql.append(" SET ");

			Iterator<String> itr = params.keySet().iterator();
			while (itr.hasNext()) {
				String key = (String)itr.next();
				String value = (String)params.get(key);
				sql.append(key);
				sql.append(" = ");
				sql.append("'");
				sql.append(value);
				sql.append("'");
				if ( itr.hasNext() ) {
					sql.append(", ");
				}
			}
			sql.append(" WHERE ");
			sql.append(condition);

			conn = connect();
			stmt = conn.createStatement();
			result = stmt.executeUpdate(sql.toString());

		} catch (SQLException e) {
			// TODO 自動生成された catch ブロック
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO 自動生成された catch ブロック
			e.printStackTrace();
		} finally {
			try {
				if (stmt != null) {
					stmt.close();
				}
				if (conn != null) {
					conn.close();
				}
			} catch (SQLException e) {
				// TODO 自動生成された catch ブロック
				e.printStackTrace();
			}
		}
		return result;
	}

	public int delete(String table, String condition) {
		Connection conn = null;
		Statement stmt = null;

		int result = 0;

		try {
			StringBuilder sql = new StringBuilder();
			sql.append("DELETE ");
			sql.append("FROM ");
			sql.append(table);
			if ( !condition.isEmpty() ) {
				sql.append(" WHERE ");
				sql.append(condition);
			}

			conn = connect();
			stmt = conn.createStatement();
			result = stmt.executeUpdate(sql.toString());
		} catch (SQLException e) {
			// TODO 自動生成された catch ブロック
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO 自動生成された catch ブロック
			e.printStackTrace();
		} finally {
			try {
				if (stmt != null) {
					stmt.close();
				}
				if (conn != null) {
					conn.close();
				}
			} catch (SQLException e) {
				// TODO 自動生成された catch ブロック
				e.printStackTrace();
			}
		}
		return result;
	}

	public ArrayList<String> getColumNames(String table) {
		ArrayList<String> params = new ArrayList<String>();
		params.add("column_name");

		ArrayList<ArrayList<String>> results = getColumNames(params, table);

		ArrayList<String> columNames = new ArrayList<String>();
		for (int ii = 0; ii < results.size(); ++ii) {
			columNames.add(results.get(ii).get(0));
		}
		return columNames;
	}
	public ArrayList<ArrayList<String>> getColumNames(ArrayList<String> params, String table) {
		StringBuilder condition = new StringBuilder();
		condition.append("table_name = ");
		condition.append("'");
		condition.append(table);
		condition.append("'");
		condition.append(" ORDER BY ordinal_position");
		return select(params, "information_schema.columns", condition.toString());
	}
}
