Skip to content
Merged

dev #28

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
4758485
Blob fix
rene-ye Jan 3, 2018
5f96797
changed function accessability
rene-ye Jan 4, 2018
83da731
Length fix
rene-ye Jan 26, 2018
c8cc20b
Merge pull request #11 from Microsoft/dev
rene-ye Jan 30, 2018
ded790c
Added information to error message
rene-ye Feb 5, 2018
c2d0997
unexpected error message
rene-ye Feb 6, 2018
923c220
Kerberos DC
rene-ye Feb 8, 2018
25301e6
Added information to error message
rene-ye Feb 5, 2018
506e070
Merge pull request #14 from rene-ye/KerbConsDel
rene-ye Feb 8, 2018
4a0e69d
Merge pull request #15 from rene-ye/UnexpectedErrMsg
rene-ye Feb 8, 2018
7a640c2
Merge pull request #16 from v-afrafi/retryLogic
rene-ye Feb 9, 2018
748aed7
Merge pull request #17 from Microsoft/dev
rene-ye Feb 19, 2018
45c65f5
Merge pull request #18 from rene-ye/blobStream
rene-ye Feb 19, 2018
f421d4c
Merge pull request #19 from Microsoft/dev
rene-ye Feb 19, 2018
91bf4d3
minor stream verification
rene-ye Feb 22, 2018
3ba5f1b
Reimplemented Blob fixes
rene-ye Feb 22, 2018
9a1300e
Additional tests
rene-ye Feb 22, 2018
19e8339
merge conflict #1
rene-ye Feb 22, 2018
bc074f2
Merge branch 'allChangesForTesting' into blobStream
rene-ye Feb 22, 2018
09fe7e4
Revert "Merge branch 'allChangesForTesting' into blobStream"
rene-ye Feb 22, 2018
b071f23
comment edit
rene-ye Feb 22, 2018
4d91bc9
slight adjustments to implementation
rene-ye Feb 23, 2018
48b9b85
SimpleInputStream fix
rene-ye Feb 23, 2018
c73f5ba
Update SNAPSHOT for upcoming preview release.
cheenamalhotra Feb 28, 2018
066b3c3
Merge pull request #639 from cheenamalhotra/dev
cheenamalhotra Feb 28, 2018
7a73172
Update Maven dependency versions for Junit Tests
cheenamalhotra Feb 28, 2018
ca0e6c0
Added a free() test
rene-ye Feb 28, 2018
bdae0b8
Merge pull request #24 from Microsoft/dev
rene-ye Mar 1, 2018
345cfa4
Merge pull request #25 from Microsoft/dev
rene-ye Mar 1, 2018
bbd4ee4
Merge pull request #640 from cheenamalhotra/dev
cheenamalhotra Mar 5, 2018
7169a3c
Merge branch 'dev' into blobStream
rene-ye Mar 5, 2018
08bd1e6
Merge branch 'dev' into UnexpectedErrMsg
rene-ye Mar 5, 2018
625a721
code style changes
rene-ye Mar 6, 2018
2512abf
remove indent
rene-ye Mar 6, 2018
923a6f4
Merge pull request #635 from rene-ye/UnexpectedErrMsg
rene-ye Mar 6, 2018
152e71b
Merge branch 'dev' into blobStream
rene-ye Mar 6, 2018
db0f41a
Merge pull request #595 from rene-ye/blobStream
rene-ye Mar 6, 2018
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
10 changes: 5 additions & 5 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<version>6.4.0.${jreVersion}</version>
<version>6.5.0-SNAPSHOT.${jreVersion}-preview</version>
<packaging>jar</packaging>

<name>Microsoft JDBC Driver for SQL Server</name>
Expand Down Expand Up @@ -40,8 +40,8 @@

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<junit.platform.version>1.0.0-M3</junit.platform.version>
<junit.jupiter.version>5.0.0-M3</junit.jupiter.version>
<junit.platform.version>1.1.0</junit.platform.version>
<junit.jupiter.version>5.1.0</junit.jupiter.version>
</properties>

