All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cubrid.jdbc.jci.UConnection Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (C) 2008 Search Solution Corporation. All rights reserved by Search Solution.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * - Redistributions of source code must retain the above copyright notice,
 *   this list of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above copyright notice,
 *   this list of conditions and the following disclaimer in the documentation
 *   and/or other materials provided with the distribution.
 *
 * - Neither the name of the  nor the names of its contributors
 *   may be used to endorse or promote products derived from this software without
 *   specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
 * OF SUCH DAMAGE.
 *
 */

/**
 * Title:        CUBRID Java Client Interface

* Description: CUBRID Java Client Interface

* @version 2.0 */ package cubrid.jdbc.jci; import java.io.DataOutputStream; import java.io.IOException; import java.io.OutputStream; import java.net.Socket; import java.net.SocketTimeoutException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.StringTokenizer; import java.util.Vector; import javax.transaction.xa.Xid; import cubrid.jdbc.driver.CUBRIDConnection; import cubrid.jdbc.driver.CUBRIDDriver; import cubrid.jdbc.driver.CUBRIDException; import cubrid.jdbc.driver.CUBRIDJDBCErrorCode; import cubrid.jdbc.driver.CUBRIDJdbcInfoTable; import cubrid.jdbc.driver.CUBRIDXid; import cubrid.jdbc.driver.ConnectionProperties; import cubrid.jdbc.log.BasicLogger; import cubrid.jdbc.log.Log; import cubrid.jdbc.net.BrokerHandler; import cubrid.sql.CUBRIDOID; public class UConnection { public final static byte DBMS_CUBRID = 1; public final static byte DBMS_MYSQL = 2; public final static byte DBMS_ORACLE = 3; public final static byte DBMS_PROXY_CUBRID = 4; public final static byte DBMS_PROXY_MYSQL = 5; public final static byte DBMS_PROXY_ORACLE = 6; /* prepare flags */ public final static byte PREPARE_INCLUDE_OID = 0x01; public final static byte PREPARE_UPDATABLE = 0x02; public final static byte PREPARE_QUERY_INFO = 0x04; public final static byte PREPARE_HOLDABLE = 0x08; public final static byte PREPARE_XASL_CACHE_PINNED = 0x10; public final static byte PREPARE_CALL = 0x40; public final static byte DROP_BY_OID = 1, IS_INSTANCE = 2, GET_READ_LOCK_BY_OID = 3, GET_WRITE_LOCK_BY_OID = 4, GET_CLASS_NAME_BY_OID = 5; public final static int OID_BYTE_SIZE = 8; // this value is defined in broker/cas_protocol.h private final static String magicString = "CUBRK"; private final static byte CAS_CLIENT_JDBC = 3; public static final int PROTOCOL_V0 = 0; public static final int PROTOCOL_V1 = 1; public static final int PROTOCOL_V2 = 2; public static final int PROTOCOL_V3 = 3; public static final int PROTOCOL_V4 = 4; public static final int PROTOCOL_V5 = 5; public static final int PROTOCOL_V6 = 6; public static final int PROTOCOL_V7 = 7; /* Current protocol version */ private final static byte CAS_PROTOCOL_VERSION = PROTOCOL_V7; private final static byte CAS_PROTO_INDICATOR = 0x40; private final static byte CAS_PROTO_VER_MASK = 0x3F; private final static byte CAS_RENEWED_ERROR_CODE = (byte) 0x80; private final static byte CAS_SUPPORT_HOLDABLE_RESULT = (byte) 0x40; /* Do not remove and rename CAS_RECONNECT_WHEN_SERVER_DOWN */ private final static byte CAS_RECONNECT_WHEN_SERVER_DOWN = (byte) 0x20; @SuppressWarnings("unused") private final static byte GET_COLLECTION_VALUE = 1, GET_SIZE_OF_COLLECTION = 2, DROP_ELEMENT_IN_SET = 3, ADD_ELEMENT_TO_SET = 4, DROP_ELEMENT_IN_SEQUENCE = 5, INSERT_ELEMENT_INTO_SEQUENCE = 6, PUT_ELEMENT_ON_SEQUENCE = 7; @SuppressWarnings("unused") private final static int DB_PARAM_ISOLATION_LEVEL = 1, DB_PARAM_LOCK_TIMEOUT = 2, DB_PARAM_AUTO_COMMIT = 4; /* end_tran constants */ private final static byte END_TRAN_COMMIT = 1; private final static byte END_TRAN_ROLLBACK = 2; private final static int LOCK_TIMEOUT_NOT_USED = -2; private final static int LOCK_TIMEOUT_INFINITE = -1; private final static int SOCKET_TIMEOUT = 5000; /* driver version */ private final static int DRIVER_VERSION_MAX_SIZE = 20; /* casinfo */ private final static byte CAS_INFO_STATUS_INACTIVE = 0; private final static byte CAS_INFO_STATUS_ACTIVE = 1; private final static int CAS_INFO_SIZE = 4; /* casinfo field def */ private final static int CAS_INFO_STATUS = 0; private final static int CAS_INFO_RESERVED_1 = 1; private final static int CAS_INFO_RESERVED_2 = 2; private final static int CAS_INFO_ADDITIONAL_FLAG = 3; private final static byte CAS_INFO_FLAG_MASK_AUTOCOMMIT = 0x01; private final static byte CAS_INFO_FLAG_MASK_FORCE_OUT_TRAN = 0x02; private final static byte CAS_INFO_FLAG_MASK_NEW_SESSION_ID = 0x04; private final static int BROKER_INFO_SIZE = 8; private final static int BROKER_INFO_DBMS_TYPE = 0; private final static int BROKER_INFO_RESERVED4 = 1; private final static int BROKER_INFO_STATEMENT_POOLING = 2; private final static int BROKER_INFO_CCI_PCONNECT = 3; private final static int BROKER_INFO_PROTO_VERSION = 4; private final static int BROKER_INFO_FUNCTION_FLAG = 5; private final static int BROKER_INFO_RESERVED2 = 6; private final static int BROKER_INFO_RESERVED3 = 7; /* For backward compatibility */ private final static int BROKER_INFO_MAJOR_VERSION = BROKER_INFO_PROTO_VERSION; private final static int BROKER_INFO_MINOR_VERSION = BROKER_INFO_FUNCTION_FLAG; private final static int BROKER_INFO_PATCH_VERSION = BROKER_INFO_RESERVED2; public static final String ZERO_DATETIME_BEHAVIOR_CONVERT_TO_NULL = "convertToNull"; public static final String ZERO_DATETIME_BEHAVIOR_EXCEPTION = "exception"; public static final String ZERO_DATETIME_BEHAVIOR_ROUND = "round"; public static final String RESULT_WITH_CUBRID_TYPES_YES = "yes"; public static final String RESULT_WITH_CUBRID_TYPES_NO = "no"; public final static int SESSION_ID_SIZE = 20; public final static int MAX_QUERY_TIMEOUT = 2000000; public final static int MAX_CONNECT_TIMEOUT = 2000000; UOutputBuffer outBuffer; CUBRIDConnection cubridcon; boolean update_executed; /* for result cache */ private boolean needReconnection; private UTimedDataInputStream input; private DataOutputStream output; public String CASIp = ""; public int CASPort; public int processId; public int casId; private Socket client; private UError errorHandler; private boolean isClosed = false; private byte[] dbInfo; private int lastIsolationLevel; private int lastLockTimeout = LOCK_TIMEOUT_NOT_USED; private boolean lastAutoCommit = true; String dbname = ""; String user = ""; String passwd = ""; String url = null; private ArrayList altHosts = null; private int connectedHostId = 0; // jci 3.0 private byte[] broker_info = null; private byte[] casinfo = null; private int brokerVersion = 0; private boolean isServerSideJdbc = false; boolean skip_checkcas = false; Vector pooled_ustmts; Vector deferred_close_handle; Object curThread; private UUrlCache url_cache = null; private boolean isAutoCommitBySelf = false; public static byte[] driverInfo; private ConnectionProperties connectionProperties = new ConnectionProperties(); private long lastFailureTime = 0; byte sessionId[] = createNullSession(); int oldSessionId = 0; private Log log; private long beginTime; static { driverInfo = new byte[10]; UJCIUtil.copy_bytes(driverInfo, 0, 5, magicString); driverInfo[5] = CAS_CLIENT_JDBC; driverInfo[6] = CAS_PROTO_INDICATOR | CAS_PROTOCOL_VERSION; driverInfo[7] = CAS_RENEWED_ERROR_CODE | CAS_SUPPORT_HOLDABLE_RESULT; driverInfo[8] = 0; // reserved driverInfo[9] = 0; // reserved } private int lastShardId = UShardInfo.SHARD_ID_INVALID; private int numShard = 0; UShardInfo[] shardInfo = null; /* * the normal constructor of the class UConnection */ UConnection(String ip, int port, String dbname, String user, String passwd, String url) throws CUBRIDException { if (ip != null) { CASIp = ip; } CASPort = port; if (dbname != null) { this.dbname = dbname; } if (user != null) { this.user = user; } if (passwd != null) { this.passwd = passwd; } this.url = url; update_executed = false; needReconnection = true; errorHandler = new UError(this); } UConnection(ArrayList altHostList, String dbname, String user, String passwd, String url) throws CUBRIDException { setAltHosts(altHostList); if (dbname != null) { this.dbname = dbname; } if (user != null) { this.user = user; } if (passwd != null) { this.passwd = passwd; } this.url = url; update_executed = false; needReconnection = true; errorHandler = new UError(this); } // This constructor is called on the server side. UConnection(Socket socket, Object curThread) throws CUBRIDException { errorHandler = new UError(this); try { client = socket; client.setTcpNoDelay(true); output = new DataOutputStream(client.getOutputStream()); output.writeInt(0x08); output.flush(); input = new UTimedDataInputStream(client.getInputStream(), CASIp, CASPort); needReconnection = false; casinfo = new byte[CAS_INFO_SIZE]; casinfo[CAS_INFO_STATUS] = CAS_INFO_STATUS_ACTIVE; casinfo[CAS_INFO_RESERVED_1] = 0; casinfo[CAS_INFO_RESERVED_2] = 0; casinfo[CAS_INFO_ADDITIONAL_FLAG] = 0; /* create default broker info */ broker_info = new byte[BROKER_INFO_SIZE]; broker_info[BROKER_INFO_DBMS_TYPE] = DBMS_CUBRID; broker_info[BROKER_INFO_RESERVED4] = 0; broker_info[BROKER_INFO_STATEMENT_POOLING] = 1; broker_info[BROKER_INFO_CCI_PCONNECT] = 0; broker_info[BROKER_INFO_PROTO_VERSION] = CAS_PROTO_INDICATOR | CAS_PROTOCOL_VERSION; broker_info[BROKER_INFO_FUNCTION_FLAG] = CAS_RENEWED_ERROR_CODE | CAS_SUPPORT_HOLDABLE_RESULT; broker_info[BROKER_INFO_RESERVED2] = 0; broker_info[BROKER_INFO_RESERVED3] = 0; brokerVersion = makeProtoVersion(CAS_PROTOCOL_VERSION); isServerSideJdbc = true; lastAutoCommit = false; this.curThread = curThread; UJCIUtil.invoke("com.cubrid.jsp.ExecuteThread", "setCharSet", new Class[] { String.class }, this.curThread, new Object[] { connectionProperties.getCharSet() }); } catch (IOException e) { UJciException je = new UJciException(UErrorCode.ER_CONNECTION); je.toUError(errorHandler); throw new CUBRIDException(errorHandler, e); } } public void tryConnect() throws CUBRIDException { initLogger(); try { if (connectionProperties.getUseLazyConnection()) { needReconnection = true; return; } setBeginTime(); checkReconnect(); endTransaction(true); } catch (UJciException e) { clientSocketClose(); e.toUError(errorHandler); throw new CUBRIDException(errorHandler, e); } catch (IOException e) { clientSocketClose(); if (e instanceof SocketTimeoutException) { throw new CUBRIDException(CUBRIDJDBCErrorCode.request_timeout, e); } throw new CUBRIDException(CUBRIDJDBCErrorCode.ioexception_in_stream, e); } } public void setAltHosts(ArrayList altHostList) throws CUBRIDException { if (altHostList.size() < 1) { throw new CUBRIDException(UErrorCode.ER_INVALID_ARGUMENT); } this.altHosts = altHostList; String hostPort = altHosts.get(0); int pos = hostPort.indexOf(':'); if (pos < 0) { CASIp = hostPort.substring(0); } else { CASIp = hostPort.substring(0, pos); } if (pos > 0) { CASPort = Integer.valueOf(hostPort.substring(pos + 1)).intValue(); } else { CASPort = CUBRIDDriver.default_port; } } public int getQueryTimeout() { return connectionProperties.getQueryTimeout(); } public void setCharset(String newCharsetName) { if (UJCIUtil.isServerSide() && isServerSideJdbc) { UJCIUtil.invoke("com.cubrid.jsp.ExecuteThread", "setCharSet", new Class[] { String.class }, this.curThread, new Object[] { newCharsetName }); } } public String getCharset() { return connectionProperties.getCharSet(); } public void setZeroDateTimeBehavior(String behavior) throws CUBRIDException { if (UJCIUtil.isServerSide() && isServerSideJdbc) { UJCIUtil.invoke("com.cubrid.jsp.ExecuteThread", "setZeroDateTimeBehavior", new Class[] { String.class }, this.curThread, new Object[] { behavior }); } } public void setResultWithCUBRIDTypes(String support) throws CUBRIDException { if (UJCIUtil.isServerSide() && isServerSideJdbc) { UJCIUtil.invoke("com.cubrid.jsp.ExecuteThread", "setResultWithCUBRIDTypes", new Class[] { String.class }, this.curThread, new Object[] { support }); } } public String getZeroDateTimeBehavior() { return connectionProperties.getZeroDateTimeBehavior(); } public String getResultWithCUBRIDTypes() { return connectionProperties.getResultWithCUBRIDTypes(); } public boolean getLogSlowQuery() { return connectionProperties.getLogSlowQueries(); } public boolean getUseOldBooleanValue() { return connectionProperties.getUseOldBooleanValue(); } synchronized public void addElementToSet(CUBRIDOID oid, String attributeName, Object value) { errorHandler = new UError(this); if (isClosed == true) { errorHandler.setErrorCode(UErrorCode.ER_IS_CLOSED); return; } try { manageElementOfSet(oid, attributeName, value, UConnection.ADD_ELEMENT_TO_SET); } catch (UJciException e) { logException(e); e.toUError(errorHandler); return; } catch (IOException e) { logException(e); errorHandler.setErrorCode(UErrorCode.ER_COMMUNICATION); return; } } synchronized public UBatchResult batchExecute(String batchSqlStmt[], int queryTimeout) { errorHandler = new UError(this); setShardId(UShardInfo.SHARD_ID_INVALID); if (isClosed == true) { errorHandler.setErrorCode(UErrorCode.ER_IS_CLOSED); return null; } if (batchSqlStmt == null) { errorHandler.setErrorCode(UErrorCode.ER_INVALID_ARGUMENT); return null; } try { checkReconnect(); if (errorHandler.getErrorCode() != UErrorCode.ER_NO_ERROR) return null; outBuffer.newRequest(output, UFunctionCode.EXECUTE_BATCH_STATEMENT); outBuffer.addByte(getAutoCommit() ? (byte) 1 : (byte) 0); if (protoVersionIsAbove(UConnection.PROTOCOL_V4)) { long remainingTime = getRemainingTime(queryTimeout * 1000); if (queryTimeout > 0 && remainingTime <= 0) { throw createJciException(UErrorCode.ER_TIMEOUT); } outBuffer.addInt((int) remainingTime); } for (int i = 0; i < batchSqlStmt.length; i++) { if (batchSqlStmt[i] != null) outBuffer.addStringWithNull(batchSqlStmt[i]); else outBuffer.addNull(); } UInputBuffer inBuffer; inBuffer = send_recv_msg(); int result; UBatchResult batchResult = new UBatchResult(inBuffer.readInt()); for (int i = 0; i < batchResult.getResultNumber(); i++) { batchResult.setStatementType(i, inBuffer.readByte()); result = inBuffer.readInt(); if (result < 0) { int err_code = inBuffer.readInt(); batchResult.setResultError(i, err_code, inBuffer.readString( inBuffer.readInt(), UJCIManager.sysCharsetName)); } else { batchResult.setResult(i, result); // jci 3.0 inBuffer.readInt(); inBuffer.readShort(); inBuffer.readShort(); } } if (protoVersionIsAbove(UConnection.PROTOCOL_V5)) { setShardId(inBuffer.readInt()); } update_executed = true; return batchResult; } catch (UJciException e) { logException(e); e.toUError(errorHandler); } catch (IOException e) { logException(e); errorHandler.setErrorCode(UErrorCode.ER_COMMUNICATION); } return null; } synchronized public void close() { errorHandler = new UError(this); if (isClosed == true) { errorHandler.setErrorCode(UErrorCode.ER_IS_CLOSED); return; } // jci 3.0 if (client != null) { disconnect(); } /* * jci 2.x if (transactionList != null && transactionList.size() > 0) * endTransaction(false); */ if (!isServerSideJdbc) { if (client != null) { clientSocketClose(); } } // System.gc(); // UJCIManager.deleteInList(this); isClosed = true; } synchronized public void dropElementInSequence(CUBRIDOID oid, String attributeName, int index) { errorHandler = new UError(this); if (isClosed == true) { errorHandler.setErrorCode(UErrorCode.ER_IS_CLOSED); return; } try { setBeginTime(); checkReconnect(); if (errorHandler.getErrorCode() != UErrorCode.ER_NO_ERROR) return; outBuffer.newRequest(output, UFunctionCode.RELATED_TO_COLLECTION); outBuffer.addByte(UConnection.DROP_ELEMENT_IN_SEQUENCE); outBuffer.addOID(oid); outBuffer.addInt(index); if (attributeName == null) outBuffer.addNull(); else outBuffer.addStringWithNull(attributeName); send_recv_msg(); } catch (UJciException e) { logException(e); e.toUError(errorHandler); } catch (IOException e) { logException(e); errorHandler.setErrorCode(UErrorCode.ER_COMMUNICATION); } } synchronized public void dropElementInSet(CUBRIDOID oid, String attributeName, Object value) { errorHandler = new UError(this); if (isClosed == true) { errorHandler.setErrorCode(UErrorCode.ER_IS_CLOSED); return; } try { manageElementOfSet(oid, attributeName, value, UConnection.DROP_ELEMENT_IN_SET); } catch (UJciException e) { logException(e); e.toUError(errorHandler); return; } catch (IOException e) { logException(e); errorHandler.setErrorCode(UErrorCode.ER_COMMUNICATION); return; } } synchronized public void endTransaction(boolean type) { errorHandler = new UError(this); if (isClosed == true) { errorHandler.setErrorCode(UErrorCode.ER_IS_CLOSED); return; } if (needReconnection == true) return; try { if (client != null && getCASInfoStatus() != CAS_INFO_STATUS_INACTIVE) { setBeginTime(); checkReconnect(); if (errorHandler.getErrorCode() != UErrorCode.ER_NO_ERROR) return; if (getCASInfoStatus() == CAS_INFO_STATUS_ACTIVE) { if (UJCIUtil.isConsoleDebug()) { if (!lastAutoCommit || isAutoCommitBySelf || type == false) { // this is ok; } else { // we need check throw new Exception("Check It Out!"); } } outBuffer.newRequest(output, UFunctionCode.END_TRANSACTION); outBuffer.addByte((type == true) ? END_TRAN_COMMIT : END_TRAN_ROLLBACK); send_recv_msg(); if (lastAutoCommit) { turnOffAutoCommitBySelf(); } } } } catch (UJciException e) { logException(e); e.toUError(errorHandler); } catch (IOException e) { logException(e); errorHandler.setErrorCode(UErrorCode.ER_COMMUNICATION); } catch (Exception e) { logException(e); errorHandler.setErrorMessage(UErrorCode.ER_UNKNOWN, e.getMessage()); } /* * if (transactionList == null || transactionList.size() == 0) * errorHandler.clear(); */ boolean keepConnection = true; long currentTime = System.currentTimeMillis() / 1000; int reconnectTime = connectionProperties.getReconnectTime(); UUnreachableHostList unreachableHosts = UUnreachableHostList.getInstance(); if (connectedHostId > 0 && lastFailureTime != 0 && reconnectTime > 0 && currentTime - lastFailureTime > reconnectTime) { if (!unreachableHosts.contains(altHosts.get(0))) { keepConnection = false; lastFailureTime = 0; } } if (errorHandler.getErrorCode() != UErrorCode.ER_NO_ERROR || keepConnection == false) // jci 3.0 { if (type == false) { errorHandler.clear(); } clientSocketClose(); needReconnection = true; } casinfo[CAS_INFO_STATUS] = CAS_INFO_STATUS_INACTIVE; update_executed = false; } synchronized public OutputStream getOutputStream() { return output; } synchronized public UStatement getByOID(CUBRIDOID oid, String[] attributeName) { UStatement returnValue = null; errorHandler = new UError(this); if (isClosed == true) { errorHandler.setErrorCode(UErrorCode.ER_IS_CLOSED); return null; } try { setBeginTime(); checkReconnect(); if (errorHandler.getErrorCode() != UErrorCode.ER_NO_ERROR) return null; outBuffer.newRequest(output, UFunctionCode.GET_BY_OID); outBuffer.addOID(oid); for (int i = 0; attributeName != null && i < attributeName.length; i++) { if (attributeName[i] != null) outBuffer.addStringWithNull(attributeName[i]); else outBuffer.addNull(); } UInputBuffer inBuffer; inBuffer = send_recv_msg(); returnValue = new UStatement(this, oid, attributeName, inBuffer); } catch (UJciException e) { logException(e); e.toUError(errorHandler); return null; } catch (IOException e) { logException(e); errorHandler.setErrorCode(UErrorCode.ER_COMMUNICATION); return null; } if (returnValue.getRecentError().getErrorCode() != UErrorCode.ER_NO_ERROR) { errorHandler.copyValue(returnValue.getRecentError()); return null; } return returnValue; } synchronized public String getDatabaseProductVersion() { errorHandler = new UError(this); if (isClosed == true) { errorHandler.setErrorCode(UErrorCode.ER_IS_CLOSED); return null; } try { setBeginTime(); checkReconnect(); if (errorHandler.getErrorCode() != UErrorCode.ER_NO_ERROR) return null; outBuffer.newRequest(output, UFunctionCode.GET_DB_VERSION); outBuffer.addByte(getAutoCommit() ? (byte) 1 : (byte) 0); UInputBuffer inBuffer; inBuffer = send_recv_msg(); return inBuffer.readString(inBuffer.remainedCapacity(), UJCIManager.sysCharsetName); } catch (UJciException e) { logException(e); e.toUError(errorHandler); } catch (IOException e) { logException(e); errorHandler.setErrorCode(UErrorCode.ER_COMMUNICATION); } return null; } synchronized public int getIsolationLevel() { errorHandler = new UError(this); if (lastIsolationLevel != CUBRIDIsolationLevel.TRAN_UNKNOWN_ISOLATION) { return lastIsolationLevel; } if (isClosed == true) { errorHandler.setErrorCode(UErrorCode.ER_IS_CLOSED); return CUBRIDIsolationLevel.TRAN_UNKNOWN_ISOLATION; } try { setBeginTime(); checkReconnect(); if (errorHandler.getErrorCode() != UErrorCode.ER_NO_ERROR) return CUBRIDIsolationLevel.TRAN_UNKNOWN_ISOLATION; outBuffer.newRequest(output, UFunctionCode.GET_DB_PARAMETER); outBuffer.addInt(DB_PARAM_ISOLATION_LEVEL); UInputBuffer inBuffer; inBuffer = send_recv_msg(); lastIsolationLevel = inBuffer.readInt(); return lastIsolationLevel; } catch (UJciException e) { logException(e); e.toUError(errorHandler); } catch (IOException e) { logException(e); errorHandler.setErrorCode(UErrorCode.ER_COMMUNICATION); } return CUBRIDIsolationLevel.TRAN_UNKNOWN_ISOLATION; } public UError getRecentError() { return errorHandler; } synchronized public String getQueryplanOnly(String sql) { String ret_val; if (sql == null) return null; errorHandler = new UError(this); if (isClosed == true) { errorHandler.setErrorCode(UErrorCode.ER_IS_CLOSED); return null; } try { setBeginTime(); checkReconnect(); outBuffer.newRequest(UFunctionCode.GET_QUERY_INFO); outBuffer.addInt(0); outBuffer.addByte(UStatement.QUERY_INFO_PLAN); outBuffer.addStringWithNull(sql); UInputBuffer inBuffer; inBuffer = send_recv_msg(); ret_val = inBuffer.readString(inBuffer.remainedCapacity(), connectionProperties.getCharSet()); } catch (UJciException e) { logException(e); e.toUError(errorHandler); return null; } catch (IOException e) { logException(e); if (errorHandler.getErrorCode() != UErrorCode.ER_CONNECTION) errorHandler.setErrorCode(UErrorCode.ER_COMMUNICATION); return null; } if (errorHandler.getErrorCode() != UErrorCode.ER_NO_ERROR) { return null; } return ret_val; } synchronized public UStatement getSchemaInfo(int type, String arg1, String arg2, byte flag, int shard_id) { UStatement returnValue = null; errorHandler = new UError(this); if (isClosed == true) { errorHandler.setErrorCode(UErrorCode.ER_IS_CLOSED); return null; } if (type < USchType.SCH_MIN || type > USchType.SCH_MAX) { errorHandler.setErrorCode(UErrorCode.ER_SCHEMA_TYPE); return null; } if (flag < 0 || flag > 3) { errorHandler.setErrorCode(UErrorCode.ER_ILLEGAL_FLAG); return null; } try { setBeginTime(); checkReconnect(); if (errorHandler.getErrorCode() != UErrorCode.ER_NO_ERROR) return null; outBuffer.newRequest(output, UFunctionCode.GET_SCHEMA_INFO); outBuffer.addInt(type); if (arg1 == null) outBuffer.addNull(); else outBuffer.addStringWithNull(arg1); if (arg2 == null) outBuffer.addNull(); else outBuffer.addStringWithNull(arg2); outBuffer.addByte(flag); if (protoVersionIsAbove(PROTOCOL_V5)) { outBuffer.addInt(shard_id); } UInputBuffer inBuffer; inBuffer = send_recv_msg(); returnValue = new UStatement(this, arg1, arg2, type, inBuffer); } catch (UJciException e) { logException(e); e.toUError(errorHandler); return null; } catch (IOException e) { logException(e); if (errorHandler.getErrorCode() != UErrorCode.ER_CONNECTION) errorHandler.setErrorCode(UErrorCode.ER_COMMUNICATION); return null; } if (returnValue.getRecentError().getErrorCode() != UErrorCode.ER_NO_ERROR) { errorHandler.copyValue(returnValue.getRecentError()); return null; } // transactionList.add(returnValue); return returnValue; } synchronized public int getSizeOfCollection(CUBRIDOID oid, String attributeName) { errorHandler = new UError(this); if (isClosed == true) { errorHandler.setErrorCode(UErrorCode.ER_IS_CLOSED); return 0; } try { setBeginTime(); checkReconnect(); if (errorHandler.getErrorCode() != UErrorCode.ER_NO_ERROR) return 0; outBuffer.newRequest(output, UFunctionCode.RELATED_TO_COLLECTION); outBuffer.addByte(UConnection.GET_SIZE_OF_COLLECTION); outBuffer.addOID(oid); if (attributeName == null) outBuffer.addNull(); else outBuffer.addStringWithNull(attributeName); UInputBuffer inBuffer; inBuffer = send_recv_msg(); return inBuffer.readInt(); } catch (UJciException e) { logException(e); e.toUError(errorHandler); } catch (IOException e) { logException(e); errorHandler.setErrorCode(UErrorCode.ER_COMMUNICATION); } return 0; } synchronized public void insertElementIntoSequence(CUBRIDOID oid, String attributeName, int index, Object value) { errorHandler = new UError(this); if (isClosed == true) { errorHandler.setErrorCode(UErrorCode.ER_IS_CLOSED); return; } try { manageElementOfSequence(oid, attributeName, index, value, UConnection.INSERT_ELEMENT_INTO_SEQUENCE); } catch (UJciException e) { logException(e); e.toUError(errorHandler); return; } catch (IOException e) { logException(e); if (errorHandler.getErrorCode() != UErrorCode.ER_CONNECTION) errorHandler.setErrorCode(UErrorCode.ER_COMMUNICATION); return; } } public boolean isClosed() { return isClosed; } public boolean isErrorCommunication (int error) { switch (error) { case UErrorCode.ER_COMMUNICATION: case UErrorCode.ER_ILLEGAL_DATA_SIZE: case UErrorCode.CAS_ER_COMMUNICATION: return true; default: return false; } } public boolean isErrorToReconnect(int error) { if (isErrorCommunication(error)) { return true; } switch (error) { case -111: // ER_TM_SERVER_DOWN_UNILATERALLY_ABORTED case -199: // ER_NET_SERVER_CRASHED case -224: // ER_OBJ_NO_CONNECT case -677: // ER_BO_CONNECT_FAILED return true; default: return false; } } private UStatement prepareInternal(String sql, byte flag, boolean recompile) throws IOException, UJciException { errorHandler.clear(); outBuffer.newRequest(output, UFunctionCode.PREPARE); outBuffer.addStringWithNull(sql); outBuffer.addByte(flag); outBuffer.addByte(getAutoCommit() ? (byte) 1 : (byte) 0); while (deferred_close_handle.isEmpty() != true) { Integer close_handle = (Integer) deferred_close_handle.remove(0); outBuffer.addInt(close_handle.intValue()); } UInputBuffer inBuffer = send_recv_msg(); UStatement stmt; if (recompile) { stmt = new UStatement(this, inBuffer, true, sql, flag); } else { stmt = new UStatement(this, inBuffer, false, sql, flag); } if (stmt.getRecentError().getErrorCode() != UErrorCode.ER_NO_ERROR) { errorHandler.copyValue(stmt.getRecentError()); return null; } pooled_ustmts.add(stmt); return stmt; } synchronized public UStatement prepare(String sql, byte flag) { return prepare(sql, flag, false); } synchronized public UStatement prepare(String sql, byte flag, boolean recompile) { errorHandler = new UError(this); if (isClosed) { errorHandler.setErrorCode(UErrorCode.ER_IS_CLOSED); return null; } UStatement stmt = null; boolean isFirstPrepareInTran = !isActive(); skip_checkcas = true; // first try { checkReconnect(); stmt = prepareInternal(sql, flag, recompile); return stmt; } catch (UJciException e) { logException(e); e.toUError(errorHandler); } catch (IOException e) { logException(e); errorHandler.setErrorCode(UErrorCode.ER_COMMUNICATION); errorHandler.setStackTrace(e.getStackTrace()); } finally { skip_checkcas = false; } if (isActive() && !isFirstPrepareInTran) { return null; } // second loop while (isErrorToReconnect(errorHandler.getJdbcErrorCode())) { if (!brokerInfoReconnectWhenServerDown() || isErrorCommunication (errorHandler.getJdbcErrorCode())) { clientSocketClose(); } try { errorHandler.clear(); checkReconnect(); if (errorHandler.getErrorCode() != UErrorCode.ER_NO_ERROR) { return null; } } catch (UJciException e) { logException(e); e.toUError(errorHandler); return null; } catch (IOException e) { logException(e); errorHandler.setErrorCode(UErrorCode.ER_COMMUNICATION); errorHandler.setStackTrace(e.getStackTrace()); return null; } try { stmt = prepareInternal(sql, flag, recompile); return stmt; } catch (UJciException e) { logException(e); e.toUError(errorHandler); } catch (IOException e) { logException(e); errorHandler.setErrorCode(UErrorCode.ER_COMMUNICATION); errorHandler.setStackTrace(e.getStackTrace()); } } return null; } synchronized public void putByOID(CUBRIDOID oid, String attributeName[], Object values[]) { errorHandler = new UError(this); if (isClosed == true) { errorHandler.setErrorCode(UErrorCode.ER_IS_CLOSED); return; } if (attributeName == null && values == null) { errorHandler.setErrorCode(UErrorCode.ER_INVALID_ARGUMENT); return; } try { UPutByOIDParameter putParameter = null; if (values != null) putParameter = new UPutByOIDParameter(attributeName, values); setBeginTime(); checkReconnect(); if (errorHandler.getErrorCode() != UErrorCode.ER_NO_ERROR) return; outBuffer.newRequest(output, UFunctionCode.PUT_BY_OID); outBuffer.addOID(oid); if (putParameter != null) putParameter.writeParameter(outBuffer); send_recv_msg(); if (getAutoCommit()) { turnOnAutoCommitBySelf(); } } catch (UJciException e) { logException(e); e.toUError(errorHandler); } catch (IOException e) { logException(e); errorHandler.setErrorCode(UErrorCode.ER_COMMUNICATION); } } synchronized public void putElementInSequence(CUBRIDOID oid, String attributeName, int index, Object value) { errorHandler = new UError(this); if (isClosed == true) { errorHandler.setErrorCode(UErrorCode.ER_IS_CLOSED); return; } try { manageElementOfSequence(oid, attributeName, index, value, UConnection.PUT_ELEMENT_ON_SEQUENCE); } catch (UJciException e) { logException(e); e.toUError(errorHandler); return; } catch (IOException e) { logException(e); if (errorHandler.getErrorCode() != UErrorCode.ER_CONNECTION) errorHandler.setErrorCode(UErrorCode.ER_COMMUNICATION); return; } } synchronized public void setIsolationLevel(int level) { errorHandler = new UError(this); if (lastIsolationLevel != CUBRIDIsolationLevel.TRAN_UNKNOWN_ISOLATION && lastIsolationLevel == level) { return; } if (isClosed == true) { errorHandler.setErrorCode(UErrorCode.ER_IS_CLOSED); return; } if (level < CUBRIDIsolationLevel.TRAN_MIN || level > CUBRIDIsolationLevel.TRAN_MAX) { errorHandler.setErrorCode(UErrorCode.ER_ISO_TYPE); return; } try { setBeginTime(); checkReconnect(); if (errorHandler.getErrorCode() != UErrorCode.ER_NO_ERROR) return; outBuffer.newRequest(output, UFunctionCode.SET_DB_PARAMETER); outBuffer.addInt(DB_PARAM_ISOLATION_LEVEL); outBuffer.addInt(level); send_recv_msg(); lastIsolationLevel = level; } catch (UJciException e) { logException(e); e.toUError(errorHandler); } catch (IOException e) { logException(e); errorHandler.setErrorCode(UErrorCode.ER_COMMUNICATION); } } synchronized public void setLockTimeout(int timeout) { errorHandler = new UError(this); if (lastLockTimeout != LOCK_TIMEOUT_NOT_USED && lastLockTimeout == timeout) { return; } if (isClosed == true) { errorHandler.setErrorCode(UErrorCode.ER_IS_CLOSED); return; } try { setBeginTime(); checkReconnect(); if (errorHandler.getErrorCode() != UErrorCode.ER_NO_ERROR) return; outBuffer.newRequest(output, UFunctionCode.SET_DB_PARAMETER); outBuffer.addInt(DB_PARAM_LOCK_TIMEOUT); outBuffer.addInt(timeout); send_recv_msg(); if (timeout < 0) lastLockTimeout = LOCK_TIMEOUT_INFINITE; else lastLockTimeout = timeout; } catch (UJciException e) { logException(e); e.toUError(errorHandler); } catch (IOException e) { logException(e); errorHandler.setErrorCode(UErrorCode.ER_COMMUNICATION); } } synchronized public int setCASChangeMode(int mode) { errorHandler = new UError(this); if (isClosed == true) { errorHandler.setErrorCode(UErrorCode.ER_IS_CLOSED); return errorHandler.getJdbcErrorCode(); } try { setBeginTime(); checkReconnect(); if (errorHandler.getErrorCode() != UErrorCode.ER_NO_ERROR) { return errorHandler.getJdbcErrorCode(); } outBuffer.newRequest(output, UFunctionCode.SET_CAS_CHANGE_MODE); outBuffer.addInt(mode); UInputBuffer inBuffer; inBuffer = send_recv_msg(); return inBuffer.readInt(); } catch (UJciException e) { logException(e); e.toUError(errorHandler); } catch (IOException e) { logException(e); errorHandler.setErrorCode(UErrorCode.ER_COMMUNICATION); } return errorHandler.getJdbcErrorCode(); } /* * 3.0 synchronized public void savepoint(int mode, String name) { * errorHandler = new UError(); if (isClosed == true) { * errorHandler.setErrorCode(UErrorCode.ER_IS_CLOSED); return; } * * try { checkReconnect(); if (errorHandler.getErrorCode() != * UErrorCode.ER_NO_ERROR) return; * * outBuffer.newRequest(out, UFunctionCode.SAVEPOINT); * outBuffer.addByte(mode); outBuffer.addStringWithNull(name); * * UInputBuffer inBuffer; inBuffer = send_recv_msg(); } catch (UJciException * e) { e.toUError(errorHandler); } catch (IOException e) { * errorHandler.setErrorCode(UErrorCode.ER_COMMUNICATION); } } */ public byte getCASInfoStatus() { if (casinfo == null) { return (byte) CAS_INFO_STATUS_INACTIVE; } return casinfo[CAS_INFO_STATUS]; } public byte[] getCASInfo() { return casinfo; } public void setCASInfo(byte[] casinfo) { this.casinfo = casinfo; } public byte getDbmsType() { // jci 3.0 if (broker_info == null) return DBMS_CUBRID; return broker_info[BROKER_INFO_DBMS_TYPE]; /* * jci 2.x return DBMS_CUBRID; */ } public boolean isConnectedToCubrid() { byte dbms_type = getDbmsType(); if (dbms_type == DBMS_CUBRID || dbms_type == DBMS_PROXY_CUBRID) { return true; } return false; } public boolean isConnectedToOracle() { byte dbms_type = getDbmsType(); if (dbms_type == DBMS_ORACLE || dbms_type == DBMS_PROXY_ORACLE) { return true; } return false; } public boolean isConnectedToProxy() { byte dbms_type = getDbmsType(); if (dbms_type == DBMS_PROXY_CUBRID || dbms_type == DBMS_PROXY_MYSQL || dbms_type == DBMS_PROXY_ORACLE) { return true; } return false; } public boolean brokerInfoStatementPooling() { if (broker_info == null) return false; if (broker_info[BROKER_INFO_STATEMENT_POOLING] == (byte) 1) return true; else return false; } public boolean brokerInfoRenewedErrorCode() { if ((broker_info[BROKER_INFO_PROTO_VERSION] & CAS_PROTO_INDICATOR) != CAS_PROTO_INDICATOR) { return false; } return (broker_info[BROKER_INFO_FUNCTION_FLAG] & CAS_RENEWED_ERROR_CODE) == CAS_RENEWED_ERROR_CODE; } public boolean brokerInfoSupportHoldableResult() { if (broker_info == null) return false; return (broker_info[BROKER_INFO_FUNCTION_FLAG] & CAS_SUPPORT_HOLDABLE_RESULT) == CAS_SUPPORT_HOLDABLE_RESULT; } public boolean brokerInfoReconnectWhenServerDown() { if (broker_info == null) return false; return (broker_info[BROKER_INFO_FUNCTION_FLAG] & CAS_RECONNECT_WHEN_SERVER_DOWN) == CAS_RECONNECT_WHEN_SERVER_DOWN; } public boolean supportHoldableResult() { if (brokerInfoSupportHoldableResult() || protoVersionIsSame(UConnection.PROTOCOL_V2)) { return true; } return false; } synchronized public void xa_endTransaction(Xid xid, boolean type) { errorHandler = new UError(this); if (isClosed == true) { errorHandler.setErrorCode(UErrorCode.ER_IS_CLOSED); return; } try { setBeginTime(); checkReconnect(); if (errorHandler.getErrorCode() != UErrorCode.ER_NO_ERROR) return; outBuffer.newRequest(output, UFunctionCode.XA_END_TRAN); outBuffer.addXid(xid); outBuffer.addByte((type == true) ? END_TRAN_COMMIT : END_TRAN_ROLLBACK); send_recv_msg(); } catch (Exception e) { errorHandler.setErrorCode(UErrorCode.ER_UNKNOWN); } finally { clientSocketClose(); needReconnection = true; } } synchronized public void xa_prepare(Xid xid) { errorHandler = new UError(this); if (isClosed == true) { errorHandler.setErrorCode(UErrorCode.ER_IS_CLOSED); return; } try { setBeginTime(); checkReconnect(); if (errorHandler.getErrorCode() != UErrorCode.ER_NO_ERROR) return; outBuffer.newRequest(output, UFunctionCode.XA_PREPARE); outBuffer.addXid(xid); send_recv_msg(); } catch (Exception e) { errorHandler.setErrorCode(UErrorCode.ER_UNKNOWN); } } synchronized public Xid[] xa_recover() { errorHandler = new UError(this); if (isClosed == true) { errorHandler.setErrorCode(UErrorCode.ER_IS_CLOSED); return null; } try { setBeginTime(); checkReconnect(); if (errorHandler.getErrorCode() != UErrorCode.ER_NO_ERROR) return null; outBuffer.newRequest(output, UFunctionCode.XA_RECOVER); UInputBuffer inBuffer; inBuffer = send_recv_msg(); int num_xid = inBuffer.getResCode(); CUBRIDXid[] xid; xid = new CUBRIDXid[num_xid]; for (int i = 0; i < num_xid; i++) { xid[i] = inBuffer.readXid(); } return xid; } catch (Exception e) { errorHandler.setErrorCode(UErrorCode.ER_UNKNOWN); return null; } } public void setCUBRIDConnection(CUBRIDConnection con) { cubridcon = con; lastIsolationLevel = CUBRIDIsolationLevel.TRAN_UNKNOWN_ISOLATION; lastLockTimeout = LOCK_TIMEOUT_NOT_USED; } public CUBRIDConnection getCUBRIDConnection() { return cubridcon; } private static void printCasInfo(byte[] prev, byte[] curr) { if (prev != null) { String fmt = "[PREV : %d, RECV : %d], [preffunc : %d, recvfunc : %d], [REQ: %d], [JID: %d]"; String msg = String.format(fmt, prev[0], curr[0], prev[1], curr[1], prev[2], curr[3]); CUBRIDDriver.printDebug(msg); } } synchronized public boolean check_cas() { if (isClosed == true) return true; if (client == null || needReconnection == true) return true; if (skip_checkcas) { return true; } try { outBuffer.newRequest(output, UFunctionCode.CHECK_CAS); send_recv_msg(); } catch (IOException e) { logException(e); return false; } catch (UJciException e) { logException(e); return false; } return true; } synchronized public boolean check_cas(String msg) { try { outBuffer.newRequest(output, UFunctionCode.CHECK_CAS); outBuffer.addStringWithNull(msg); send_recv_msg(); } catch (Exception e) { return false; } return true; } synchronized public void reset_connection() { try { if (client != null) client.close(); } catch (Exception e) { } client = null; needReconnection = true; } synchronized public Object oidCmd(CUBRIDOID oid, byte cmd) { errorHandler = new UError(this); if (isClosed == true) { errorHandler.setErrorCode(UErrorCode.ER_IS_CLOSED); return null; } try { setBeginTime(); checkReconnect(); if (errorHandler.getErrorCode() != UErrorCode.ER_NO_ERROR) return null; outBuffer.newRequest(output, UFunctionCode.RELATED_TO_OID); outBuffer.addByte(cmd); outBuffer.addOID(oid); UInputBuffer inBuffer; inBuffer = send_recv_msg(); int res_code; res_code = inBuffer.getResCode(); if (cmd == IS_INSTANCE) { if (res_code == 1) return oid; } else if (cmd == GET_CLASS_NAME_BY_OID) { return inBuffer.readString(inBuffer.remainedCapacity(), connectionProperties.getCharSet()); } } catch (UJciException e) { logException(e); e.toUError(errorHandler); } catch (IOException e) { logException(e); errorHandler.setErrorCode(UErrorCode.ER_COMMUNICATION); } return null; } synchronized public byte[] lobNew(int lob_type) { errorHandler = new UError(this); if (isClosed == true) { errorHandler.setErrorCode(UErrorCode.ER_IS_CLOSED); return null; } try { setBeginTime(); checkReconnect(); if (errorHandler.getErrorCode() != UErrorCode.ER_NO_ERROR) return null; outBuffer.newRequest(output, UFunctionCode.NEW_LOB); outBuffer.addInt(lob_type); UInputBuffer inBuffer; inBuffer = send_recv_msg(); int res_code; res_code = inBuffer.getResCode(); if (res_code < 0) { errorHandler.setErrorCode(UErrorCode.ER_UNKNOWN); return null; } byte[] packedLobHandle = new byte[res_code]; inBuffer.readBytes(packedLobHandle); return packedLobHandle; } catch (UJciException e) { logException(e); e.toUError(errorHandler); } catch (IOException e) { logException(e); errorHandler.setErrorCode(UErrorCode.ER_COMMUNICATION); } catch (Exception e) { logException(e); errorHandler.setErrorCode(UErrorCode.ER_UNKNOWN); } return null; } synchronized public int lobWrite(byte[] packedLobHandle, long offset, byte[] buf, int start, int len) { errorHandler = new UError(this); if (isClosed == true) { errorHandler.setErrorCode(UErrorCode.ER_IS_CLOSED); return -1; } try { setBeginTime(); checkReconnect(); if (errorHandler.getErrorCode() != UErrorCode.ER_NO_ERROR) return -1; outBuffer.newRequest(output, UFunctionCode.WRITE_LOB); outBuffer.addBytes(packedLobHandle); outBuffer.addLong(offset); outBuffer.addBytes(buf, start, len); UInputBuffer inBuffer; inBuffer = send_recv_msg(); int res_code; res_code = inBuffer.getResCode(); if (res_code < 0) { errorHandler.setErrorCode(UErrorCode.ER_UNKNOWN); } return res_code; } catch (UJciException e) { logException(e); e.toUError(errorHandler); } catch (IOException e) { logException(e); errorHandler.setErrorCode(UErrorCode.ER_COMMUNICATION); } catch (Exception e) { logException(e); errorHandler.setErrorCode(UErrorCode.ER_UNKNOWN); } return -1; } synchronized public int lobRead(byte[] packedLobHandle, long offset, byte[] buf, int start, int len) { errorHandler = new UError(this); if (isClosed == true) { errorHandler.setErrorCode(UErrorCode.ER_IS_CLOSED); return -1; } try { setBeginTime(); checkReconnect(); if (errorHandler.getErrorCode() != UErrorCode.ER_NO_ERROR) return -1; outBuffer.newRequest(output, UFunctionCode.READ_LOB); outBuffer.addBytes(packedLobHandle); outBuffer.addLong(offset); outBuffer.addInt(len); UInputBuffer inBuffer; inBuffer = send_recv_msg(); int res_code; res_code = inBuffer.getResCode(); if (res_code < 0) { errorHandler.setErrorCode(UErrorCode.ER_UNKNOWN); } else { inBuffer.readBytes(buf, start, res_code); } return res_code; } catch (UJciException e) { logException(e); e.toUError(errorHandler); } catch (IOException e) { logException(e); errorHandler.setErrorCode(UErrorCode.ER_COMMUNICATION); } catch (Exception e) { logException(e); errorHandler.setErrorCode(UErrorCode.ER_UNKNOWN); } return -1; } synchronized public void setAutoCommit(boolean autoCommit) { if (!isServerSideJdbc) { if (lastAutoCommit != autoCommit) { lastAutoCommit = autoCommit; } } /* * errorHandler = new UError(); if (isClosed == true){ * errorHandler.setErrorCode(UErrorCode.ER_IS_CLOSED); return; } try{ * checkReconnect(); if (errorHandler.getErrorCode() != * UErrorCode.ER_NO_ERROR) return; outBuffer.newRequest(out, * UFunctionCode.SET_DB_PARAMETER); * outBuffer.addInt(DB_PARAM_AUTO_COMMIT); outBuffer.addInt(autoCommit ? * 1 : 0 ); UInputBuffer inBuffer; inBuffer = send_recv_msg(); * lastAutoCommit = autoCommit; }catch(UJciException e){ * e.toUError(errorHandler); }catch(IOException e){ * errorHandler.setErrorCode(UErrorCode.ER_COMMUNICATION); } */ } public boolean getAutoCommit() { return lastAutoCommit; } public int currentIsolationLevel() { return lastIsolationLevel; } public static byte[] createDBInfo(String dbname, String user, String passwd, String url) { // see broker/cas_protocol.h // #define SRV_CON_DBNAME_SIZE 32 // #define SRV_CON_DBUSER_SIZE 32 // #define SRV_CON_DBPASSWD_SIZE 32 // #define SRV_CON_DBSESS_ID_SIZE 20 // #define SRV_CON_URL_SIZE 512 // #define SRV_CON_DB_INFO_SIZE \ // (SRV_CON_DBNAME_SIZE + SRV_CON_DBUSER_SIZE + // SRV_CON_DBPASSWD_SIZE + \ // SRV_CON_URL_SIZE + SRV_CON_DBSESS_ID_SIZE) byte[] info = new byte[32 + 32 + 32 + 512 + 20]; UJCIUtil.copy_bytes(info, 0, 32, dbname); UJCIUtil.copy_bytes(info, 32, 32, user); UJCIUtil.copy_bytes(info, 64, 32, passwd); UJCIUtil.copy_bytes(info, 96, 511, url); if (url == null) { UJCIUtil.copy_byte(info, 96, (byte) 0); // null UJCIUtil.copy_byte(info, 97, (byte) 0); // length } else { String version = CUBRIDDriver.version_string; int index = 96 + url.getBytes().length + 1; if ((version.getBytes().length <= DRIVER_VERSION_MAX_SIZE) && (url.getBytes().length + version.getBytes().length + 3 <= 512)) { // url = ( url string + length (1byte) + version string ) byte len = (byte) version.getBytes().length; UJCIUtil.copy_byte(info, index, len); UJCIUtil.copy_bytes(info, index + 1, version.getBytes().length + 1, version); } else { UJCIUtil.copy_byte(info, index, (byte) 0); // length } } return info; } void clientSocketClose() { try { needReconnection = true; if (client != null) { client.setSoLinger(true, 0); client.close(); } client = null; } catch (IOException e) { logException(e); } clearPooledUStatements(); deferred_close_handle.clear(); } UInputBuffer send_recv_msg(boolean recv_result) throws UJciException, IOException { byte prev_casinfo[] = casinfo; outBuffer.sendData(); /* set cas info to UConnection member variable and return InputBuffer */ UInputBuffer inputBuffer = new UInputBuffer(input, this); if (UJCIUtil.isConsoleDebug()) { printCasInfo(prev_casinfo, casinfo); } return inputBuffer; } UInputBuffer send_recv_msg() throws UJciException, IOException { if (client == null) { createJciException(UErrorCode.ER_COMMUNICATION); } return send_recv_msg(true); } void cancel() throws UJciException, IOException { if (protoVersionIsAbove(PROTOCOL_V4)) { BrokerHandler.cancelBrokerEx(CASIp, CASPort, processId, 0); } else { BrokerHandler.cancelBroker(CASIp, CASPort, processId, 0); } } UUrlCache getUrlCache() { if (url_cache == null) { UUrlHostKey key = new UUrlHostKey(CASIp, CASPort, dbname, user); url_cache = UJCIManager.getUrlCache(key); } return url_cache; } private int getTimeout(long endTimestamp, int timeout) throws UJciException { if (endTimestamp == 0) { return timeout; } long diff = endTimestamp - System.currentTimeMillis(); if (diff <= 0) { throw new UJciException(UErrorCode.ER_TIMEOUT); } if (diff < timeout) { return (int)diff; } return timeout; } private void reconnectWorker(long endTimestamp) throws IOException, UJciException { if (UJCIUtil.isConsoleDebug()) { CUBRIDDriver.printDebug(String.format("Try Connect (%s,%d)", CASIp, CASPort)); } int timeout = connectionProperties.getConnectTimeout() * 1000; client = BrokerHandler.connectBroker(CASIp, CASPort, getTimeout(endTimestamp, timeout)); output = new DataOutputStream(client.getOutputStream()); input = new UTimedDataInputStream(client.getInputStream(), CASIp, CASPort); connectDB(getTimeout(endTimestamp, timeout)); client.setTcpNoDelay(true); client.setSoTimeout(SOCKET_TIMEOUT); needReconnection = false; isClosed = false; if (lastIsolationLevel != CUBRIDIsolationLevel.TRAN_UNKNOWN_ISOLATION) setIsolationLevel(lastIsolationLevel); if (lastLockTimeout != LOCK_TIMEOUT_NOT_USED) setLockTimeout(lastLockTimeout); /* * if(!lastAutoCommit) setAutoCommit(lastAutoCommit); */ } private void connectDB(int timeout) throws IOException, UJciException { UTimedDataInputStream is = new UTimedDataInputStream(client.getInputStream(), CASIp, CASPort, timeout); DataOutputStream os = new DataOutputStream(client.getOutputStream()); // send database information os.write(dbInfo); // receive header int dataLength = is.readInt(); casinfo = new byte[CAS_INFO_SIZE]; is.readFully(casinfo); if (dataLength < 0) { throw new UJciException(UErrorCode.ER_ILLEGAL_DATA_SIZE); } // receive data int response = is.readInt(); if (response < 0) { int code = is.readInt(); // the error greater than -10000 with CAS_ERROR_INDICATOR is sent by old broker // -1018 (CAS_ER_NOT_AUTHORIZED_CLIENT) is especial case if ((response == UErrorCode.CAS_ERROR_INDICATOR && code > -10000) || code == -1018) { code -= 9000; } byte msg[] = new byte[dataLength - 8]; is.readFully(msg); throw new UJciException(UErrorCode.ER_DBMS, response, code, new String(msg, 0, Math.max(msg.length - 1, 0))); } processId = response; if (broker_info == null) { broker_info = new byte[BROKER_INFO_SIZE]; } is.readFully(broker_info); /* synchronize with broker_info */ byte version = broker_info[BROKER_INFO_PROTO_VERSION]; if ((version & CAS_PROTO_INDICATOR) == CAS_PROTO_INDICATOR) { brokerVersion = makeProtoVersion(version & CAS_PROTO_VER_MASK); } else { brokerVersion = makeBrokerVersion( (int) broker_info[BROKER_INFO_MAJOR_VERSION], (int) broker_info[BROKER_INFO_MINOR_VERSION], (int) broker_info[BROKER_INFO_PATCH_VERSION]); } if (protoVersionIsAbove(PROTOCOL_V4)) { casId = is.readInt(); } else { casId = -1; } if (protoVersionIsAbove(PROTOCOL_V3)) { is.readFully(sessionId); } else { oldSessionId = is.readInt(); } } private boolean setActiveHost(int hostId) throws UJciException { if (hostId >= altHosts.size()) return false; String info = altHosts.get(hostId); setConnectInfo(info); return true; } private long getLoginEndTimestamp(long timestamp) { int timeout = connectionProperties.getConnectTimeout(); if (timeout <= 0) { return 0; } return timestamp + (timeout * 1000); } private void reconnect() throws IOException, UJciException { if (altHosts == null) { reconnectWorker(getLoginEndTimestamp(beginTime)); } else { int retry = 0; UUnreachableHostList unreachableHosts = UUnreachableHostList.getInstance(); do { for (int hostId = 0; hostId < altHosts.size(); hostId++) { /* * if all hosts turn out to be unreachable, ignore host * reachability and try one more time */ if (!unreachableHosts.contains(altHosts.get(hostId)) || retry == 1) { try { setActiveHost(hostId); reconnectWorker(getLoginEndTimestamp(System.currentTimeMillis())); connectedHostId = hostId; unreachableHosts.remove(altHosts.get(hostId)); return; // success to connect } catch (IOException e) { logException(e); throw e; } catch (UJciException e) { logException(e); int errno = e.getJciError(); if (errno == UErrorCode.ER_COMMUNICATION || errno == UErrorCode.ER_CONNECTION || errno == UErrorCode.ER_TIMEOUT || errno == UErrorCode.CAS_ER_FREE_SERVER) { unreachableHosts.add(altHosts.get(hostId)); } else { throw e; } } } lastFailureTime = System.currentTimeMillis() / 1000; } retry++; } while (retry < 2); // failed to connect to neither hosts throw createJciException(UErrorCode.ER_CONNECTION); } } private int makeBrokerVersion(int major, int minor, int patch) { int version = 0; if ((major < 0 || major > Byte.MAX_VALUE) || (minor < 0 || minor > Byte.MAX_VALUE) || (patch < 0 || patch > Byte.MAX_VALUE)) { return 0; } version = ((int) major << 24) | ((int) minor << 16) | ((int) patch << 8); return version; } private int makeProtoVersion(int ver) { return ((int) CAS_PROTO_INDICATOR << 24) | ver; } public int brokerInfoVersion() { return brokerVersion; } public boolean protoVersionIsSame(int ver) { if (brokerInfoVersion() == makeProtoVersion(ver)) { return true; } return false; } public boolean protoVersionIsUnder(int ver) { if (brokerInfoVersion() < makeProtoVersion(ver)) { return true; } return false; } public boolean protoVersionIsAbove(int ver) { if (isServerSideJdbc() || (brokerInfoVersion() >= makeProtoVersion(ver))) { return true; } return false; } private void setConnectInfo(String info) throws UJciException { StringTokenizer st = new StringTokenizer(info, ":"); if (st.countTokens() != 2) { throw createJciException(UErrorCode.ER_CONNECTION); } CASIp = st.nextToken(); CASPort = Integer.valueOf(st.nextToken()).intValue(); } private void manageElementOfSequence(CUBRIDOID oid, String attributeName, int index, Object value, byte flag) throws UJciException, IOException { UAParameter aParameter; aParameter = new UAParameter(attributeName, value); setBeginTime(); checkReconnect(); if (errorHandler.getErrorCode() != UErrorCode.ER_NO_ERROR) return; outBuffer.newRequest(output, UFunctionCode.RELATED_TO_COLLECTION); outBuffer.addByte(flag); outBuffer.addOID(oid); outBuffer.addInt(index); aParameter.writeParameter(outBuffer); send_recv_msg(); } private void manageElementOfSet(CUBRIDOID oid, String attributeName, Object value, byte flag) throws UJciException, IOException { UAParameter aParameter; aParameter = new UAParameter(attributeName, value); setBeginTime(); checkReconnect(); if (errorHandler.getErrorCode() != UErrorCode.ER_NO_ERROR) return; outBuffer.newRequest(output, UFunctionCode.RELATED_TO_COLLECTION); outBuffer.addByte(flag); outBuffer.addOID(oid); aParameter.writeParameter(outBuffer); send_recv_msg(); } void checkReconnect() throws IOException, UJciException { if (dbInfo == null) { dbInfo = createDBInfo(dbname, user, passwd, url); } // set the session id if (brokerInfoVersion() == 0) { /* Interpretable session information supporting version * later than PROTOCOL_V3 as well as version earlier * than PROTOCOL_V3 should be delivered since no broker information * is provided at the time of initial connection. */ String id = "0"; UJCIUtil.copy_bytes(dbInfo, 608, 20, id); } else if (protoVersionIsAbove(PROTOCOL_V3)) { System.arraycopy(sessionId, 0, dbInfo, 608, 20); } else { UJCIUtil.copy_bytes(dbInfo, 608, 20, new Integer(oldSessionId).toString()); } if (outBuffer == null) { outBuffer = new UOutputBuffer(this); } if (pooled_ustmts == null) { pooled_ustmts = new Vector(); } if (deferred_close_handle == null) { deferred_close_handle = new Vector(); } if (!isServerSideJdbc) { if (getCASInfoStatus() == CAS_INFO_STATUS_INACTIVE && check_cas() == false) { clientSocketClose(); } if (needReconnection == true) { reconnect(); if (UJCIUtil.isSendAppInfo()) { sendAppInfo(); } } } } private void sendAppInfo() { String msg; msg = CUBRIDJdbcInfoTable.getValue(); if (msg == null) return; check_cas(msg); } public void closeSession() { try { setBeginTime(); checkReconnect(); if (errorHandler.getErrorCode() != UErrorCode.ER_NO_ERROR) return; outBuffer.newRequest(output, UFunctionCode.END_SESSION); send_recv_msg(); sessionId = createNullSession(); oldSessionId = 0; } catch (Exception e) { } } private byte[] createNullSession() { return new byte[SESSION_ID_SIZE]; } // jci 3.0 private void disconnect() { try { setBeginTime(); checkReconnect(); if (errorHandler.getErrorCode() != UErrorCode.ER_NO_ERROR) return; outBuffer.newRequest(output, UFunctionCode.CON_CLOSE); send_recv_msg(); } catch (Exception e) { } } // end jci 3.0 private void clearPooledUStatements() { if (pooled_ustmts == null) return; while (pooled_ustmts.isEmpty() != true) { UStatement tmp_ustmt = (UStatement) pooled_ustmts.remove(0); if (tmp_ustmt != null) tmp_ustmt.close(false); } } public boolean isServerSideJdbc() { return isServerSideJdbc; } public void turnOnAutoCommitBySelf() { isAutoCommitBySelf = true; } public void turnOffAutoCommitBySelf() { isAutoCommitBySelf = false; } public void setConnectionProperties(ConnectionProperties connProperties) { this.connectionProperties = connProperties; } private Log getLogger() { if (log == null) { log = new BasicLogger(connectionProperties.getLogFile()); } return log; } private void initLogger() { if (connectionProperties.getLogOnException() || connectionProperties.getLogSlowQueries()) { log = getLogger(); } } public UJciException createJciException(int err) { UJciException e = new UJciException(err); if (connectionProperties == null || !connectionProperties.getLogOnException()) { return e; } StringBuffer b = new StringBuffer(); b.append("DUMP EXCEPTION\n"); b.append("[JCI EXCEPTION]"); synchronized (this) { getLogger().logInfo(b.toString(), e); } return e; } public UJciException createJciException(int err, int indicator, int srv_err, String msg) { UJciException e = new UJciException(err, indicator, srv_err, msg); logException(e); return e; } public void logException(Throwable t) { if (connectionProperties == null || !connectionProperties.getLogOnException()) { return; } StringBuffer b = new StringBuffer(); b.append("DUMP EXCEPTION\n"); b.append("[" + t.getClass().getName() + "]"); synchronized (this) { getLogger().logInfo(b.toString(), t); } } private SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); public void logSlowQuery(long begin, long end, String sql, UBindParameter p) { if (connectionProperties == null || connectionProperties.getLogSlowQueries() != true) { return; } long elapsed = end - begin; if (connectionProperties.getSlowQueryThresholdMillis() > elapsed) { return; } StringBuffer b = new StringBuffer(); b.append("SLOW QUERY\n"); b.append(String.format("[CAS INFO]\n%s:%d, %d, %d\n", CASIp, CASPort, casId, processId)); b.append(String.format("[TIME]\nSTART: %s, ELAPSED: %d\n", dateFormat.format(new Date(begin)), elapsed)); b.append("[SQL]\n").append(sql).append('\n'); if (p != null) { b.append("[BIND]\n"); for (int i = 0; i < p.values.length; i++) { if (i != 0) b.append(", "); b.append(p.values[i].toString()); } b.append('\n'); } synchronized (this) { getLogger().logInfo(b.toString()); } } public boolean isActive() { return getCASInfoStatus() == CAS_INFO_STATUS_ACTIVE; } public void setBeginTime() { beginTime = System.currentTimeMillis(); } public long getRemainingTime(long timeout) { if (beginTime == 0 || timeout == 0) { return timeout; } long now = System.currentTimeMillis(); return timeout - (now - beginTime); } public void resetBeginTime() { beginTime = 0; } public boolean isRenewedSessionId() { return (brokerInfoReconnectWhenServerDown() && ((casinfo[CAS_INFO_ADDITIONAL_FLAG] & CAS_INFO_FLAG_MASK_NEW_SESSION_ID) == CAS_INFO_FLAG_MASK_NEW_SESSION_ID)); } public void setNewSessionId(byte[] newSessionId) { sessionId = newSessionId; } public void setShardId(int shardId) { lastShardId = shardId; } public int getShardId() { return lastShardId; } public int getShardCount() { if (isConnectedToProxy() == false) { return 0; } if (numShard == 0) { int num_shard = shardInfo(); if (num_shard == 0 || errorHandler.getErrorCode() != UErrorCode.ER_NO_ERROR) { return 0; } } return numShard; } synchronized public int shardInfo() { errorHandler = new UError(this); if (isClosed == true) { errorHandler.setErrorCode(UErrorCode.ER_IS_CLOSED); return 0; } if (isConnectedToProxy() == false) { errorHandler.setErrorCode(UErrorCode.ER_NO_SHARD_AVAILABLE); return 0; } if (numShard > 0) { return numShard; // return cached shard info } try { setBeginTime(); checkReconnect(); if (errorHandler.getErrorCode() != UErrorCode.ER_NO_ERROR) { return 0; } outBuffer.newRequest(output, UFunctionCode.GET_SHARD_INFO); UInputBuffer inBuffer; inBuffer = send_recv_msg(); int num_shard = inBuffer.getResCode(); if (num_shard > 0) { shardInfo = new UShardInfo[num_shard]; for (int i=0; i= numShard) { errorHandler.setErrorCode(UErrorCode.ER_INVALID_SHARD); return null; } return shardInfo[shard_id]; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy