| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package org.apache.ignite.internal.jdbc; |
| |
| import java.sql.Connection; |
| import java.sql.ResultSet; |
| import java.sql.SQLException; |
| import java.sql.SQLFeatureNotSupportedException; |
| import java.sql.SQLWarning; |
| import java.sql.Statement; |
| import java.util.Collection; |
| import java.util.List; |
| import java.util.UUID; |
| import org.apache.ignite.internal.client.GridClientException; |
| import org.apache.ignite.internal.util.typedef.internal.U; |
| |
| import static java.sql.ResultSet.CONCUR_READ_ONLY; |
| import static java.sql.ResultSet.FETCH_FORWARD; |
| import static java.sql.ResultSet.HOLD_CURSORS_OVER_COMMIT; |
| import static java.sql.ResultSet.TYPE_FORWARD_ONLY; |
| |
| /** |
| * JDBC statement implementation. |
| * |
| * @deprecated Using Ignite client node based JDBC driver is preferable. |
| * See documentation of {@link org.apache.ignite.IgniteJdbcDriver} for details. |
| */ |
| @Deprecated |
| public class JdbcStatement implements Statement { |
| /** Task name. */ |
| private static final String TASK_NAME = |
| "org.apache.ignite.internal.processors.cache.query.jdbc.GridCacheQueryJdbcTask"; |
| |
| /** Default fetch size. */ |
| private static final int DFLT_FETCH_SIZE = 1024; |
| |
| /** Connection. */ |
| private final JdbcConnection conn; |
| |
| /** Closed flag. */ |
| private boolean closed; |
| |
| /** Rows limit. */ |
| private int maxRows; |
| |
| /** Query timeout. */ |
| private int timeout; |
| |
| /** Current result set. */ |
| private ResultSet rs; |
| |
| /** Query arguments. */ |
| protected Object[] args; |
| |
| /** Fetch size. */ |
| private int fetchSize = DFLT_FETCH_SIZE; |
| |
| /** |
| * Creates new statement. |
| * |
| * @param conn Connection. |
| */ |
| JdbcStatement(JdbcConnection conn) { |
| assert conn != null; |
| |
| this.conn = conn; |
| } |
| |
| /** {@inheritDoc} */ |
| @Override public ResultSet executeQuery(String sql) throws SQLException { |
| ensureNotClosed(); |
| |
| rs = null; |
| |
| if (sql == null || sql.isEmpty()) |
| throw new SQLException("SQL query is empty"); |
| |
| try { |
| byte[] packet = conn.client().compute().execute(TASK_NAME, |
| JdbcUtils.marshalArgument(JdbcUtils.taskArgument(conn.nodeId(), conn.cacheName(), sql, |
| timeout, args, fetchSize, maxRows))); |
| |
| byte status = packet[0]; |
| byte[] data = new byte[packet.length - 1]; |
| |
| U.arrayCopy(packet, 1, data, 0, data.length); |
| |
| if (status == 1) |
| throw JdbcUtils.unmarshalError(data); |
| else { |
| List<?> msg = JdbcUtils.unmarshal(data); |
| |
| assert msg.size() == 7; |
| |
| UUID nodeId = (UUID)msg.get(0); |
| UUID futId = (UUID)msg.get(1); |
| List<String> tbls = (List<String>)msg.get(2); |
| List<String> cols = (List<String>)msg.get(3); |
| List<String> types = (List<String>)msg.get(4); |
| Collection<List<Object>> fields = (Collection<List<Object>>)msg.get(5); |
| boolean finished = (Boolean)msg.get(6); |
| |
| return new JdbcResultSet(this, nodeId, futId, tbls, cols, types, fields, finished, fetchSize); |
| } |
| } |
| catch (GridClientException e) { |
| throw new SQLException("Failed to query Ignite.", e); |
| } |
| } |
| |
| /** {@inheritDoc} */ |
| @Override public int executeUpdate(String sql) throws SQLException { |
| ensureNotClosed(); |
| |
| throw new SQLFeatureNotSupportedException("Updates are not supported."); |
| } |
| |
| /** {@inheritDoc} */ |
| @Override public void close() throws SQLException { |
| closed = true; |
| } |
| |
| /** {@inheritDoc} */ |
| @Override public int getMaxFieldSize() throws SQLException { |
| ensureNotClosed(); |
| |
| return 0; |
| } |
| |
| /** {@inheritDoc} */ |
| @Override public void setMaxFieldSize(int max) throws SQLException { |
| ensureNotClosed(); |
| |
| throw new SQLFeatureNotSupportedException("Field size limitation is not supported."); |
| } |
| |
| /** {@inheritDoc} */ |
| @Override public int getMaxRows() throws SQLException { |
| ensureNotClosed(); |
| |
| return maxRows; |
| } |
| |
| /** {@inheritDoc} */ |
| @Override public void setMaxRows(int maxRows) throws SQLException { |
| ensureNotClosed(); |
| |
| this.maxRows = maxRows; |
| } |
| |
| /** {@inheritDoc} */ |
| @Override public void setEscapeProcessing(boolean enable) throws SQLException { |
| ensureNotClosed(); |
| } |
| |
| /** {@inheritDoc} */ |
| @Override public int getQueryTimeout() throws SQLException { |
| ensureNotClosed(); |
| |
| return timeout; |
| } |
| |
| /** {@inheritDoc} */ |
| @Override public void setQueryTimeout(int timeout) throws SQLException { |
| ensureNotClosed(); |
| |
| this.timeout = timeout * 1000; |
| } |
| |
| /** {@inheritDoc} */ |
| @Override public void cancel() throws SQLException { |
| ensureNotClosed(); |
| |
| throw new SQLFeatureNotSupportedException("Cancellation is not supported."); |
| } |
| |
| /** {@inheritDoc} */ |
| @Override public SQLWarning getWarnings() throws SQLException { |
| ensureNotClosed(); |
| |
| return null; |
| } |
| |
| /** {@inheritDoc} */ |
| @Override public void clearWarnings() throws SQLException { |
| ensureNotClosed(); |
| } |
| |
| /** {@inheritDoc} */ |
| @Override public void setCursorName(String name) throws SQLException { |
| ensureNotClosed(); |
| |
| throw new SQLFeatureNotSupportedException("Updates are not supported."); |
| } |
| |
| /** {@inheritDoc} */ |
| @Override public boolean execute(String sql) throws SQLException { |
| ensureNotClosed(); |
| |
| rs = executeQuery(sql); |
| |
| return true; |
| } |
| |
| /** {@inheritDoc} */ |
| @Override public ResultSet getResultSet() throws SQLException { |
| ensureNotClosed(); |
| |
| ResultSet rs0 = rs; |
| |
| rs = null; |
| |
| return rs0; |
| } |
| |
| /** {@inheritDoc} */ |
| @Override public int getUpdateCount() throws SQLException { |
| ensureNotClosed(); |
| |
| return -1; |
| } |
| |
| /** {@inheritDoc} */ |
| @Override public boolean getMoreResults() throws SQLException { |
| ensureNotClosed(); |
| |
| return false; |
| } |
| |
| /** {@inheritDoc} */ |
| @Override public void setFetchDirection(int direction) throws SQLException { |
| ensureNotClosed(); |
| |
| if (direction != FETCH_FORWARD) |
| throw new SQLFeatureNotSupportedException("Only forward direction is supported"); |
| } |
| |
| /** {@inheritDoc} */ |
| @Override public int getFetchDirection() throws SQLException { |
| ensureNotClosed(); |
| |
| return FETCH_FORWARD; |
| } |
| |
| /** {@inheritDoc} */ |
| @Override public void setFetchSize(int fetchSize) throws SQLException { |
| ensureNotClosed(); |
| |
| if (fetchSize <= 0) |
| throw new SQLException("Fetch size must be greater than zero."); |
| |
| this.fetchSize = fetchSize; |
| } |
| |
| /** {@inheritDoc} */ |
| @Override public int getFetchSize() throws SQLException { |
| ensureNotClosed(); |
| |
| return fetchSize; |
| } |
| |
| /** {@inheritDoc} */ |
| @Override public int getResultSetConcurrency() throws SQLException { |
| ensureNotClosed(); |
| |
| return CONCUR_READ_ONLY; |
| } |
| |
| /** {@inheritDoc} */ |
| @Override public int getResultSetType() throws SQLException { |
| ensureNotClosed(); |
| |
| return TYPE_FORWARD_ONLY; |
| } |
| |
| /** {@inheritDoc} */ |
| @Override public void addBatch(String sql) throws SQLException { |
| ensureNotClosed(); |
| |
| throw new SQLFeatureNotSupportedException("Updates are not supported."); |
| } |
| |
| /** {@inheritDoc} */ |
| @Override public void clearBatch() throws SQLException { |
| ensureNotClosed(); |
| |
| throw new SQLFeatureNotSupportedException("Updates are not supported."); |
| } |
| |
| /** {@inheritDoc} */ |
| @Override public int[] executeBatch() throws SQLException { |
| ensureNotClosed(); |
| |
| throw new SQLFeatureNotSupportedException("Updates are not supported."); |
| } |
| |
| /** {@inheritDoc} */ |
| @Override public Connection getConnection() throws SQLException { |
| ensureNotClosed(); |
| |
| return conn; |
| } |
| |
| /** {@inheritDoc} */ |
| @Override public boolean getMoreResults(int curr) throws SQLException { |
| ensureNotClosed(); |
| |
| if (curr == KEEP_CURRENT_RESULT || curr == CLOSE_ALL_RESULTS) |
| throw new SQLFeatureNotSupportedException("Multiple open results are not supported."); |
| |
| return false; |
| } |
| |
| /** {@inheritDoc} */ |
| @Override public ResultSet getGeneratedKeys() throws SQLException { |
| ensureNotClosed(); |
| |
| throw new SQLFeatureNotSupportedException("Updates are not supported."); |
| } |
| |
| /** {@inheritDoc} */ |
| @Override public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException { |
| ensureNotClosed(); |
| |
| throw new SQLFeatureNotSupportedException("Updates are not supported."); |
| } |
| |
| /** {@inheritDoc} */ |
| @Override public int executeUpdate(String sql, int[] colIndexes) throws SQLException { |
| ensureNotClosed(); |
| |
| throw new SQLFeatureNotSupportedException("Updates are not supported."); |
| } |
| |
| /** {@inheritDoc} */ |
| @Override public int executeUpdate(String sql, String[] colNames) throws SQLException { |
| ensureNotClosed(); |
| |
| throw new SQLFeatureNotSupportedException("Updates are not supported."); |
| } |
| |
| /** {@inheritDoc} */ |
| @Override public boolean execute(String sql, int autoGeneratedKeys) throws SQLException { |
| ensureNotClosed(); |
| |
| if (autoGeneratedKeys == RETURN_GENERATED_KEYS) |
| throw new SQLFeatureNotSupportedException("Updates are not supported."); |
| |
| return execute(sql); |
| } |
| |
| /** {@inheritDoc} */ |
| @Override public boolean execute(String sql, int[] colIndexes) throws SQLException { |
| ensureNotClosed(); |
| |
| if (colIndexes != null && colIndexes.length > 0) |
| throw new SQLFeatureNotSupportedException("Updates are not supported."); |
| |
| return execute(sql); |
| } |
| |
| /** {@inheritDoc} */ |
| @Override public boolean execute(String sql, String[] colNames) throws SQLException { |
| ensureNotClosed(); |
| |
| if (colNames != null && colNames.length > 0) |
| throw new SQLFeatureNotSupportedException("Updates are not supported."); |
| |
| return execute(sql); |
| } |
| |
| /** {@inheritDoc} */ |
| @Override public int getResultSetHoldability() throws SQLException { |
| ensureNotClosed(); |
| |
| return HOLD_CURSORS_OVER_COMMIT; |
| } |
| |
| /** {@inheritDoc} */ |
| @Override public boolean isClosed() throws SQLException { |
| return closed; |
| } |
| |
| /** {@inheritDoc} */ |
| @Override public void setPoolable(boolean poolable) throws SQLException { |
| ensureNotClosed(); |
| |
| if (poolable) |
| throw new SQLFeatureNotSupportedException("Pooling is not supported."); |
| } |
| |
| /** {@inheritDoc} */ |
| @Override public boolean isPoolable() throws SQLException { |
| ensureNotClosed(); |
| |
| return false; |
| } |
| |
| /** {@inheritDoc} */ |
| @Override public <T> T unwrap(Class<T> iface) throws SQLException { |
| if (!isWrapperFor(iface)) |
| throw new SQLException("Statement is not a wrapper for " + iface.getName()); |
| |
| return (T)this; |
| } |
| |
| /** {@inheritDoc} */ |
| @Override public boolean isWrapperFor(Class<?> iface) throws SQLException { |
| return iface != null && iface == Statement.class; |
| } |
| |
| /** {@inheritDoc} */ |
| @Override public void closeOnCompletion() throws SQLException { |
| throw new SQLFeatureNotSupportedException("closeOnCompletion is not supported."); |
| } |
| |
| /** {@inheritDoc} */ |
| @Override public boolean isCloseOnCompletion() throws SQLException { |
| ensureNotClosed(); |
| |
| return false; |
| } |
| |
| /** |
| * Sets timeout in milliseconds. |
| * |
| * @param timeout Timeout. |
| */ |
| void timeout(int timeout) { |
| this.timeout = timeout; |
| } |
| |
| /** |
| * @return Connection. |
| */ |
| JdbcConnection connection() { |
| return conn; |
| } |
| |
| /** |
| * Ensures that statement is not closed. |
| * |
| * @throws SQLException If statement is closed. |
| */ |
| protected void ensureNotClosed() throws SQLException { |
| if (closed) |
| throw new SQLException("Statement is closed."); |
| } |
| } |