/*
 * Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Oracle - initial API and implementation from Oracle TopLink
//     Dies Koper - add support for creating indices on tables
//     01/11/2013-2.5 Guy Pelletier
//       - 389090: JPA 2.1 DDL Generation Support
//     02/04/2013-2.5 Guy Pelletier
//       - 389090: JPA 2.1 DDL Generation Support
//     04/12/2013-2.5 Guy Pelletier
//       - 405640: JPA 2.1 schema generation drop operation fails to include dropping defaulted fk constraints.
package org.eclipse.persistence.tools.schemaframework;

import java.io.Writer;
import java.net.URL;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
import java.util.Vector;

import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.exceptions.DatabaseException;
import org.eclipse.persistence.exceptions.EclipseLinkException;
import org.eclipse.persistence.exceptions.ValidationException;
import org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor;
import org.eclipse.persistence.internal.helper.Helper;
import org.eclipse.persistence.internal.sequencing.Sequencing;
import org.eclipse.persistence.internal.sessions.AbstractRecord;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.internal.sessions.DatabaseSessionImpl;
import org.eclipse.persistence.sequencing.DefaultSequence;
import org.eclipse.persistence.sequencing.NativeSequence;
import org.eclipse.persistence.sequencing.Sequence;
import org.eclipse.persistence.sequencing.TableSequence;
import org.eclipse.persistence.sequencing.UnaryTableSequence;

/**
 * <p>
 * <b>Purpose</b>: Define all user level protocol for development time database manipulation.
 * <p>
 * <b>Responsibilities</b>:
 * <ul>
 * <li> Define protocol for schema creation.
 * <li> Define any useful testing specific protocol.
 * </ul>
 */
public class SchemaManager {
    protected DatabaseSessionImpl session;
    protected Writer createSchemaWriter;
    protected Writer dropSchemaWriter;
    protected boolean createSQLFiles = true; //if true, schema writer will add terminator string.
    protected TableCreator defaultTableCreator;

    /** Allow table creator to occur "fast" by just deleting all the rows. */
    public static boolean FAST_TABLE_CREATOR = false;

    /** Allow replacing of table to force the drop, this may require several passes. */
    public static boolean FORCE_DROP = true;

    /** Flag to determine if database schemas should be created during DDL generation */
    protected boolean createDatabaseSchemas = false;
    protected HashSet<String> createdDatabaseSchemas = new HashSet<>();
    protected HashSet<String> createdDatabaseSchemasOnDatabase = new HashSet<>();
    protected HashMap<String, DatabaseObjectDefinition> dropDatabaseSchemas = new HashMap<>();

    public SchemaManager(DatabaseSessionImpl session) {
        this.session = session;
    }

    public SchemaManager(org.eclipse.persistence.sessions.DatabaseSession session) {
        this.session = ((DatabaseSessionImpl)session);
    }

    protected Writer getDropSchemaWriter() {
        return (dropSchemaWriter == null) ? createSchemaWriter : dropSchemaWriter;
    }

    /**
     * PUBLIC: If the schema manager is writing to a writer, append this string
     * to that writer.
     */
    public void appendToDDLWriter(String stringToWrite) {
        // If this method is called, we know that it is the old case and
        // it would not matter which schemaWriter we use as both the
        // create and drop schemaWriters are essentially the same.
        // So just pick one.
        appendToDDLWriter(createSchemaWriter, stringToWrite);
    }

    public void appendToDDLWriter(Writer schemaWriter, String stringToWrite) {
        if (schemaWriter == null) {
            return; //do nothing.  Ignore append request
        }

        try {
            schemaWriter.write(stringToWrite);
            schemaWriter.flush();
        } catch (java.io.IOException ioException) {
            throw ValidationException.fileError(ioException);
        }
    }

    /**
     * INTERNAL:
     * builds the field names based on the type read in from the builder
     */
    public void buildFieldTypes(TableDefinition tableDef) {
        tableDef.buildFieldTypes(getSession());
    }

    /**
     * PUBLIC:
     * Close the schema writer.
     */
    public void closeDDLWriter() {
        closeDDLWriter(createSchemaWriter);
        closeDDLWriter(dropSchemaWriter);
        createSchemaWriter = null;
        dropSchemaWriter = null;
    }

    public void closeDDLWriter(Writer schemaWriter) {
        if (schemaWriter == null) {
            return;
        }

        try {
            schemaWriter.flush();
            schemaWriter.close();
        } catch (java.io.IOException ioException) {
            throw ValidationException.fileError(ioException);
        }
    }

    /**
     * INTERNAL:
     * Called when dropping tables. Will build a map of those schemas (and a
     * table that references it) that should be dropped.
     */
    protected void collectDatabaseSchemasForDrop(DatabaseObjectDefinition databaseObjectDefinition) {
        if (createDatabaseSchemas && databaseObjectDefinition.hasDatabaseSchema()) {
            if (! dropDatabaseSchemas.containsKey(databaseObjectDefinition.getDatabaseSchema())) {
                dropDatabaseSchemas.put(databaseObjectDefinition.getDatabaseSchema(), databaseObjectDefinition);
            }
        }
    }

    /**
     * Use the table definition to add the constraints to the database, this is normally done
     * in two steps to avoid dependencies.
     */
    public void createConstraints(TableDefinition tableDefinition) throws EclipseLinkException {
        boolean usesBatchWriting = false;

        if (getSession().getPlatform().usesBatchWriting()) {
            usesBatchWriting = true;
            getSession().getPlatform().setUsesBatchWriting(false);
        }

        try {
            if (shouldWriteToDatabase()) {
                tableDefinition.createConstraintsOnDatabase(getSession());
            } else {
                tableDefinition.setCreateSQLFiles(createSQLFiles);
                tableDefinition.createConstraints(getSession(), createSchemaWriter);
            }
        } finally {
            if (usesBatchWriting) {
                getSession().getPlatform().setUsesBatchWriting(true);
            }
        }
    }

