Skip to content

Commit

Permalink
Merge pull request #172 from v-afrafi/lobs_materialization
Browse files Browse the repository at this point in the history
Lobs materialisation issue
  • Loading branch information
Suraiya Hameed authored Mar 28, 2017
2 parents 48e622e + 49bfc85 commit 9cd0229
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 20 deletions.
52 changes: 43 additions & 9 deletions src/main/java/com/microsoft/sqlserver/jdbc/SQLServerBlob.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,9 @@ public final class SQLServerBlob implements java.sql.Blob, java.io.Serializable

static private final Logger logger = Logger.getLogger("com.microsoft.sqlserver.jdbc.internals.SQLServerBlob");

static private final AtomicInteger baseID = new AtomicInteger(0); // Unique id generator for each instance (used for logging).
static private final AtomicInteger baseID = new AtomicInteger(0); // Unique id generator for each instance (used for logging).
final private String traceID;

final public String toString() {
return traceID;
}
Expand Down Expand Up @@ -94,7 +94,7 @@ public SQLServerBlob(SQLServerConnection connection,

SQLServerBlob(BaseInputStream stream) throws SQLServerException {
traceID = " SQLServerBlob:" + nextInstanceID();
value = stream.getBytes();
activeStreams.add(stream);
if (logger.isLoggable(Level.FINE))
logger.fine(toString() + " created by (null connection)");
}
Expand Down Expand Up @@ -142,7 +142,19 @@ private void checkClosed() throws SQLServerException {
public InputStream getBinaryStream() throws SQLException {
checkClosed();

return getBinaryStreamInternal(0, value.length);
if (null == value && !activeStreams.isEmpty()) {
InputStream stream = (InputStream) activeStreams.get(0);
try {
stream.reset();
}
catch (IOException e) {
throw new SQLServerException(e.getMessage(), null, 0, e);
}
return (InputStream) activeStreams.get(0);
}
else {
return getBinaryStreamInternal(0, value.length);
}
}

public InputStream getBinaryStream(long pos,
Expand Down Expand Up @@ -182,6 +194,7 @@ public byte[] getBytes(long pos,
int length) throws SQLException {
checkClosed();

getBytesFromStream();
if (pos < 1) {
MessageFormat form = new MessageFormat(SQLServerException.getErrString("R_invalidPositionIndex"));
Object[] msgArgs = {new Long(pos)};
Expand Down Expand Up @@ -219,9 +232,26 @@ public byte[] getBytes(long pos,
*/
public long length() throws SQLException {
checkClosed();

getBytesFromStream();
return value.length;
}

/**
* Converts stream to byte[]
* @throws SQLServerException
*/
private void getBytesFromStream() throws SQLServerException {
if (null == value) {
BaseInputStream stream = (BaseInputStream) activeStreams.get(0);
try {
stream.reset();
}
catch (IOException e) {
throw new SQLServerException(e.getMessage(), null, 0, e);
}
value = stream.getBytes();
}
}

/**
* Retrieves the byte position in the BLOB value designated by this Blob object at which pattern begins. The search begins at position start.
Expand All @@ -237,7 +267,8 @@ public long length() throws SQLException {
public long position(Blob pattern,
long start) throws SQLException {
checkClosed();


getBytesFromStream();
if (start < 1) {
MessageFormat form = new MessageFormat(SQLServerException.getErrString("R_invalidPositionIndex"));
Object[] msgArgs = {new Long(start)};
Expand Down Expand Up @@ -265,7 +296,7 @@ public long position(Blob pattern,
public long position(byte[] bPattern,
long start) throws SQLException {
checkClosed();

getBytesFromStream();
if (start < 1) {
MessageFormat form = new MessageFormat(SQLServerException.getErrString("R_invalidPositionIndex"));
Object[] msgArgs = {new Long(start)};
Expand Down Expand Up @@ -309,7 +340,8 @@ public long position(byte[] bPattern,
*/
public void truncate(long len) throws SQLException {
checkClosed();

getBytesFromStream();

if (len < 0) {
MessageFormat form = new MessageFormat(SQLServerException.getErrString("R_invalidLength"));
Object[] msgArgs = {new Long(len)};
Expand Down Expand Up @@ -357,7 +389,8 @@ public java.io.OutputStream setBinaryStream(long pos) throws SQLException {
public int setBytes(long pos,
byte[] bytes) throws SQLException {
checkClosed();


getBytesFromStream();
if (null == bytes)
SQLServerException.makeFromDriverError(con, null, SQLServerException.getErrString("R_cantSetNull"), null, true);

Expand Down Expand Up @@ -389,6 +422,7 @@ public int setBytes(long pos,
int offset,
int len) throws SQLException {
checkClosed();
getBytesFromStream();

if (null == bytes)
SQLServerException.makeFromDriverError(con, null, SQLServerException.getErrString("R_cantSetNull"), null, true);
Expand Down
69 changes: 60 additions & 9 deletions src/main/java/com/microsoft/sqlserver/jdbc/SQLServerClob.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.Serializable;
import java.io.StringReader;
Expand Down Expand Up @@ -48,19 +49,19 @@ public class SQLServerClob extends SQLServerClobBase implements Clob {
@Deprecated
public SQLServerClob(SQLServerConnection connection,
String data) {
super(connection, data, (null == connection) ? null : connection.getDatabaseCollation(), logger);
super(connection, data, (null == connection) ? null : connection.getDatabaseCollation(), logger, null);

if (null == data)
throw new NullPointerException(SQLServerException.getErrString("R_cantSetNull"));
}

SQLServerClob(SQLServerConnection connection) {
super(connection, "", connection.getDatabaseCollation(), logger);
super(connection, "", connection.getDatabaseCollation(), logger, null);
}

SQLServerClob(BaseInputStream stream,
TypeInfo typeInfo) throws SQLServerException, UnsupportedEncodingException {
super(null, new String(stream.getBytes(), typeInfo.getCharset()), typeInfo.getSQLCollation(), logger);
super(null, stream, typeInfo.getSQLCollation(), logger , typeInfo);
}

final JDBCType getJdbcType() {
Expand All @@ -78,6 +79,8 @@ abstract class SQLServerClobBase implements Serializable {
private final SQLCollation sqlCollation;

private boolean isClosed = false;

private final TypeInfo typeInfo;

// Active streams which must be closed when the Clob/NClob is closed
//
Expand All @@ -94,7 +97,7 @@ final public String toString() {
return traceID;
}

static private final AtomicInteger baseID = new AtomicInteger(0); // Unique id generator for each instance (used for logging).
static private final AtomicInteger baseID = new AtomicInteger(0); // Unique id generator for each instance (used for logging).
// Returns unique id for each instance.

private static int nextInstanceID() {
Expand All @@ -118,14 +121,24 @@ private String getDisplayClassName() {
* @param collation
* the data collation
* @param logger
* logger information
* @param typeInfo
* the column TYPE_INFO
*/
SQLServerClobBase(SQLServerConnection connection,
String data,
Object data,
SQLCollation collation,
Logger logger) {
Logger logger,
TypeInfo typeInfo) {
this.con = connection;
this.value = data;
if (data instanceof BaseInputStream) {
activeStreams.add((Closeable) data);
}
else {
this.value = (String) data;
}
this.sqlCollation = collation;
this.typeInfo = typeInfo;
SQLServerClobBase.logger = logger;

if (logger.isLoggable(Level.FINE)) {
Expand Down Expand Up @@ -191,9 +204,23 @@ public InputStream getAsciiStream() throws SQLException {
DataTypes.throwConversionError(getDisplayClassName(), "AsciiStream");

// Need to use a BufferedInputStream since the stream returned by this method is assumed to support mark/reset
InputStream getterStream = new BufferedInputStream(new ReaderInputStream(new StringReader(value), US_ASCII, value.length()));
InputStream getterStream = null;
if (null == value && !activeStreams.isEmpty()) {
InputStream inputStream = (InputStream) activeStreams.get(0);
try {
inputStream.reset();
getterStream = new BufferedInputStream(
new ReaderInputStream(new InputStreamReader(inputStream), US_ASCII, inputStream.available()));
}
catch (IOException e) {
throw new SQLServerException(e.getMessage(), null, 0, e);
}
}
else {
getStringFromStream();
getterStream = new BufferedInputStream(new ReaderInputStream(new StringReader(value), US_ASCII, value.length()));

activeStreams.add(getterStream);
}
return getterStream;
}

Expand All @@ -207,6 +234,7 @@ public InputStream getAsciiStream() throws SQLException {
public Reader getCharacterStream() throws SQLException {
checkClosed();

getStringFromStream();
Reader getterStream = new StringReader(value);
activeStreams.add(getterStream);
return getterStream;
Expand Down Expand Up @@ -247,6 +275,7 @@ public String getSubString(long pos,
int length) throws SQLException {
checkClosed();

getStringFromStream();
if (pos < 1) {
MessageFormat form = new MessageFormat(SQLServerException.getErrString("R_invalidPositionIndex"));
Object[] msgArgs = {new Long(pos)};
Expand Down Expand Up @@ -285,8 +314,26 @@ public String getSubString(long pos,
public long length() throws SQLException {
checkClosed();

getStringFromStream();
return value.length();
}

/**
* Converts the stream to String
* @throws SQLServerException
*/
private void getStringFromStream() throws SQLServerException {
if (null == value && !activeStreams.isEmpty()) {
BaseInputStream stream = (BaseInputStream) activeStreams.get(0);
try {
stream.reset();
}
catch (IOException e) {
throw new SQLServerException(e.getMessage(), null, 0, e);
}
value = new String((stream).getBytes(), typeInfo.getCharset());
}
}

/**
* Retrieves the character position at which the specified Clob object searchstr appears in this Clob object. The search begins at position start.
Expand All @@ -303,6 +350,7 @@ public long position(Clob searchstr,
long start) throws SQLException {
checkClosed();

getStringFromStream();
if (start < 1) {
MessageFormat form = new MessageFormat(SQLServerException.getErrString("R_invalidPositionIndex"));
Object[] msgArgs = {new Long(start)};
Expand Down Expand Up @@ -331,6 +379,7 @@ public long position(String searchstr,
long start) throws SQLException {
checkClosed();

getStringFromStream();
if (start < 1) {
MessageFormat form = new MessageFormat(SQLServerException.getErrString("R_invalidPositionIndex"));
Object[] msgArgs = {new Long(start)};
Expand Down Expand Up @@ -362,6 +411,7 @@ public long position(String searchstr,
public void truncate(long len) throws SQLException {
checkClosed();

getStringFromStream();
if (len < 0) {
MessageFormat form = new MessageFormat(SQLServerException.getErrString("R_invalidLength"));
Object[] msgArgs = {new Long(len)};
Expand Down Expand Up @@ -460,6 +510,7 @@ public int setString(long pos,
int len) throws SQLException {
checkClosed();

getStringFromStream();
if (null == str)
SQLServerException.makeFromDriverError(con, null, SQLServerException.getErrString("R_cantSetNull"), null, true);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ public final class SQLServerNClob extends SQLServerClobBase implements NClob {
private static final Logger logger = Logger.getLogger("com.microsoft.sqlserver.jdbc.internals.SQLServerNClob");

SQLServerNClob(SQLServerConnection connection) {
super(connection, "", connection.getDatabaseCollation(), logger);
super(connection, "", connection.getDatabaseCollation(), logger, null);
}

SQLServerNClob(BaseInputStream stream,
TypeInfo typeInfo) throws SQLServerException, UnsupportedEncodingException {
super(null, new String(stream.getBytes(), typeInfo.getCharset()), typeInfo.getSQLCollation(), logger);
super(null, stream, typeInfo.getSQLCollation(), logger , typeInfo);
}

final JDBCType getJdbcType() {
Expand Down

0 comments on commit 9cd0229

Please sign in to comment.