/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.openjpa.jdbc.schema;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.Writer;
import java.net.URL;
import java.security.AccessController;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

import javax.sql.DataSource;

import org.apache.openjpa.conf.OpenJPAConfiguration;
import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
import org.apache.openjpa.jdbc.conf.JDBCConfigurationImpl;
import org.apache.openjpa.jdbc.identifier.DBIdentifier;
import org.apache.openjpa.jdbc.sql.DBDictionary;
import org.apache.openjpa.jdbc.sql.SQLExceptions;
import org.apache.openjpa.lib.conf.Configurations;
import org.apache.openjpa.lib.jdbc.DelegatingDataSource;
import org.apache.openjpa.lib.log.Log;
import org.apache.openjpa.lib.meta.MetaDataSerializer;
import org.apache.openjpa.lib.util.Files;
import org.apache.openjpa.lib.util.J2DoPrivHelper;
import org.apache.openjpa.lib.util.Localizer;
import org.apache.openjpa.lib.util.Options;
import org.apache.openjpa.lib.util.StringUtil;
import org.apache.openjpa.util.InvalidStateException;

/**
 * The SchemaTool is used to manage the database schema. Note that the
 * tool never adds or drops unique constraints from existing tables, because
 * JDBC {@link DatabaseMetaData} does not include information on these
 * constraints.
 *
 * @author Abe White
 * @author Patrick Linskey
 */
public class SchemaTool {

    public static final String ACTION_ADD = "add";
    public static final String ACTION_DROP = "drop";
    public static final String ACTION_DROP_SCHEMA = "dropSchema";
    public static final String ACTION_RETAIN = "retain";
    public static final String ACTION_REFRESH = "refresh";
    public static final String ACTION_BUILD = "build";
    public static final String ACTION_REFLECT = "reflect";
    public static final String ACTION_CREATEDB = "createDB";
    public static final String ACTION_DROPDB = "dropDB";
    public static final String ACTION_IMPORT = "import";
    public static final String ACTION_EXPORT = "export";
    public static final String ACTION_DELETE_TABLE_CONTENTS = "deleteTableContents";
    public static final String ACTION_EXECUTE_SCRIPT = "executeScript";

    public static final String[] ACTIONS = new String[]{
        ACTION_ADD,
        ACTION_DROP,
        ACTION_DROP_SCHEMA,
        ACTION_RETAIN,
        ACTION_REFRESH,
        ACTION_BUILD,
        ACTION_REFLECT,
        ACTION_CREATEDB,
        ACTION_DROPDB,
        ACTION_IMPORT,
        ACTION_EXPORT,
        ACTION_DELETE_TABLE_CONTENTS,
        ACTION_EXECUTE_SCRIPT
    };

    protected static final Localizer _loc = Localizer.forPackage(SchemaTool.class);

    protected final JDBCConfiguration _conf;
    protected final DataSource _ds;
    protected final Log _log;
    protected final DBDictionary _dict;
    private final String _action;
    private boolean _ignoreErrs = false;
    private boolean _openjpaTables = false;
    private boolean _dropTables = true;
    private boolean _dropSeqs = true;
    private boolean _pks = true;
    private boolean _fks = true;
    private boolean _indexes = true;
    private boolean _seqs = true;
    private boolean _rollbackBeforeDDL = true;
    private PrintWriter _writer = null;
    private SchemaGroup _group = null;
    private SchemaGroup _db = null;
    protected boolean _fullDB = false;
    protected String _sqlTerminator = ";";
    protected String _scriptToExecute = null;

    /**
     * Default constructor. Tools constructed this way will not have an
     * action, so the {@link #run()} method will be a no-op.
     */
    public SchemaTool(JDBCConfiguration conf) {
        this(conf, null);
    }

    /**
     * Construct a tool to perform the given action.
     */
    public SchemaTool(JDBCConfiguration conf, String action) {
        if (action != null && !Arrays.asList(ACTIONS).contains(action)) {
            Configurations.configureInstance(this, conf, action, action);
        }

        _conf = conf;
        _action = action;
        _ds = ACTION_BUILD.equals(action) ? null : conf.getDataSource2(null);
        _log = conf.getLog(JDBCConfiguration.LOG_SCHEMA);

        // initialize this up-front; otherwise the dbdictionaryfactory might
        // try to take a connection to initialize when we've already got one:
        // bad news if the max pool is 1
        _dict = _conf.getDBDictionaryInstance();
    }

    /**
     * Cleanup DataSource after run()/record()
     */
    public void clear() {
        if (_ds != null && _ds instanceof DelegatingDataSource) {
            try {
                ((DelegatingDataSource)_ds).close();
            } catch (Exception e) {
                // no-op
            }
        }
    }

    /**
     * The action supplied on construction.
     */
    public String getAction() {
        return _action;
    }

    /**
     * If true, SQLExceptions thrown during schema manipulation will be
     * printed but ignored.
     */
    public boolean getIgnoreErrors() {
        return _ignoreErrs;
    }

    /**
     * If true, SQLExceptions thrown during schema manipulation will be
     * printed but ignored.
     */
    public void setIgnoreErrors(boolean ignoreErrs) {
        _ignoreErrs = ignoreErrs;
    }

    /**
     * Whether to act on special tables used by OpenJPA components
     * for bookkeeping.
     */
    public boolean getOpenJPATables() {
        return _openjpaTables;
    }

    /**
     * Whether to act on special tables used by OpenJPA components
     * for bookkeeping.
     */
    public void setOpenJPATables(boolean openjpaTables) {
        _openjpaTables = openjpaTables;
    }

    /**
     * If true, tables that appear to be unused will be dropped. Defaults to
     * true.
     */
    public boolean getDropTables() {
        return _dropTables;
    }

    /**
     * If true, tables that appear to be unused will be dropped. Defaults to
     * true.
     */
    public void setDropTables(boolean dropTables) {
        _dropTables = dropTables;
    }

    /**
     * If true, sequences that appear to be unused will be dropped. Defaults
     * to true.
     */
    public boolean getDropSequences() {
        return _dropSeqs;
    }

    /**
     * If true, sequences that appear to be unused will be dropped. Defaults
     * to true.
     */
    public void setDropSequences(boolean dropSeqs) {
        _dropSeqs = dropSeqs;
        if (dropSeqs)
            setSequences(true);
    }

    /**
     * If true, rollback will be performed before each DDL statement is executed. Defaults to true.
     */
    public boolean getRollbackBeforeDDL() {
        return _rollbackBeforeDDL;
    }