    void createUniqueConstraints(TableDefinition tableDefinition) throws EclipseLinkException {
        if (shouldWriteToDatabase()) {
            tableDefinition.createUniqueConstraintsOnDatabase(getSession());
        } else {
            tableDefinition.setCreateSQLFiles(createSQLFiles);
            tableDefinition.createUniqueConstraints(getSession(), createSchemaWriter);
        }
    }

    void createForeignConstraints(TableDefinition tableDefinition) throws EclipseLinkException {
        if (shouldWriteToDatabase()) {
            tableDefinition.createForeignConstraintsOnDatabase(getSession());
        } else {
            tableDefinition.setCreateSQLFiles(createSQLFiles);
            tableDefinition.createForeignConstraints(getSession(), createSchemaWriter);
        }
    }

    /**
     * Use the definition object to create the schema entity on the database.
     * This is used for creating tables, views, procedures ... etc ...
     */
    public void createObject(DatabaseObjectDefinition databaseObjectDefinition) throws EclipseLinkException {
        boolean usesBatchWriting = false;

        if (getSession().getPlatform().usesBatchWriting()) {
            usesBatchWriting = true;
            getSession().getPlatform().setUsesBatchWriting(false);
        }

        try {
            if (shouldWriteToDatabase()) {
                // Check if we should create a database schema for this
                // database object definition on the database. It is only
                // create once and for the first database object definition
                // that references it.
                if (shouldCreateDatabaseSchema(databaseObjectDefinition, createdDatabaseSchemasOnDatabase)) {
                    databaseObjectDefinition.createDatabaseSchemaOnDatabase(getSession(), createdDatabaseSchemasOnDatabase);
                }

                databaseObjectDefinition.createOnDatabase(getSession());
            } else {
                // Check if we should create a database schema for this
                // database object definition on the database. It is only
                // create once and for the first database object definition
                // that references it.
                if (shouldCreateDatabaseSchema(databaseObjectDefinition, createdDatabaseSchemas)) {
                    databaseObjectDefinition.createDatabaseSchema(getSession(), createSchemaWriter, createdDatabaseSchemas);
                    appendToDDLWriter(createSchemaWriter, "\n");
                }

                databaseObjectDefinition.createObject(getSession(), createSchemaWriter);
                if (createSQLFiles){
                    this.appendToDDLWriter(createSchemaWriter, getSession().getPlatform().getStoredProcedureTerminationToken());
                }
                this.appendToDDLWriter(createSchemaWriter, "\n");
            }
            databaseObjectDefinition.postCreateObject(getSession(), createSchemaWriter, createSQLFiles);
        } finally {
            if (usesBatchWriting) {
                getSession().getPlatform().setUsesBatchWriting(true);
            }
        }
    }

    /**
     * Create all the receiver's sequences on the database for all of the loaded descriptors.
     */
    public void createSequences() throws EclipseLinkException {
        createOrReplaceSequences(true);
    }

    /**
     * INTERNAL:
     * Set to true if database schemas should be built during the DDL generation.
     */
    public void setCreateDatabaseSchemas(boolean createDatabaseSchemas) {
        this.createDatabaseSchemas = createDatabaseSchemas;
    }

    public void setCreateSQLFiles(boolean genFlag) {
        this.createSQLFiles = genFlag;
    }

    /**
     * Drop and recreate all the receiver's sequences on the database for all of the loaded descriptors.
     */
    public void replaceSequences() throws EclipseLinkException {
        createOrReplaceSequences(false);
    }

    /**
     * Common implementor for createSequence and replaceSequence
     * @param create - true to create the sequences, false to replace them (dropped then create)
     */
    protected void createOrReplaceSequences(boolean create) throws EclipseLinkException {
        createOrReplaceSequences(create, create);
    }

    /**
     * Common implementor for createSequence and replaceSequence, distinguishes between sequence tables and sequence objects
     * @param createSequenceTables - true to create the sequences tables, false to replace them (dropped then create)
     * @param createSequences - true to create the sequences objects, false to replace them (dropped then create)
     */
    protected void createOrReplaceSequences(boolean createSequenceTables, boolean createSequences) throws EclipseLinkException {
        // PERF: Allow a special "fast" flag to be set on the session causes a delete from the table instead of a replace.
        boolean fast = FAST_TABLE_CREATOR;
        if (fast) {
            // Assume sequences already created.
            return;
        }

        processSequenceDefinitions(createSequenceTables, createSequences, true);
    }

    /**
     * This will drop the database schemas if managing the database schemas.
     */
    protected void dropSequences() {
        processSequenceDefinitions(false, false, false);
    }

