package jef.database.dialect.type;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Blob;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import jef.common.BigDataBuffer;
import jef.database.DbCfg;
import jef.database.ORMConfig;
import jef.database.dialect.DatabaseDialect;
import jef.database.jdbc.result.IResultSet;
import jef.database.meta.Feature;
import jef.tools.IOUtils;
import jef.tools.JefConfiguration;
public class BlobObjectMapping extends AColumnMapping {
static int blobType;
static {
String type = JefConfiguration.get(DbCfg.DB_BLOB_RETURN_TYPE, "stream");
if ("stream".equalsIgnoreCase(type)) {
blobType = 1;
} else if ("string".equalsIgnoreCase(type)) {
blobType = 2;
} else if ("byte".equalsIgnoreCase(type)) {
blobType = 3;
} else if ("file".equalsIgnoreCase(type)) {
blobType = 4;
} else {
throw new IllegalArgumentException("Invalid config of db.blob.return.type=" + type);
}
}
public Object jdbcSet(PreparedStatement st, Object value, int index, DatabaseDialect profile) throws SQLException {
if (value == null) {
st.setNull(index, profile.getImplementationSqlType(Types.BLOB));
} else if (value instanceof byte[]) {
byte[] data = (byte[]) value;
st.setBytes(index, data);
} else if (value instanceof File) {
File file = (File) value;
try {
if (profile.has(Feature.NOT_SUPPORT_SET_BINARY)) {
st.setBytes(index, IOUtils.toByteArray(file));
} else {
st.setBinaryStream(index, IOUtils.getInputStream(file), file.length());
}
} catch (IOException e) {
throw new SQLException("Can not read file" + file, e);
}
} else {
throw new SQLException("Can not set to Blob for" + value.getClass().getName());
}
return value;
}
public void jdbcUpdate(ResultSet rs, String column, Object value, DatabaseDialect profile) throws SQLException {
if (value instanceof byte[]) {
byte[] data = (byte[]) value;
rs.updateBytes(column, data);
} else if (value instanceof File) {
File file = (File) value;
try {
if (profile.has(Feature.NOT_SUPPORT_SET_BINARY)) {
rs.updateBytes(column, IOUtils.toByteArray(file));
} else {
rs.updateBinaryStream(column, IOUtils.getInputStream(file), file.length());
}
} catch (IOException e) {
throw new SQLException("Can not read file" + file, e);
}
}
}
public int getSqlType() {
return java.sql.Types.BLOB;
}
public Object jdbcGet(IResultSet rs, int n) throws SQLException {
Object value = rs.getObject(n);
if (value == null)
return null;
try {
if (value instanceof byte[]) {
return cast((byte[]) value);
} else {
return cast((Blob) value);
}
} catch (IOException e) {
throw new SQLException(e);
}
}
private Object cast(Blob value) throws SQLException, IOException {
switch (blobType) {
case 1:
BigDataBuffer bf = new BigDataBuffer();
byte[] buffer = new byte[4096];
int res;
InputStream in = value.getBinaryStream();
while ((res = in.read(buffer)) != -1) {
bf.write(buffer, 0, res);
}
return bf.getAsStream();
case 2:
return IOUtils.asString(value.getBinaryStream(), ORMConfig.getInstance().getDbEncoding(), true);
case 3:
return IOUtils.toByteArray(value.getBinaryStream());
case 4:
return IOUtils.saveAsTempFile(value.getBinaryStream());
}
return IOUtils.toByteArray(value.getBinaryStream());
}
private Object cast(byte[] value) throws IOException {
switch (blobType) {
case 1:
return new ByteArrayInputStream(value);
case 2:
return new String(value, ORMConfig.getInstance().getDbEncodingCharset());
case 3:
return value;
case 4:
return IOUtils.saveAsTempFile(new ByteArrayInputStream(value));
}
return value;
}
@Override
protected String getSqlExpression(Object value, DatabaseDialect profile) {
throw new UnsupportedOperationException();
}
@Override
protected Class<?> getDefaultJavaType() {
return Object.class;
}
}