Skip to content

Commit 2a796da

Browse files
committed
Refactor Logging to remove SQL Dependency, keeping same Functionality
As of this commit the classes StateLogger and StateToReproduce are no longer dependent on SQL strings. The functionality is now supported by a LoggableFactory, specifically for all current DBMSs the SQLLoggableFactory. Parts of the functionality may be removed later, for example commentStatements is now marked depricated.
1 parent 3d7e766 commit 2a796da

20 files changed

+183
-57
lines changed

src/sqlancer/DatabaseProvider.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
import java.sql.Connection;
44
import java.sql.SQLException;
55

6+
import sqlancer.common.log.LoggableFactory;
7+
68
public interface DatabaseProvider<G extends GlobalState<O, ?>, O extends DBMSSpecificOptions<?>> {
79

810
/**
@@ -37,6 +39,8 @@ public interface DatabaseProvider<G extends GlobalState<O, ?>, O extends DBMSSpe
3739
*/
3840
String getDBMSName();
3941

42+
LoggableFactory getLoggableFactory();
43+
4044
StateToReproduce getStateToReproduce(String databaseName);
4145

4246
}

src/sqlancer/Main.java

Lines changed: 20 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@
33
import java.io.File;
44
import java.io.FileWriter;
55
import java.io.IOException;
6-
import java.io.PrintWriter;
7-
import java.io.StringWriter;
86
import java.io.Writer;
97
import java.nio.file.Files;
108
import java.sql.Connection;
@@ -29,6 +27,7 @@
2927
import sqlancer.citus.CitusProvider;
3028
import sqlancer.clickhouse.ClickHouseProvider;
3129
import sqlancer.cockroachdb.CockroachDBProvider;
30+
import sqlancer.common.log.Loggable;
3231
import sqlancer.common.query.Query;
3332
import sqlancer.common.query.SQLancerResultSet;
3433
import sqlancer.duckdb.DuckDBProvider;
@@ -67,6 +66,7 @@ public static final class StateLogger {
6766
public FileWriter currentFileWriter;
6867
private static final List<String> INITIALIZED_PROVIDER_NAMES = new ArrayList<>();
6968
private final boolean logEachSelect;
69+
private final DatabaseProvider<?, ?> databaseProvider;
7070

7171
private static final class AlsoWriteToConsoleFileWriter extends FileWriter {
7272

@@ -98,6 +98,7 @@ public StateLogger(String databaseName, DatabaseProvider<?, ?> provider, MainOpt
9898
if (logEachSelect) {
9999
curFile = new File(dir, databaseName + "-cur.log");
100100
}
101+
this.databaseProvider = provider;
101102
}
102103

103104
private void ensureExistsAndIsEmpty(File dir, DatabaseProvider<?, ?> provider) {
@@ -161,37 +162,32 @@ public void writeCurrent(StateToReproduce state) {
161162
}
162163
}
163164

164-
public void writeCurrent(String queryString) {
165-
write(queryString, "\n");
165+
public void writeCurrent(String input) {
166+
write(databaseProvider.getLoggableFactory().createLoggable(input));
166167
}
167168

168-
private void write(String queryString, String suffix) {
169+
public void writeCurrentNoLineBreak(String input) {
170+
write(databaseProvider.getLoggableFactory().createLoggableWithNoLinebreak(input));
171+
}
172+
173+
private void write(Loggable loggable) {
169174
if (!logEachSelect) {
170175
throw new UnsupportedOperationException();
171176
}
172177
try {
173-
getCurrentFileWriter().write(queryString);
174-
if (!queryString.endsWith(";")) {
175-
getCurrentFileWriter().write(';');
176-
}
177-
if (suffix != null && suffix.length() != 0) {
178-
getCurrentFileWriter().write(suffix);
179-
}
178+
getCurrentFileWriter().write(loggable.getLogString());
179+
180180
currentFileWriter.flush();
181181
} catch (IOException e) {
182182
throw new AssertionError();
183183
}
184184
}
185185

186-
public void writeCurrentNoLineBreak(String queryString) {
187-
write(queryString, "");
188-
}
189-
190186
public void logException(Throwable reduce, StateToReproduce state) {
191-
String stackTrace = getStackTrace(reduce);
187+
Loggable stackTrace = getStackTrace(reduce);
192188
FileWriter logFileWriter2 = getLogFileWriter();
193189
try {
194-
logFileWriter2.write(stackTrace);
190+
logFileWriter2.write(stackTrace.getLogString());
195191
printState(logFileWriter2, state);
196192
} catch (IOException e) {
197193
throw new AssertionError(e);
@@ -205,21 +201,16 @@ public void logException(Throwable reduce, StateToReproduce state) {
205201
}
206202
}
207203

208-
private String getStackTrace(Throwable e1) {
209-
StringWriter sw = new StringWriter();
210-
PrintWriter pw = new PrintWriter(sw);
211-
e1.printStackTrace(pw);
212-
return "--" + sw.toString().replace("\n", "\n--");
204+
private Loggable getStackTrace(Throwable e1) {
205+
return databaseProvider.getLoggableFactory().convertStacktraceToLoggable(e1);
213206
}
214207

215208
private void printState(FileWriter writer, StateToReproduce state) {
216209
StringBuilder sb = new StringBuilder();
217-
DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
218-
Date date = new Date();
219-
sb.append("-- Time: " + dateFormat.format(date) + "\n");
220-
sb.append("-- Database: " + state.getDatabaseName() + "\n");
221-
sb.append("-- Database version: " + state.getDatabaseVersion() + "\n");
222-
sb.append("-- seed value: " + state.getSeedValue() + "\n");
210+
211+
sb.append(databaseProvider.getLoggableFactory()
212+
.getInfo(state.getDatabaseName(), state.getDatabaseVersion(), state.getSeedValue()).getLogString());
213+
223214
for (Query s : state.getStatements()) {
224215
sb.append(s.getQueryString());
225216
sb.append('\n');

src/sqlancer/ProviderAdapter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public ProviderAdapter(Class<G> globalClass, Class<O> optionClass) {
2323

2424
@Override
2525
public StateToReproduce getStateToReproduce(String databaseName) {
26-
return new StateToReproduce(databaseName);
26+
return new StateToReproduce(databaseName, this);
2727
}
2828

2929
@Override
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package sqlancer;
2+
3+
import sqlancer.common.log.LoggableFactory;
4+
import sqlancer.common.log.SQLLoggableFactory;
5+
6+
public abstract class SQLProviderAdapter<G extends GlobalState<O, ?>, O extends DBMSSpecificOptions<? extends OracleFactory<G>>>
7+
extends ProviderAdapter<G, O> {
8+
public SQLProviderAdapter(Class<G> globalClass, Class<O> optionClass) {
9+
super(globalClass, optionClass);
10+
}
11+
12+
@Override
13+
public LoggableFactory getLoggableFactory() {
14+
return new SQLLoggableFactory();
15+
}
16+
}

src/sqlancer/StateToReproduce.java

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,15 @@
66
import java.util.List;
77

88
import sqlancer.common.query.Query;
9-
import sqlancer.common.query.QueryAdapter;
109

1110
public class StateToReproduce {
1211

1312
private final List<Query> statements = new ArrayList<>();
1413

1514
private final String databaseName;
1615

16+
private final DatabaseProvider<?, ?> databaseProvider;
17+
1718
public String databaseVersion;
1819

1920
protected long seedValue;
@@ -22,8 +23,9 @@ public class StateToReproduce {
2223

2324
public OracleRunReproductionState localState;
2425

25-
public StateToReproduce(String databaseName) {
26+
public StateToReproduce(String databaseName, DatabaseProvider<?, ?> databaseProvider) {
2627
this.databaseName = databaseName;
28+
this.databaseProvider = databaseProvider;
2729
}
2830

2931
public String getException() {
@@ -48,7 +50,7 @@ public void logStatement(String queryString) {
4850
if (queryString == null) {
4951
throw new IllegalArgumentException();
5052
}
51-
logStatement(new QueryAdapter(queryString));
53+
logStatement(databaseProvider.getLoggableFactory().getQueryForStateToReproduce(queryString));
5254
}
5355

5456
/**
@@ -68,12 +70,12 @@ public List<Query> getStatements() {
6870
return Collections.unmodifiableList(statements);
6971
}
7072

73+
@Deprecated
7174
public void commentStatements() {
7275
for (int i = 0; i < statements.size(); i++) {
7376
Query statement = statements.get(i);
74-
String queryString = statement.getQueryString();
75-
String newQueryString = "-- " + queryString;
76-
statements.set(i, new QueryAdapter(newQueryString));
77+
Query newQuery = databaseProvider.getLoggableFactory().commentOutQuery(statement);
78+
statements.set(i, newQuery);
7779
}
7880
}
7981

@@ -109,7 +111,7 @@ public void executedWithoutError() {
109111
}
110112

111113
public void log(String s) {
112-
statements.add(new QueryAdapter(s));
114+
statements.add(databaseProvider.getLoggableFactory().getQueryForStateToReproduce(s));
113115
}
114116

115117
@Override

src/sqlancer/clickhouse/ClickHouseProvider.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
import sqlancer.AbstractAction;
1010
import sqlancer.GlobalState;
1111
import sqlancer.IgnoreMeException;
12-
import sqlancer.ProviderAdapter;
1312
import sqlancer.Randomly;
13+
import sqlancer.SQLProviderAdapter;
1414
import sqlancer.StatementExecutor;
1515
import sqlancer.clickhouse.ClickHouseProvider.ClickHouseGlobalState;
1616
import sqlancer.clickhouse.gen.ClickHouseCommon;
@@ -19,7 +19,7 @@
1919
import sqlancer.common.query.Query;
2020
import sqlancer.common.query.QueryProvider;
2121

22-
public class ClickHouseProvider extends ProviderAdapter<ClickHouseGlobalState, ClickHouseOptions> {
22+
public class ClickHouseProvider extends SQLProviderAdapter<ClickHouseGlobalState, ClickHouseOptions> {
2323

2424
public ClickHouseProvider() {
2525
super(ClickHouseGlobalState.class, ClickHouseOptions.class);

src/sqlancer/cockroachdb/CockroachDBProvider.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@
1212
import sqlancer.IgnoreMeException;
1313
import sqlancer.Main.QueryManager;
1414
import sqlancer.MainOptions;
15-
import sqlancer.ProviderAdapter;
1615
import sqlancer.Randomly;
16+
import sqlancer.SQLProviderAdapter;
1717
import sqlancer.cockroachdb.CockroachDBProvider.CockroachDBGlobalState;
1818
import sqlancer.cockroachdb.CockroachDBSchema.CockroachDBTable;
1919
import sqlancer.cockroachdb.gen.CockroachDBCommentOnGenerator;
@@ -34,7 +34,7 @@
3434
import sqlancer.common.query.QueryAdapter;
3535
import sqlancer.common.query.QueryProvider;
3636

37-
public class CockroachDBProvider extends ProviderAdapter<CockroachDBGlobalState, CockroachDBOptions> {
37+
public class CockroachDBProvider extends SQLProviderAdapter<CockroachDBGlobalState, CockroachDBOptions> {
3838

3939
public CockroachDBProvider() {
4040
super(CockroachDBGlobalState.class, CockroachDBOptions.class);
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package sqlancer.common.log;
2+
3+
public interface Loggable {
4+
String getLogString();
5+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package sqlancer.common.log;
2+
3+
import java.text.DateFormat;
4+
import java.text.SimpleDateFormat;
5+
import java.util.Date;
6+
7+
import sqlancer.common.query.Query;
8+
9+
public abstract class LoggableFactory {
10+
11+
public Loggable createLoggableWithNoLinebreak(String input) {
12+
return createLoggable(input, "");
13+
}
14+
15+
public Loggable createLoggable(String input) {
16+
return createLoggable(input, "\n");
17+
}
18+
19+
protected abstract Loggable createLoggable(String input, String suffix);
20+
21+
public abstract Query getQueryForStateToReproduce(String queryString);
22+
23+
@Deprecated
24+
public abstract Query commentOutQuery(Query query);
25+
26+
public Loggable getInfo(String databaseName, String databaseVersion, long seedValue) {
27+
Date date = new Date();
28+
DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
29+
return infoToLoggable(dateFormat.format(date), databaseName, databaseVersion, seedValue);
30+
}
31+
32+
protected abstract Loggable infoToLoggable(String time, String databaseName, String databaseVersion,
33+
long seedValue);
34+
35+
public abstract Loggable convertStacktraceToLoggable(Throwable throwable);
36+
37+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package sqlancer.common.log;
2+
3+
public class LoggedString implements Loggable {
4+
5+
private final String loggedString;
6+
7+
public LoggedString(String loggedString) {
8+
this.loggedString = loggedString;
9+
}
10+
11+
@Override
12+
public String getLogString() {
13+
return this.loggedString;
14+
}
15+
}

0 commit comments

Comments
 (0)