    /**
     * Method creates database tables/objects. If create is true, it will
     * attempt to create the object and silently ignore exceptions. If create
     * is false, it will drop the object ignoring any exceptions, then create
     * it if the replace flag is true (otherwise a drop only).
     *
     * @param definition - the sequence definition
     * @param createTables - true if table sequence table definitions should be created.
     * @param createSequences - true if the sequence definition should be created,
     *        false if it should be dropped.
     * @param replace - true if table definitions and sequence definitions should be replaced.
     */
    protected void processSequenceDefinition(SequenceDefinition definition, final boolean createTables, final boolean createSequences, final boolean replace, Set<String> createdTableNames, Set<String> droppedTableNames) throws EclipseLinkException {
        try {
            // Handle the table definitions first.
            if (definition.isTableSequenceDefinition()) {
                TableDefinition tableDefinition = definition.buildTableDefinition();
                // Check that we haven't already created the table.
                if (! createdTableNames.contains(tableDefinition.getFullName())) {
                    createdTableNames.add(tableDefinition.getFullName());

                    // Check if it exists on the database. NOTE: when writing to scripts only with
                    // no connection, this of course will always return false hence the need for
                    // the createdSequenceTableNames collection above.
                    boolean exists = checkTableExists(tableDefinition);

                    if (createTables) {
                        // Don't create it if it already exists on the database.
                        // In all all other cases, write it out.
                        if ((shouldWriteToDatabase() && ! exists) || ! shouldWriteToDatabase()) {
                            createObject(tableDefinition);
                        }
                    } else {
                        // Don't check exists since if writing to scripts only with no connection,
                        // we'll never write the sql out. When executing to the database, the drop
                        // will fail and we'll ignore it. Note: TableSequenceDefinition's will drop
                        // their table definitions as needed (i.e.) when the jpa create database
                        // schemas flag is set and the table definition has a schema. Otherwise,
                        // we should not drop sequence tables since they may be re-used across
                        // persistence units (default behavior right now).
                        // TODO: We should drop them really unless it is the default SEQUENCE table??
                        if (replace) {
                            dropObject(tableDefinition);
                            createObject(tableDefinition);
                        }
                    }
                }
            }
        } catch (DatabaseException exception) {
            // ignore any database exceptions here and keep going.
        }

        // Handle the sequence objects second.
        try {
            if (createSequences) {
                createObject(definition);
            } else {
                try {
                    // If the sequence definition has and will drop a table definition, then check
                    // if we have already dropped it. Table definitions are dropped as a whole if
                    // they have a schema name and the jpa create database schemas flag is set to true.
                    if (definition.isTableSequenceDefinition()) {
                        if (((TableSequenceDefinition) definition).shouldDropTableDefinition()) {
                            String tableDefinitionTableName = ((TableSequenceDefinition) definition).getSequenceTableName();

                            // If we have already dropped it, move on, otherwise drop it!
                            if (droppedTableNames.contains(tableDefinitionTableName)) {
                                return; // cut out early, we've already seen this table.
                            } else {
                                droppedTableNames.add(tableDefinitionTableName);
                            }
                        }
                    }

                    dropObject(definition);
                } catch (DatabaseException exception) {
                    // Ignore table not found for first creation
                }

                // Drop only scripts we don't want to replace.
                if (replace) {
                    createObject(definition);
                }
            }
        } catch (Exception exception) {
            // ignore any database exceptions here and keep chugging
        }
    }

    /**
     * Common implementor for createSequence and replaceSequence, distinguishes between sequence tables and sequence objects
     * @param createSequenceTables - true to create the sequences tables, false to replace them (dropped then create)
     * @param createSequences - true to create the sequences objects, false to replace them (dropped then create)
     * @param replaceSequences - true to actually replace, false to drop only.
     */
    protected void processSequenceDefinitions(boolean createSequenceTables, boolean createSequences, boolean replaceSequences) throws EclipseLinkException {
        Sequencing sequencing = getSession().getSequencing();

        // Not required on Sybase native etc.
        if (sequencing != null && sequencing.whenShouldAcquireValueForAll() != Sequencing.AFTER_INSERT) {
            // Build the sequence definitions.
            Set<SequenceDefinition> sequenceDefinitions = buildSequenceDefinitions();

            // Now process the sequence definitions.
            // CR 3870467, do not log stack
            boolean shouldLogExceptionStackTrace = session.getSessionLog().shouldLogExceptionStackTrace();
            session.getSessionLog().setShouldLogExceptionStackTrace(false);
            Set<String> createdSequenceTableNames = new HashSet<>();
            Set<String> droppedSequenceTableNames = new HashSet<>();

            for (SequenceDefinition sequenceDefinition : sequenceDefinitions) {
                processSequenceDefinition(sequenceDefinition, createSequenceTables, createSequences, replaceSequences, createdSequenceTableNames, droppedSequenceTableNames);
            }

            // Set the log stack trace flag back.
            session.getSessionLog().setShouldLogExceptionStackTrace(shouldLogExceptionStackTrace);
        }
    }

    /**
     * INTERNAL:
     * Build the sequence definitions.
     */
    protected Set<SequenceDefinition> buildSequenceDefinitions() {
        // Remember the processed - to handle each sequence just once.
        Set<String> processedSequenceNames = new HashSet<>();
        Set<SequenceDefinition> sequenceDefinitions = new HashSet<>();

        for (ClassDescriptor descriptor : getSession().getDescriptors().values()) {
            if (descriptor.usesSequenceNumbers()) {
                String seqName = descriptor.getSequenceNumberName();

                if (seqName == null) {
                    seqName = getSession().getDatasourcePlatform().getDefaultSequence().getName();
                }

                if (! processedSequenceNames.contains(seqName)) {
                    processedSequenceNames.add(seqName);

                    Sequence sequence = getSession().getDatasourcePlatform().getSequence(seqName);
                    SequenceDefinition sequenceDefinition = buildSequenceDefinition(sequence);

                    if (sequenceDefinition != null) {
                        sequenceDefinitions.add(sequenceDefinition);
                    }
                }
            }
        }

        return sequenceDefinitions;
    }

    /**
     * Check if the table exists by issuing a query.
     * @param table database table meta-data
     * @param suppressLogging whether to suppress logging during query execution
     * @return value of {@code true} if given table exists or {@code false} otherwise
     */
    public boolean checkTableExists(TableDefinition table, final boolean suppressLogging) {
        final boolean loggingOff = session.isLoggingOff();
        try {
            return session.getPlatform().checkTableExists(session, table, suppressLogging);
        } finally {
            session.setLoggingOff(loggingOff);
        }
    }

    /**
     * Check if the table exists by issuing a query.
     * Logging is suppressed during query execution.
     * @param table database table meta-data
     * @return value of {@code true} if given table exists or {@code false} otherwise
     */
    public boolean checkTableExists(TableDefinition table) {
        return checkTableExists(table, true);
    }

    protected SequenceDefinition buildSequenceDefinition(Sequence sequence) {
        if (sequence.shouldAcquireValueAfterInsert()) {
            return null;
        }
        if (sequence instanceof TableSequence ||
            (sequence instanceof DefaultSequence && ((DefaultSequence)sequence).getDefaultSequence() instanceof TableSequence)) {
            return new TableSequenceDefinition(sequence, createDatabaseSchemas);
        } else if (sequence instanceof UnaryTableSequence ||
                   (sequence instanceof DefaultSequence && ((DefaultSequence)sequence).getDefaultSequence() instanceof UnaryTableSequence)) {
            return new UnaryTableSequenceDefinition(sequence, createDatabaseSchemas);
        } else if (sequence instanceof NativeSequence ||
                   (sequence instanceof DefaultSequence && ((DefaultSequence)sequence).getDefaultSequence() instanceof NativeSequence)) {
            NativeSequence nativeSequence = null;
            if (sequence instanceof NativeSequence) {
                nativeSequence = (NativeSequence)sequence;
            } else {
                nativeSequence = (NativeSequence)((DefaultSequence)sequence).getDefaultSequence();
            }
            if (nativeSequence.hasDelegateSequence()) {
                return buildSequenceDefinition(((NativeSequence)sequence).getDelegateSequence());
            }
            return new SequenceObjectDefinition(sequence);
        } else {
            return null;
        }
    }

