package org.openlca.core.database;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public final class NativeSql {
private Logger log = LoggerFactory.getLogger(this.getClass());
private final int MAX_BATCH_SIZE = 1000;
private final IDatabase database;
public static NativeSql on(IDatabase database) {
return new NativeSql(database);
}
private NativeSql(IDatabase database) {
this.database = database;
}
public int getCount(String query) throws SQLException {
log.trace("execute query {}", query);
try (Connection con = database.createConnection();
Statement stmt = con.createStatement();
ResultSet result = stmt.executeQuery(query)) {
if (result.next())
return result.getInt(1);
}
return 0;
}
public void query(String query, QueryResultHandler handler) throws SQLException {
log.trace("execute query {}", query);
try (Connection con = database.createConnection()) {
Statement stmt = con.createStatement();
ResultSet result = stmt.executeQuery(query);
while (result.next()) {
boolean b = handler.nextResult(result);
if (!b)
break;
}
result.close();
stmt.close();
}
}
public void runUpdate(String statement) throws SQLException {
log.trace("run update statement {}", statement);
try (Connection con = database.createConnection()) {
Statement stmt = con.createStatement();
stmt.executeUpdate(statement);
con.commit();
stmt.close();
log.trace("update done");
}
}
public void batchInsert(String preparedStatement, int size,
BatchInsertHandler fn) throws SQLException {
log.trace("execute batch insert {}", preparedStatement);
if (size <= 0) {
log.trace("size {} <= 0; nothing to do", size);
return;
}
try (Connection con = database.createConnection()) {
PreparedStatement ps = con.prepareStatement(preparedStatement);
insertRows(size, fn, ps);
con.commit();
ps.close();
log.trace("inserts done");
}
}
private void insertRows(int size, BatchInsertHandler fn,
PreparedStatement ps) throws SQLException {
for (int i = 0; i < size; i++) {
boolean b = fn.addBatch(i, ps);
if (!b) {
log.trace("stop inserting at {} of {}", i, size);
break;
}
ps.addBatch();
if (i % MAX_BATCH_SIZE == 0) {
int[] rows = ps.executeBatch();
log.trace("executed batch with {} rows", rows.length);
}
}
int[] rows = ps.executeBatch();
log.trace("executed batch with {} rows", rows.length);
}
public void batchUpdate(Iterable<String> statements) throws SQLException {
log.trace("execute batch update");
try (Connection con = database.createConnection()) {
Statement stmt = con.createStatement();
int batchSize = 0;
for (String statement : statements) {
stmt.addBatch(statement);
if (batchSize % MAX_BATCH_SIZE == 0) {
int[] s = stmt.executeBatch();
log.trace("{} statements executed", s.length);
}
batchSize++;
}
int[] s = stmt.executeBatch();
log.trace("{} statements executed", s.length);
con.commit();
stmt.close();
}
}
public interface BatchInsertHandler {
boolean addBatch(int i, PreparedStatement stmt) throws SQLException;
}
public interface QueryResultHandler {
boolean nextResult(ResultSet result) throws SQLException;
}
}