    /**
     * If true, rollback will be performed before each DDL statement is executed. Defaults to true.
     */
    public void setRollbackBeforeDDL(boolean rollbackBeforeDDL) {
        _rollbackBeforeDDL = rollbackBeforeDDL;
    }

    /**
     * Whether sequences should be manipulated. Defaults to true.
     */
    public boolean getSequences() {
        return _seqs;
    }

    /**
     * Whether sequences should be manipulated. Defaults to true.
     */
    public void setSequences(boolean seqs) {
        _seqs = seqs;
    }

    /**
     * Whether indexes on existing tables should be manipulated.
     * Defaults to true.
     */
    public boolean getIndexes() {
        return _indexes;
    }

    /**
     * Whether indexes on existing tables should be manipulated.
     * Defaults to true.
     */
    public void setIndexes(boolean indexes) {
        _indexes = indexes;
    }

    /**
     * Whether foreign keys on existing tables should be manipulated.
     * Defaults to true.
     */
    public boolean getForeignKeys() {
        return _fks;
    }

    /**
     * Whether foreign keys on existing tables should be manipulated.
     * Defaults to true.
     */
    public void setForeignKeys(boolean fks) {
        _fks = fks;
    }

    /**
     * Whether primary keys on existing tables should be manipulated.
     * Defaults to true.
     */
    public boolean getPrimaryKeys() {
        return _pks;
    }

    /**
     * Whether primary keys on existing tables should be manipulated.
     * Defaults to true.
     */
    public void setPrimaryKeys(boolean pks) {
        _pks = pks;
    }

    /**
     * The stream to write to for the creation of SQL scripts. If the
     * stream is non-null, all SQL will be written to this stream rather than
     * executed against the database.
     */
    public Writer getWriter() {
        return _writer;
    }

    /**
     * The stream to write to for the creation of SQL scripts. If the
     * stream is non-null, all SQL will be written to this stream rather than
     * executed against the database.
     */
    public void setWriter(Writer writer) {
        if (writer == null)
            _writer = null;
        else if (writer instanceof PrintWriter)
            _writer = (PrintWriter) writer;
        else
            _writer = new PrintWriter(writer);
    }

    public void setSQLTerminator(String t) {
    	_sqlTerminator = t;
    }

    public void setScriptToExecute(String scriptToExecute) {
        _scriptToExecute = scriptToExecute;
    }

    /**
     * Return the schema group the tool will act on.
     */
    public SchemaGroup getSchemaGroup() {
        return _group;
    }

    /**
     * Set the schema group the tool will act on.
     */
    public void setSchemaGroup(SchemaGroup group) {
        _group = group;
    }

    ///////////
    // Actions
    ///////////

    /**
     * Run the tool action.
     */
    public void run()
        throws SQLException {
        if (_action == null)
            return;

        if (ACTION_ADD.equals(_action))
            add();
        else if (ACTION_DROP.equals(_action))
            drop();
        else if (ACTION_DROP_SCHEMA.equals(_action))
            dropSchema();
        else if (ACTION_RETAIN.equals(_action))
            retain();
        else if (ACTION_REFRESH.equals(_action))
            refresh();
        else if (ACTION_BUILD.equals(_action))
            build();
        else if (ACTION_CREATEDB.equals(_action))
            createDB();
        else if (ACTION_DROPDB.equals(_action))
            dropDB();
        else if (ACTION_DELETE_TABLE_CONTENTS.equals(_action))
            deleteTableContents();
        else if (ACTION_EXECUTE_SCRIPT.equals(_action)) {
            executeScript();
        }
    }

    /**
     * Adds any components present in the schema repository but absent from
     * the database.
     */
    protected void add()
        throws SQLException {
        add(getDBSchemaGroup(false), assertSchemaGroup());
    }

    /**
     * Drops all schema components in the schema repository that also exist
     * in the database.
     */
    protected void drop()
        throws SQLException {
        drop(getDBSchemaGroup(false), assertSchemaGroup());
    }

    /**
     * Drops all schema components in the schema repository.
     */
    protected void dropSchema()
        throws SQLException {
        drop(getDBSchemaGroup(false), assertSchemaGroup(), false);
    }

    /**
     * Drops database components that are not mentioned in the schema
     * repository.
     */
    protected void retain()
        throws SQLException {
        retain(getDBSchemaGroup(true), assertSchemaGroup(),
            getDropTables(), getDropSequences());
    }

    /**
     * Adds any components present in the schema repository but absent from
     * the database, and drops unused database components.
     */
    protected void refresh()
        throws SQLException {
        SchemaGroup local = assertSchemaGroup();
        SchemaGroup db = getDBSchemaGroup(true);
        retain(db, local, getDropTables(), getDropSequences());
        add(db, local);
    }

    /**
     * Re-execute all SQL used for the creation of the current database;
     * this action is usually used when creating SQL scripts.
     */
    protected void createDB()
        throws SQLException {
        SchemaGroup group = new SchemaGroup();
        group.addSchema();
        add(group, getDBSchemaGroup(true));
    }

    /**
     * Re-execute all SQL used for the creation of the current database;
     * this action is usually used when creating SQL scripts.
     */
    protected void build()
        throws SQLException {
        SchemaGroup group = new SchemaGroup();
        group.addSchema();
        buildSchema(group, assertSchemaGroup(), true);
    }

    /**
     * Drop the current database.
     */
    protected void dropDB()
        throws SQLException {
        retain(getDBSchemaGroup(true), new SchemaGroup(), true, true);
    }

    /**
     * Issue DELETE statement against all known tables.
     */
    protected void deleteTableContents()
        throws SQLException {
        SchemaGroup group = getSchemaGroup();
        Schema[] schemas = group.getSchemas();
        Collection<Table> tables = new LinkedHashSet<>();
        for (Schema schema : schemas) {
            Table[] ts = schema.getTables();
            for (Table t : ts) {
                tables.add(t);
            }
        }
        Table[] tableArray = tables.toArray(new Table[tables.size()]);
        Connection conn = _ds.getConnection();
        try {
            String[] sql = _conf.getDBDictionaryInstance()
                .getDeleteTableContentsSQL(tableArray, conn);
            if (!executeSQL(sql)) {
                _log.warn(_loc.get("delete-table-contents"));
            }
        } finally {
            closeConnection(conn);
        }
    }