    /**
     * Use the table definition to drop the constraints from the table, this is normally done
     * in two steps to avoid dependencies.
     */
    public void dropConstraints(TableDefinition tableDefinition) throws EclipseLinkException {
        boolean usesBatchWriting = false;

        if (getSession().getPlatform().usesBatchWriting()) {
            usesBatchWriting = true;
            getSession().getPlatform().setUsesBatchWriting(false);
        }

        try {
            if (shouldWriteToDatabase()) {
                tableDefinition.dropConstraintsOnDatabase(getSession());
            } else {
                tableDefinition.setCreateSQLFiles(createSQLFiles);
                tableDefinition.dropConstraints(getSession(), getDropSchemaWriter());
            }
        } finally {
            if (usesBatchWriting) {
                getSession().getPlatform().setUsesBatchWriting(true);
            }
        }
    }

    /**
     * Use the definition object to drop the schema entity from the database.
     * This is used for dropping tables, views, procedures ... etc ...
     */
    public void dropObject(DatabaseObjectDefinition databaseObjectDefinition) throws EclipseLinkException {
        boolean usesBatchWriting = false;

        if (getSession().getPlatform().usesBatchWriting()) {
            usesBatchWriting = true;
            getSession().getPlatform().setUsesBatchWriting(false);
        }

        try {
            // If the object definition has a database schema collect it.
            collectDatabaseSchemasForDrop(databaseObjectDefinition);

            databaseObjectDefinition.preDropObject(getSession(), getDropSchemaWriter(), this.createSQLFiles);
            if (shouldWriteToDatabase()) {
                // drop actual object
                databaseObjectDefinition.dropFromDatabase(getSession());
            } else {
                Writer dropSchemaWriter = getDropSchemaWriter();

                // drop actual object
                databaseObjectDefinition.dropObject(getSession(), dropSchemaWriter, createSQLFiles);
                if (this.createSQLFiles){
                    this.appendToDDLWriter(dropSchemaWriter, getSession().getPlatform().getStoredProcedureTerminationToken());
                }
                this.appendToDDLWriter(dropSchemaWriter, "\n");
            }
        } finally {
            if (usesBatchWriting) {
                getSession().getPlatform().setUsesBatchWriting(true);
            }
        }
    }

    /**
     * Drop (delete) the table named tableName from the database.
     */
    public void dropTable(String tableName) throws EclipseLinkException {
        TableDefinition tableDefinition;

        tableDefinition = new TableDefinition();
        tableDefinition.setName(tableName);
        dropObject(tableDefinition);
    }

    /**
     * INTERNAL:
     * Close the schema writer when the schema manger is garbage collected
     */
    @Override
    public void finalize() {
        try {
            this.closeDDLWriter();
        } catch (ValidationException exception) {
            // do nothing
        }
    }

    /**
     * PUBLIC:
     * Use this method to generate stored procedures based on the dynamic SQL generated
     * for your mappings and descriptors.  This should be used with caution as it maintenance
     * will be high.  Stored procedures may be generated either directly on the database
     * or to a file.
     */
    public void generateStoredProcedures() throws EclipseLinkException {
        new StoredProcedureGenerator(this).generateStoredProcedures();
    }

    /**
     * PUBLIC:
     * Use this method to generate stored procedures based on the dynamic SQL generated
     * for your mappings and descriptors.  This should be used with caution as it maintenance
     * will be high.  Stored procedures may be generated either directly on the database
     * or to a file.
     */
    public void generateStoredProcedures(Writer writer) throws EclipseLinkException {
        new StoredProcedureGenerator(this).generateStoredProcedures(writer);
    }

    /**
     * PUBLIC:
     * Use this method to generate stored procedures based on the dynamic SQL generated
     * for your mappings and descriptors.  This should be used with caution as it maintenance
     * will be high.  Stored procedures may be generated either directly on the database
     * or to a file.
     */
    public void generateStoredProceduresAndAmendmentClass(Writer writer, String fullyQualifiedClassName) throws EclipseLinkException {
        String className = fullyQualifiedClassName.substring(fullyQualifiedClassName.lastIndexOf('.') + 1);
        String packageName = fullyQualifiedClassName.substring(0, fullyQualifiedClassName.lastIndexOf('.'));
        StoredProcedureGenerator storedProcedureGenerator = new StoredProcedureGenerator(this);
        storedProcedureGenerator.generateStoredProcedures();

        storedProcedureGenerator.generateAmendmentClass(writer, packageName, className);
    }

    /**
     * PUBLIC:
     * Use this method to generate stored procedures based on the dynamic SQL generated
     * for your mappings and descriptors.  This should be used with caution as it maintenance
     * will be high.  Stored procedures may be generated either directly on the database
     * or to a file.
     */
    public void generateStoredProceduresAndAmendmentClass(String path, String fullyQualifiedClassName) throws EclipseLinkException {
        java.io.FileWriter fileWriter = null;
        try {
            StoredProcedureGenerator storedProcedureGenerator = new StoredProcedureGenerator(this);

            if (!(path.endsWith("\\") || path.endsWith("/"))) {
                path = path + "\\";
            }

            String className = fullyQualifiedClassName.substring(fullyQualifiedClassName.lastIndexOf('.') + 1);
            String packageName = fullyQualifiedClassName.substring(0, fullyQualifiedClassName.lastIndexOf('.'));
            String fileName = path + className + ".java";
            fileWriter = new java.io.FileWriter(fileName);
            storedProcedureGenerator.generateStoredProcedures();
            storedProcedureGenerator.generateAmendmentClass(fileWriter, packageName, className);
            fileWriter.close();
        } catch (java.io.IOException ioException) {
            throw ValidationException.fileError(ioException);
        } finally {
            Helper.close(fileWriter);
        }
    }

