/*
* 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);
}
}
}