    protected void executeScript() throws SQLException {
        if (_scriptToExecute == null) {
            _log.warn(_loc.get("generating-execute-script-not-defined"));
            return;
        }

        URL url = AccessController.doPrivileged(
                J2DoPrivHelper.getResourceAction(_conf.getClassResolverInstance().
                        getClassLoader(SchemaTool.class, null), _scriptToExecute));

        if (url == null) {
            _log.error(_loc.get("generating-execute-script-not-found", _scriptToExecute));
            return;
        }

        _log.info(_loc.get("generating-execute-script", _scriptToExecute));
        BufferedReader reader = null;
        try {
            reader = new BufferedReader(new InputStreamReader(url.openStream()));
            String sql;
            List<String> script = new ArrayList<>();
            while ((sql = reader.readLine()) != null) {
                sql = sql.trim();
                if (sql.startsWith("--") || sql.startsWith("/*") || sql.startsWith("//")) {
                    continue;
                }

                int semiColonPosition = sql.indexOf(";"); // ';' can be in string, don't blindly drop it
                if (sql.endsWith(";")) {
                    sql = sql.substring(0, sql.length() - 1);
                }
                if (sql.isEmpty()) {
                    continue;
                }
                script.add(sql);
            }

            executeSQL(script.toArray(new String[script.size()]));
        } catch (IOException e) {
            _log.error(e.getMessage(), e);
        } finally {
            try {
                if (reader != null) {
                    reader.close();
                }
            } catch (IOException e) {
                _log.error(e.getMessage(), e);
            }
        }
    }

    /**
     * Record the changes made to the DB in the current {@link SchemaFactory}.
     */
    public void record() {
        if (_db != null && _writer == null)
            _conf.getSchemaFactoryInstance().storeSchema(_db);
    }

    /**
     * Adds all database components in the repository schema that are not
     * present in the given database schema to the database.
     */
    protected void add(SchemaGroup db, SchemaGroup repos)
        throws SQLException {

        buildSchema(db, repos, true);
    }

    protected void buildSchema(SchemaGroup db, SchemaGroup repos, boolean considerDatabaseState) throws SQLException {
        // add sequences
        Schema[] schemas = repos.getSchemas();
        Schema schema;
        if (_seqs) {
            Sequence[] seqs;
            for (Schema value : schemas) {
                seqs = value.getSequences();
                for (Sequence seq : seqs) {
                    if (considerDatabaseState && db.findSequence(value, seq.getQualifiedPath()) != null) {
                        continue;
                    }

                    if (createSequence(seq)) {
                        schema = db.getSchema(seq.getSchemaIdentifier());
                        if (schema == null)
                            schema = db.addSchema(seq.getSchemaIdentifier());
                        schema.importSequence(seq);
                    }
                    else
                        _log.warn(_loc.get("add-seq", seq));
                }
            }
        }

        // order is important in this method; start with columns
        Table[] tabs;
        Table dbTable = null;
        Column[] cols;
        Column col;
        DBIdentifier defaultSchemaName = DBIdentifier.newSchema(_dict.getDefaultSchemaName());
        for (Schema schema2 : schemas) {
            tabs = schema2.getTables();
            for (Table tab : tabs) {
                cols = tab.getColumns();
                if (considerDatabaseState) {
                    dbTable = db.findTable(schema2, tab.getQualifiedPath(), defaultSchemaName);
                }
                for (Column column : cols) {
                    if (dbTable != null) {
                        DBIdentifier colName = column.getIdentifier();
                        col = dbTable.getColumn(colName);
                        if (col == null) {
                            if (addColumn(column))
                                dbTable.importColumn(column);
                            else
                                _log.warn(_loc.get("add-col", column,
                                        tab));
                        }
                        else if (!column.equalsColumn(_dict, col)) {
                            _log.warn(_loc.get("bad-col", new Object[]{
                                    col, dbTable, col.getDescription(),
                                    column.getDescription()}));
                        }
                    }
                }
            }
        }

        // primary keys
        if (_pks) {
            PrimaryKey pk;
            for (Schema value : schemas) {
                tabs = value.getTables();
                for (Table tab : tabs) {
                    pk = tab.getPrimaryKey();
                    if (considerDatabaseState) {
                        dbTable = db.findTable(value, tab.getQualifiedPath());
                    }
                    if (pk != null && !pk.isLogical() && dbTable != null) {
                        if (dbTable.getPrimaryKey() == null
                                && addPrimaryKey(pk))
                            dbTable.importPrimaryKey(pk);
                        else if (dbTable.getPrimaryKey() == null)
                            _log.warn(_loc.get("add-pk", pk, tab));
                        else if (!pk.equalsPrimaryKey(dbTable.getPrimaryKey()))
                            _log.warn(_loc.get("bad-pk",
                                    dbTable.getPrimaryKey(), dbTable));
                    }
                }
            }
        }

        // tables
        Set<Table> newTables = new HashSet<>();
        for (Schema schema1 : schemas) {
            tabs = schema1.getTables();
            for (Table tab : tabs) {
                if (considerDatabaseState && db.findTable(schema1, tab.getQualifiedPath()) != null) {
                    continue;
                }

                if (createTable(tab)) {
                    newTables.add(tab);
                    schema = db.getSchema(tab.getSchemaIdentifier());
                    if (schema == null)
                        schema = db.addSchema(tab.getSchemaIdentifier());
                    schema.importTable(tab);
                }
                else
                    _log.warn(_loc.get("add-table", tab));
            }
        }

        // indexes
        Index[] idxs;
        Index idx;
        for (Schema element : schemas) {
            tabs = element.getTables();
            for (Table tab : tabs) {
                // create indexes on new tables even if indexes
                // have been turned off
                if (!_indexes && !newTables.contains(tab))
                    continue;

                idxs = tab.getIndexes();
                if (considerDatabaseState) {
                    dbTable = db.findTable(element, tab.getQualifiedPath());
                }
                for (Index index : idxs) {
                    if (dbTable != null) {
                        idx = findIndex(dbTable, index);
                        if (idx == null) {
                            if (createIndex(index, dbTable, tab.getUniques()))
                                dbTable.importIndex(index);
                            else
                                _log.warn(_loc.get("add-index", index,
                                        tab));
                        }
                        else if (!index.equalsIndex(idx))
                            _log.warn(_loc.get("bad-index", idx, dbTable));
                    }
                }
            }
        }

        // Unique Constraints on group of columns
        Unique[] uniques;
        for (Schema item : schemas) {
            tabs = item.getTables();
            for (Table tab : tabs) {
                // create unique constraints only on new tables
                if (!newTables.contains(tab)) {
                    continue;
                }

                uniques = tab.getUniques();
                if (uniques == null || uniques.length == 0)
                    continue;
                if (considerDatabaseState) {
                    dbTable = db.findTable(tab);
                }
                if (dbTable == null)
                    continue;
                for (Unique unique : uniques) {
                    dbTable.importUnique(unique);
                }
            }
        }

        // foreign keys
        ForeignKey[] fks;
        ForeignKey fk;
        for (Schema value : schemas) {
            tabs = value.getTables();
            for (Table tab : tabs) {
                // create foreign keys on new tables even if fks
                // have been turned off
                if (!_fks && !newTables.contains(tab)) {
                    continue;
                }

                fks = tab.getForeignKeys();
                if (considerDatabaseState) {
                    dbTable = db.findTable(value, tab.getQualifiedPath());
                }
                for (ForeignKey foreignKey : fks) {
                    if (!foreignKey.isLogical() && dbTable != null) {
                        fk = findForeignKey(dbTable, foreignKey);
                        if (fk == null) {
                            if (addForeignKey(foreignKey))
                                dbTable.importForeignKey(foreignKey);
                            else
                                _log.warn(_loc.get("add-fk",
                                        foreignKey, tab));
                        }
                        else if (!foreignKey.equalsForeignKey(fk))
                            _log.warn(_loc.get("bad-fk", fk, dbTable));
                    }
                }
            }
        }
    }