    /**
     * Return the appropriate accessor.
     * Assume we are dealing with a JDBC accessor.
     */
    protected DatabaseAccessor getAccessor() {
        return (DatabaseAccessor) getSession().getAccessor();
    }

    /**
     * Get a description of table columns available in a catalog.
     *
     * <P>Each column description has the following columns:
     *  <OL>
     *    <LI><B>TABLE_CAT</B> String {@literal =>} table catalog (may be null)
     *    <LI><B>TABLE_SCHEM</B> String {@literal =>} table schema (may be null)
     *    <LI><B>TABLE_NAME</B> String {@literal =>} table name
     *    <LI><B>COLUMN_NAME</B> String {@literal =>} column name
     *    <LI><B>DATA_TYPE</B> short {@literal =>} SQL type from java.sql.Types
     *    <LI><B>TYPE_NAME</B> String {@literal =>} Data source dependent type name
     *    <LI><B>COLUMN_SIZE</B> int {@literal =>} column size.  For char or date
     *        types this is the maximum number of characters, for numeric or
     *        decimal types this is precision.
     *    <LI><B>BUFFER_LENGTH</B> is not used.
     *    <LI><B>DECIMAL_DIGITS</B> int {@literal =>} the number of fractional digits
     *    <LI><B>NUM_PREC_RADIX</B> int {@literal =>} Radix (typically either 10 or 2)
     *    <LI><B>NULLABLE</B> int {@literal =>} is NULL allowed?
     *      <UL>
     *      <LI> columnNoNulls - might not allow NULL values
     *      <LI> columnNullable - definitely allows NULL values
     *      <LI> columnNullableUnknown - nullability unknown
     *      </UL>
     *    <LI><B>REMARKS</B> String {@literal =>} comment describing column (may be null)
     *     <LI><B>COLUMN_DEF</B> String {@literal =>} default value (may be null)
     *    <LI><B>SQL_DATA_TYPE</B> int {@literal =>} unused
     *    <LI><B>SQL_DATETIME_SUB</B> int {@literal =>} unused
     *    <LI><B>CHAR_OCTET_LENGTH</B> int {@literal =>} for char types the
     *       maximum number of bytes in the column
     *    <LI><B>ORDINAL_POSITION</B> int    {@literal =>} index of column in table
     *      (starting at 1)
     *    <LI><B>IS_NULLABLE</B> String {@literal =>} "NO" means column definitely
     *      does not allow NULL values; "YES" means the column might
     *      allow NULL values.  An empty string means nobody knows.
     *  </OL>
     *
     * @param tableName a table name pattern
     * @return a Vector of Records.
     */
    public Vector<AbstractRecord> getAllColumnNames(String tableName) throws DatabaseException {
        return getAccessor().getColumnInfo(null, null, tableName, null, getSession());
    }

    /**
     * Get a description of table columns available in a catalog.
     *
     * <P>Each column description has the following columns:
     *  <OL>
     *    <LI><B>TABLE_CAT</B> String {@literal =>} table catalog (may be null)
     *    <LI><B>TABLE_SCHEM</B> String {@literal =>} table schema (may be null)
     *    <LI><B>TABLE_NAME</B> String {@literal =>} table name
     *    <LI><B>COLUMN_NAME</B> String {@literal =>} column name
     *    <LI><B>DATA_TYPE</B> short {@literal =>} SQL type from java.sql.Types
     *    <LI><B>TYPE_NAME</B> String {@literal =>} Data source dependent type name
     *    <LI><B>COLUMN_SIZE</B> int {@literal =>} column size.  For char or date
     *        types this is the maximum number of characters, for numeric or
     *        decimal types this is precision.
     *    <LI><B>BUFFER_LENGTH</B> is not used.
     *    <LI><B>DECIMAL_DIGITS</B> int {@literal =>} the number of fractional digits
     *    <LI><B>NUM_PREC_RADIX</B> int {@literal =>} Radix (typically either 10 or 2)
     *    <LI><B>NULLABLE</B> int {@literal =>} is NULL allowed?
     *      <UL>
     *      <LI> columnNoNulls - might not allow NULL values
     *      <LI> columnNullable - definitely allows NULL values
     *      <LI> columnNullableUnknown - nullability unknown
     *      </UL>
     *    <LI><B>REMARKS</B> String {@literal =>} comment describing column (may be null)
     *     <LI><B>COLUMN_DEF</B> String {@literal =>} default value (may be null)
     *    <LI><B>SQL_DATA_TYPE</B> int {@literal =>} unused
     *    <LI><B>SQL_DATETIME_SUB</B> int {@literal =>} unused
     *    <LI><B>CHAR_OCTET_LENGTH</B> int {@literal =>} for char types the
     *       maximum number of bytes in the column
     *    <LI><B>ORDINAL_POSITION</B> int    {@literal =>} index of column in table
     *      (starting at 1)
     *    <LI><B>IS_NULLABLE</B> String {@literal =>} "NO" means column definitely
     *      does not allow NULL values; "YES" means the column might
     *      allow NULL values.  An empty string means nobody knows.
     *  </OL>
     *
     * @param creatorName a schema name pattern; "" retrieves those
     * without a schema
     * @param tableName a table name pattern
     * @return a Vector of Records.
     */
    public Vector<AbstractRecord> getAllColumnNames(String creatorName, String tableName) throws DatabaseException {
        return getAccessor().getColumnInfo(null, creatorName, tableName, null, getSession());
    }

