org.accidia.echo.mysql.relational.MySqlProtobufRowMapper Maven / Gradle / Ivy
package org.accidia.echo.mysql.relational;
import com.google.protobuf.ByteString;
import com.google.protobuf.Message;
import org.accidia.echo.protos.Protos;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.sql.Blob;
import java.sql.ResultSet;
import java.sql.SQLException;
import static com.google.protobuf.Descriptors.FieldDescriptor;
public class MySqlProtobufRowMapper {
private static final Logger logger = LoggerFactory.getLogger(MySqlProtobufRowMapper.class);
public Message mapResultSet(final ResultSet resultSet, final Message.Builder builder) throws SQLException {
logger.debug("mapRow(resultSet,rowNum)");
for (final FieldDescriptor fieldDescriptor : builder.getDescriptorForType().getFields()) {
final String fieldName = fieldDescriptor.getName().toUpperCase();
final int columnIndex;
try {
columnIndex = resultSet.findColumn(fieldName);
} catch (final SQLException e) {
// field is not present in the result set -> moving on...
continue;
}
// if field is repeated, load as binary into a List
if (fieldDescriptor.isRepeated()) {
// TODO test this thing
final Blob blob = resultSet.getBlob(columnIndex);
if (blob == null) {
// no value -> moving on...
logger.debug("no value set for field {} -> moving on", fieldName);
continue;
}
final Protos.ListResult objectList;
try {
final ByteString byteString = ByteString.readFrom(blob.getBinaryStream());
objectList = Protos.ListResult.parseFrom(byteString);
} catch (IOException e) {
logger.warn("failed to read from byte input stream for field {} -> moving on", fieldName);
continue;
}
builder.setField(fieldDescriptor, objectList);
continue;
}
if (fieldDescriptor.getJavaType() == FieldDescriptor.JavaType.STRING) {
final String value = resultSet.getString(columnIndex);
if (value == null) {
continue;
}
builder.setField(fieldDescriptor, value);
} else if (fieldDescriptor.getJavaType() == FieldDescriptor.JavaType.INT) {
builder.setField(fieldDescriptor, resultSet.getInt(columnIndex));
} else if (fieldDescriptor.getJavaType() == FieldDescriptor.JavaType.LONG) {
builder.setField(fieldDescriptor, resultSet.getLong(columnIndex));
} else if (fieldDescriptor.getJavaType() == FieldDescriptor.JavaType.FLOAT) {
builder.setField(fieldDescriptor, resultSet.getFloat(columnIndex));
} else if (fieldDescriptor.getJavaType() == FieldDescriptor.JavaType.DOUBLE) {
builder.setField(fieldDescriptor, resultSet.getDouble(columnIndex));
} else if (fieldDescriptor.getJavaType() == FieldDescriptor.JavaType.BOOLEAN) {
builder.setField(fieldDescriptor, resultSet.getBoolean(columnIndex));
} else if (fieldDescriptor.getJavaType() == FieldDescriptor.JavaType.BYTE_STRING) {
final Blob blob = resultSet.getBlob(columnIndex);
if (blob == null) {
// no value -> moving on...
logger.debug("no value set for field {} -> moving on", fieldName);
continue;
}
final ByteString byteString;
try {
byteString = ByteString.readFrom(blob.getBinaryStream());
} catch (IOException e) {
logger.warn("failed to read from byte input stream for field {} -> moving on", fieldName);
continue;
}
builder.setField(fieldDescriptor, byteString);
} else if (fieldDescriptor.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
// TODO load a message
// get dao for object type and load based on relationship
}
}
return builder.buildPartial();
}
}