    /**
     * Drops all database components that are in the given database schema
     * but not in the repository schema.
     */
    protected void retain(SchemaGroup db, SchemaGroup repos, boolean tables,
        boolean sequences)
        throws SQLException {
        Schema[] schemas = db.getSchemas();
        if (_seqs && sequences) {
            Sequence[] seqs;
            for (Schema schema : schemas) {
                seqs = schema.getSequences();
                for (Sequence seq : seqs) {
                    if (!isDroppable(seq))
                        continue;
                    if (repos.findSequence(seq) == null) {
                        if (dropSequence(seq))
                            schema.removeSequence(seq);
                        else
                            _log.warn(_loc.get("drop-seq", seq));
                    }
                }
            }
        }

        // order is important in this method; start with foreign keys
        Table[] tabs;
        Table reposTable;
        if (_fks) {
            ForeignKey[] fks;
            ForeignKey fk;
            for (Schema schema : schemas) {
                tabs = schema.getTables();
                for (Table tab : tabs) {
                    if (!isDroppable(tab))
                        continue;
                    fks = tab.getForeignKeys();
                    reposTable = repos.findTable(tab);
                    if (!tables && reposTable == null)
                        continue;

                    for (ForeignKey foreignKey : fks) {
                        if (foreignKey.isLogical())
                            continue;

                        fk = null;
                        if (reposTable != null)
                            fk = findForeignKey(reposTable, foreignKey);
                        if (reposTable == null || fk == null
                                || !foreignKey.equalsForeignKey(fk)) {
                            if (dropForeignKey(foreignKey))
                                tab.removeForeignKey(foreignKey);
                            else
                                _log.warn(_loc.get("drop-fk", foreignKey,
                                        tab));
                        }
                    }
                }
            }
        }

        // primary keys
        if (_pks) {
            PrimaryKey pk;
            for (Schema schema : schemas) {
                tabs = schema.getTables();
                for (Table tab : tabs) {
                    if (!isDroppable(tab))
                        continue;
                    pk = tab.getPrimaryKey();
                    if (pk != null && pk.isLogical())
                        continue;

                    reposTable = repos.findTable(tab);
                    if (pk != null && reposTable != null
                            && (reposTable.getPrimaryKey() == null
                            || !pk.equalsPrimaryKey(reposTable.getPrimaryKey()))) {
                        if (dropPrimaryKey(pk))
                            tab.removePrimaryKey();
                        else
                            _log.warn(_loc.get("drop-pk", pk, tab));
                    }
                }
            }
        }

        // columns
        Column[] cols;
        Column col;
        Collection<Table> drops = new LinkedList<>();
        for (Schema value : schemas) {
            tabs = value.getTables();
            for (Table tab : tabs) {
                if (!isDroppable(tab))
                    continue;
                cols = tab.getColumns();
                reposTable = repos.findTable(tab);
                if (reposTable != null) {
                    for (Column column : cols) {
                        col = reposTable.getColumn(column.getIdentifier());
                        if (col == null || !column.equalsColumn(_dict, col)) {
                            if (tab.getColumns().length == 1)
                                drops.add(tab);
                            else if (dropColumn(column))
                                tab.removeColumn(column);
                            else
                                _log.warn(_loc.get("drop-col", column,
                                        tab));
                        }
                    }
                }
            }
        }

        // now tables
        if (tables) {
            for (Schema schema : schemas) {
                tabs = schema.getTables();
                for (Table tab : tabs)
                    if (isDroppable(tab)
                            && repos.findTable(tab) == null)
                        drops.add(tab);
            }
        }
        dropTables(drops, db);
    }

    protected void drop(SchemaGroup db, SchemaGroup repos)
        throws SQLException {

        drop(db, repos, true);
    }