<dependencies>
Expand Down Expand Up @@ -118,13 +118,13 @@
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>2.7.4</version>
<version>2.7.8</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2 </artifactId>
<version>2.1.1</version>
<version>2.2.0</version>
<scope>test</scope>
</dependency>
<!--
Expand Down
13 changes: 13 additions & 0 deletions src/main/java/com/microsoft/sqlserver/jdbc/SQLServerBlob.java
Original file line number Diff line number Diff line change
Expand Up @@ -232,10 +232,23 @@ public byte[] getBytes(long pos,
*/
public long length() throws SQLException {
checkClosed();
if (value == null && activeStreams.get(0) instanceof PLPInputStream) {
return (long)((PLPInputStream)activeStreams.get(0)).payloadLength;
}
getBytesFromStream();
return value.length;
}

/**
* Function for the result set to maintain blobs it has created
* @throws SQLException
*/
void fillByteArray() throws SQLException {
if(!isClosed) {
getBytesFromStream();
}
}

/**
* Converts stream to byte[]
* @throws SQLServerException
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1450,6 +1450,8 @@ public NClob getNClob(String parameterName) throws SQLException {
int l = 0;
if (paramNames != null)
l = paramNames.size();
if (l == 0)//Server didn't return anything, user might not have access
return 1;//attempting to look up the first column will return no access exception

// handle `@name` as well as `name`, since `@name` is what's returned
// by DatabaseMetaData#getProcedureColumns
Expand Down
28 changes: 28 additions & 0 deletions src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ final void setCurrentRowType(RowType rowType) {
* occurs
*/
private Closeable activeStream;
private Blob activeBlob;

/**
* A window of fetchSize quickly accessible rows for scrollable result sets
Expand Down Expand Up @@ -669,6 +670,7 @@ final Column getColumn(int columnIndex) throws SQLServerException {
// before moving to another one.
if (null != activeStream) {
try {
fillBlobs();
activeStream.close();
}
catch (IOException e) {
Expand Down Expand Up @@ -747,6 +749,7 @@ private Column loadColumn(int index) throws SQLServerException {
/* ----------------- JDBC API methods ------------------ */

private void moverInit() throws SQLServerException {
fillBlobs();
cancelInsert();
cancelUpdates();
}
Expand Down Expand Up @@ -1035,6 +1038,7 @@ public boolean next() throws SQLServerException {
public boolean wasNull() throws SQLServerException {
loggerExternal.entering(getClassNameLogging(), "wasNull");
checkClosed();
fillBlobs();
loggerExternal.exiting(getClassNameLogging(), "wasNull", lastValueWasNull);
return lastValueWasNull;
}
Expand Down Expand Up @@ -1892,6 +1896,7 @@ Column getterGetColumn(int index) throws SQLServerException {
if (logger.isLoggable(java.util.logging.Level.FINER))
logger.finer(toString() + " Getting Column:" + index);

fillBlobs();
return loadColumn(index);
}

Expand Down Expand Up @@ -2657,6 +2662,7 @@ public Blob getBlob(int i) throws SQLServerException {
checkClosed();
Blob value = (Blob) getValue(i, JDBCType.BLOB);
loggerExternal.exiting(getClassNameLogging(), "getBlob", value);
activeBlob = value;
return value;
}

Expand All @@ -2665,6 +2671,7 @@ public Blob getBlob(String colName) throws SQLServerException {
checkClosed();
Blob value = (Blob) getValue(findColumn(colName), JDBCType.BLOB);
loggerExternal.exiting(getClassNameLogging(), "getBlob", value);
activeBlob = value;
return value;
}

Expand Down Expand Up @@ -6507,6 +6514,24 @@ final void doServerFetch(int fetchType,
scrollWindow.reset();
}
}

/*
* Iterates through the list of objects which rely on the stream that's about to be closed, filling them with their data
* Will skip over closed blobs, implemented in SQLServerBlob
*/
private void fillBlobs() {
if (null != activeBlob && activeBlob instanceof SQLServerBlob) {
try {
((SQLServerBlob)activeBlob).fillByteArray();
} catch (SQLException e) {
if (logger.isLoggable(java.util.logging.Level.FINER)) {
logger.finer(toString() + "Filling blobs before closing: " + e.getMessage());
}
} finally {
activeBlob = null;
}
}
}

/**
* Discards the contents of the current fetch buffer.
Expand All @@ -6519,6 +6544,9 @@ final void doServerFetch(int fetchType,
* fetch buffer is considered to be discarded.
*/
private void discardFetchBuffer() {
//fills blobs before discarding anything
fillBlobs();

// Clear the TDSReader mark at the start of the fetch buffer
fetchBuffer.clearStartMark();

Expand Down
139 changes: 139 additions & 0 deletions src/test/java/com/microsoft/sqlserver/jdbc/unit/lobs/lobsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,59 @@ else if (lobClass == Blob.class)
}
}

