Skip to content

Commit

Permalink
[APIS-825] Supports ResultSet.getBlob() or ResultSet.getClob() method…
Browse files Browse the repository at this point in the history
… to read BIT VARYING type or VARCHAR type. (#2303) (#2329)

http://jira.cubrid.org/browse/APIS-825

backport #2303
  • Loading branch information
hornetmj authored May 20, 2020
1 parent 4f6d97a commit 7eff8bb
Show file tree
Hide file tree
Showing 6 changed files with 144 additions and 54 deletions.
41 changes: 27 additions & 14 deletions src/jdbc/cubrid/jdbc/driver/CUBRIDBlob.java
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ public class CUBRIDBlob implements Blob {
*/
private CUBRIDConnection conn;
private boolean isWritable;
private boolean isLobLocator;
private CUBRIDLobHandle lobHandle;

private ArrayList<java.io.Flushable> streamList = new ArrayList<java.io.Flushable>();
Expand All @@ -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);
}

/*
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -253,6 +261,7 @@ public void free() throws SQLException {
lobHandle = null;
streamList = null;
isWritable = false;
isLobLocator = true;
}

public CUBRIDLobHandle getLobHandle() {
Expand All @@ -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) {
Expand Down
55 changes: 46 additions & 9 deletions src/jdbc/cubrid/jdbc/driver/CUBRIDClob.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -60,6 +61,7 @@ public class CUBRIDClob implements Clob {
*/
private CUBRIDConnection conn;
private boolean isWritable;
private boolean isLobLocator;
private CUBRIDLobHandle lobHandle;
private String charsetName;

Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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));
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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;
Expand Down
46 changes: 26 additions & 20 deletions src/jdbc/cubrid/jdbc/driver/CUBRIDLobHandle.java
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
34 changes: 34 additions & 0 deletions src/jdbc/cubrid/jdbc/jci/UGetTypeConvertedValue.java
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
4 changes: 2 additions & 2 deletions src/jdbc/cubrid/jdbc/jci/UInputBuffer.java
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand All @@ -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);
}
Expand Down
18 changes: 9 additions & 9 deletions src/jdbc/cubrid/jdbc/jci/UStatement.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand All @@ -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;
}

Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit 7eff8bb

Please sign in to comment.