    /**
     * Drops all database components in the given repository schema.
     */
    private void drop(SchemaGroup db, SchemaGroup repos, boolean considerDatabaseState)
        throws SQLException {
        // drop sequences
        Schema[] schemas = repos.getSchemas();
        if (_seqs) {
            Sequence[] seqs;
            Sequence dbSeq;
            for (Schema schema : schemas) {
                seqs = schema.getSequences();
                for (Sequence seq : seqs) {
                    if (!isDroppable(seq))
                        continue;
                    dbSeq = db.findSequence(seq);
                    if (dbSeq != null) {
                        if (dropSequence(seq))
                            dbSeq.getSchema().removeSequence(dbSeq);
                        else
                            _log.warn(_loc.get("drop-seq", seq));
                    }
                    else if (_writer != null) {
                        dropSequence(seq);
                    }
                }
            }
        }

        // calculate tables to drop; we can only drop tables if we're sure
        // the user listed the entire table definition in the stuff they want
        // dropped; else they might just want to drop a few columns
        Collection<Table> drops = new LinkedList<>();
        Table[] tabs;
        Table dbTable;
        Column[] dbCols;
        for (Schema value : schemas) {
            tabs = value.getTables();
            tables:
            for (Table tab : tabs) {
                if (!isDroppable(tab))
                    continue;

                if (!considerDatabaseState) {
                    drops.add(tab);
                    continue;
                }

                dbTable = db.findTable(tab);
                if (dbTable == null) {
                    if (_writer != null) {
                        drops.add(tab);
                    }
                    continue;
                }

                dbCols = dbTable.getColumns();
                for (Column dbCol : dbCols) {
                    if (!dbCol.getIdentifier().getName().equals(_dict.getIdentityColumnName()) &&
                            !tab.containsColumn(dbCol))
                        continue tables;
                }
                drops.add(tab);
            }
        }

        // order is important in this method; start with foreign keys mentioned
        // in the drop schema
        if (_fks) {
            ForeignKey[] fks;
            ForeignKey fk;
            for (Schema schema : schemas) {
                tabs = schema.getTables();
                for (Table tab : tabs) {
                    if (!isDroppable(tab))
                        continue;
                    fks = tab.getForeignKeys();
                    dbTable = db.findTable(tab);
                    for (ForeignKey foreignKey : fks) {
                        if (foreignKey.isLogical())
                            continue;

                        fk = null;
                        if (dbTable != null)
                            fk = findForeignKey(dbTable, foreignKey);
                        if (dbTable == null || fk == null)
                            continue;

                        if (dropForeignKey(foreignKey))
                            if (dbTable != null)
                                dbTable.removeForeignKey(fk);
                            else
                                _log.warn(_loc.get("drop-fk", foreignKey, tab));
                    }
                }
            }

            // also drop imported foreign keys for tables that will be dropped
            Table tab;
            for (Table drop : drops) {
                tab = drop;
                dbTable = db.findTable(tab);
                if (dbTable == null)
                    continue;

                fks = db.findExportedForeignKeys(dbTable.getPrimaryKey());
                for (ForeignKey foreignKey : fks) {
                    if (dropForeignKey(foreignKey))
                        dbTable.removeForeignKey(foreignKey);
                    else
                        _log.warn(_loc.get("drop-fk", foreignKey, dbTable));
                }
            }
        }

        // drop the tables we calculated above
        dropTables(drops, db);

        if (considerDatabaseState) {
            // columns
            Column[] cols;
            Column col;
            for (Schema schema : schemas) {
                tabs = schema.getTables();
                for (Table tab : tabs) {
                    if (!isDroppable(tab))
                        continue;
                    cols = tab.getColumns();
                    dbTable = db.findTable(tab);
                    for (Column column : cols) {
                        col = null;
                        if (dbTable != null)
                            col = dbTable.getColumn(column.getIdentifier());
                        if (dbTable == null || col == null)
                            continue;

                        if (dropColumn(column)) {
                            dbTable.removeColumn(col);
                        }
                    }
                }
            }
        }
    }

    /**
     * Return true if the table is droppable.
     */
    protected boolean isDroppable(Table table) {
        return _openjpaTables
            || (!DBIdentifier.toUpper(table.getIdentifier()).getName().startsWith("OPENJPA_")
            && !DBIdentifier.toUpper(table.getIdentifier()).getName().startsWith("JDO_")); // legacy
    }

    /**
     * Return true if the sequence is droppable.
     */
    protected boolean isDroppable(Sequence seq) {
        return _openjpaTables
            || (!DBIdentifier.toUpper(seq.getIdentifier()).getName().startsWith("OPENJPA_")
            && !DBIdentifier.toUpper(seq.getIdentifier()).getName().startsWith("JDO_")); // legacy
    }

    /**
     * Find an index in the given table that matches the given one.
     */
    protected Index findIndex(Table dbTable, Index idx) {
        Index[] idxs = dbTable.getIndexes();
        for (Index index : idxs)
            if (idx.columnsMatch(index.getColumns()))
                return index;
        return null;
    }

    /**
     * Find a foreign key in the given table that matches the given one.
     */
    protected ForeignKey findForeignKey(Table dbTable, ForeignKey fk) {
        if (fk.getConstantColumns().length > 0
            || fk.getConstantPrimaryKeyColumns().length > 0)
            return null;
        ForeignKey[] fks = dbTable.getForeignKeys();
        for (ForeignKey foreignKey : fks)
            if (fk.columnsMatch(foreignKey.getColumns(),
                    foreignKey.getPrimaryKeyColumns()))
                return foreignKey;
        return null;
    }

    /**
     * Remove the given collection of tables from the database schema. Orders
     * the removals according to foreign key constraints on the tables.
     */
    protected void dropTables(Collection<Table> tables, SchemaGroup change)
        throws SQLException {
        if (tables.isEmpty())
            return;

        Table table;
        Table changeTable;
        for (Table value : tables) {
            table = value;
            if (dropTable(table)) {
                changeTable = change.findTable(table);
                if (changeTable != null)
                    changeTable.getSchema().removeTable(changeTable);
            }
            else
                _log.warn(_loc.get("drop-table", table));
        }
    }

    /**
     * Add the given table to the database schema.
     *
     * @return true if the operation was successful, false otherwise
     */
    public boolean createTable(Table table)
        throws SQLException {
        return executeSQL(_dict.getCreateTableSQL(table, _db));
    }

    /**
     * Drop the given table from the database schema.
     *
     * @return true if the operation was successful, false otherwise
     */
    public boolean dropTable(Table table)
        throws SQLException {
        return executeSQL(_dict.getDropTableSQL(table));
    }

    /**
     * Add the given sequence to the database schema.
     *
     * @return true if the operation was successful, false otherwise
     */
    public boolean createSequence(Sequence seq)
        throws SQLException {
        return executeSQL(_dict.getCreateSequenceSQL(seq));
    }

    /**
     * Drop the given sequence from the database schema.
     *
     * @return true if the operation was successful, false otherwise
     */
    public boolean dropSequence(Sequence seq)
        throws SQLException {
        return executeSQL(_dict.getDropSequenceSQL(seq));
    }

    /**
     * Add the given index to the database schema.
     *
     * @return true if the operation was successful, false otherwise
     */
    public boolean createIndex(Index idx, Table table)
        throws SQLException {
        return createIndex(idx, table, null);
    }

    public boolean createIndex(Index idx, Table table, Unique[] uniques)
        throws SQLException {
        // Informix will automatically create a unique index for the
        // primary key, so don't create another index again

        if (!_dict.needsToCreateIndex(idx,table,uniques))
            return false;

        int max = _dict.maxIndexesPerTable;

        int len = table.getIndexes().length;
        if (table.getPrimaryKey() != null)
            len += table.getPrimaryKey().getColumns().length;

        if (len >= max) {
            _log.warn(_loc.get("too-many-indexes", idx, table, max + ""));
            return false;
        }

        return executeSQL(_dict.getCreateIndexSQL(idx));
    }