    /**
     * Get a description of tables available in a catalog.
     *
     * <P>Each table description has the following columns:
     *  <OL>
     *    <LI><B>TABLE_CAT</B> String {@literal =>} table catalog (may be null)
     *    <LI><B>TABLE_SCHEM</B> String {@literal =>} table schema (may be null)
     *    <LI><B>TABLE_NAME</B> String {@literal =>} table name
     *    <LI><B>TABLE_TYPE</B> String {@literal =>} table type.  Typical types are "TABLE",
     *            "VIEW",    "SYSTEM TABLE", "GLOBAL TEMPORARY",
     *            "LOCAL TEMPORARY", "ALIAS", "SYNONYM".
     *    <LI><B>REMARKS</B> String {@literal =>} explanatory comment on the table
     *  </OL>
     *
     * <P><B>Note:</B> Some databases may not return information for
     * all tables.
     *
     * @return a Vector of Records.
     */
    public Vector<AbstractRecord> getAllTableNames() throws DatabaseException {
        return getAccessor().getTableInfo(null, null, null, null, getSession());
    }

    /**
     * Get a description of table columns available in a catalog.
     *
     * <P>Each column description has the following columns:
     *  <OL>
     *    <LI><B>TABLE_CAT</B> String {@literal =>} table catalog (may be null)
     *    <LI><B>TABLE_SCHEM</B> String {@literal =>} table schema (may be null)
     *    <LI><B>TABLE_NAME</B> String {@literal =>} table name
     *    <LI><B>COLUMN_NAME</B> String {@literal =>} column name
     *    <LI><B>DATA_TYPE</B> short {@literal =>} SQL type from java.sql.Types
     *    <LI><B>TYPE_NAME</B> String {@literal =>} Data source dependent type name
     *    <LI><B>COLUMN_SIZE</B> int {@literal =>} column size.  For char or date
     *        types this is the maximum number of characters, for numeric or
     *        decimal types this is precision.
     *    <LI><B>BUFFER_LENGTH</B> is not used.
     *    <LI><B>DECIMAL_DIGITS</B> int {@literal =>} the number of fractional digits
     *    <LI><B>NUM_PREC_RADIX</B> int {@literal =>} Radix (typically either 10 or 2)
     *    <LI><B>NULLABLE</B> int {@literal =>} is NULL allowed?
     *      <UL>
     *      <LI> columnNoNulls - might not allow NULL values
     *      <LI> columnNullable - definitely allows NULL values
     *      <LI> columnNullableUnknown - nullability unknown
     *      </UL>
     *    <LI><B>REMARKS</B> String {@literal =>} comment describing column (may be null)
     *     <LI><B>COLUMN_DEF</B> String {@literal =>} default value (may be null)
     *    <LI><B>SQL_DATA_TYPE</B> int {@literal =>} unused
     *    <LI><B>SQL_DATETIME_SUB</B> int {@literal =>} unused
     *    <LI><B>CHAR_OCTET_LENGTH</B> int {@literal =>} for char types the
     *       maximum number of bytes in the column
     *    <LI><B>ORDINAL_POSITION</B> int    {@literal =>} index of column in table
     *      (starting at 1)
     *    <LI><B>IS_NULLABLE</B> String {@literal =>} "NO" means column definitely
     *      does not allow NULL values; "YES" means the column might
     *      allow NULL values.  An empty string means nobody knows.
     *  </OL>
     *
     * @param creatorName a schema name pattern; "" retrieves those
     * without a schema
     * @return a Vector of Records.
     */
    public Vector<AbstractRecord> getAllTableNames(String creatorName) throws DatabaseException {
        return getAccessor().getTableInfo(null, creatorName, null, null, getSession());
    }

    /**
     * Get a description of table columns available in a catalog.
     *
     * <P>Only column descriptions matching the catalog, schema, table
     * and column name criteria are returned.  They are ordered by
     * TABLE_SCHEM, TABLE_NAME and ORDINAL_POSITION.
     *
     * <P>Each column description has the following columns:
     *  <OL>
     *    <LI><B>TABLE_CAT</B> String {@literal =>} table catalog (may be null)
     *    <LI><B>TABLE_SCHEM</B> String {@literal =>} table schema (may be null)
     *    <LI><B>TABLE_NAME</B> String {@literal =>} table name
     *    <LI><B>COLUMN_NAME</B> String {@literal =>} column name
     *    <LI><B>DATA_TYPE</B> short {@literal =>} SQL type from java.sql.Types
     *    <LI><B>TYPE_NAME</B> String {@literal =>} Data source dependent type name
     *    <LI><B>COLUMN_SIZE</B> int {@literal =>} column size.  For char or date
     *        types this is the maximum number of characters, for numeric or
     *        decimal types this is precision.
     *    <LI><B>BUFFER_LENGTH</B> is not used.
     *    <LI><B>DECIMAL_DIGITS</B> int {@literal =>} the number of fractional digits
     *    <LI><B>NUM_PREC_RADIX</B> int {@literal =>} Radix (typically either 10 or 2)
     *    <LI><B>NULLABLE</B> int {@literal =>} is NULL allowed?
     *      <UL>
     *      <LI> columnNoNulls - might not allow NULL values
     *      <LI> columnNullable - definitely allows NULL values
     *      <LI> columnNullableUnknown - nullability unknown
     *      </UL>
     *    <LI><B>REMARKS</B> String {@literal =>} comment describing column (may be null)
     *     <LI><B>COLUMN_DEF</B> String {@literal =>} default value (may be null)
     *    <LI><B>SQL_DATA_TYPE</B> int {@literal =>} unused
     *    <LI><B>SQL_DATETIME_SUB</B> int {@literal =>} unused
     *    <LI><B>CHAR_OCTET_LENGTH</B> int {@literal =>} for char types the
     *       maximum number of bytes in the column
     *    <LI><B>ORDINAL_POSITION</B> int    {@literal =>} index of column in table
     *      (starting at 1)
     *    <LI><B>IS_NULLABLE</B> String {@literal =>} "NO" means column definitely
     *      does not allow NULL values; "YES" means the column might
     *      allow NULL values.  An empty string means nobody knows.
     *  </OL>
     *
     * @param catalog a catalog name; "" retrieves those without a
     * catalog; null means drop catalog name from the selection criteria
     * @param schema a schema name pattern; "" retrieves those
     * without a schema
     * @param tableName a table name pattern
     * @param columnName a column name pattern
     * @return a Vector of Records.
     */
    public Vector<AbstractRecord> getColumnInfo(String catalog, String schema, String tableName, String columnName) throws DatabaseException {
        return getAccessor().getColumnInfo(catalog, schema, tableName, columnName, getSession());
    }

