ScanCallback callback, Object ctx, int scanChunk) {
Connection conn = threadLocalConnection.get();
if (conn == null) {
callback.scanFailed(ctx, new ServiceDownException("Not connected to derby"));
return;
}
long currentSeqId;
currentSeqId = startSeqId;
PreparedStatement stmt = null;
try {
try {
stmt = conn.prepareStatement("SELECT * FROM " + getTableNameForTopic(topic) + " WHERE " + ID_FIELD_NAME
+ " >= ? AND " + ID_FIELD_NAME + " <= ?");
} catch (SQLException sqle) {
String theError = (sqle).getSQLState();
if (theError.equals("42X05")) {
// No table, scan is over
callback.scanFinished(ctx, ReasonForFinish.NO_MORE_MESSAGES);
return;
} else {
throw sqle;
}
}
int numMessages = 0;
long totalSize = 0;
while (true) {
stmt.setLong(1, currentSeqId);
stmt.setLong(2, currentSeqId + scanChunk);
if (!stmt.execute()) {
String errorMsg = "Select query did not return a result set";
logger.error(errorMsg);
stmt.close();
callback.scanFailed(ctx, new ServiceDownException(errorMsg));
return;
}
ResultSet resultSet = stmt.getResultSet();
if (!resultSet.next()) {
stmt.close();
callback.scanFinished(ctx, ReasonForFinish.NO_MORE_MESSAGES);
return;
}
do {
long localSeqId = resultSet.getLong(1);
Message.Builder messageBuilder = Message.newBuilder().mergeFrom(resultSet.getBinaryStream(2));
// Merge in the local seq-id since that is not stored with
// the message
Message message = MessageIdUtils.mergeLocalSeqId(messageBuilder, localSeqId);
callback.messageScanned(ctx, message);
numMessages++;
totalSize += message.getBody().size();
if (numMessages > messageLimit) {
stmt.close();
callback.scanFinished(ctx, ReasonForFinish.NUM_MESSAGES_LIMIT_EXCEEDED);
return;
} else if (totalSize > sizeLimit) {
stmt.close();
callback.scanFinished(ctx, ReasonForFinish.SIZE_LIMIT_EXCEEDED);
return;
}
} while (resultSet.next());
currentSeqId += SCAN_CHUNK;
}
} catch (SQLException e) {
logger.error("SQL Exception", e);
callback.scanFailed(ctx, new ServiceDownException(e));
return;
} catch (IOException e) {
logger.error("Message stored in derby is not parseable", e);
callback.scanFailed(ctx, new ServiceDownException(e));
return;
} finally {
try {
if (stmt != null) {
stmt.close();