Browse Source

Support -1 for undetermined length in SqlBinaryValue/SqlCharacterValue

Closes gh-36219
pull/36221/head
Juergen Hoeller 5 days ago
parent
commit
7da65fe4fc
  1. 2
      spring-core/src/main/java/org/springframework/core/io/Resource.java
  2. 18
      spring-jdbc/src/main/java/org/springframework/jdbc/core/support/SqlBinaryValue.java
  3. 40
      spring-jdbc/src/main/java/org/springframework/jdbc/core/support/SqlCharacterValue.java
  4. 36
      spring-jdbc/src/test/java/org/springframework/jdbc/core/support/SqlBinaryValueTests.java
  5. 36
      spring-jdbc/src/test/java/org/springframework/jdbc/core/support/SqlCharacterValueTests.java

2
spring-core/src/main/java/org/springframework/core/io/Resource.java

@ -183,6 +183,7 @@ public interface Resource extends InputStreamSource { @@ -183,6 +183,7 @@ public interface Resource extends InputStreamSource {
/**
* Determine the content length for this resource.
* @return the content length (or -1 if undetermined)
* @throws IOException if the resource cannot be resolved
* (in the file system or as some other known physical resource type)
*/
@ -190,6 +191,7 @@ public interface Resource extends InputStreamSource { @@ -190,6 +191,7 @@ public interface Resource extends InputStreamSource {
/**
* Determine the last-modified timestamp for this resource.
* @return the last-modified timestamp (or 0 if not known)
* @throws IOException if the resource cannot be resolved
* (in the file system or as some other known physical resource type)
*/

18
spring-jdbc/src/main/java/org/springframework/jdbc/core/support/SqlBinaryValue.java

@ -71,7 +71,7 @@ public class SqlBinaryValue implements SqlTypeValue { @@ -71,7 +71,7 @@ public class SqlBinaryValue implements SqlTypeValue {
/**
* Create a new {@code SqlBinaryValue} for the given content.
* @param stream the content stream
* @param length the length of the content
* @param length the length of the content (or -1 if undetermined)
*/
public SqlBinaryValue(InputStream stream, long length) {
this.content = stream;
@ -83,7 +83,7 @@ public class SqlBinaryValue implements SqlTypeValue { @@ -83,7 +83,7 @@ public class SqlBinaryValue implements SqlTypeValue {
* <p>Consider specifying a {@link Resource} with content length support
* when available: {@link SqlBinaryValue#SqlBinaryValue(Resource)}.
* @param resource the resource to obtain a content stream from
* @param length the length of the content
* @param length the length of the content (or -1 if undetermined)
*/
public SqlBinaryValue(InputStreamSource resource, long length) {
this.content = resource;
@ -147,10 +147,20 @@ public class SqlBinaryValue implements SqlTypeValue { @@ -147,10 +147,20 @@ public class SqlBinaryValue implements SqlTypeValue {
throws SQLException {
if (sqlType == Types.BLOB) {
ps.setBlob(paramIndex, is, length);
if (length >= 0) {
ps.setBlob(paramIndex, is, length);
}
else {
ps.setBlob(paramIndex, is);
}
}
else {
ps.setBinaryStream(paramIndex, is, length);
if (length >= 0) {
ps.setBinaryStream(paramIndex, is, length);
}
else {
ps.setBinaryStream(paramIndex, is);
}
}
}

40
spring-jdbc/src/main/java/org/springframework/jdbc/core/support/SqlCharacterValue.java

@ -78,7 +78,7 @@ public class SqlCharacterValue implements SqlTypeValue { @@ -78,7 +78,7 @@ public class SqlCharacterValue implements SqlTypeValue {
/**
* Create a new {@code SqlCharacterValue} for the given content.
* @param reader the content reader
* @param length the length of the content
* @param length the length of the content (or -1 if undetermined)
*/
public SqlCharacterValue(Reader reader, long length) {
this.content = reader;
@ -88,7 +88,7 @@ public class SqlCharacterValue implements SqlTypeValue { @@ -88,7 +88,7 @@ public class SqlCharacterValue implements SqlTypeValue {
/**
* Create a new {@code SqlCharacterValue} for the given content.
* @param asciiStream the content as ASCII stream
* @param length the length of the content
* @param length the length of the content (or -1 if undetermined)
*/
public SqlCharacterValue(InputStream asciiStream, long length) {
this.content = asciiStream;
@ -109,8 +109,8 @@ public class SqlCharacterValue implements SqlTypeValue { @@ -109,8 +109,8 @@ public class SqlCharacterValue implements SqlTypeValue {
else if (this.content instanceof Reader reader) {
setReader(ps, paramIndex, sqlType, reader, this.length);
}
else if (this.content instanceof InputStream asciiStream) {
ps.setAsciiStream(paramIndex, asciiStream, this.length);
else if (this.content instanceof InputStream inputStream) {
setInputStream(ps, paramIndex, inputStream, this.length);
}
else {
throw new IllegalArgumentException("Illegal content type: " + this.content.getClass().getName());
@ -135,13 +135,39 @@ public class SqlCharacterValue implements SqlTypeValue { @@ -135,13 +135,39 @@ public class SqlCharacterValue implements SqlTypeValue {
throws SQLException {
if (sqlType == Types.CLOB) {
ps.setClob(paramIndex, reader, length);
if (length >= 0) {
ps.setClob(paramIndex, reader, length);
}
else {
ps.setClob(paramIndex, reader);
}
}
else if (sqlType == Types.NCLOB) {
ps.setNClob(paramIndex, reader, length);
if (length >= 0) {
ps.setNClob(paramIndex, reader, length);
}
else {
ps.setNClob(paramIndex, reader);
}
}
else {
ps.setCharacterStream(paramIndex, reader, length);
if (length >= 0) {
ps.setCharacterStream(paramIndex, reader, length);
}
else {
ps.setCharacterStream(paramIndex, reader);
}
}
}
private void setInputStream(PreparedStatement ps, int paramIndex, InputStream is, long length)
throws SQLException {
if (length >= 0) {
ps.setAsciiStream(paramIndex, is, length);
}
else {
ps.setAsciiStream(paramIndex, is);
}
}

36
spring-jdbc/src/test/java/org/springframework/jdbc/core/support/SqlBinaryValueTests.java

@ -65,6 +65,15 @@ class SqlBinaryValueTests { @@ -65,6 +65,15 @@ class SqlBinaryValueTests {
verify(ps).setBinaryStream(1, content, 3L);
}
@Test
void withInputStreamUndeterminedLength() throws SQLException {
InputStream content = new ByteArrayInputStream(new byte[] {0, 1, 2});
SqlBinaryValue value = new SqlBinaryValue(content, -1);
PreparedStatement ps = mock();
value.setTypeValue(ps, 1, JdbcUtils.TYPE_UNKNOWN, null);
verify(ps).setBinaryStream(1, content);
}
@Test
void withInputStreamForBlob() throws SQLException {
InputStream content = new ByteArrayInputStream(new byte[] {0, 1, 2});
@ -74,6 +83,15 @@ class SqlBinaryValueTests { @@ -74,6 +83,15 @@ class SqlBinaryValueTests {
verify(ps).setBlob(1, content, 3L);
}
@Test
void withInputStreamForBlobUndeterminedLength() throws SQLException {
InputStream content = new ByteArrayInputStream(new byte[] {0, 1, 2});
SqlBinaryValue value = new SqlBinaryValue(content, -1);
PreparedStatement ps = mock();
value.setTypeValue(ps, 1, Types.BLOB, null);
verify(ps).setBlob(1, content);
}
@Test
void withInputStreamSource() throws SQLException {
InputStream content = new ByteArrayInputStream(new byte[] {0, 1, 2});
@ -83,6 +101,15 @@ class SqlBinaryValueTests { @@ -83,6 +101,15 @@ class SqlBinaryValueTests {
verify(ps).setBinaryStream(1, content, 3L);
}
@Test
void withInputStreamSourceUndeterminedLength() throws SQLException {
InputStream content = new ByteArrayInputStream(new byte[] {0, 1, 2});
SqlBinaryValue value = new SqlBinaryValue(() -> content, -1);
PreparedStatement ps = mock();
value.setTypeValue(ps, 1, JdbcUtils.TYPE_UNKNOWN, null);
verify(ps).setBinaryStream(1, content);
}
@Test
void withInputStreamSourceForBlob() throws SQLException {
InputStream content = new ByteArrayInputStream(new byte[] {0, 1, 2});
@ -92,6 +119,15 @@ class SqlBinaryValueTests { @@ -92,6 +119,15 @@ class SqlBinaryValueTests {
verify(ps).setBlob(1, content, 3L);
}
@Test
void withInputStreamSourceForBlobUndeterminedLength() throws SQLException {
InputStream content = new ByteArrayInputStream(new byte[] {0, 1, 2});
SqlBinaryValue value = new SqlBinaryValue(() -> content, -1);
PreparedStatement ps = mock();
value.setTypeValue(ps, 1, Types.BLOB, null);
verify(ps).setBlob(1, content);
}
@Test
void withResource() throws SQLException {
byte[] content = new byte[] {0, 1, 2};

36
spring-jdbc/src/test/java/org/springframework/jdbc/core/support/SqlCharacterValueTests.java

@ -104,6 +104,15 @@ class SqlCharacterValueTests { @@ -104,6 +104,15 @@ class SqlCharacterValueTests {
verify(ps).setCharacterStream(1, content, 3L);
}
@Test
void withReaderUndeterminedLength() throws SQLException {
Reader content = new StringReader("abc");
SqlCharacterValue value = new SqlCharacterValue(content, -1);
PreparedStatement ps = mock();
value.setTypeValue(ps, 1, JdbcUtils.TYPE_UNKNOWN, null);
verify(ps).setCharacterStream(1, content);
}
@Test
void withReaderForClob() throws SQLException {
Reader content = new StringReader("abc");
@ -113,6 +122,15 @@ class SqlCharacterValueTests { @@ -113,6 +122,15 @@ class SqlCharacterValueTests {
verify(ps).setClob(1, content, 3L);
}
@Test
void withReaderForClobUndeterminedLength() throws SQLException {
Reader content = new StringReader("abc");
SqlCharacterValue value = new SqlCharacterValue(content, -1);
PreparedStatement ps = mock();
value.setTypeValue(ps, 1, Types.CLOB, null);
verify(ps).setClob(1, content);
}
@Test
void withReaderForNClob() throws SQLException {
Reader content = new StringReader("abc");
@ -122,6 +140,15 @@ class SqlCharacterValueTests { @@ -122,6 +140,15 @@ class SqlCharacterValueTests {
verify(ps).setNClob(1, content, 3L);
}
@Test
void withReaderForNClobUndeterminedLength() throws SQLException {
Reader content = new StringReader("abc");
SqlCharacterValue value = new SqlCharacterValue(content, -1);
PreparedStatement ps = mock();
value.setTypeValue(ps, 1, Types.NCLOB, null);
verify(ps).setNClob(1, content);
}
@Test
void withAsciiStream() throws SQLException {
InputStream content = new ByteArrayInputStream("abc".getBytes(StandardCharsets.US_ASCII));
@ -131,4 +158,13 @@ class SqlCharacterValueTests { @@ -131,4 +158,13 @@ class SqlCharacterValueTests {
verify(ps).setAsciiStream(1, content, 3L);
}
@Test
void withAsciiStreamUndeterminedLength() throws SQLException {
InputStream content = new ByteArrayInputStream("abc".getBytes(StandardCharsets.US_ASCII));
SqlCharacterValue value = new SqlCharacterValue(content, -1);
PreparedStatement ps = mock();
value.setTypeValue(ps, 1, JdbcUtils.TYPE_UNKNOWN, null);
verify(ps).setAsciiStream(1, content);
}
}

Loading…
Cancel
Save