Search in sources :

Example 1 with ResolverResult

use of henplus.util.DependencyResolver.ResolverResult 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;
}
Also used : LinkedHashSet(java.util.LinkedHashSet) PrintStream(java.io.PrintStream) Table(henplus.sqlmodel.Table) NameCompleter(henplus.view.util.NameCompleter) ResolverResult(henplus.util.DependencyResolver.ResolverResult) SortedSet(java.util.SortedSet) SQLException(java.sql.SQLException) IOException(java.io.IOException) DependencyResolver(henplus.util.DependencyResolver) SQLMetaData(henplus.SQLMetaData) StringTokenizer(java.util.StringTokenizer) SQLMetaDataBuilder(henplus.SQLMetaDataBuilder) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet)

Aggregations

SQLMetaData (henplus.SQLMetaData)1 SQLMetaDataBuilder (henplus.SQLMetaDataBuilder)1 Table (henplus.sqlmodel.Table)1 DependencyResolver (henplus.util.DependencyResolver)1 ResolverResult (henplus.util.DependencyResolver.ResolverResult)1 NameCompleter (henplus.view.util.NameCompleter)1 IOException (java.io.IOException)1 PrintStream (java.io.PrintStream)1 SQLException (java.sql.SQLException)1 HashSet (java.util.HashSet)1 LinkedHashSet (java.util.LinkedHashSet)1 SortedSet (java.util.SortedSet)1 StringTokenizer (java.util.StringTokenizer)1