    public AbstractSession getSession() {
        return session;
    }

    /**
     * Get a description of tables available in a catalog.
     *
     * <P>Only table descriptions matching the catalog, schema, table
     * name and type criteria are returned.  They are ordered by
     * TABLE_TYPE, TABLE_SCHEM and TABLE_NAME.
     *
     * <P>Each table description has the following columns:
     *  <OL>
     *    <LI><B>TABLE_CAT</B> String {@literal =>} table catalog (may be null)
     *    <LI><B>TABLE_SCHEM</B> String {@literal =>} table schema (may be null)
     *    <LI><B>TABLE_NAME</B> String {@literal =>} table name
     *    <LI><B>TABLE_TYPE</B> String {@literal =>} table type.  Typical types are "TABLE",
     *            "VIEW",    "SYSTEM TABLE", "GLOBAL TEMPORARY",
     *            "LOCAL TEMPORARY", "ALIAS", "SYNONYM".
     *    <LI><B>REMARKS</B> String {@literal =>} explanatory comment on the table
     *  </OL>
     *
     * <P><B>Note:</B> Some databases may not return information for
     * all tables.
     *
     * @param catalog a catalog name; "" retrieves those without a
     * catalog; null means drop catalog name from the selection criteria
     * @param schema a schema name pattern; "" retrieves those
     * without a schema
     * @param tableName a table name pattern
     * @param types a list of table types to include; null returns all types
     * @return a Vector of Records.
     */
    public Vector<AbstractRecord> getTableInfo(String catalog, String schema, String tableName, String[] types) throws DatabaseException {
        return getAccessor().getTableInfo(catalog, schema, tableName, types, getSession());
    }

    /**
     * PUBLIC:
     * Output all DDL statements directly to the database.
     */
    public void outputDDLToDatabase() {
        this.createSchemaWriter = null;
        this.dropSchemaWriter = null;
    }

    /**
     * PUBLIC:
     * Output all DDL statements to a file writer specified by the name in the parameter.
     */
    public void outputDDLToFile(String fileName) {
        this.createSchemaWriter = getWriter(fileName);
    }

    public void outputCreateDDLToFile(String fileName) {
        this.createSchemaWriter = getWriter(fileName);
    }

    public void outputDropDDLToFile(String fileName) {
        this.dropSchemaWriter = getWriter(fileName);
    }

    protected Writer getWriter(String fileName) {
        try {
            return new java.io.FileWriter(fileName);
        } catch (java.io.IOException ioException) {
            // Try a url next, otherwise throw the existing error.
            try {
                URL url = new URL(fileName);
                return new java.io.FileWriter(url.getFile());
            } catch (Exception e) {
                // MalformedURLException and IOException
                throw ValidationException.fileError(ioException);
            }
        }
    }

    /**
     * PUBLIC:
     * Output all DDL statements to a writer specified in the parameter.
     */
    public void outputDDLToWriter(Writer schemaWriter) {
        this.createSchemaWriter = schemaWriter;
    }

    public void outputCreateDDLToWriter(Writer createWriter) {
        this.createSchemaWriter = createWriter;
    }

    public void outputDropDDLToWriter(Writer dropWriter) {
        this.dropSchemaWriter = dropWriter;
    }

    /**
     * Use the definition object to drop and recreate the schema entity on the database.
     * This is used for dropping tables, views, procedures ... etc ...
     * This handles and ignore any database error while dropping in case the object did not previously exist.
     */
    public void replaceObject(DatabaseObjectDefinition databaseDefinition) throws EclipseLinkException {
        // PERF: Allow a special "fast" flag to be set on the session causes a delete from the table instead of a replace.
        boolean fast = FAST_TABLE_CREATOR;
        if (fast && (databaseDefinition instanceof TableDefinition)) {
            session.executeNonSelectingSQL("DELETE FROM " + databaseDefinition.getName());
        } else if (fast && (databaseDefinition instanceof StoredProcedureDefinition)) {
            // do nothing
        } else {
            // CR 3870467, do not log stack
            boolean shouldLogExceptionStackTrace = getSession().getSessionLog().shouldLogExceptionStackTrace();

            if (shouldLogExceptionStackTrace) {
                getSession().getSessionLog().setShouldLogExceptionStackTrace(false);
            }
            try {
                dropObject(databaseDefinition);
            } catch (DatabaseException exception) {
                // Ignore error
            } finally {
                if (shouldLogExceptionStackTrace) {
                    getSession().getSessionLog().setShouldLogExceptionStackTrace(true);
                }
            }

            createObject(databaseDefinition);
        }
    }

    /**
     * Construct the default TableCreator.
     * If the default TableCreator is already created, just returns it.
     */
    protected TableCreator getDefaultTableCreator(boolean generateFKConstraints) {
        if(defaultTableCreator == null) {
            defaultTableCreator = new DefaultTableGenerator(session.getProject(),generateFKConstraints).generateDefaultTableCreator();
            defaultTableCreator.setIgnoreDatabaseException(true);
        }
        return defaultTableCreator;
    }

    /**
     * Create the default table schema for the project this session associated with.
     */
    public void createDefaultTables(boolean generateFKConstraints) {
        //Create each table w/o throwing exception and/or exit if some of them are already existed in the db.
        //If a table is already existed, skip the creation.

        boolean shouldLogExceptionStackTrace = getSession().getSessionLog().shouldLogExceptionStackTrace();
        getSession().getSessionLog().setShouldLogExceptionStackTrace(false);

        try {
            TableCreator tableCreator = getDefaultTableCreator(generateFKConstraints);
            tableCreator.createTables(this.session, this);
        } catch (DatabaseException ex) {
            // Ignore error
        } finally {
            getSession().getSessionLog().setShouldLogExceptionStackTrace(shouldLogExceptionStackTrace);
        }
        // Reset database change events to new tables.
        if (this.session.getDatabaseEventListener() != null) {
            this.session.getDatabaseEventListener().remove(this.session);
            this.session.getDatabaseEventListener().register(this.session);
        }
    }

