mirror of
https://github.com/spring-projects/spring-framework
synced 2026-06-08 17:33:33 +00:00
Support -1 for undetermined length in SqlBinaryValue/SqlCharacterValue
Closes gh-36219
This commit is contained in:
@@ -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 {
|
||||
|
||||
/**
|
||||
* 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)
|
||||
*/
|
||||
|
||||
+14
-4
@@ -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 {
|
||||
* <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 {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+33
-7
@@ -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 {
|
||||
/**
|
||||
* 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 {
|
||||
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 {
|
||||
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
@@ -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 {
|
||||
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 {
|
||||
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 {
|
||||
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
@@ -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 {
|
||||
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 {
|
||||
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 {
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user