    /**
     * Drop the given index from the database schema.
     *
     * @return true if the operation was successful, false otherwise
     */
    public boolean dropIndex(Index idx)
        throws SQLException {
        return executeSQL(_dict.getDropIndexSQL(idx));
    }

    /**
     * Add the given column to the database schema.
     *
     * @return true if the operation was successful, false otherwise
     */
    public boolean addColumn(Column col)
        throws SQLException {
        return executeSQL(_dict.getAddColumnSQL(col));
    }

    /**
     * Drop the given column from the database schema.
     *
     * @return true if the operation was successful, false otherwise
     */
    public boolean dropColumn(Column col)
        throws SQLException {
        return executeSQL(_dict.getDropColumnSQL(col));
    }

    /**
     * Add the given primary key to the database schema.
     *
     * @return true if the operation was successful, false otherwise
     */
    public boolean addPrimaryKey(PrimaryKey pk)
        throws SQLException {
        return executeSQL(_dict.getAddPrimaryKeySQL(pk));
    }

    /**
     * Drop the given primary key from the database schema.
     *
     * @return true if the operation was successful, false otherwise
     */
    public boolean dropPrimaryKey(PrimaryKey pk)
        throws SQLException {
        return executeSQL(_dict.getDropPrimaryKeySQL(pk));
    }

    /**
     * Add the given foreign key to the database schema.
     *
     * @return true if the operation was successful, false otherwise
     */
    public boolean addForeignKey(ForeignKey fk)
        throws SQLException {
        return executeSQL(_dict.getAddForeignKeySQL(fk));
    }

    /**
     * Drop the given foreign key from the database schema.
     *
     * @return true if the operation was successful, false otherwise
     */
    public boolean dropForeignKey(ForeignKey fk)
        throws SQLException {
        Connection conn = _ds.getConnection();
        try {
            return executeSQL(_dict.getDropForeignKeySQL(fk,conn));
        } finally {
            closeConnection(conn);
        }

    }

    /**
     * Return the database schema.
     */
    public SchemaGroup getDBSchemaGroup() {
        try {
            return getDBSchemaGroup(true);
        } catch (SQLException se) {
            throw SQLExceptions.getStore(se, _dict);
        }
    }

    /**
     * Set the database schema.
     */
    public void setDBSchemaGroup(SchemaGroup db) {
        _db = db;
        if (db != null)
            _fullDB = true;
    }

    /**
     * Return the database schema.
     *
     * @param full if false, only the tables named in the set schema
     * repository will be generated
     */
    protected SchemaGroup getDBSchemaGroup(boolean full)
        throws SQLException {
        if (_db == null || (full && !_fullDB)) {
            SchemaGenerator gen = new SchemaGenerator(_conf);
            gen.setPrimaryKeys(_pks);
            gen.setForeignKeys(_fks);
            gen.setIndexes(_indexes);
            if (full)
                gen.generateSchemas();
            else {
                // generate only the tables in the given repository
                // group; some may not exist yet, which is OK; we just need
                // to make sure we can detect the changes to the ones that
                // do exist
                Collection<DBIdentifier> tables = new LinkedList<>();
                SchemaGroup group = assertSchemaGroup();
                Schema[] schemas = group.getSchemas();
                Table[] tabs;
                for (Schema schema : schemas) {
                    tabs = schema.getTables();
                    for (Table tab : tabs) {
                        if (DBIdentifier.isNull(tab.getSchemaIdentifier())) {
                            tables.add(tab.getIdentifier());
                        }
                        else {
                            DBIdentifier sName = tab.getFullIdentifier();
                            tables.add(sName);
                        }
                    }
                }
                if (!tables.isEmpty())
                    gen.generateSchemas(tables.toArray(new DBIdentifier[tables.size()]));
            }
            _db = gen.getSchemaGroup();
        }
        return _db;
    }

    protected SchemaGroup assertSchemaGroup() {
        SchemaGroup local = getSchemaGroup();
        if (local == null)
            throw new InvalidStateException(_loc.get("tool-norepos"));
        return local;
    }

    /////////////
    // Utilities
    /////////////

    /**
     * Executes the given array of non-selecting SQL statements, correctly
     * logging the SQL calls and optionally ignoring errors.
     *
     * @return true if there was SQL to execute and the calls were
     * successful, false otherwise
     */
    protected boolean executeSQL(String[] sql)
        throws SQLException {
        // if no sql, probably b/c dictionary doesn't support operation
        if (sql.length == 0)
            return false;

        boolean err = false;
        if (_writer == null) {
            // this is outside the try-catch because a failure here is
            // really bad, and should not be ignored.
            Connection conn = _ds.getConnection();
            Statement statement = null;
            boolean wasAuto = true;
            try {
                if (_rollbackBeforeDDL) {
                    wasAuto = conn.getAutoCommit();
                    if (!wasAuto) {
                        conn.setAutoCommit(true);
                    }
                }
                for (String s : sql) {
                    try {
                        if (_rollbackBeforeDDL) {
                            // some connections require that rollback be
                            // called on the connection before any DDL statements
                            // can be run on it, even when autocommit is on.
                            // This is sometimes because the connection does not
                            // allow DDL statements when there are multiple
                            // commands issued on the connection, and the
                            // connection pool may have issued some validation SQL.
                            try {
                                conn.rollback();
                            }
                            catch (Exception e) {
                            }
                        }

                        statement = conn.createStatement();
                        statement.executeUpdate(s);

                        // some connections seem to require an explicit
                        // commit for DDL statements, even when autocommit
                        // is on. The DataDirect drivers seem to suffer from
                        // this limitation.
                        try {
                            conn.commit();
                        }
                        catch (Exception e) {
                        }
                    }
                    catch (SQLException se) {
                        err = true;
                        handleException(se);
                    }
                    finally {
                        if (statement != null)
                            try {
                                statement.close();
                            }
                            catch (SQLException se) {
                            }
                    }
                }
            }
            finally {
                if (_rollbackBeforeDDL && !wasAuto) {
                    conn.setAutoCommit(false);
                }

                try {
                    closeConnection(conn);
                } catch (SQLException se) {
                    //X TODO why catch silently?
                }
            }
        } else {
            for (String s : sql) {
                _writer.println(s + _sqlTerminator);
            }
            _writer.flush();
        }

        return !err;
    }

