package sqlancer;
import java.io.Closeable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import sqlancer.common.query.Query;
public class StateToReproduce {
private final List> statements = new ArrayList<>();
private final String databaseName;
private final DatabaseProvider, ?, ?> databaseProvider;
public String databaseVersion;
protected long seedValue;
String exception;
public OracleRunReproductionState localState;
public StateToReproduce(String databaseName, DatabaseProvider, ?, ?> databaseProvider) {
this.databaseName = databaseName;
this.databaseProvider = databaseProvider;
}
public String getException() {
return exception;
}
public String getDatabaseName() {
return databaseName;
}
public String getDatabaseVersion() {
return databaseVersion;
}
/**
* Logs the statement string without executing the corresponding statement.
*
* @param queryString
* the query string to be logged
*/
public void logStatement(String queryString) {
if (queryString == null) {
throw new IllegalArgumentException();
}
logStatement(databaseProvider.getLoggableFactory().getQueryForStateToReproduce(queryString));
}
/**
* Logs the statement without executing it.
*
* @param query
* the query to be logged
*/
public void logStatement(Query> query) {
if (query == null) {
throw new IllegalArgumentException();
}
statements.add(query);
}
public List> getStatements() {
return Collections.unmodifiableList(statements);
}
@Deprecated
public void commentStatements() {
for (int i = 0; i < statements.size(); i++) {
Query> statement = statements.get(i);
Query> newQuery = databaseProvider.getLoggableFactory().commentOutQuery(statement);
statements.set(i, newQuery);
}
}
public long getSeedValue() {
return seedValue;
}
/**
* Returns a local state in which a test oracle can save useful information about a single run. If the local state
* is closed without indicating access to it, the local statements will be added to the global state.
*
* @return the local state for logging
*/
public OracleRunReproductionState getLocalState() {
return localState;
}
/**
* State information that is logged if the test oracle finds a bug or if an exception is thrown.
*/
public class OracleRunReproductionState implements Closeable {
private final List> statements = new ArrayList<>();
public boolean success;
public OracleRunReproductionState() {
StateToReproduce.this.localState = this;
}
public void executedWithoutError() {
this.success = true;
}
public void log(String s) {
statements.add(databaseProvider.getLoggableFactory().getQueryForStateToReproduce(s));
}
@Override
public void close() {
if (!success) {
StateToReproduce.this.statements.addAll(statements);
}
}
}
public OracleRunReproductionState createLocalState() {
return new OracleRunReproductionState();
}
}