@Test
@DisplayName("testFreedBlobs")
private void testFreedBlobs(Class lobClass,
boolean isResultSet) throws SQLException {
String types[] = {"varbinary(max)"};
try {
table = createTable(table, types, false); // create empty table
int size = 10000;

byte[] data = new byte[size];
ThreadLocalRandom.current().nextBytes(data);

Blob blob = null;
InputStream stream = null;
for (int i = 0; i < 5; i++)
{
PreparedStatement ps = conn.prepareStatement("INSERT INTO " + table.getEscapedTableName() + " VALUES(?)");
blob = conn.createBlob();
blob.setBytes(1, data);
ps.setBlob(1, blob);
ps.executeUpdate();
}

byte[] chunk = new byte[size];
ResultSet rs = stmt.executeQuery("select * from " + table.getEscapedTableName());
for (int i = 0; i < 5; i++)
{
rs.next();

blob = rs.getBlob(1);
stream = blob.getBinaryStream();
while (stream.available() > 0)
stream.read();
blob.free();
try {
stream = blob.getBinaryStream();
} catch (SQLException e) {
assertTrue(e.getMessage().contains("This Blob object has been freed."));
}
}
rs.close();
try {
stream = blob.getBinaryStream();
} catch (SQLException e) {
assertTrue(e.getMessage().contains("This Blob object has been freed."));
}
}
catch (Exception e) {
this.dropTables(table);
e.printStackTrace();
}
}

