View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *     http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  package org.apache.shardingsphere.driver.jdbc.core.resultset;
19  
20  import org.apache.shardingsphere.driver.jdbc.adapter.AbstractResultSetAdapter;
21  import org.apache.shardingsphere.infra.annotation.HighFrequencyInvocation;
22  import org.apache.shardingsphere.infra.executor.sql.context.ExecutionContext;
23  import org.apache.shardingsphere.infra.executor.sql.execute.result.query.impl.driver.jdbc.type.util.ResultSetUtils;
24  import org.apache.shardingsphere.infra.merge.result.MergedResult;
25  import org.apache.shardingsphere.infra.exception.core.ShardingSpherePreconditions;
26  
27  import java.io.InputStream;
28  import java.io.Reader;
29  import java.math.BigDecimal;
30  import java.math.BigInteger;
31  import java.net.URL;
32  import java.sql.Array;
33  import java.sql.Blob;
34  import java.sql.Clob;
35  import java.sql.Date;
36  import java.sql.ResultSet;
37  import java.sql.SQLException;
38  import java.sql.SQLFeatureNotSupportedException;
39  import java.sql.SQLXML;
40  import java.sql.Statement;
41  import java.sql.Time;
42  import java.sql.Timestamp;
43  import java.time.LocalDate;
44  import java.time.LocalDateTime;
45  import java.time.LocalTime;
46  import java.time.OffsetDateTime;
47  import java.util.Calendar;
48  import java.util.List;
49  import java.util.Map;
50  
51  /**
52   * ShardingSphere result set.
53   */
54  @HighFrequencyInvocation
55  public final class ShardingSphereResultSet extends AbstractResultSetAdapter {
56      
57      private static final String ASCII = "Ascii";
58      
59      private static final String UNICODE = "Unicode";
60      
61      private static final String BINARY = "Binary";
62      
63      private final MergedResult mergeResultSet;
64      
65      private final Map<String, Integer> columnLabelAndIndexMap;
66      
67      public ShardingSphereResultSet(final List<ResultSet> resultSets, final MergedResult mergeResultSet, final Statement statement, final boolean selectContainsEnhancedTable,
68                                     final ExecutionContext executionContext) throws SQLException {
69          super(resultSets, statement, selectContainsEnhancedTable, executionContext);
70          this.mergeResultSet = mergeResultSet;
71          columnLabelAndIndexMap = ShardingSphereResultSetUtils.createColumnLabelAndIndexMap(executionContext.getSqlStatementContext(), selectContainsEnhancedTable, resultSets.get(0).getMetaData());
72      }
73      
74      public ShardingSphereResultSet(final List<ResultSet> resultSets, final MergedResult mergeResultSet, final Statement statement, final boolean selectContainsEnhancedTable,
75                                     final ExecutionContext executionContext, final Map<String, Integer> columnLabelAndIndexMap) {
76          super(resultSets, statement, selectContainsEnhancedTable, executionContext);
77          this.mergeResultSet = mergeResultSet;
78          this.columnLabelAndIndexMap = columnLabelAndIndexMap;
79      }
80      
81      @Override
82      public boolean next() throws SQLException {
83          return mergeResultSet.next();
84      }
85      
86      @Override
87      public boolean wasNull() throws SQLException {
88          return mergeResultSet.wasNull();
89      }
90      
91      @Override
92      public boolean getBoolean(final int columnIndex) throws SQLException {
93          return (boolean) ResultSetUtils.convertValue(mergeResultSet.getValue(columnIndex, boolean.class), boolean.class);
94      }
95      
96      @Override
97      public boolean getBoolean(final String columnLabel) throws SQLException {
98          return getBoolean(getIndexFromColumnLabelAndIndexMap(columnLabel));
99      }
100     
101     @Override
102     public byte getByte(final int columnIndex) throws SQLException {
103         return (byte) ResultSetUtils.convertValue(mergeResultSet.getValue(columnIndex, byte.class), byte.class);
104     }
105     
106     @Override
107     public byte getByte(final String columnLabel) throws SQLException {
108         return getByte(getIndexFromColumnLabelAndIndexMap(columnLabel));
109     }
110     
111     @Override
112     public short getShort(final int columnIndex) throws SQLException {
113         return (short) ResultSetUtils.convertValue(mergeResultSet.getValue(columnIndex, short.class), short.class);
114     }
115     
116     @Override
117     public short getShort(final String columnLabel) throws SQLException {
118         return getShort(getIndexFromColumnLabelAndIndexMap(columnLabel));
119     }
120     
121     @Override
122     public int getInt(final int columnIndex) throws SQLException {
123         return (int) ResultSetUtils.convertValue(mergeResultSet.getValue(columnIndex, int.class), int.class);
124     }
125     
126     @Override
127     public int getInt(final String columnLabel) throws SQLException {
128         return getInt(getIndexFromColumnLabelAndIndexMap(columnLabel));
129     }
130     
131     @Override
132     public long getLong(final int columnIndex) throws SQLException {
133         return (long) ResultSetUtils.convertValue(mergeResultSet.getValue(columnIndex, long.class), long.class);
134     }
135     
136     @Override
137     public long getLong(final String columnLabel) throws SQLException {
138         return getLong(getIndexFromColumnLabelAndIndexMap(columnLabel));
139     }
140     
141     @Override
142     public float getFloat(final int columnIndex) throws SQLException {
143         return (float) ResultSetUtils.convertValue(mergeResultSet.getValue(columnIndex, float.class), float.class);
144     }
145     
146     @Override
147     public float getFloat(final String columnLabel) throws SQLException {
148         return getFloat(getIndexFromColumnLabelAndIndexMap(columnLabel));
149     }
150     
151     @Override
152     public double getDouble(final int columnIndex) throws SQLException {
153         return (double) ResultSetUtils.convertValue(mergeResultSet.getValue(columnIndex, double.class), double.class);
154     }
155     
156     @Override
157     public double getDouble(final String columnLabel) throws SQLException {
158         return getDouble(getIndexFromColumnLabelAndIndexMap(columnLabel));
159     }
160     
161     @Override
162     public String getString(final int columnIndex) throws SQLException {
163         return (String) ResultSetUtils.convertValue(mergeResultSet.getValue(columnIndex, String.class), String.class);
164     }
165     
166     @Override
167     public String getString(final String columnLabel) throws SQLException {
168         return getString(getIndexFromColumnLabelAndIndexMap(columnLabel));
169     }
170     
171     @Override
172     public String getNString(final int columnIndex) throws SQLException {
173         return getString(columnIndex);
174     }
175     
176     @Override
177     public String getNString(final String columnLabel) throws SQLException {
178         return getString(columnLabel);
179     }
180     
181     @Override
182     public BigDecimal getBigDecimal(final int columnIndex) throws SQLException {
183         return (BigDecimal) ResultSetUtils.convertValue(mergeResultSet.getValue(columnIndex, BigDecimal.class), BigDecimal.class);
184     }
185     
186     @Override
187     public BigDecimal getBigDecimal(final String columnLabel) throws SQLException {
188         return getBigDecimal(getIndexFromColumnLabelAndIndexMap(columnLabel));
189     }
190     
191     @Override
192     public BigDecimal getBigDecimal(final int columnIndex, final int scale) throws SQLException {
193         return (BigDecimal) ResultSetUtils.convertValue(mergeResultSet.getValue(columnIndex, BigDecimal.class), BigDecimal.class);
194     }
195     
196     @Override
197     public BigDecimal getBigDecimal(final String columnLabel, final int scale) throws SQLException {
198         return getBigDecimal(getIndexFromColumnLabelAndIndexMap(columnLabel));
199     }
200     
201     @Override
202     public byte[] getBytes(final int columnIndex) throws SQLException {
203         return (byte[]) ResultSetUtils.convertValue(mergeResultSet.getValue(columnIndex, byte[].class), byte[].class);
204     }
205     
206     @Override
207     public byte[] getBytes(final String columnLabel) throws SQLException {
208         return getBytes(getIndexFromColumnLabelAndIndexMap(columnLabel));
209     }
210     
211     @Override
212     public Date getDate(final int columnIndex) throws SQLException {
213         return (Date) ResultSetUtils.convertValue(mergeResultSet.getValue(columnIndex, Date.class), Date.class);
214     }
215     
216     @Override
217     public Date getDate(final String columnLabel) throws SQLException {
218         return getDate(getIndexFromColumnLabelAndIndexMap(columnLabel));
219     }
220     
221     @Override
222     public Date getDate(final int columnIndex, final Calendar cal) throws SQLException {
223         return (Date) ResultSetUtils.convertValue(mergeResultSet.getCalendarValue(columnIndex, Date.class, cal), Date.class);
224     }
225     
226     @Override
227     public Date getDate(final String columnLabel, final Calendar cal) throws SQLException {
228         return getDate(getIndexFromColumnLabelAndIndexMap(columnLabel), cal);
229     }
230     
231     @Override
232     public Time getTime(final int columnIndex) throws SQLException {
233         return (Time) ResultSetUtils.convertValue(mergeResultSet.getValue(columnIndex, Time.class), Time.class);
234     }
235     
236     @Override
237     public Time getTime(final String columnLabel) throws SQLException {
238         return getTime(getIndexFromColumnLabelAndIndexMap(columnLabel));
239     }
240     
241     @Override
242     public Time getTime(final int columnIndex, final Calendar cal) throws SQLException {
243         return (Time) ResultSetUtils.convertValue(mergeResultSet.getCalendarValue(columnIndex, Time.class, cal), Time.class);
244     }
245     
246     @Override
247     public Time getTime(final String columnLabel, final Calendar cal) throws SQLException {
248         return getTime(getIndexFromColumnLabelAndIndexMap(columnLabel), cal);
249     }
250     
251     @Override
252     public Timestamp getTimestamp(final int columnIndex) throws SQLException {
253         return (Timestamp) ResultSetUtils.convertValue(mergeResultSet.getValue(columnIndex, Timestamp.class), Timestamp.class);
254     }
255     
256     @Override
257     public Timestamp getTimestamp(final String columnLabel) throws SQLException {
258         return getTimestamp(getIndexFromColumnLabelAndIndexMap(columnLabel));
259     }
260     
261     @Override
262     public Timestamp getTimestamp(final int columnIndex, final Calendar cal) throws SQLException {
263         return (Timestamp) ResultSetUtils.convertValue(mergeResultSet.getCalendarValue(columnIndex, Timestamp.class, cal), Timestamp.class);
264     }
265     
266     @Override
267     public Timestamp getTimestamp(final String columnLabel, final Calendar cal) throws SQLException {
268         return getTimestamp(getIndexFromColumnLabelAndIndexMap(columnLabel), cal);
269     }
270     
271     @Override
272     public InputStream getAsciiStream(final int columnIndex) throws SQLException {
273         return mergeResultSet.getInputStream(columnIndex, ASCII);
274     }
275     
276     @Override
277     public InputStream getAsciiStream(final String columnLabel) throws SQLException {
278         return getAsciiStream(getIndexFromColumnLabelAndIndexMap(columnLabel));
279     }
280     
281     @Override
282     public InputStream getUnicodeStream(final int columnIndex) throws SQLException {
283         return mergeResultSet.getInputStream(columnIndex, UNICODE);
284     }
285     
286     @Override
287     public InputStream getUnicodeStream(final String columnLabel) throws SQLException {
288         return getUnicodeStream(getIndexFromColumnLabelAndIndexMap(columnLabel));
289     }
290     
291     @Override
292     public InputStream getBinaryStream(final int columnIndex) throws SQLException {
293         return mergeResultSet.getInputStream(columnIndex, BINARY);
294     }
295     
296     @Override
297     public InputStream getBinaryStream(final String columnLabel) throws SQLException {
298         return getBinaryStream(getIndexFromColumnLabelAndIndexMap(columnLabel));
299     }
300     
301     @Override
302     public Reader getCharacterStream(final int columnIndex) throws SQLException {
303         // TODO To be supported: encrypt, mask, and so on
304         return mergeResultSet.getCharacterStream(columnIndex);
305     }
306     
307     @Override
308     public Reader getCharacterStream(final String columnLabel) throws SQLException {
309         return getCharacterStream(getIndexFromColumnLabelAndIndexMap(columnLabel));
310     }
311     
312     @Override
313     public Blob getBlob(final int columnIndex) throws SQLException {
314         return (Blob) mergeResultSet.getValue(columnIndex, Blob.class);
315     }
316     
317     @Override
318     public Blob getBlob(final String columnLabel) throws SQLException {
319         return getBlob(getIndexFromColumnLabelAndIndexMap(columnLabel));
320     }
321     
322     @Override
323     public Clob getClob(final int columnIndex) throws SQLException {
324         return (Clob) mergeResultSet.getValue(columnIndex, Clob.class);
325     }
326     
327     @Override
328     public Clob getClob(final String columnLabel) throws SQLException {
329         return getClob(getIndexFromColumnLabelAndIndexMap(columnLabel));
330     }
331     
332     @Override
333     public Array getArray(final int columnIndex) throws SQLException {
334         return (Array) mergeResultSet.getValue(columnIndex, Array.class);
335     }
336     
337     @Override
338     public Array getArray(final String columnLabel) throws SQLException {
339         return getArray(getIndexFromColumnLabelAndIndexMap(columnLabel));
340     }
341     
342     @Override
343     public URL getURL(final int columnIndex) throws SQLException {
344         return (URL) mergeResultSet.getValue(columnIndex, URL.class);
345     }
346     
347     @Override
348     public URL getURL(final String columnLabel) throws SQLException {
349         return getURL(getIndexFromColumnLabelAndIndexMap(columnLabel));
350     }
351     
352     @Override
353     public SQLXML getSQLXML(final int columnIndex) throws SQLException {
354         return (SQLXML) mergeResultSet.getValue(columnIndex, SQLXML.class);
355     }
356     
357     @Override
358     public SQLXML getSQLXML(final String columnLabel) throws SQLException {
359         return getSQLXML(getIndexFromColumnLabelAndIndexMap(columnLabel));
360     }
361     
362     @Override
363     public Object getObject(final int columnIndex) throws SQLException {
364         return mergeResultSet.getValue(columnIndex, Object.class);
365     }
366     
367     @Override
368     public Object getObject(final String columnLabel) throws SQLException {
369         return getObject(getIndexFromColumnLabelAndIndexMap(columnLabel));
370     }
371     
372     @SuppressWarnings("unchecked")
373     @Override
374     public <T> T getObject(final int columnIndex, final Class<T> type) throws SQLException {
375         if (BigInteger.class.equals(type)) {
376             return (T) BigInteger.valueOf(getLong(columnIndex));
377         }
378         if (Blob.class.equals(type)) {
379             return (T) getBlob(columnIndex);
380         }
381         if (Clob.class.equals(type)) {
382             return (T) getClob(columnIndex);
383         }
384         if (LocalDateTime.class.equals(type) || LocalDate.class.equals(type) || LocalTime.class.equals(type) || OffsetDateTime.class.equals(type)) {
385             return (T) ResultSetUtils.convertValue(mergeResultSet.getValue(columnIndex, Timestamp.class), type);
386         }
387         return (T) ResultSetUtils.convertValue(mergeResultSet.getValue(columnIndex, type), type);
388     }
389     
390     @Override
391     public <T> T getObject(final String columnLabel, final Class<T> type) throws SQLException {
392         return getObject(getIndexFromColumnLabelAndIndexMap(columnLabel), type);
393     }
394     
395     private Integer getIndexFromColumnLabelAndIndexMap(final String columnLabel) throws SQLException {
396         Integer result = columnLabelAndIndexMap.get(columnLabel);
397         ShardingSpherePreconditions.checkNotNull(result, () -> new SQLFeatureNotSupportedException(String.format("Can not get index from column label `%s`.", columnLabel)));
398         return result;
399     }
400 }