use of henplus.view.util.NameCompleter 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;
}
use of henplus.view.util.NameCompleter in project henplus by neurolabs.
the class DumpCommand method complete.
/**
* complete the table name.
*/
@Override
public Iterator<String> complete(final CommandDispatcher disp, final String partialCommand, String lastWord) {
final StringTokenizer st = new StringTokenizer(partialCommand);
final String cmd = (String) st.nextElement();
int argc = st.countTokens();
if (lastWord.length() > 0) {
argc--;
}
if ("dump-conditional".equals(cmd)) {
if (argc == 0) {
return new FileCompletionIterator(partialCommand, lastWord);
} else if (argc == 1) {
if (lastWord.startsWith("\"")) {
lastWord = lastWord.substring(1);
}
return _tableCompleter.completeTableName(HenPlus.getInstance().getCurrentSession(), lastWord);
} else if (argc > 1) {
// discard filename.
st.nextElement();
final String table = (String) st.nextElement();
final Collection<String> columns = _tableCompleter.columnsFor(table);
final NameCompleter compl = new NameCompleter(columns);
return compl.getAlternatives(lastWord);
}
} else if ("dump-out".equals(cmd)) {
// this is true for dump-out und verify-dump
if (argc == 0) {
return new FileCompletionIterator(partialCommand, lastWord);
}
if (argc > 0) {
if (lastWord.startsWith("\"")) {
lastWord = lastWord.substring(1);
}
final HashSet<String> alreadyGiven = new HashSet<String>();
/*
* do not complete the tables we already gave on the
* commandline.
*/
while (st.hasMoreElements()) {
alreadyGiven.add(st.nextToken());
}
final Iterator<String> it = _tableCompleter.completeTableName(HenPlus.getInstance().getCurrentSession(), lastWord);
return new Iterator<String>() {
String table = null;
@Override
public boolean hasNext() {
while (it.hasNext()) {
table = (String) it.next();
if (alreadyGiven.contains(table)) {
continue;
}
return true;
}
return false;
}
@Override
public String next() {
return table;
}
@Override
public void remove() {
throw new UnsupportedOperationException("no!");
}
};
}
} else {
if (argc == 0) {
return new FileCompletionIterator(partialCommand, lastWord);
}
}
return null;
}
use of henplus.view.util.NameCompleter in project henplus by neurolabs.
the class SQLCommand method complete.
// very simple completer: try to determine wether we can complete a
// table name. that is: if some keyword has been found before, switch to
// table-completer-mode :-)
@Override
public Iterator<String> complete(final CommandDispatcher disp, final String partialCommand, final String lastWord) {
final String canonCmd = partialCommand.toUpperCase();
/*
* look for keywords that expect table names
*/
int tableMatch = -1;
for (int i = 0; i < TABLE_COMPLETER_KEYWORD.length; ++i) {
final int match = canonCmd.indexOf(TABLE_COMPLETER_KEYWORD[i]);
if (match >= 0) {
tableMatch = match + TABLE_COMPLETER_KEYWORD[i].length();
break;
}
}
if (tableMatch < 0) {
/*
* ok, try to complete all columns from all tables since we don't
* know yet what table the column will be from.
*/
return _tableCompleter.completeAllColumns(lastWord);
}
// where the table declaration ends.
int endTabMatch = -1;
if (canonCmd.indexOf("UPDATE") >= 0) {
endTabMatch = canonCmd.indexOf("SET");
} else if (canonCmd.indexOf("INSERT") >= 0) {
endTabMatch = canonCmd.indexOf("(");
} else if (canonCmd.indexOf("WHERE") >= 0) {
endTabMatch = canonCmd.indexOf("WHERE");
} else if (canonCmd.indexOf("ORDER BY") >= 0) {
endTabMatch = canonCmd.indexOf("ORDER BY");
} else if (canonCmd.indexOf("GROUP BY") >= 0) {
endTabMatch = canonCmd.indexOf("GROUP BY");
}
if (endTabMatch < 0) {
endTabMatch = canonCmd.indexOf(";");
}
if (endTabMatch > tableMatch) {
/*
* column completion for the tables mentioned between in the table
* area. This acknowledges as well aliases and prepends the names
* with these aliases, if necessary.
*/
final String tables = partialCommand.substring(tableMatch, endTabMatch);
final HashMap<String, Set<String>> tmp = new HashMap<String, Set<String>>();
for (Entry<String, String> entry : tableDeclParser(tables).entrySet()) {
final String alias = entry.getKey();
String tabName = entry.getValue();
tabName = _tableCompleter.correctTableName(tabName);
if (tabName == null) {
continue;
}
final Collection<String> columns = _tableCompleter.columnsFor(tabName);
final Iterator<String> cit = columns.iterator();
while (cit.hasNext()) {
final String col = cit.next();
Set<String> aliases = tmp.get(col);
if (aliases == null) {
aliases = new HashSet<String>();
}
aliases.add(alias);
tmp.put(col, aliases);
}
}
final NameCompleter completer = new NameCompleter();
for (Entry<String, Set<String>> entry : tmp.entrySet()) {
final String col = entry.getKey();
final Set<String> aliases = entry.getValue();
if (aliases.size() == 1) {
completer.addName(col);
} else {
for (String name : aliases) {
completer.addName(name);
}
}
}
return completer.getAlternatives(lastWord);
} else {
// table completion.
return _tableCompleter.completeTableName(HenPlus.getInstance().getCurrentSession(), lastWord);
}
}
use of henplus.view.util.NameCompleter in project henplus by neurolabs.
the class ListUserObjectsCommand method getAllColumnsCompleter.
private NameCompleter getAllColumnsCompleter(final SQLSession session) {
NameCompleter compl = _sessionColumns.get(session);
if (compl != null) {
return compl;
}
/*
* This may be a lengthy process..
*/
_interrupted = false;
SigIntHandler.getInstance().pushInterruptable(this);
final NameCompleter tables = getTableCompleter(session);
if (tables == null) {
return null;
}
final Iterator<String> table = tables.getAllNamesIterator();
compl = new NameCompleter();
while (!_interrupted && table.hasNext()) {
final String tabName = table.next();
final Collection<String> columns = columnsFor(tabName);
final Iterator<String> cit = columns.iterator();
while (cit.hasNext()) {
final String col = cit.next();
compl.addName(col);
}
}
if (_interrupted) {
compl = null;
} else {
_sessionColumns.put(session, compl);
}
SigIntHandler.getInstance().popInterruptable();
return compl;
}
use of henplus.view.util.NameCompleter in project henplus by neurolabs.
the class ListUserObjectsCommand method rehash.
/**
* rehash table names.
*/
private NameCompleter rehash(final SQLSession session) {
final NameCompleter result = new NameCompleter();
// use createStmt
final Connection conn = session.getConnection();
ResultSet rset = null;
try {
final DatabaseMetaData meta = conn.getMetaData();
rset = meta.getTables(null, null, null, LIST_TABLES_VIEWS);
while (rset.next()) {
result.addName(rset.getString(3));
}
} catch (final Exception e) {
// ignore.
} finally {
if (rset != null) {
try {
rset.close();
} catch (final Exception e) {
}
}
}
_sessionTables.put(session, result);
_sessionColumns.remove(session);
return result;
}
Aggregations