1 | /* |
2 | * Copyright 2004-2014 H2 Group. Multiple-Licensed under the MPL 2.0, |
3 | * and the EPL 1.0 (http://h2database.com/html/license.html). |
4 | * Initial Developer: H2 Group |
5 | */ |
6 | package org.h2.value; |
7 | |
8 | import java.sql.PreparedStatement; |
9 | import java.sql.ResultSet; |
10 | import java.sql.ResultSetMetaData; |
11 | import java.sql.SQLException; |
12 | import org.h2.message.DbException; |
13 | import org.h2.tools.SimpleResultSet; |
14 | import org.h2.util.StatementBuilder; |
15 | |
16 | /** |
17 | * Implementation of the RESULT_SET data type. |
18 | */ |
19 | public class ValueResultSet extends Value { |
20 | |
21 | private final ResultSet result; |
22 | |
23 | private ValueResultSet(ResultSet rs) { |
24 | this.result = rs; |
25 | } |
26 | |
27 | /** |
28 | * Create a result set value for the given result set. |
29 | * The result set will be wrapped. |
30 | * |
31 | * @param rs the result set |
32 | * @return the value |
33 | */ |
34 | public static ValueResultSet get(ResultSet rs) { |
35 | ValueResultSet val = new ValueResultSet(rs); |
36 | return val; |
37 | } |
38 | |
39 | /** |
40 | * Create a result set value for the given result set. The result set will |
41 | * be fully read in memory. The original result set is not closed. |
42 | * |
43 | * @param rs the result set |
44 | * @param maxrows the maximum number of rows to read (0 to just read the |
45 | * meta data) |
46 | * @return the value |
47 | */ |
48 | public static ValueResultSet getCopy(ResultSet rs, int maxrows) { |
49 | try { |
50 | ResultSetMetaData meta = rs.getMetaData(); |
51 | int columnCount = meta.getColumnCount(); |
52 | SimpleResultSet simple = new SimpleResultSet(); |
53 | simple.setAutoClose(false); |
54 | ValueResultSet val = new ValueResultSet(simple); |
55 | for (int i = 0; i < columnCount; i++) { |
56 | String name = meta.getColumnLabel(i + 1); |
57 | int sqlType = meta.getColumnType(i + 1); |
58 | int precision = meta.getPrecision(i + 1); |
59 | int scale = meta.getScale(i + 1); |
60 | simple.addColumn(name, sqlType, precision, scale); |
61 | } |
62 | for (int i = 0; i < maxrows && rs.next(); i++) { |
63 | Object[] list = new Object[columnCount]; |
64 | for (int j = 0; j < columnCount; j++) { |
65 | list[j] = rs.getObject(j + 1); |
66 | } |
67 | simple.addRow(list); |
68 | } |
69 | return val; |
70 | } catch (SQLException e) { |
71 | throw DbException.convert(e); |
72 | } |
73 | } |
74 | |
75 | @Override |
76 | public int getType() { |
77 | return Value.RESULT_SET; |
78 | } |
79 | |
80 | @Override |
81 | public long getPrecision() { |
82 | return Integer.MAX_VALUE; |
83 | } |
84 | |
85 | @Override |
86 | public int getDisplaySize() { |
87 | // it doesn't make sense to calculate it |
88 | return Integer.MAX_VALUE; |
89 | } |
90 | |
91 | @Override |
92 | public String getString() { |
93 | try { |
94 | StatementBuilder buff = new StatementBuilder("("); |
95 | result.beforeFirst(); |
96 | ResultSetMetaData meta = result.getMetaData(); |
97 | int columnCount = meta.getColumnCount(); |
98 | for (int i = 0; result.next(); i++) { |
99 | if (i > 0) { |
100 | buff.append(", "); |
101 | } |
102 | buff.append('('); |
103 | buff.resetCount(); |
104 | for (int j = 0; j < columnCount; j++) { |
105 | buff.appendExceptFirst(", "); |
106 | int t = DataType.getValueTypeFromResultSet(meta, j + 1); |
107 | Value v = DataType.readValue(null, result, j+1, t); |
108 | buff.append(v.getString()); |
109 | } |
110 | buff.append(')'); |
111 | } |
112 | result.beforeFirst(); |
113 | return buff.append(')').toString(); |
114 | } catch (SQLException e) { |
115 | throw DbException.convert(e); |
116 | } |
117 | } |
118 | |
119 | @Override |
120 | protected int compareSecure(Value v, CompareMode mode) { |
121 | return this == v ? 0 : super.toString().compareTo(v.toString()); |
122 | } |
123 | |
124 | @Override |
125 | public boolean equals(Object other) { |
126 | return other == this; |
127 | } |
128 | |
129 | @Override |
130 | public int hashCode() { |
131 | return 0; |
132 | } |
133 | |
134 | @Override |
135 | public Object getObject() { |
136 | return result; |
137 | } |
138 | |
139 | @Override |
140 | public ResultSet getResultSet() { |
141 | return result; |
142 | } |
143 | |
144 | @Override |
145 | public void set(PreparedStatement prep, int parameterIndex) { |
146 | throw throwUnsupportedExceptionForType("PreparedStatement.set"); |
147 | } |
148 | |
149 | @Override |
150 | public String getSQL() { |
151 | return ""; |
152 | } |
153 | |
154 | @Override |
155 | public Value convertPrecision(long precision, boolean force) { |
156 | if (!force) { |
157 | return this; |
158 | } |
159 | SimpleResultSet rs = new SimpleResultSet(); |
160 | rs.setAutoClose(false); |
161 | return ValueResultSet.get(rs); |
162 | } |
163 | |
164 | } |