-
Notifications
You must be signed in to change notification settings - Fork 398
Expand file tree
/
Copy pathArangoDBProvider.java
More file actions
134 lines (112 loc) · 4.78 KB
/
ArangoDBProvider.java
File metadata and controls
134 lines (112 loc) · 4.78 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
package sqlancer.arangodb;
import java.util.ArrayList;
import java.util.List;
import com.arangodb.ArangoDB;
import com.arangodb.ArangoDatabase;
import sqlancer.AbstractAction;
import sqlancer.ExecutionTimer;
import sqlancer.GlobalState;
import sqlancer.IgnoreMeException;
import sqlancer.ProviderAdapter;
import sqlancer.Randomly;
import sqlancer.StatementExecutor;
import sqlancer.arangodb.gen.ArangoDBCreateIndexGenerator;
import sqlancer.arangodb.gen.ArangoDBInsertGenerator;
import sqlancer.arangodb.gen.ArangoDBTableGenerator;
import sqlancer.common.log.LoggableFactory;
import sqlancer.common.query.Query;
public class ArangoDBProvider
extends ProviderAdapter<ArangoDBProvider.ArangoDBGlobalState, ArangoDBOptions, ArangoDBConnection> {
public ArangoDBProvider() {
super(ArangoDBGlobalState.class, ArangoDBOptions.class);
}
enum Action implements AbstractAction<ArangoDBGlobalState> {
INSERT(ArangoDBInsertGenerator::getQuery), CREATE_INDEX(ArangoDBCreateIndexGenerator::getQuery);
private final ArangoDBQueryProvider<ArangoDBGlobalState> queryProvider;
Action(ArangoDBQueryProvider<ArangoDBGlobalState> queryProvider) {
this.queryProvider = queryProvider;
}
@Override
public Query<?> getQuery(ArangoDBGlobalState globalState) throws Exception {
return queryProvider.getQuery(globalState);
}
}
private static int mapActions(ArangoDBGlobalState globalState, Action a) {
Randomly r = globalState.getRandomly();
switch (a) {
case INSERT:
return r.getInteger(0, globalState.getOptions().getMaxNumberInserts());
case CREATE_INDEX:
return r.getInteger(0, globalState.getDmbsSpecificOptions().maxNumberIndexes);
default:
throw new AssertionError(a);
}
}
public static class ArangoDBGlobalState extends GlobalState<ArangoDBOptions, ArangoDBSchema, ArangoDBConnection> {
private final List<ArangoDBSchema.ArangoDBTable> schemaTables = new ArrayList<>();
public void addTable(ArangoDBSchema.ArangoDBTable table) {
schemaTables.add(table);
}
@Override
protected void executeEpilogue(Query<?> q, boolean success, ExecutionTimer timer) throws Exception {
boolean logExecutionTime = getOptions().logExecutionTime();
if (success && getOptions().printSucceedingStatements()) {
System.out.println(q.getLogString());
}
if (logExecutionTime) {
getLogger().writeCurrent("//" + timer.end().asString());
}
if (q.couldAffectSchema()) {
updateSchema();
}
}
@Override
protected ArangoDBSchema readSchema() throws Exception {
return new ArangoDBSchema(schemaTables);
}
}
@Override
protected void checkViewsAreValid(ArangoDBGlobalState globalState) {
}
@Override
public void generateDatabase(ArangoDBGlobalState globalState) throws Exception {
for (int i = 0; i < Randomly.fromOptions(4, 5, 6); i++) {
boolean success;
do {
ArangoDBQueryAdapter queryAdapter = new ArangoDBTableGenerator().getQuery(globalState);
success = globalState.executeStatement(queryAdapter);
} while (!success);
}
StatementExecutor<ArangoDBGlobalState, Action> se = new StatementExecutor<>(globalState, Action.values(),
ArangoDBProvider::mapActions, (q) -> {
if (globalState.getSchema().getDatabaseTables().isEmpty()) {
throw new IgnoreMeException();
}
});
se.executeStatements();
}
@Override
public ArangoDBConnection createDatabase(ArangoDBGlobalState globalState) throws Exception {
ArangoDB arangoDB = new ArangoDB.Builder().user(globalState.getOptions().getUserName())
.password(globalState.getOptions().getPassword()).build();
ArangoDatabase database = arangoDB.db(globalState.getDatabaseName());
try {
database.drop();
// When the database does not exist, an ArangoDB exception is thrown. Since we are not sure
// if this is the first time the database is used, the simplest is dropping it and ignoring
// the exception.
} catch (Exception ignored) {
}
arangoDB.createDatabase(globalState.getDatabaseName());
database = arangoDB.db(globalState.getDatabaseName());
return new ArangoDBConnection(arangoDB, database);
}
@Override
public String getDBMSName() {
return "arangodb";
}
@Override
public LoggableFactory getLoggableFactory() {
return new ArangoDBLoggableFactory();
}
}