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