/* * Copyright 2004-2011 H2 Group. Multiple-Licensed under the H2 License, * Version 1.0, and under the Eclipse Public License, Version 1.0 * (http://h2database.com/html/license.html). * Initial Developer: H2 Group */ package org.h2.test.db; import java.io.InputStream; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.h2.util.JdbcUtils; /** * A simple wrapper around the JDBC API. * Currently used for testing. * Features: * <ul> * <li>No checked exceptions * </li><li>Easy to use, fluent API * </li></ul> */ public class Db { private Connection conn; private Statement stat; private HashMap<String, PreparedStatement> prepared = new HashMap<String, PreparedStatement>(); /** * Create a database object using the given connection. * * @param conn the database connection */ public Db(Connection conn) { try { this.conn = conn; stat = conn.createStatement(); } catch (SQLException e) { throw convert(e); } } /** * Open the database connection. For most databases, it is not required to * load the driver before calling this method. * * @param url the database URL * @param user the user name * @param password the password * @return the database */ public static Db open(String url, String user, String password) { try { JdbcUtils.load(url); return new Db(DriverManager.getConnection(url, user, password)); } catch (SQLException e) { throw convert(e); } } /** * Prepare a SQL statement. * * @param sql the SQL statement * @return the prepared statement */ public Prepared prepare(String sql) { try { PreparedStatement prep = prepared.get(sql); if (prep == null) { prep = conn.prepareStatement(sql); prepared.put(sql, prep); } return new Prepared(conn.prepareStatement(sql)); } catch (SQLException e) { throw convert(e); } } /** * Execute a SQL statement. * * @param sql the SQL statement */ public void execute(String sql) { try { stat.execute(sql); } catch (SQLException e) { throw convert(e); } } /** * Read a result set. * * @param rs the result set * @return a list of maps */ static List<Map<String, Object>> query(ResultSet rs) throws SQLException { List<Map<String, Object>> list = new ArrayList<Map<String, Object>>(); ResultSetMetaData meta = rs.getMetaData(); int columnCount = meta.getColumnCount(); while (rs.next()) { HashMap<String, Object> map = new HashMap<String, Object>(); for (int i = 0; i < columnCount; i++) { map.put(meta.getColumnLabel(i+1), rs.getObject(i+1)); } list.add(map); } return list; } /** * Execute a SQL statement. * * @param sql the SQL statement * @return a list of maps */ public List<Map<String, Object>> query(String sql) { try { return query(stat.executeQuery(sql)); } catch (SQLException e) { throw convert(e); } } /** * Close the database connection. */ public void close() { try { conn.close(); } catch (SQLException e) { throw convert(e); } } /** * This class represents a prepared statement. */ public static class Prepared { private PreparedStatement prep; private int index; Prepared(PreparedStatement prep) { this.prep = prep; } /** * Set the value of the current parameter. * * @param x the value * @return itself */ public Prepared set(int x) { try { prep.setInt(++index, x); return this; } catch (SQLException e) { throw convert(e); } } /** * Set the value of the current parameter. * * @param x the value * @return itself */ public Prepared set(String x) { try { prep.setString(++index, x); return this; } catch (SQLException e) { throw convert(e); } } /** * Set the value of the current parameter. * * @param x the value * @return itself */ public Prepared set(byte[] x) { try { prep.setBytes(++index, x); return this; } catch (SQLException e) { throw convert(e); } } /** * Set the value of the current parameter. * * @param x the value * @return itself */ public Prepared set(InputStream x) { try { prep.setBinaryStream(++index, x, -1); return this; } catch (SQLException e) { throw convert(e); } } /** * Execute the prepared statement. */ public void execute() { try { prep.execute(); } catch (SQLException e) { throw convert(e); } } /** * Execute the prepared query. * * @return the result list */ public List<Map<String, Object>> query() { try { return Db.query(prep.executeQuery()); } catch (SQLException e) { throw convert(e); } } } /** * Convert a checked exception to a runtime exception. * * @param e the checked exception * @return the runtime exception */ static RuntimeException convert(Exception e) { return new RuntimeException(e.toString(), e); } public void setAutoCommit(boolean autoCommit) { try { conn.setAutoCommit(autoCommit); } catch (SQLException e) { throw convert(e); } } /** * Commit a pending transaction. */ public void commit() { try { conn.commit(); } catch (SQLException e) { throw convert(e); } } }