use of henplus.SQLMetaData in project henplus by neurolabs.
the class DumpCommand method execute.
/**
* execute the command given.
*/
@Override
public int execute(final SQLSession session, final String cmd, final String param) {
// final String FILE_ENCODING = System.getProperty("file.encoding");
final StringTokenizer st = new StringTokenizer(param);
final int argc = st.countTokens();
if ("dump-select".equals(cmd)) {
if (session == null) {
Logger.error("not connected.");
return EXEC_FAILED;
}
if (argc < 4) {
return SYNTAX_ERROR;
}
final String fileName = st.nextToken();
final String tabName = st.nextToken();
final String select = st.nextToken();
if (!select.toUpperCase().equals("SELECT")) {
Logger.error("'select' expected.");
return SYNTAX_ERROR;
}
final StringBuilder statement = new StringBuilder("select");
while (st.hasMoreElements()) {
statement.append(" ").append(st.nextToken());
}
PrintStream out = null;
beginInterruptableSection();
try {
out = openOutputStream(fileName, FILE_ENCODING);
final int result = dumpSelect(session, tabName, statement.toString(), out, FILE_ENCODING);
return result;
} catch (final Exception e) {
Logger.error("failed: ", e);
return EXEC_FAILED;
} finally {
if (out != null) {
out.close();
}
endInterruptableSection();
}
} else if ("dump-conditional".equals(cmd)) {
if (session == null) {
Logger.error("not connected.");
return EXEC_FAILED;
}
if (argc < 2) {
return SYNTAX_ERROR;
}
final String fileName = (String) st.nextElement();
final String tabName = (String) st.nextElement();
String whereClause = null;
if (argc >= 3) {
// till EOL
whereClause = st.nextToken("\n");
whereClause = whereClause.trim();
if (whereClause.toUpperCase().startsWith("WHERE")) {
whereClause = whereClause.substring(5);
whereClause = whereClause.trim();
}
}
PrintStream out = null;
beginInterruptableSection();
try {
out = openOutputStream(fileName, FILE_ENCODING);
final int result = dumpTable(session, tabName, whereClause, out, FILE_ENCODING);
return result;
} catch (final Exception e) {
Logger.error("failed: ", e);
e.printStackTrace();
return EXEC_FAILED;
} finally {
if (out != null) {
out.close();
}
endInterruptableSection();
}
} else if ("dump-out".equals(cmd)) {
if (session == null) {
Logger.error("not connected.");
return EXEC_FAILED;
}
if (argc < 2) {
return SYNTAX_ERROR;
}
final String fileName = (String) st.nextElement();
PrintStream out = null;
final String tabName = null;
beginInterruptableSection();
try {
final long startTime = System.currentTimeMillis();
// which tables got already
final Set<String> alreadyDumped = new HashSet<String>();
// dumped?
out = openOutputStream(fileName, FILE_ENCODING);
final Set<String> tableSet = new LinkedHashSet<String>();
/*
* right now, we do only a sort, if there is any '*' found in
* tables. Probably we might want to make this an option to
* dump-in
*/
boolean needsSort = false;
int dumpResult = SUCCESS;
/* 1) collect tables */
while (st.hasMoreElements()) {
final String nextToken = st.nextToken();
if ("*".equals(nextToken) || nextToken.indexOf('*') > -1) {
needsSort = true;
Iterator<String> iter = null;
if ("*".equals(nextToken)) {
iter = _tableCompleter.getTableNamesIteratorForSession(session);
} else if (nextToken.indexOf('*') > -1) {
final String tablePrefix = nextToken.substring(0, nextToken.length() - 1);
final SortedSet<String> tableNames = _tableCompleter.getTableNamesForSession(session);
final NameCompleter compl = new NameCompleter(tableNames);
iter = compl.getAlternatives(tablePrefix);
}
while (iter.hasNext()) {
tableSet.add(iter.next());
}
} else {
tableSet.add(nextToken);
}
}
/* 2) resolve dependencies */
ResolverResult resolverResult = null;
List<String> tableSequence;
if (needsSort) {
tableSequence = new ArrayList<String>();
Logger.info("Retrieving and sorting tables. This may take a while, please be patient.");
// get sorted tables
final SQLMetaData meta = new SQLMetaDataBuilder().getMetaData(session, tableSet.iterator());
final DependencyResolver dr = new DependencyResolver(meta.getTables());
resolverResult = dr.sortTables();
final Collection<Table> tabs = resolverResult.getTables();
final Iterator<Table> it = tabs.iterator();
while (it.hasNext()) {
tableSequence.add(it.next().getName());
}
} else {
tableSequence = new ArrayList<String>(tableSet);
}
/* 3) dump out */
if (tableSequence.size() > 1) {
Logger.info("%s tables to dump.", tableSequence.size());
}
final Iterator<String> it = tableSequence.iterator();
while (_running && it.hasNext()) {
final String table = it.next();
if (!alreadyDumped.contains(table)) {
final int result = dumpTable(session, table, null, out, FILE_ENCODING, alreadyDumped);
if (result != SUCCESS) {
dumpResult = result;
}
}
}
if (tableSequence.size() > 1) {
final long duration = System.currentTimeMillis() - startTime;
// TODO: move to Logger, timerenderer returns strings.
HenPlus.msg().print("Dumping " + tableSequence.size() + " tables took ");
TimeRenderer.printTime(duration, HenPlus.msg());
HenPlus.msg().println();
}
/* 4) warn about cycles */
if (resolverResult != null && resolverResult.getCyclicDependencies() != null && resolverResult.getCyclicDependencies().size() > 0) {
HenPlus.msg().println("-----------\n" + "NOTE: There have been cyclic dependencies between several tables detected.\n" + "These may cause trouble when dumping in the currently dumped data.");
// TODO: soll count nicht vielleicht hochgezählt werden
final int count = 0;
final StringBuilder sb = new StringBuilder();
for (Collection<Table> tables : resolverResult.getCyclicDependencies()) {
sb.append("Cycle ").append(count).append(": ");
for (Table table : tables) {
sb.append(table.getName()).append(" -> ");
}
sb.delete(sb.length() - 4, sb.length()).append('\n');
}
HenPlus.msg().print(sb.toString());
/* todo: print out, what constraint to disable */
}
return dumpResult;
} catch (final Exception e) {
HenPlus.msg().println("dump table '" + tabName + "' failed: " + e.getMessage());
e.printStackTrace();
return EXEC_FAILED;
} finally {
if (out != null) {
out.close();
}
endInterruptableSection();
}
} else if ("dump-in".equals(cmd)) {
if (session == null) {
HenPlus.msg().println("not connected. Only verify-dump possible.");
return EXEC_FAILED;
}
if (argc < 1 || argc > 2) {
return SYNTAX_ERROR;
}
final String fileName = (String) st.nextElement();
int commitPoint = -1;
if (argc == 2) {
try {
final String val = (String) st.nextElement();
commitPoint = Integer.valueOf(val).intValue();
} catch (final NumberFormatException e) {
HenPlus.msg().println("commit point number expected: " + e);
return SYNTAX_ERROR;
}
}
return retryReadDump(fileName, session, commitPoint);
} else if ("verify-dump".equals(cmd)) {
if (argc != 1) {
return SYNTAX_ERROR;
}
final String fileName = (String) st.nextElement();
return retryReadDump(fileName, null, -1);
}
return SYNTAX_ERROR;
}
Aggregations