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.sqlfederation.executor.enumerator;
19  
20  import lombok.RequiredArgsConstructor;
21  import lombok.SneakyThrows;
22  import org.apache.calcite.linq4j.Enumerator;
23  import org.apache.shardingsphere.infra.executor.sql.execute.result.query.QueryResultMetaData;
24  import org.apache.shardingsphere.infra.executor.sql.execute.result.query.impl.driver.jdbc.type.util.ResultSetUtils;
25  import org.apache.shardingsphere.infra.merge.result.MergedResult;
26  import org.apache.shardingsphere.infra.exception.core.external.sql.type.wrapper.SQLWrapperException;
27  
28  import java.sql.SQLException;
29  import java.sql.Statement;
30  import java.sql.Timestamp;
31  import java.time.LocalDateTime;
32  import java.util.Collection;
33  
34  /**
35   * JDBC row enumerator.
36   */
37  @RequiredArgsConstructor
38  public final class JDBCRowEnumerator implements Enumerator<Object> {
39      
40      private final MergedResult queryResult;
41      
42      private final QueryResultMetaData metaData;
43      
44      private final Collection<Statement> statements;
45      
46      private Object currentRow;
47      
48      @Override
49      public Object current() {
50          return currentRow;
51      }
52      
53      @SneakyThrows
54      @Override
55      public boolean moveNext() {
56          return moveNext0();
57      }
58      
59      private boolean moveNext0() throws SQLException {
60          if (queryResult.next()) {
61              setCurrentRow();
62              return true;
63          }
64          return false;
65      }
66      
67      private void setCurrentRow() throws SQLException {
68          Object[] rowValues = new Object[metaData.getColumnCount()];
69          for (int i = 0; i < metaData.getColumnCount(); i++) {
70              rowValues[i] = getValue(i);
71          }
72          currentRow = 1 == metaData.getColumnCount() ? rowValues[0] : rowValues;
73      }
74      
75      private Object getValue(final int index) throws SQLException {
76          Object result = queryResult.getValue(index + 1, Object.class);
77          return result instanceof LocalDateTime ? ResultSetUtils.convertValue(result, Timestamp.class) : result;
78      }
79      
80      @Override
81      public void reset() {
82      }
83      
84      @Override
85      public void close() {
86          try {
87              for (Statement each : statements) {
88                  each.close();
89              }
90              currentRow = null;
91          } catch (final SQLException ex) {
92              throw new SQLWrapperException(ex);
93          }
94      }
95  }