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
135
136
137
138
139
140
141
142
143
144
145
package edu.caltech.nanodb.commands;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Set;
import edu.caltech.nanodb.relations.TableInfo;
import edu.caltech.nanodb.server.NanoDBServer;
import edu.caltech.nanodb.storage.StorageManager;
import edu.caltech.nanodb.storage.TableManager;
/**
* This Command class represents the <tt>ANALYZE</tt> SQL command, which
* analyzes a table's internal data and updates its cached statistics to be as
* up-to-date as possible. This is not a standard SQL command, but virtually
* every good database has a mechanism to manually perform this task.
*/
public class AnalyzeCommand extends Command {
/**
* Table names are kept in a set so that we don't need to worry about a
* particular table being specified multiple times.
*/
private LinkedHashSet<String> tableNames;
private boolean verbose = false;
/**
* Construct a new <tt>ANALYZE</tt> command with an empty table list.
* Tables can be added to the internal list using the {@link #addTable}
* method.
*
* @param verbose a flag indicating whether this command should produce
* verbose output
*/
public AnalyzeCommand(boolean verbose) {
super(Command.Type.UTILITY);
tableNames = new LinkedHashSet<>();
this.verbose = verbose;
}
/**
* Construct a new <tt>ANALYZE</tt> command with an empty table list.
* Tables can be added to the internal list using the {@link #addTable}
* method.
*/
public AnalyzeCommand() {
this(false);
}
/**
* Construct a new <tt>ANALYZE</tt> command to analyze the specified table.
*
* @param tableName the name of the table to analyze.
*/
public AnalyzeCommand(String tableName) {
this(tableName, false);
}
/**
* Construct a new <tt>ANALYZE</tt> command to analyze the specified table.
*
* @param tableName the name of the table to analyze.
* @param verbose a flag indicating whether this command should produce
* verbose output
*/
public AnalyzeCommand(String tableName, boolean verbose) {
this(verbose);
addTable(tableName);
}
/**
* Add a table to the list of tables to analyze.
*
* @param tableName the name of the table to analyze.
*/
public void addTable(String tableName) {
if (tableName == null)
throw new NullPointerException("tableName cannot be null");
tableNames.add(tableName);
}
/**
* Returns the set of tables to analyze in an unmodifiable set.
*
* @return the set of tables to analyze in an unmodifiable set.
*/
public Set<String> getTableNames() {
return Collections.unmodifiableSet(tableNames);
}
@Override
public void execute(NanoDBServer server) throws ExecutionException {
// Make sure that all the tables are valid.
StorageManager storageManager = server.getStorageManager();
TableManager tableManager = storageManager.getTableManager();
ArrayList<TableInfo> tableInfos = new ArrayList<>();
for (String table : tableNames) {
TableInfo tableInfo = tableManager.openTable(table);
tableInfos.add(tableInfo);
}
// Now, analyze each table.
for (TableInfo tableInfo : tableInfos) {
out.println("Analyzing table " + tableInfo.getTableName());
tableManager.analyzeTable(tableInfo);
if (verbose) {
// TODO: Implement
out.println("TODO: Add verbose output... :-P");
}
}
out.println("Analysis complete.");
}
/**
* Prints a simple representation of the analyze command, including the
* names of the tables to be analyzed.
*
* @return a string representing this analyze command
*/
@Override
public String toString() {
return "Analyze[" + tableNames + "]";
}
}