/* * Copyright 2014-2015 the original author or authors * * Licensed 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 com.wplatform.ddal.excutor; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.List; import java.util.concurrent.Callable; import javax.sql.DataSource; import com.wplatform.ddal.engine.Session; import com.wplatform.ddal.message.DbException; import com.wplatform.ddal.message.ErrorCode; import com.wplatform.ddal.message.Trace; import com.wplatform.ddal.shards.DataSourceRepository; import com.wplatform.ddal.util.JdbcUtils; import com.wplatform.ddal.value.Value; /** * @author <a href="mailto:jorgie.mail@gmail.com">jorgie li</a> * */ public abstract class JdbcWorker<T> implements Callable<T> { protected final Session session; protected final Trace trace; protected final String shardName; protected final String sql; protected final List<Value> params; private Connection rtConn; private Statement rtStmt; private ResultSet rtRs; public JdbcWorker(Session session, String shardName, String sql, List<Value> params) { super(); this.session = session; this.shardName = shardName; this.sql = sql; this.params = params; this.trace = session.getDatabase().getTrace(Trace.EXECUTOR); } public abstract T doWork(); public T call() throws Exception { return doWork(); } public void attach(Connection conn) { if(this.rtConn != null) { throw new IllegalStateException(); } this.rtConn = conn; } public void attach(Statement stmt) { if(this.rtStmt != null) { throw new IllegalStateException(); } this.rtStmt = stmt; } public void attach(ResultSet rs) { if(this.rtRs != null) { throw new IllegalStateException(); } this.rtRs = rs; } /** * @return the rtConn */ public Connection getRuntimeConnection() { return rtConn; } /** * @return the rtStmt */ public Statement getRuntimeStatement() { return rtStmt; } /** * @return the rtRs */ public ResultSet getRuntimeResultSet() { return rtRs; } /** * @return the shardName */ public String getShardName() { return shardName; } /** * @return the sql */ public String getSql() { return sql; } /** * @return the params */ public List<Value> getParams() { return params; } public void cancel() { try { if(rtStmt == null) { return; } rtStmt.cancel(); } catch (Exception e) { } } public void closeResource() { JdbcUtils.closeSilently(rtRs); JdbcUtils.closeSilently(rtStmt); JdbcUtils.closeSilently(rtConn); } protected void applyQueryTimeout(Statement stmt) throws SQLException { //The session timeout of a query in milliseconds int queryTimeout = session.getQueryTimeout(); if(queryTimeout > 0) { int seconds = queryTimeout / 1000; trace.debug("apply {0} query time out from statement.", seconds); stmt.setQueryTimeout(seconds); } } protected DataSource getDataSource() { DataSourceRepository dataSourceRepository = session.getDataSourceRepository(); DataSource dataSource = dataSourceRepository.getDataSourceByShardName(shardName); return dataSource; } /** * Wrap a SQL exception that occurred while accessing a linked table. * * @param sql the SQL statement * @param ex the exception from the remote database * @return the wrapped exception */ protected static DbException wrapException(String sql, Exception ex) { SQLException e = DbException.toSQLException(ex); return DbException.get(ErrorCode.ERROR_ACCESSING_DATABASE_TABLE_2, e, sql, e.toString()); } }