    /**
     * INTERNAL:
     * Iterate over the schemas that need to be dropped.
     */
    public void dropDatabaseSchemas() {
        for (DatabaseObjectDefinition dod : dropDatabaseSchemas.values()) {
            if (shouldWriteToDatabase()) {
                dod.dropDatabaseSchemaOnDatabase(getSession());
            } else {
                dod.dropDatabaseSchema(getSession(), getDropSchemaWriter());
                appendToDDLWriter(getDropSchemaWriter(), "\n");
            }
        }
    }

    /**
     * Create the default table schema for the project this session associated with.
     */
    public void dropDefaultTables() {
        // Drop each table w/o throwing exception and/or exit if some don't exist.
        boolean shouldLogExceptionStackTrace = getSession().getSessionLog().shouldLogExceptionStackTrace();
        getSession().getSessionLog().setShouldLogExceptionStackTrace(false);

        try {
            // Drop the tables.
            TableCreator tableCreator = getDefaultTableCreator(true);
            tableCreator.dropTables(this.session, this);

            // Drop the sequences.
            dropSequences();

            // Drop all the database schemas now if set to do so. This must be
            // called after all the constraints, tables etc. are dropped.
            dropDatabaseSchemas();
        } catch (DatabaseException ex) {
            // Ignore error
        } finally {
            getSession().getSessionLog().setShouldLogExceptionStackTrace(shouldLogExceptionStackTrace);
        }
        // Reset database change events to new tables.
        if (this.session.getDatabaseEventListener() != null) {
            this.session.getDatabaseEventListener().remove(this.session);
            this.session.getDatabaseEventListener().register(this.session);
        }
    }

    /**
     * Drop and recreate the default table schema for the project this session associated with.
     */
    public void replaceDefaultTables() throws EclipseLinkException {
        replaceDefaultTables(true, true, true);
    }

    /**
     * Drop and recreate the default table schema for the project this session associated with.
     */
    public void replaceDefaultTables(boolean createSequenceTables, boolean generateFKConstraints) throws EclipseLinkException {
        replaceDefaultTables(createSequenceTables, false, generateFKConstraints);
    }

    /**
     * Drop and recreate the default table schema for the project this session associated with.
     */
    public void replaceDefaultTables(boolean createSequenceTables, boolean createSequences, boolean generateFKConstraints) throws EclipseLinkException {
        boolean shouldLogExceptionStackTrace = getSession().getSessionLog().shouldLogExceptionStackTrace();
        this.session.getSessionLog().setShouldLogExceptionStackTrace(false);

        try {
            TableCreator tableCreator = getDefaultTableCreator(generateFKConstraints);
            tableCreator.replaceTables(this.session, this, createSequenceTables, createSequences);

            // Drop all the database schemas now if set to do so. This must be
            // called after all the constraints, tables etc. are dropped.
            dropDatabaseSchemas();
        } catch (DatabaseException exception) {
            // Ignore error
        } finally {
            this.session.getSessionLog().setShouldLogExceptionStackTrace(shouldLogExceptionStackTrace);
        }
        // Reset database change events to new tables.
        if (this.session.getDatabaseEventListener() != null) {
            this.session.getDatabaseEventListener().remove(this.session);
            this.session.getDatabaseEventListener().register(this.session);
        }
    }

    public void setSession(DatabaseSessionImpl session) {
        this.session = session;
    }

    /**
     * INTERNAL:
     * Returns true if a database schema should be created during ddl generation
     * for the given databaseObjectDefinition.
     */
    protected boolean shouldCreateDatabaseSchema(DatabaseObjectDefinition databaseObjectDefinition, Set<String> createdDatabaseSchemas) {
        return (createDatabaseSchemas && databaseObjectDefinition.shouldCreateDatabaseSchema(createdDatabaseSchemas));
    }

    /**
     * PUBLIC:
     * Return true if this SchemaManager should write to the database directly
     */
    public boolean shouldWriteToDatabase() {
        return ((this.createSchemaWriter == null) && (this.dropSchemaWriter == null));
    }

    /**
     * Use the definition to alter sequence.
     */
    public void alterSequence(SequenceDefinition sequenceDefinition) throws EclipseLinkException {
        if (!sequenceDefinition.isAlterSupported(getSession())) {
            return;
        }

        boolean usesBatchWriting = false;

        if (getSession().getPlatform().usesBatchWriting()) {
            usesBatchWriting = true;
            getSession().getPlatform().setUsesBatchWriting(false);
        }

        try {
            if (shouldWriteToDatabase()) {
                sequenceDefinition.alterOnDatabase(getSession());
            } else {
                sequenceDefinition.alter(getSession(), createSchemaWriter);
            }
        } finally {
            if (usesBatchWriting) {
                getSession().getPlatform().setUsesBatchWriting(true);
            }
        }
    }

    /**
     * Create or extend the default table schema for the project this session associated with.
     */
    public void extendDefaultTables(boolean generateFKConstraints) throws EclipseLinkException {
        boolean shouldLogExceptionStackTrace = getSession().getSessionLog().shouldLogExceptionStackTrace();
        this.session.getSessionLog().setShouldLogExceptionStackTrace(false);

        try {
            TableCreator tableCreator = getDefaultTableCreator(generateFKConstraints);
            tableCreator.extendTables(this.session, this);
        } catch (DatabaseException exception) {
            // Ignore error
        } finally {
            this.session.getSessionLog().setShouldLogExceptionStackTrace(shouldLogExceptionStackTrace);
        }
        // Reset database change events to new tables.
        if (this.session.getDatabaseEventListener() != null) {
            this.session.getDatabaseEventListener().remove(this.session);
            this.session.getDatabaseEventListener().register(this.session);
        }
    }

}
