package ca.sqlpower.sql;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import org.apache.log4j.Logger;
public class SQLServerSequenceGenerator extends SequenceGenerator {
private static final Logger logger = Logger.getLogger(SQLServerSequenceGenerator.class);
private Connection con;
public SQLServerSequenceGenerator(Connection con) {
super();
this.con = con;
}
@Override
public long nextLong(String sequenceTable) throws SQLException {
StringBuffer selectSql = new StringBuffer();
selectSql.append("SELECT currval FROM ").append(SQL.escapeStatement(sequenceTable)).append(";");
long nextval;
logger.debug("Sequence Generator select SQL statement is: " + selectSql);
Statement stmt = null;
int oldTransactionIsolation;
oldTransactionIsolation = con.getTransactionIsolation();
try {
con.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
stmt = con.createStatement();
ResultSet rs = stmt.executeQuery(selectSql.toString());
if (!rs.next()) {
throw new SQLException("The sequence returned nothing!");
}
nextval = rs.getLong(1)+1;
StringBuffer updateSql = new StringBuffer();
updateSql.append("UPDATE ").append(SQL.escapeStatement(sequenceTable));
updateSql.append(" SET currval=" + nextval);
logger.debug("Sequence Generator update SQL statement is: " + updateSql);
int updateRS = stmt.executeUpdate(updateSql.toString());
if (updateRS == 0) {
throw new SQLException("No rows were updated. Serializability should prevent this.");
}
rs.close();
} finally {
con.setTransactionIsolation(oldTransactionIsolation);
if (stmt != null)
stmt.close();
}
return nextval;
}
/**
* Closes the connection that was passed to the constructor. You
* should probably close it yourself rather than calling this
* method.
*/
public void close() throws SQLException {
if (con != null) {
con.close();
}
}
}