package util;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.zip.GZIPOutputStream;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.jdbc.core.JdbcTemplate;
import flex.messaging.io.SerializationContext;
import flex.messaging.io.amf.Amf3Output;
public class SqlRequestThread extends Thread {
// CONSTANT DEFINE THE NUMBER OF ROWS PER ARRAY WHEN WE STREAM FROM DATABASE
private final static int STREAM_LENGTH = 10000;
// REQUEST TO BE EXECUTED
private String request;
// USEFULL OBJECT FROM SPRING
private JdbcTemplate t;
// FILE LOGGER
private final Log logger = LogFactory.getLog(SqlRequestThread.class);
// Constructor
public SqlRequestThread(String request, JdbcTemplate t) {
super();
this.t = t;
this.request = request;
}
// THREAD CONTENT
public void run() {
PreparedStatement stat;
try {
// CREATE AND EXECUTE QUERY ------------
stat = t.getDataSource().getConnection().prepareStatement(request,
ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
if (t.getDataSource().getConnection().getMetaData().getDriverName()
.toUpperCase().contains("MYSQL"))
stat.setFetchSize(Integer.MIN_VALUE);
else
stat.setFetchSize(1500);
ResultSet results = stat.executeQuery();
// -------------------------------------------
// Grab the number of columns of the table
int numberColum = results.getMetaData().getColumnCount();
// Send message to air to notice that we start to send data
try {
Messenger.sendMessage(ApplicationConstants.SQL_START, null);
} catch (Exception e) {
logger.error(e.getMessage());
}
// Prepare for amf serialization
SerializationContext context = SerializationContext
.getSerializationContext();
// Index for the array (row index)
int nb = 1;
// Declare the data array
String[][] data;
// Instantiate the array with correct length
data = new String[STREAM_LENGTH][numberColum];
// first entry in the array is the header column
for (int i = 0; i < numberColum; i++) {
data[0][i] = results.getMetaData().getColumnName(i + 1);
}
// Boolean to know if the last rows has been sent
boolean isSended = false;
// Copying data
while (results.next()) {
isSended = false;
// Copy the content of the row in the array
for (int j = 0; j < numberColum; j++) {
data[nb % STREAM_LENGTH][j] = results.getString(j + 1);
}
// Test if the array is full
if (nb == STREAM_LENGTH-1) {
// and serialize
ByteArrayOutputStream bout = new ByteArrayOutputStream();
Amf3Output amf3Output = new Amf3Output(context);
amf3Output.setOutputStream(bout);
amf3Output.writeObject(data);
amf3Output.flush();
byte[] b = bout.toByteArray();
amf3Output.close();
String filename = "" + System.nanoTime();
File path = new File(filename + ".data");
FileOutputStream outFile = new FileOutputStream(path);
GZIPOutputStream zipOut = new GZIPOutputStream(outFile);
zipOut.write(b);
zipOut.flush();
zipOut.close();
// Ok now sending the array to flex by merapi
Messenger.sendMessage(ApplicationConstants.SQL_RESULT,
path.getAbsoluteFile().toString());
// Create a new array and the array has no reference on it, so it can be collected by the GC! Hope for this.
data = new String[STREAM_LENGTH][numberColum];
nb=-1;
isSended=true;
}
nb++;
}
if(!isSended){
String[][] lastData = new String [nb][numberColum];
for (int i = 0 ; i < nb ; i++) {
lastData[i] = data[i].clone();
}
ByteArrayOutputStream bout = new ByteArrayOutputStream();
Amf3Output amf3Output = new Amf3Output(context);
amf3Output.setOutputStream(bout);
amf3Output.writeObject(lastData);
amf3Output.flush();
byte[] b = bout.toByteArray();
amf3Output.close();
String filename = "" + System.nanoTime();
File path = new File(filename + ".data");
FileOutputStream outFile = new FileOutputStream(path);
GZIPOutputStream zipOut = new GZIPOutputStream(outFile);
zipOut.write(b);
zipOut.flush();
zipOut.close();
Messenger.sendMessage(ApplicationConstants.SQL_RESULT, path.getAbsoluteFile().toString());
}
// Now saying to flex all is done
Messenger.sendMessage(ApplicationConstants.SQL_STOP, "success");
// --------------------------------------------------------------------
} catch (Exception e2) {
logger.error(e2.getMessage());
try {
Messenger.sendMessage(ApplicationConstants.SQL_INFO, "ERROR : " + e2.getMessage());
} catch (Exception e) {
e.printStackTrace();
logger.error(e.getMessage());
}
}
}
}