package com.revolsys.gis.postgresql.type; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.nio.charset.StandardCharsets; import java.sql.Blob; import java.sql.PreparedStatement; import java.sql.SQLException; import java.util.Map; import org.apache.commons.dbcp2.DelegatingConnection; import org.postgresql.PGConnection; import org.postgresql.largeobject.LargeObject; import org.postgresql.largeobject.LargeObjectManager; import com.revolsys.jdbc.field.JdbcBlobFieldDefinition; import com.revolsys.spring.resource.Resource; import com.revolsys.util.Exceptions; public class PostgreSQLJdbcBlobFieldDefinition extends JdbcBlobFieldDefinition { public PostgreSQLJdbcBlobFieldDefinition(final String dbName, final String name, final String dataType, final int sqlType, final int length, final int scale, final boolean required, final String description, final Map<String, Object> properties) { super(dbName, name, sqlType, length, required, description, properties); } @Override public int setPreparedStatementValue(final PreparedStatement statement, final int parameterIndex, final Object value) throws SQLException { if (value == null) { final int sqlType = getSqlType(); statement.setNull(parameterIndex, sqlType); } else { Blob blob; if (value instanceof Blob) { blob = (Blob)value; statement.setBlob(parameterIndex, blob); } else { InputStream in; if (value instanceof InputStream) { in = (InputStream)value; } else if (value instanceof byte[]) { final byte[] bytes = (byte[])value; in = new ByteArrayInputStream(bytes); } else if (value instanceof CharSequence) { final String string = ((CharSequence)value).toString(); final byte[] bytes = string.getBytes(StandardCharsets.UTF_8); in = new ByteArrayInputStream(bytes); } else { try { final Resource resource = Resource.getResource(value); in = resource.newBufferedInputStream(); } catch (final IllegalArgumentException e) { throw new IllegalArgumentException(value.getClass() + " not valid for a blob column"); } } try { final PGConnection pgConnection = (PGConnection)((DelegatingConnection<?>)statement .getConnection()).getInnermostDelegate(); final LargeObjectManager lobManager = pgConnection.getLargeObjectAPI(); final long lobId = lobManager .createLO(LargeObjectManager.READ | LargeObjectManager.WRITE); final LargeObject lob = lobManager.open(lobId, LargeObjectManager.WRITE); try { final byte buffer[] = new byte[2048]; int readCount = 0; while ((readCount = in.read(buffer, 0, 2048)) > 0) { lob.write(buffer, 0, readCount); } } finally { lob.close(); } statement.setLong(parameterIndex, lobId); } catch (final IOException e) { Exceptions.throwUncheckedException(e); } } } return parameterIndex + 1; } }