    /**
     * Handle the given exception, logging it and optionally ignoring it,
     * depending on the flags this SchemaTool was created with.
     */
    protected void handleException(SQLException sql)
        throws SQLException {
        if (!_ignoreErrs)
            throw sql;
        _log.warn(sql.getMessage(), sql);
    }

    ////////
    // Main
    ////////

    /**
     * Usage: java org.apache.openjpa.jdbc.schema.SchemaTool [option]*
     * [-action/-a &lt;add | retain | drop | refresh | createDB | dropDB
     * | build | reflect | import | export&gt;]
     * &lt;.schema file or resource&gt;*
     *  Where the following options are recognized.
     * <ul>
     * <li><i>-properties/-p &lt;properties file or resource&gt;</i>: The
     * path or resource name of a OpenJPA properties file containing
     * information such as the license key	and connection data as
     * outlined in {@link JDBCConfiguration}. Optional.</li>
     * <li><i>-&lt;property name&gt; &lt;property value&gt;</i>: All bean
     * properties of the OpenJPA {@link JDBCConfiguration} can be set by
     * using their	names and supplying a value. For example:
     * <code>-licenseKey adslfja83r3lkadf</code></li>
     * <li><i>-ignoreErrors/-i &lt;true/t | false/f&gt;</i>: If false, an
     * exception will will be thrown if the tool encounters any database
     * exceptions; defaults to <code>false</code>.</li>
     * <li><i>-file/-f &lt;stdout | output file or resource&gt;</i>: Use this
     * option to write a SQL script for the planned schema modifications,
     * rather than committing them to the database. This option also
     * applies to the <code>export</code> and <code>reflect</code> actions.</li>
     * <li><i>-openjpaTables/-kt &lt;true/t | false/f&gt;</i>: Under the
     * <code>reflect</code> action, whether to reflect on tables with
     * the name <code>OPENJPA_*</code>. Under other actions, whether to
     * drop such tables. Defaults to <code>false</code>.</li>
     * <li><i>-dropTables/-dt &lt;true/t | false/f&gt;</i>: Set this option to
     * true to drop tables that appear to be unused during
     * <code>retain</code>	and <code>refresh</code> actions. Defaults to
     * <code>true</code>.</li>
     * <li><i>-dropSequences/-dsq &lt;true/t | false/f&gt;</i>: Set this option
     * to true to drop sequences that appear to be unused during
     * <code>retain</code>	and <code>refresh</code> actions. Defaults to
     * <code>true</code>.</li>
     * <li><i>-rollbackBeforeDDL/-rbddl &lt;true/t | false/f&gt;</i>: Set this option
     * to true to send an initail rollback on the connection before any DDL statement
     * is sent</li>
     * <li><i>-primaryKeys/-pk &lt;true/t | false/f&gt;</i>: Whether primary
     * keys on existing tables are manipulated. Defaults to true.</li>
     * <li><i>-foreignKeys/-fk &lt;true/t | false/f&gt;</i>: Whether foreign
     * keys on existing tables are manipulated. Defaults to true.</li>
     * <li><i>-indexes/-ix &lt;true/t | false/f&gt;</i>: Whether indexes
     * on existing tables are manipulated. Defaults to true.</li>
     * <li><i>-sequences/-sq &lt;true/t | false/f&gt;</i>: Whether to
     * manipulate sequences. Defaults to true.</li>
     * <li><i>-record/-r &lt;true/t | false/f&gt;</i>: Set this option to
     * <code>false</code> to prevent writing the schema changes to the
     * current {@link SchemaFactory}.</li>
     * </ul>
     *  Actions can be composed in a comma-separated list. The various actions
     *  are as follows.
     * <ul>
     * <li><i>add</i>: Bring the schema up-to-date with the latest
     * changes to the schema XML data by adding tables, columns,
     * indexes, etc. This action never drops any data. This is the
     * default action.</li>
     * <li><i>retain</i>: Keep all schema components in the schema XML, but
     * drop the rest from the database. This action never adds any data.</li>
     * <li><i>drop</i>: Drop all the schema components in the schema XML.</li>
     * <li><i>refresh</i>: Equivalent to retain, then add.</li>
     * <li><i>createDB</i>: Execute SQL to re-create the current database.
     * This action is typically used in conjuction with the
     * <code>file</code> option.</li>
     * <li><i>build</i>: Execute SQL to build the schema defined in the XML.
     * Because it doesn't take the current database schema into account,
     * this action is typically used in conjuction with the
     * <code>file</code> option.</li>
     * <li><i>reflect</i>: Reflect on the current database schema. Write the
     * schema's XML representation to the file specified with the
     * <code>file</code> option, or to stdout if no file is given.</li>
     * <li><i>dropDB</i>: Execute SQL to drop the current database. This
     * action implies <code>dropTables</code>.</li>
     * <li><i>deleteTableContents</i>: Execute SQL to delete all rows from
     * all tables that OpenJPA knows about.</li>
     * <li><i>import</i>: Import the given XML schema definition into the
     * current {@link SchemaFactory}.</li>
     * <li><i>export</i>: Export the current {@link SchemaFactory}'s recorded
     * schema to an XML schema definition file.</li>
     * </ul>
     *  Examples:
     * <ul>
     * <li>Write a script to stdout to re-create the current database
     * schema:<br />
     * <code>java org.apache.openjpa.jdbc.schema.SchemaTool -f stdout
     * -a createDB</code></li>
     * <li>Drop the current database schema:<br />
     * <code>java org.apache.openjpa.jdbc.schema.SchemaTool
     * -a dropDB</code></li>
     * <li>Refresh the schema and delete all records in all tables:<br />
     * <code>java org.apache.openjpa.jdbc.schema.SchemaTool
     * -a refresh,deleteTableContents</code></li>
     * <li>Create a schema based on an XML schema definition file:<br />
     * <code>java org.apache.openjpa.jdbc.schema.SchemaTool
     * myschema.xml</code></li>
     * </ul>
     */
    public static void main(String[] args)
        throws IOException, SQLException {
        Options opts = new Options();
        final String[] arguments = opts.setFromCmdLine(args);
        boolean ret = Configurations.runAgainstAllAnchors(opts,
            new Configurations.Runnable() {
            @Override
            public boolean run(Options opts) throws Exception {
                JDBCConfiguration conf = new JDBCConfigurationImpl();
                try {
                    return SchemaTool.run(conf, arguments, opts);
                } finally {
                    conf.close();
                }
            }
        });
        if (!ret) {
            // START - ALLOW PRINT STATEMENTS
            System.out.println(_loc.get("tool-usage"));
            // STOP - ALLOW PRINT STATEMENTS
        }
    }

