/* * 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.value; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import org.h2.message.DbException; import org.h2.tools.SimpleResultSet; import org.h2.util.StatementBuilder; /** * Implementation of the RESULT_SET data type. */ public class ValueResultSet extends Value { private final ResultSet result; private ValueResultSet(ResultSet rs) { this.result = rs; } /** * Create a result set value for the given result set. * The result set will be wrapped. * * @param rs the result set * @return the value */ public static ValueResultSet get(ResultSet rs) { ValueResultSet val = new ValueResultSet(rs); return val; } /** * Create a result set value for the given result set. The result set will * be fully read in memory. The original result set is not closed. * * @param rs the result set * @param maxrows the maximum number of rows to read (0 to just read the * meta data) * @return the value */ public static ValueResultSet getCopy(ResultSet rs, int maxrows) { try { ResultSetMetaData meta = rs.getMetaData(); int columnCount = meta.getColumnCount(); SimpleResultSet simple = new SimpleResultSet(); simple.setAutoClose(false); ValueResultSet val = new ValueResultSet(simple); for (int i = 0; i < columnCount; i++) { String name = meta.getColumnLabel(i + 1); int sqlType = meta.getColumnType(i + 1); int precision = meta.getPrecision(i + 1); int scale = meta.getScale(i + 1); simple.addColumn(name, sqlType, precision, scale); } for (int i = 0; i < maxrows && rs.next(); i++) { Object[] list = new Object[columnCount]; for (int j = 0; j < columnCount; j++) { list[j] = rs.getObject(j + 1); } simple.addRow(list); } return val; } catch (SQLException e) { throw DbException.convert(e); } } public int getType() { return Value.RESULT_SET; } public long getPrecision() { return Integer.MAX_VALUE; } public int getDisplaySize() { // it doesn't make sense to calculate it return Integer.MAX_VALUE; } public String getString() { try { StatementBuilder buff = new StatementBuilder("("); result.beforeFirst(); ResultSetMetaData meta = result.getMetaData(); int columnCount = meta.getColumnCount(); for (int i = 0; result.next(); i++) { if (i > 0) { buff.append(", "); } buff.append('('); buff.resetCount(); for (int j = 0; j < columnCount; j++) { buff.appendExceptFirst(", "); int t = DataType.convertSQLTypeToValueType(meta.getColumnType(j + 1)); Value v = DataType.readValue(null, result, j+1, t); buff.append(v.getString()); } buff.append(')'); } result.beforeFirst(); return buff.append(')').toString(); } catch (SQLException e) { throw DbException.convert(e); } } protected int compareSecure(Value v, CompareMode mode) { return this == v ? 0 : super.toString().compareTo(v.toString()); } public boolean equals(Object other) { return other == this; } public int hashCode() { return 0; } public Object getObject() { return result; } public ResultSet getResultSet() { return result; } public void set(PreparedStatement prep, int parameterIndex) { throw throwUnsupportedExceptionForType("PreparedStatement.set"); } public String getSQL() { return ""; } public Value convertPrecision(long precision, boolean force) { if (!force) { return this; } return ValueResultSet.get(new SimpleResultSet()); } }