@Test
@DisplayName("testMultipleCloseCharacterStream")
public void testMultipleCloseCharacterStream() throws Exception {
Expand Down Expand Up @@ -413,6 +466,92 @@ public void testUpdatorClob() throws Exception {
String types[] = {"varchar(max)"};
testUpdateLobs(types, Clob.class);
}

@Test
@DisplayName("readBlobStreamAfterClosingRS")
public void readBlobStreamAfterClosingRS() throws Exception {
String types[] = {"varbinary(max)"};
table = createTable(table, types, false); // create empty table
int size = 10000;

byte[] data = new byte[size];
ThreadLocalRandom.current().nextBytes(data);

Blob blob = null;
InputStream stream = null;
PreparedStatement ps = conn.prepareStatement("INSERT INTO " + table.getEscapedTableName() + " VALUES(?)");
blob = conn.createBlob();
blob.setBytes(1, data);
ps.setBlob(1, blob);
ps.executeUpdate();

byte[] chunk = new byte[size];
ResultSet rs = stmt.executeQuery("select * from " + table.getEscapedTableName());
rs.next();

blob = rs.getBlob(1);
stream = blob.getBinaryStream();
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
int read = 0;
while ((read = stream.read(chunk)) > 0)
buffer.write(chunk, 0, read);
assertEquals(chunk.length, size);
rs.close();
stream = blob.getBinaryStream();
buffer = new ByteArrayOutputStream();
read = 0;
while ((read = stream.read(chunk)) > 0)
buffer.write(chunk, 0, read);
assertEquals(chunk.length, size);

if (null != blob)
blob.free();
dropTables(table);
}

@Test
@DisplayName("readMultipleBlobStreamsThenCloseRS")
public void readMultipleBlobStreamsThenCloseRS() throws Exception {
String types[] = {"varbinary(max)"};
table = createTable(table, types, false);
int size = 10000;

byte[] data = new byte[size];
Blob[] blobs = {null, null, null, null, null};
InputStream stream = null;
for (int i = 0; i < 5; i++)//create 5 blobs
{
PreparedStatement ps = conn.prepareStatement("INSERT INTO " + table.getEscapedTableName() + " VALUES(?)");
blobs[i] = conn.createBlob();
ThreadLocalRandom.current().nextBytes(data);
blobs[i].setBytes(1, data);
ps.setBlob(1, blobs[i]);
ps.executeUpdate();
}
byte[] chunk = new byte[size];
ResultSet rs = stmt.executeQuery("select * from " + table.getEscapedTableName());
for (int i = 0; i < 5; i++)
{
rs.next();
blobs[i] = rs.getBlob(1);
stream = blobs[i].getBinaryStream();
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
int read = 0;
while ((read = stream.read(chunk)) > 0)
buffer.write(chunk, 0, read);
assertEquals(chunk.length, size);
}
rs.close();
for (int i = 0; i < 5; i++)
{
stream = blobs[i].getBinaryStream();
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
int read = 0;
while ((read = stream.read(chunk)) > 0)
buffer.write(chunk, 0, read);
assertEquals(chunk.length, size);
}
}

private void testUpdateLobs(String types[],
Class lobClass) throws Exception {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,16 +92,16 @@ public static void compareExpectedAndActual(int dataType,
else
switch (dataType) {
case java.sql.Types.BIGINT:
assertTrue((((Long) expectedValue).longValue() == ((Long) actualValue).longValue()), "Unexpected bigint value");
assertTrue((((Long) expectedValue).longValue() == ((Long) actualValue).longValue()), "Unexpected bigint value. Expected:" + ((Long) expectedValue).longValue() + " Actual:" + ((Long) actualValue).longValue());
break;

case java.sql.Types.INTEGER:
assertTrue((((Integer) expectedValue).intValue() == ((Integer) actualValue).intValue()), "Unexpected int value");
assertTrue((((Integer) expectedValue).intValue() == ((Integer) actualValue).intValue()), "Unexpected int value. Expected:" + ((Integer) expectedValue).intValue() + " Actual:" + ((Integer) actualValue).intValue());
break;

case java.sql.Types.SMALLINT:
case java.sql.Types.TINYINT:
assertTrue((((Short) expectedValue).shortValue() == ((Short) actualValue).shortValue()), "Unexpected smallint/tinyint value");
assertTrue((((Short) expectedValue).shortValue() == ((Short) actualValue).shortValue()), "Unexpected smallint/tinyint value. Expected:" + ((Short) expectedValue).shortValue() + " Actual:" + ((Short) actualValue).shortValue());
break;

case java.sql.Types.BIT:
Expand All @@ -115,11 +115,11 @@ public static void compareExpectedAndActual(int dataType,
break;

case java.sql.Types.DOUBLE:
assertTrue((((Double) expectedValue).doubleValue() == ((Double) actualValue).doubleValue()), "Unexpected float value");
assertTrue((((Double) expectedValue).doubleValue() == ((Double) actualValue).doubleValue()), "Unexpected double value. Expected:" + ((Double) expectedValue).doubleValue() + " Actual:" + ((Double) actualValue).doubleValue());
break;

case java.sql.Types.REAL:
assertTrue((((Float) expectedValue).floatValue() == ((Float) actualValue).floatValue()), "Unexpected real value");
assertTrue((((Float) expectedValue).floatValue() == ((Float) actualValue).floatValue()), "Unexpected real/float value. Expected:" + ((Float) expectedValue).floatValue() + " Actual:" + ((Float) actualValue).floatValue());
break;

case java.sql.Types.VARCHAR:
Expand Down