diff --git a/src/jdbc/cubrid/jdbc/driver/CUBRIDBlob.java b/src/jdbc/cubrid/jdbc/driver/CUBRIDBlob.java index 1c058afbe7b..20c2ae5c3ab 100644 --- a/src/jdbc/cubrid/jdbc/driver/CUBRIDBlob.java +++ b/src/jdbc/cubrid/jdbc/driver/CUBRIDBlob.java @@ -55,6 +55,7 @@ public class CUBRIDBlob implements Blob { */ private CUBRIDConnection conn; private boolean isWritable; + private boolean isLobLocator; private CUBRIDLobHandle lobHandle; private ArrayList streamList = new ArrayList(); @@ -74,18 +75,20 @@ public CUBRIDBlob(CUBRIDConnection conn) throws SQLException { this.conn = conn; isWritable = true; - lobHandle = new CUBRIDLobHandle(UUType.U_TYPE_BLOB, packedLobHandle); + isLobLocator = true; + lobHandle = new CUBRIDLobHandle(UUType.U_TYPE_BLOB, packedLobHandle, isLobLocator); } // get blob from existing result set - public CUBRIDBlob(CUBRIDConnection conn, byte[] packedLobHandle) throws SQLException { + public CUBRIDBlob(CUBRIDConnection conn, byte[] packedLobHandle, boolean isLobLocator) throws SQLException { if (conn == null || packedLobHandle == null) { throw new CUBRIDException(CUBRIDJDBCErrorCode.invalid_value); } this.conn = conn; isWritable = false; - lobHandle = new CUBRIDLobHandle(UUType.U_TYPE_BLOB, packedLobHandle); + this.isLobLocator = isLobLocator; + lobHandle = new CUBRIDLobHandle(UUType.U_TYPE_BLOB, packedLobHandle, isLobLocator); } /* @@ -124,18 +127,23 @@ public byte[] getBytes(long pos, int length) throws SQLException { byte[] buf = new byte[length]; - while (length > 0) { - read_len = Math.min(length, BLOB_MAX_IO_LENGTH); - real_read_len = conn.lobRead(lobHandle.getPackedLobHandle(), pos, - buf, total_read_len, read_len); + if (isLobLocator) { + while (length > 0) { + read_len = Math.min(length, BLOB_MAX_IO_LENGTH); + real_read_len = conn.lobRead(lobHandle.getPackedLobHandle(), pos, + buf, total_read_len, read_len); - pos += real_read_len; - length -= real_read_len; - total_read_len += real_read_len; + pos += real_read_len; + length -= real_read_len; + total_read_len += real_read_len; - if (real_read_len == 0) { - break; + if (real_read_len == 0) { + break; + } } + } else { + System.arraycopy(lobHandle.getPackedLobHandle(), (int) pos, buf, 0, length); + total_read_len = length; } if (total_read_len < buf.length) { @@ -253,6 +261,7 @@ public void free() throws SQLException { lobHandle = null; streamList = null; isWritable = false; + isLobLocator = true; } public CUBRIDLobHandle getLobHandle() { @@ -278,8 +287,12 @@ public void flushFlushableStreams() { } } - public String toString() { - return lobHandle.toString(); + public String toString() throws RuntimeException { + if (isLobLocator == true) { + return lobHandle.toString(); + } else { + throw new RuntimeException("The lob locator does not exist because the column type has changed."); + } } public boolean equals(Object obj) { diff --git a/src/jdbc/cubrid/jdbc/driver/CUBRIDClob.java b/src/jdbc/cubrid/jdbc/driver/CUBRIDClob.java index 586a6b7d648..a7723988c3f 100644 --- a/src/jdbc/cubrid/jdbc/driver/CUBRIDClob.java +++ b/src/jdbc/cubrid/jdbc/driver/CUBRIDClob.java @@ -37,6 +37,7 @@ import java.io.Reader; import java.io.UnsupportedEncodingException; import java.io.Writer; +import java.lang.System; import java.sql.Clob; import java.sql.SQLException; import java.util.ArrayList; @@ -60,6 +61,7 @@ public class CUBRIDClob implements Clob { */ private CUBRIDConnection conn; private boolean isWritable; + private boolean isLobLocator; private CUBRIDLobHandle lobHandle; private String charsetName; @@ -90,7 +92,8 @@ public CUBRIDClob(CUBRIDConnection conn, String charsetName) this.conn = conn; isWritable = true; - lobHandle = new CUBRIDLobHandle(UUType.U_TYPE_CLOB, packedLobHandle); + isLobLocator = true; + lobHandle = new CUBRIDLobHandle(UUType.U_TYPE_CLOB, packedLobHandle, isLobLocator); this.charsetName = charsetName; clobCharPos = 0; @@ -101,14 +104,15 @@ public CUBRIDClob(CUBRIDConnection conn, String charsetName) // get clob from existing result set public CUBRIDClob(CUBRIDConnection conn, byte[] packedLobHandle, - String charsetName) throws SQLException { + String charsetName, boolean isLobLocator) throws SQLException { if (conn == null || packedLobHandle == null) { throw new CUBRIDException(CUBRIDJDBCErrorCode.invalid_value); } this.conn = conn; isWritable = false; - lobHandle = new CUBRIDLobHandle(UUType.U_TYPE_CLOB, packedLobHandle); + this.isLobLocator = isLobLocator; + lobHandle = new CUBRIDLobHandle(UUType.U_TYPE_CLOB, packedLobHandle, isLobLocator); this.charsetName = charsetName; clobCharPos = 0; @@ -307,6 +311,7 @@ public void free() throws SQLException { clobCharBuffer = null; clobByteBuffer = null; isWritable = false; + isLobLocator = true; } private int readClobPartially(long pos, int length) throws SQLException { @@ -356,13 +361,36 @@ private int readClobPartially(long pos, int length) throws SQLException { return length; } + private int lobRead(long offset, byte[] buf, int start, int len) throws SQLException { + int read_len; + long remaining_size; + + remaining_size = lobHandle.getLobSize() - offset; + + if (remaining_size <= 0) { + return 0; + } + + read_len = Math.min((int) remaining_size, len); + + System.arraycopy(lobHandle.getPackedLobHandle(), (int) offset, buf, start, read_len); + + return read_len; + } + private void readClob() throws SQLException { + int read_len; + if (conn == null || lobHandle == null) { throw new NullPointerException(); } - int read_len = conn.lobRead(lobHandle.getPackedLobHandle(), - clobNextReadBytePos, clobByteBuffer, 0, CLOB_MAX_IO_LENGTH); + if (isLobLocator == true) { + read_len = conn.lobRead(lobHandle.getPackedLobHandle(), + clobNextReadBytePos, clobByteBuffer, 0, CLOB_MAX_IO_LENGTH); + } else { + read_len = lobRead(clobNextReadBytePos, clobByteBuffer, 0, CLOB_MAX_IO_LENGTH); + } StringBuffer sb = new StringBuffer(bytes2string(clobByteBuffer, 0, read_len)); @@ -420,8 +448,12 @@ public void flushFlushableStreams() { } } - public String toString() { - return lobHandle.toString(); + public String toString() throws RuntimeException { + if (isLobLocator == true) { + return lobHandle.toString(); + } else { + throw new RuntimeException("The lob locator does not exist because the column type has changed."); + } } public boolean equals(Object obj) { @@ -454,8 +486,13 @@ public byte[] getBytes(long pos, int length) throws SQLException { while (length > 0) { read_len = Math.min(length, CLOB_MAX_IO_LENGTH); - real_read_len = conn.lobRead(lobHandle.getPackedLobHandle(), pos, - buf, total_read_len, read_len); + + if (isLobLocator == true) { + real_read_len = conn.lobRead(lobHandle.getPackedLobHandle(), pos, + buf, total_read_len, read_len); + } else { + real_read_len = lobRead(pos, buf, total_read_len, read_len); + } pos += real_read_len; length -= real_read_len; diff --git a/src/jdbc/cubrid/jdbc/driver/CUBRIDLobHandle.java b/src/jdbc/cubrid/jdbc/driver/CUBRIDLobHandle.java index cb00e9bd4f1..25e7cbf37a6 100644 --- a/src/jdbc/cubrid/jdbc/driver/CUBRIDLobHandle.java +++ b/src/jdbc/cubrid/jdbc/driver/CUBRIDLobHandle.java @@ -36,37 +36,43 @@ public class CUBRIDLobHandle { private byte[] packedLobHandle; private String locator; - public CUBRIDLobHandle(int lobType, byte[] packedLobHandle) { + public CUBRIDLobHandle(int lobType, byte[] packedLobHandle, boolean isLobLocator) { this.lobType = lobType; this.packedLobHandle = packedLobHandle; - initLob(); + initLob(isLobLocator); } - private void initLob() { + private void initLob(boolean isLobLocator) { int pos = 0; if (packedLobHandle == null) { throw new NullPointerException(); } - pos += 4; // skip db_type - - lobSize = 0; - for (int i = pos; i < pos + 8; i++) { - lobSize <<= 8; - lobSize |= (packedLobHandle[i] & 0xff); + if (isLobLocator == true) { + pos += 4; // skip db_type + + lobSize = 0; + for (int i = pos; i < pos + 8; i++) { + lobSize <<= 8; + lobSize |= (packedLobHandle[i] & 0xff); + } + pos += 8; // lob_size + + int locatorSize = 0; + for (int i = pos; i < pos + 4; i++) { + locatorSize <<= 8; + locatorSize |= (packedLobHandle[i] & 0xff); + } + pos += 4; // locator_size + + locator = new String(packedLobHandle, pos, locatorSize - 1); + // remove terminating null character + } else + { + lobSize = packedLobHandle.length; + locator = packedLobHandle.toString(); } - pos += 8; // lob_size - - int locatorSize = 0; - for (int i = pos; i < pos + 4; i++) { - locatorSize <<= 8; - locatorSize |= (packedLobHandle[i] & 0xff); - } - pos += 4; // locator_size - - locator = new String(packedLobHandle, pos, locatorSize - 1); - // remove terminating null character } public void setLobSize(long size) { diff --git a/src/jdbc/cubrid/jdbc/jci/UGetTypeConvertedValue.java b/src/jdbc/cubrid/jdbc/jci/UGetTypeConvertedValue.java index cecff247551..0de1eda5e40 100755 --- a/src/jdbc/cubrid/jdbc/jci/UGetTypeConvertedValue.java +++ b/src/jdbc/cubrid/jdbc/jci/UGetTypeConvertedValue.java @@ -48,6 +48,9 @@ import cubrid.sql.CUBRIDTimestamptz; import cubrid.sql.CUBRIDTimetz; import cubrid.jdbc.driver.CUBRIDBinaryString; +import cubrid.jdbc.driver.CUBRIDBlob; +import cubrid.jdbc.driver.CUBRIDClob; +import cubrid.jdbc.driver.CUBRIDConnection; import cubrid.jdbc.driver.CUBRIDException; abstract public class UGetTypeConvertedValue { @@ -75,6 +78,21 @@ else if (data instanceof Boolean) throw new UJciException(UErrorCode.ER_TYPE_CONVERSION); } + static public CUBRIDBlob getBlob(Object data, CUBRIDConnection conn) throws UJciException { + if (data == null) + return null; + else if (data instanceof CUBRIDBlob) + return (CUBRIDBlob) data; + else if (data instanceof byte[]) { + try { + return new CUBRIDBlob(conn, (byte[]) data, false); + } catch (Exception e) { + throw new UJciException(UErrorCode.ER_TYPE_CONVERSION); + } + } + throw new UJciException(UErrorCode.ER_TYPE_CONVERSION); + } + static public boolean getBoolean(Object data) throws UJciException { if (data == null) return false; @@ -121,6 +139,22 @@ static public byte[] getBytes(Object data) throws UJciException { throw new UJciException(UErrorCode.ER_TYPE_CONVERSION); } + static public CUBRIDClob getClob(Object data, CUBRIDConnection conn) throws UJciException { + if (data == null) + return null; + else if (data instanceof CUBRIDClob) + return (CUBRIDClob) data; + else if (data instanceof String) { + try { + return new CUBRIDClob(conn, ((String) data).getBytes(), + conn.getUConnection().getCharset(), false); + } catch (Exception e) { + throw new UJciException(UErrorCode.ER_TYPE_CONVERSION); + } + } + throw new UJciException(UErrorCode.ER_TYPE_CONVERSION); + } + static public Date getDate(Object data) throws UJciException { if (data == null) return null; diff --git a/src/jdbc/cubrid/jdbc/jci/UInputBuffer.java b/src/jdbc/cubrid/jdbc/jci/UInputBuffer.java index 5f79818fa13..034bd0a81c7 100644 --- a/src/jdbc/cubrid/jdbc/jci/UInputBuffer.java +++ b/src/jdbc/cubrid/jdbc/jci/UInputBuffer.java @@ -529,7 +529,7 @@ CUBRIDBlob readBlob(int packedLobHandleSize, CUBRIDConnection conn) throws UJciException { try { byte[] packedLobHandle = readBytes(packedLobHandleSize); - return new CUBRIDBlob(conn, packedLobHandle); + return new CUBRIDBlob(conn, packedLobHandle, true); } catch (Exception e) { throw uconn.createJciException(UErrorCode.ER_UNKNOWN); } @@ -540,7 +540,7 @@ CUBRIDClob readClob(int packedLobHandleSize, CUBRIDConnection conn) try { byte[] packedLobHandle = readBytes(packedLobHandleSize); return new CUBRIDClob(conn, packedLobHandle, conn.getUConnection() - .getCharset()); + .getCharset(), true); } catch (Exception e) { throw uconn.createJciException(UErrorCode.ER_UNKNOWN); } diff --git a/src/jdbc/cubrid/jdbc/jci/UStatement.java b/src/jdbc/cubrid/jdbc/jci/UStatement.java index a7902ccc842..1187755e74f 100755 --- a/src/jdbc/cubrid/jdbc/jci/UStatement.java +++ b/src/jdbc/cubrid/jdbc/jci/UStatement.java @@ -1318,11 +1318,11 @@ synchronized public CUBRIDBlob getBlob(int index) { if (obj == null) return null; - if (obj instanceof CUBRIDBlob) { - return ((CUBRIDBlob) obj); + try { + return (UGetTypeConvertedValue.getBlob(obj, relatedConnection.getCUBRIDConnection())); + } catch (UJciException e) { + e.toUError(errorHandler); } - - errorHandler.setErrorCode(UErrorCode.ER_TYPE_CONVERSION); return null; } @@ -1333,11 +1333,11 @@ synchronized public CUBRIDClob getClob(int index) { if (obj == null) return null; - if (obj instanceof CUBRIDClob) { - return ((CUBRIDClob) obj); + try { + return (UGetTypeConvertedValue.getClob(obj, relatedConnection.getCUBRIDConnection())); + } catch (UJciException e) { + e.toUError(errorHandler); } - - errorHandler.setErrorCode(UErrorCode.ER_TYPE_CONVERSION); return null; } @@ -2147,7 +2147,7 @@ private Object readAAttribute(int index, UInputBuffer inBuffer) String charsetName; size = inBuffer.readInt(); - if (size <= 0) + if (size < 0) return null; typeInfo = readTypeFromData(index, inBuffer);