package me.eccentric_nz.TARDIS.database;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.HashMap;
import me.eccentric_nz.TARDIS.TARDIS;
public class TARDISRecordingTask implements Runnable {
private final TARDIS plugin;
public TARDISRecordingTask(TARDIS plugin) {
this.plugin = plugin;
}
public void save() {
if (!TARDISRecordingQueue.getQUEUE().isEmpty()) {
insertIntoDatabase();
}
}
public void insertIntoDatabase() {
PreparedStatement s = null;
Connection connection;
try {
int perBatch = 100;
if (!TARDISRecordingQueue.getQUEUE().isEmpty()) {
//plugin.debug("Beginning batch insert from queue. " + System.currentTimeMillis());
TARDISDatabaseConnection service = TARDISDatabaseConnection.getInstance();
connection = service.getConnection();
// Handle dead connections
if (connection == null || connection.isClosed()) {
if (TARDISRecordingManager.failedDbConnectionCount == 0) {
plugin.debug("TARDIS database error. Connection should be there but it's not. Leaving actions to log in queue.");
}
TARDISRecordingManager.failedDbConnectionCount++;
if (TARDISRecordingManager.failedDbConnectionCount > 5) {
plugin.debug("Too many problems connecting. Giving up for a bit.");
scheduleNextRecording();
}
plugin.debug("Database connection still missing, incrementing count.");
return;
} else {
TARDISRecordingManager.failedDbConnectionCount = 0;
}
// Connection valid, proceed
connection.setAutoCommit(false);
s = connection.prepareStatement("INSERT INTO blocks (tardis_id,location,block,data,police_box) VALUES (?,?,?,?,1)");
int i = 0;
while (!TARDISRecordingQueue.getQUEUE().isEmpty()) {
if (connection.isClosed()) {
plugin.debug("TARDIS database error. We have to bail in the middle of building primary bulk insert query.");
break;
}
final String a = TARDISRecordingQueue.getQUEUE().poll();
// poll() returns null if queue is empty
if (a == null) {
break;
}
HashMap<String, Object> where = new HashMap<String, Object>();
where.put("location", a);
ResultSetBlocks rs = new ResultSetBlocks(plugin, where, false);
if (rs.resultSet()) {
String loco = plugin.getLocationUtils().getLocationFromBukkitString(a).add(0.0d, -1.0d, 0.0d).toString();
s.setInt(1, rs.getReplacedBlock().getTardis_id());
s.setString(2, loco);
s.setInt(3, 208);
s.setInt(4, 0);
s.addBatch();
}
// Break out of the loop and just commit what we have
if (i >= perBatch) {
plugin.debug("Recorder: Batch max exceeded, running insert. Queue remaining: " + TARDISRecordingQueue.getQUEUE().size());
break;
}
i++;
}
s.executeBatch();
if (connection.isClosed()) {
plugin.debug("TARDIS database error. We have to bail in the middle of building primary bulk insert query.");
} else {
connection.commit();
connection.setAutoCommit(true);
//plugin.debug("Batch insert was commited: " + System.currentTimeMillis());
}
}
} catch (final SQLException e) {
e.printStackTrace();
} finally {
try {
if (s != null) {
s.close();
}
} catch (final SQLException ignored) {
}
}
}
@Override
public void run() {
save();
scheduleNextRecording();
}
protected int getTickDelayForNextBatch() {
// If we have too many rejected connections, increase the schedule
if (TARDISRecordingManager.failedDbConnectionCount > 5) {
return TARDISRecordingManager.failedDbConnectionCount * 20;
}
return 5;
}
protected void scheduleNextRecording() {
if (!plugin.isEnabled()) {
plugin.debug("Can't schedule new recording tasks as plugin is now disabled. If you're shutting down the server, ignore me.");
return;
}
plugin.setRecordingTask(plugin.getServer().getScheduler().runTaskLaterAsynchronously(plugin, new TARDISRecordingTask(plugin), getTickDelayForNextBatch()));
}
}