-
Notifications
You must be signed in to change notification settings - Fork 397
Expand file tree
/
Copy pathMongoDBProvider.java
More file actions
125 lines (105 loc) · 4.3 KB
/
MongoDBProvider.java
File metadata and controls
125 lines (105 loc) · 4.3 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
package sqlancer.mongodb;
import java.util.ArrayList;
import java.util.List;
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
import com.mongodb.client.MongoDatabase;
import sqlancer.AbstractAction;
import sqlancer.ExecutionTimer;
import sqlancer.GlobalState;
import sqlancer.IgnoreMeException;
import sqlancer.ProviderAdapter;
import sqlancer.Randomly;
import sqlancer.StatementExecutor;
import sqlancer.common.log.LoggableFactory;
import sqlancer.common.query.Query;
import sqlancer.mongodb.MongoDBSchema.MongoDBTable;
import sqlancer.mongodb.gen.MongoDBIndexGenerator;
import sqlancer.mongodb.gen.MongoDBInsertGenerator;
import sqlancer.mongodb.gen.MongoDBTableGenerator;
public class MongoDBProvider
extends ProviderAdapter<MongoDBProvider.MongoDBGlobalState, MongoDBOptions, MongoDBConnection> {
public MongoDBProvider() {
super(MongoDBGlobalState.class, MongoDBOptions.class);
}
public enum Action implements AbstractAction<MongoDBGlobalState> {
INSERT(MongoDBInsertGenerator::getQuery), CREATE_INDEX(MongoDBIndexGenerator::getQuery);
private final MongoDBQueryProvider<MongoDBGlobalState> queryProvider;
Action(MongoDBQueryProvider<MongoDBGlobalState> queryProvider) {
this.queryProvider = queryProvider;
}
@Override
public Query<MongoDBConnection> getQuery(MongoDBGlobalState globalState) throws Exception {
return queryProvider.getQuery(globalState);
}
}
public static int mapActions(MongoDBGlobalState 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 MongoDBGlobalState extends GlobalState<MongoDBOptions, MongoDBSchema, MongoDBConnection> {
private final List<MongoDBTable> schemaTables = new ArrayList<>();
public void addTable(MongoDBTable 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 MongoDBSchema readSchema() throws Exception {
return new MongoDBSchema(schemaTables);
}
}
@Override
public void generateDatabase(MongoDBGlobalState globalState) throws Exception {
for (int i = 0; i < Randomly.fromOptions(4, 5, 6); i++) {
boolean success;
do {
MongoDBQueryAdapter query = new MongoDBTableGenerator(globalState).getQuery(globalState);
success = globalState.executeStatement(query);
} while (!success);
}
StatementExecutor<MongoDBGlobalState, Action> se = new StatementExecutor<>(globalState, Action.values(),
MongoDBProvider::mapActions, (q) -> {
if (globalState.getSchema().getDatabaseTables().isEmpty()) {
throw new IgnoreMeException();
}
});
se.executeStatements();
}
@Override
public MongoDBConnection createDatabase(MongoDBGlobalState globalState) throws Exception {
MongoClient mongoClient = MongoClients.create();
MongoDatabase database = mongoClient.getDatabase(globalState.getDatabaseName());
database.drop();
return new MongoDBConnection(mongoClient, database);
}
@Override
public String getDBMSName() {
return "mongodb";
}
@Override
public LoggableFactory getLoggableFactory() {
return new MongoDBLoggableFactory();
}
@Override
protected void checkViewsAreValid(MongoDBGlobalState globalState) {
}
}