Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[APIS-825] Supports ResultSet.getBlob() or ResultSet.getClob() method to read BIT VARYING type or VARCHAR type. (#2303) #2329

Merged
merged 1 commit into from
May 20, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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