    /**
     * Run the tool. Returns false if any invalid options were given.
     *
     * @see #main
     */
    public static boolean run(JDBCConfiguration conf, String[] args,
        Options opts)
        throws IOException, SQLException {
        Flags flags = new Flags();
        flags.dropTables = opts.removeBooleanProperty
            ("dropTables", "dt", flags.dropTables);
        flags.dropSequences = opts.removeBooleanProperty
            ("dropSequences", "dsq", flags.dropSequences);
        flags.rollbackBeforeDDL = opts.removeBooleanProperty
            ("rollbackBeforeDDL", "rbddl", flags.rollbackBeforeDDL);
        flags.ignoreErrors = opts.removeBooleanProperty
            ("ignoreErrors", "i", flags.ignoreErrors);
        flags.openjpaTables = opts.removeBooleanProperty
            ("openjpaTables", "ot", flags.openjpaTables);
        flags.primaryKeys = opts.removeBooleanProperty
            ("primaryKeys", "pk", flags.primaryKeys);
        flags.foreignKeys = opts.removeBooleanProperty
            ("foreignKeys", "fks", flags.foreignKeys);
        flags.indexes = opts.removeBooleanProperty
            ("indexes", "ix", flags.indexes);
        flags.sequences = opts.removeBooleanProperty
            ("sequences", "sq", flags.sequences);
        flags.record = opts.removeBooleanProperty("record", "r", flags.record);
        String fileName = opts.removeProperty("file", "f", null);
        String schemas = opts.removeProperty("s");
        if (schemas != null)
            opts.setProperty("schemas", schemas);

        String[] actions = opts.removeProperty("action", "a", flags.action)
            .split(",");

        // setup a configuration instance with cmd-line info
        Configurations.populateConfiguration(conf, opts);

        // create script writer
        ClassLoader loader = conf.getClassResolverInstance().
            getClassLoader(SchemaTool.class, null);
        flags.writer = Files.getWriter(fileName, loader);

        boolean returnValue = true;
        for (String action : actions) {
            flags.action = action;
            returnValue &= run(conf, args, flags, loader);
        }

        return returnValue;
    }

    /**
     * Run the tool. Return false if invalid options were given.
     */
    public static boolean run(JDBCConfiguration conf, String[] args,
        Flags flags, ClassLoader loader)
        throws IOException, SQLException {
        Log log = conf.getLog(OpenJPAConfiguration.LOG_TOOL);
        if (ACTION_REFLECT.equals(flags.action)) {
            if (args.length > 0)
                return false;
            if (flags.writer == null)
                flags.writer = new PrintWriter(System.out);

            SchemaGenerator gen = new SchemaGenerator(conf);
            gen.setPrimaryKeys(flags.primaryKeys);
            gen.setIndexes(flags.indexes);
            gen.setForeignKeys(flags.foreignKeys);
            gen.setSequences(flags.sequences);
            gen.setOpenJPATables(flags.openjpaTables);

            String schemas = conf.getSchemas();
            if (StringUtil.isEmpty(schemas))
                schemas = "all";
            log.info(_loc.get("sch-reflect", schemas));
            gen.generateSchemas();

            // record the schema
            log.info(_loc.get("sch-reflect-write"));
            SchemaSerializer ser = new XMLSchemaSerializer(conf);
            ser.addAll(gen.getSchemaGroup());
            ser.serialize(flags.writer, MetaDataSerializer.PRETTY);
            return true;
        }

        if (args.length == 0
            && !ACTION_CREATEDB.equals(flags.action)
            && !ACTION_DROPDB.equals(flags.action)
            && !ACTION_EXPORT.equals(flags.action)
            && !ACTION_DELETE_TABLE_CONTENTS.equals(flags.action))
            return false;

        // parse in the arguments
        SchemaParser parser = new XMLSchemaParser(conf);
        parser.setDelayConstraintResolve(true);
        File file;
        for (String arg : args) {
            file = Files.getFile(arg, loader);
            log.info(_loc.get("tool-running", file));
            parser.parse(file);
        }
        parser.resolveConstraints();

        if (ACTION_IMPORT.equals(flags.action)) {
            log.info(_loc.get("tool-import-store"));
            SchemaGroup schema = parser.getSchemaGroup();
            conf.getSchemaFactoryInstance().storeSchema(schema);
            return true;
        }
        if (ACTION_EXPORT.equals(flags.action)) {
            if (flags.writer == null)
                flags.writer = new PrintWriter(System.out);

            log.info(_loc.get("tool-export-gen"));
            SchemaGroup schema = conf.getSchemaFactoryInstance().readSchema();

            log.info(_loc.get("tool-export-write"));
            SchemaSerializer ser = new XMLSchemaSerializer(conf);
            ser.addAll(schema);
            ser.serialize(flags.writer, MetaDataSerializer.PRETTY);
            return true;
        }

        SchemaTool tool = new SchemaTool(conf, flags.action);
        tool.setIgnoreErrors(flags.ignoreErrors);
        tool.setDropTables(flags.dropTables);
        tool.setSequences(flags.sequences); // set before dropseqs
        tool.setDropSequences(flags.dropSequences);
        tool.setRollbackBeforeDDL(flags.rollbackBeforeDDL);
        tool.setPrimaryKeys(flags.primaryKeys);
        tool.setForeignKeys(flags.foreignKeys);
        tool.setIndexes(flags.indexes);
        tool.setOpenJPATables(flags.openjpaTables);
        if (args.length > 0)
            tool.setSchemaGroup(parser.getSchemaGroup());
        if (flags.writer != null)
            tool.setWriter(flags.writer);

        log.info(_loc.get("tool-action", flags.action));
        try {
            tool.run();
        } finally {
            if (flags.record) {
                log.info(_loc.get("tool-record"));
                tool.record();
            }
        }
        if (flags.writer != null)
            flags.writer.flush();

        return true;
    }

    private void closeConnection(Connection conn) throws SQLException {
        if (conn != null && !conn.isClosed()) {
            conn.close();
        }
    }

    /**
     * Run flags.
     */
    public static class Flags {

        public String action = ACTION_ADD;
        public Writer writer = null;
        public boolean dropTables = true;
        public boolean rollbackBeforeDDL = true;
        public boolean dropSequences = true;
        public boolean ignoreErrors = false;
        public boolean openjpaTables = false;
        public boolean primaryKeys = true;
        public boolean foreignKeys = true;
        public boolean indexes = true;
        public boolean sequences = true;
        public boolean record = true;
    }
}
