/*
 * Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved.
 * Copyright (c) 2019, 2020 IBM Corporation. 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
//     09/29/2016-2.7 Tomas Kraus
//       - 426852: @GeneratedValue(strategy=GenerationType.IDENTITY) support in Oracle 12c
//     09/14/2017-2.6 Will Dazey
//       - 522312: Add the eclipselink.sequencing.start-sequence-at-nextval property
//     02/20/2018-2.7 Will Dazey
//       - 529602: Added support for CLOBs in DELETE statements for Oracle
package org.eclipse.persistence.internal.databaseaccess;

import java.io.IOException;
import java.io.Writer;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.Vector;

import org.eclipse.persistence.descriptors.DescriptorQueryManager;
import org.eclipse.persistence.exceptions.ConversionException;
import org.eclipse.persistence.exceptions.ValidationException;
import org.eclipse.persistence.expressions.Expression;
import org.eclipse.persistence.expressions.ExpressionOperator;
import org.eclipse.persistence.internal.helper.ClassConstants;
import org.eclipse.persistence.internal.helper.ConversionManager;
import org.eclipse.persistence.internal.helper.DatabaseField;
import org.eclipse.persistence.internal.helper.Helper;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.queries.Call;
import org.eclipse.persistence.queries.DataModifyQuery;
import org.eclipse.persistence.queries.DatabaseQuery;
import org.eclipse.persistence.queries.SQLCall;
import org.eclipse.persistence.queries.ValueReadQuery;
import org.eclipse.persistence.sequencing.DefaultSequence;
import org.eclipse.persistence.sequencing.QuerySequence;
import org.eclipse.persistence.sequencing.Sequence;
import org.eclipse.persistence.sessions.Session;

/**
 * DatasourcePlatform is private to TopLink. It encapsulates behavior specific to a datasource platform
 * (eg. Oracle, Sybase, DB2, Attunity, MQSeries), and provides protocol for TopLink to access this behavior.
 *
 * @see DatabasePlatform
 * @see org.eclipse.persistence.eis.EISPlatform
 *
 * @since OracleAS TopLink 10<i>g</i> (10.0.3)
 */
public class DatasourcePlatform implements Platform {

    /** Supporting name scopes in database by prefixing the table names with the table qualifier/creator. */
    protected String tableQualifier;

    /** Allow for conversion to be customized in the platform. */
    protected transient ConversionManager conversionManager;

    /** Store the query use to query the current server time. */
    protected ValueReadQuery timestampQuery;

    /** Operators specific to this platform */
    protected transient Map platformOperators;

    /** Store the list of Classes that can be converted to from the key. */
    protected Hashtable dataTypesConvertedFromAClass;

    /** Store the list of Classes that can be converted from to the key. */
    protected Hashtable dataTypesConvertedToAClass;

    /** Store default sequence */
    protected Sequence defaultSequence;

    /** Store map of sequence names to sequences */
    protected Map<String, Sequence> sequences;

    /** Delimiter to use for fields and tables using spaces or other special values */
    protected String startDelimiter = null;
    protected String endDelimiter = null;

    /** Ensures that only one thread at a time can add/remove sequences */
    protected Object sequencesLock = Boolean.valueOf(true);

    /** If the native sequence type is not supported, if table sequencing should be used. */
    protected boolean defaultNativeSequenceToTable;

    /** If sequences should start at Next Value */
    protected boolean defaultSeqenceAtNextValue;

    public DatasourcePlatform() {
        this.tableQualifier = "";
        this.startDelimiter = "";
        this.endDelimiter = "";
    }

    /**
     * Return if the native sequence type is not supported, if table sequencing should be used.
     */
    public boolean getDefaultNativeSequenceToTable() {
        return defaultNativeSequenceToTable;
    }

    /**
     * Set if the native sequence type is not supported, if table sequencing should be used.
     */
    public void setDefaultNativeSequenceToTable(boolean defaultNativeSequenceToTable) {
        this.defaultNativeSequenceToTable = defaultNativeSequenceToTable;
    }

    /**
     * Return if the sequence generation should start at next value.
     */
    public boolean getDefaultSeqenceAtNextValue() {
        return defaultSeqenceAtNextValue;
    }

    /**
     * Set if the sequence generation should start at next value.
     */
    public void setDefaultSeqenceAtNextValue(boolean defaultSeqenceAtNextValue) {
        this.defaultSeqenceAtNextValue = defaultSeqenceAtNextValue;
    }

    protected void addOperator(ExpressionOperator operator) {
        platformOperators.put(Integer.valueOf(operator.getSelector()), operator);
    }

    /**
     * Add the parameter.
     * Convert the parameter to a string and write it.
     */
    @Override
    public void appendParameter(Call call, Writer writer, Object parameter) {
        String parameterValue = (String)getConversionManager().convertObject(parameter, ClassConstants.STRING);
        if (parameterValue == null) {
            parameterValue = "";
        }
        try {
            writer.write(parameterValue);
        } catch (IOException exception) {
            throw ValidationException.fileError(exception);
        }
    }

    /**
     * Allow for the platform to handle the representation of parameters specially.
     */
    @Override
    public Object getCustomModifyValueForCall(Call call, Object value, DatabaseField field, boolean shouldBind) {
        return value;
    }

    /**
     * Used by SQLCall.appendModify(..)
     * If the field should be passed to customModifyInDatabaseCall, retun true,
     * otherwise false.
     * Methods shouldCustomModifyInDatabaseCall and customModifyInDatabaseCall should be
     * kept in sync: shouldCustomModifyInDatabaseCall should return true if and only if the field
     * is handled by customModifyInDatabaseCall.
     */
    @Override
    public boolean shouldUseCustomModifyForCall(DatabaseField field) {
        return false;
    }

    @Override
    public Object clone() {
        try {
            DatasourcePlatform clone = (DatasourcePlatform)super.clone();
            clone.sequencesAfterCloneCleanup();
            return clone;
        } catch (CloneNotSupportedException exception) {
            //Do nothing
        }

        return null;
    }

    protected void sequencesAfterCloneCleanup() {
        Sequence defaultSequenceClone = null;
        if (hasDefaultSequence()) {
            defaultSequenceClone = (Sequence)getDefaultSequence().clone();
            setDefaultSequence(defaultSequenceClone);
        }
        if (getSequences() != null) {
            HashMap sequencesCopy = new HashMap(getSequences());
            HashMap sequencesDeepClone = new HashMap(getSequences().size());
            Iterator it = sequencesCopy.values().iterator();
            while (it.hasNext()) {
                Sequence sequence = (Sequence)it.next();
                if ((defaultSequenceClone != null) && (sequence == getDefaultSequence())) {
                    sequencesDeepClone.put(defaultSequenceClone.getName(), defaultSequenceClone);
                } else {
                    Sequence sequenceClone = (Sequence)sequence.clone();
                    if (sequenceClone instanceof DefaultSequence) {
                        if (!((DefaultSequence)sequenceClone).hasPreallocationSize()) {
                            continue;
                        }
                    }
                    sequencesDeepClone.put(sequenceClone.getName(), sequenceClone);
                }
            }
            this.setSequences(sequencesDeepClone);
        }
    }

    /**
     * Convert the object to the appropriate type by invoking the appropriate
     * ConversionManager method
     * @param sourceObject the object that must be converted
     * @param javaClass the class that the object must be converted to
     * @exception ConversionException all exceptions will be thrown as this type.
     * @return the newly converted object
     */
    @Override
    public Object convertObject(Object sourceObject, Class javaClass) throws ConversionException {
        return getConversionManager().convertObject(sourceObject, javaClass);
    }

    /**
     * Copy the state into the new platform.
     */
    @Override
    public void copyInto(Platform platform) {
        if (!(platform instanceof DatasourcePlatform)) {
            return;
        }
        DatasourcePlatform datasourcePlatform = (DatasourcePlatform)platform;
        datasourcePlatform.setTableQualifier(getTableQualifier());
        datasourcePlatform.setTimestampQuery(this.timestampQuery);
        datasourcePlatform.setConversionManager(getConversionManager());
        if (hasDefaultSequence()) {
            datasourcePlatform.setDefaultSequence(getDefaultSequence());
        }
        datasourcePlatform.setSequences(getSequences());
        datasourcePlatform.sequencesAfterCloneCleanup();
        datasourcePlatform.setDefaultNativeSequenceToTable(getDefaultNativeSequenceToTable());
        datasourcePlatform.setDefaultSeqenceAtNextValue(getDefaultSeqenceAtNextValue());
    }

    /**
     * The platform hold its own instance of conversion manager to allow customization.
     */
    @Override
    public ConversionManager getConversionManager() {
        // Lazy init for serialization.
        if (conversionManager == null) {
            //Clone the default to allow customers to easily override the conversion manager
            conversionManager = (ConversionManager)ConversionManager.getDefaultManager().clone();
        }
        return conversionManager;
    }

    /**
     * The platform hold its own instance of conversion manager to allow customization.
     */
    @Override
    public void setConversionManager(ConversionManager conversionManager) {
        this.conversionManager = conversionManager;
    }

    /**
     * Delimiter to use for fields and tables using spaces or other special values.
     *
     * Some databases use different delimiters for the beginning and end of the value.
     * This delimiter indicates the end of the value.
     */
    @Override
    public String getEndDelimiter() {
        return endDelimiter;
    }

    /**
     * Delimiter to use for fields and tables using spaces or other special values.
     *
     * Some databases use different delimiters for the beginning and end of the value.
     * This delimiter indicates the end of the value.
     */
    public void setEndDelimiter(String endDelimiter) {
        this.endDelimiter = endDelimiter;
    }

    /**
     * Return the operator for the operator constant defined in ExpressionOperator.
     */
    public ExpressionOperator getOperator(int selector) {
        return (ExpressionOperator)getPlatformOperators().get(Integer.valueOf(selector));
    }

    /**
     * Return any platform-specific operators
     */
    public Map getPlatformOperators() {
        if (platformOperators == null) {
            synchronized (this) {
                if (platformOperators == null) {
                    initializePlatformOperators();
                }
            }
        }
        return platformOperators;
    }

    /**
     * OBSOLETE:
     * This method lazy initializes the select sequence number query.  It
     * allows for other queries to be used instead of the default one.
     */
    public ValueReadQuery getSelectSequenceQuery() {
        if (getDefaultSequence() instanceof QuerySequence) {
            return ((QuerySequence)getDefaultSequence()).getSelectQuery();
        } else {
            throw ValidationException.wrongSequenceType(Helper.getShortClassName(getDefaultSequence()), "getSelectQuery");
        }
    }

    public int getSequencePreallocationSize() {
        return getDefaultSequence().getPreallocationSize();
    }


    /**
     * Delimiter to use for fields and tables using spaces or other special values.
     *
     * Some databases use different delimiters for the beginning and end of the value.
     * This delimiter indicates the start of the value.
     */
    @Override
    public String getStartDelimiter() {
        return startDelimiter;
    }

    /**
     * Delimiter to use for fields and tables using spaces or other special values.
     *
     * Some databases use different delimiters for the beginning and end of the value.
     * This delimiter indicates the start of the value.
     */
    public void setStartDelimiter(String startDelimiter) {
        this.startDelimiter = startDelimiter;
    }

    /**
     * Return the qualifier for the table. Required by some
     * databases such as Oracle and DB2
     */
    @Override
    public String getTableQualifier() {
        return tableQualifier;
    }

    /**
     * Answer the timestamp from the server.
     */
    @Override
    public java.sql.Timestamp getTimestampFromServer(AbstractSession session, String sessionName) {
        if (getTimestampQuery() == null) {
            return new java.sql.Timestamp(System.currentTimeMillis());
        } else {
            getTimestampQuery().setSessionName(sessionName);
            Object result = session.executeQuery(getTimestampQuery());
            return (java.sql.Timestamp) session.getDatasourcePlatform().convertObject(result, ClassConstants.TIMESTAMP);
        }
    }

    /**
     * This method can be overridden by subclasses to return a
     * query that will return the timestamp from the server.
     * return null if the time should be the local time.
     */
    @Override
    public ValueReadQuery getTimestampQuery() {
        return timestampQuery;
    }

    /**
     * OBSOLETE:
     * This method lazy initializes the update sequence number query.  It
     * allows for other queries to be used instead of the default one.
     */
    public DataModifyQuery getUpdateSequenceQuery() {
        if (getDefaultSequence() instanceof QuerySequence) {
            return ((QuerySequence)getDefaultSequence()).getUpdateQuery();
        } else {
            throw ValidationException.wrongSequenceType(Helper.getShortClassName(getDefaultSequence()), "getUpdateQuery");
        }
    }

    /**
     * Initialize any platform-specific operators
     */
    protected void initializePlatformOperators() {
        this.platformOperators = new HashMap();

        // Outer join
        addOperator(ExpressionOperator.equalOuterJoin());

        // General
        addOperator(ExpressionOperator.toUpperCase());
        addOperator(ExpressionOperator.toLowerCase());
        addOperator(ExpressionOperator.chr());
        addOperator(ExpressionOperator.concat());
        addOperator(ExpressionOperator.hexToRaw());
        addOperator(ExpressionOperator.initcap());
        addOperator(ExpressionOperator.instring());
        addOperator(ExpressionOperator.soundex());
        addOperator(ExpressionOperator.leftPad());
        addOperator(ExpressionOperator.leftTrim());
        addOperator(ExpressionOperator.leftTrim2());
        addOperator(ExpressionOperator.replace());
        addOperator(ExpressionOperator.rightPad());
        addOperator(ExpressionOperator.rightTrim());
        addOperator(ExpressionOperator.rightTrim2());
        addOperator(ExpressionOperator.substring());
        addOperator(ExpressionOperator.substringSingleArg());
        addOperator(ExpressionOperator.toNumber());
        addOperator(ExpressionOperator.toChar());
        addOperator(ExpressionOperator.toCharWithFormat());
        addOperator(ExpressionOperator.translate());
        addOperator(ExpressionOperator.trim());
        addOperator(ExpressionOperator.trim2());
        addOperator(ExpressionOperator.ascii());
        addOperator(ExpressionOperator.length());
        addOperator(ExpressionOperator.locate());
        addOperator(ExpressionOperator.locate2());
        addOperator(ExpressionOperator.nullIf());
        addOperator(ExpressionOperator.ifNull());
        addOperator(ExpressionOperator.cast());
        addOperator(ExpressionOperator.regexp());
        addOperator(ExpressionOperator.union());
        addOperator(ExpressionOperator.unionAll());
        addOperator(ExpressionOperator.intersect());
        addOperator(ExpressionOperator.intersectAll());
        addOperator(ExpressionOperator.except());
        addOperator(ExpressionOperator.exceptAll());

        // Date
        addOperator(ExpressionOperator.addMonths());
        addOperator(ExpressionOperator.dateToString());
        addOperator(ExpressionOperator.lastDay());
        addOperator(ExpressionOperator.monthsBetween());
        addOperator(ExpressionOperator.nextDay());
        addOperator(ExpressionOperator.roundDate());
        addOperator(ExpressionOperator.toDate());
        addOperator(ExpressionOperator.today());
        addOperator(ExpressionOperator.currentDate());
        addOperator(ExpressionOperator.currentTime());
        addOperator(ExpressionOperator.extract());

        // Math
        addOperator(ExpressionOperator.simpleMath(ExpressionOperator.Add, "+"));
        addOperator(ExpressionOperator.simpleMath(ExpressionOperator.Subtract, "-"));
        addOperator(ExpressionOperator.simpleMath(ExpressionOperator.Multiply, "*"));
        addOperator(ExpressionOperator.simpleMath(ExpressionOperator.Divide, "/"));
        addOperator(ExpressionOperator.negate());

        addOperator(ExpressionOperator.ceil());
        addOperator(ExpressionOperator.cos());
        addOperator(ExpressionOperator.cosh());
        addOperator(ExpressionOperator.abs());
        addOperator(ExpressionOperator.acos());
        addOperator(ExpressionOperator.asin());
        addOperator(ExpressionOperator.atan());
        addOperator(ExpressionOperator.exp());
        addOperator(ExpressionOperator.sqrt());
        addOperator(ExpressionOperator.floor());
        addOperator(ExpressionOperator.ln());
        addOperator(ExpressionOperator.log());
        addOperator(ExpressionOperator.mod());
        addOperator(ExpressionOperator.power());
        addOperator(ExpressionOperator.round());
        addOperator(ExpressionOperator.sign());
        addOperator(ExpressionOperator.sin());
        addOperator(ExpressionOperator.sinh());
        addOperator(ExpressionOperator.tan());
        addOperator(ExpressionOperator.tanh());
        addOperator(ExpressionOperator.trunc());
        addOperator(ExpressionOperator.greatest());
        addOperator(ExpressionOperator.least());

        addOperator(ExpressionOperator.standardDeviation());
        addOperator(ExpressionOperator.variance());

        // Object-relational
        addOperator(ExpressionOperator.deref());
        addOperator(ExpressionOperator.ref());
        addOperator(ExpressionOperator.refToHex());
        addOperator(ExpressionOperator.value());

        addOperator(ExpressionOperator.coalesce());
        addOperator(ExpressionOperator.caseStatement());
        addOperator(ExpressionOperator.caseConditionStatement());
    }

    /**
     * INTERNAL:
     * Allow the platform to initialize the CRUD queries to defaults.
     * This is mainly used by EIS platforms, but could be used by relational ones for special behavior.
     */
    public void initializeDefaultQueries(DescriptorQueryManager queryManager, AbstractSession session) {

    }

    @Override
    public boolean isAccess() {
        return false;
    }

    @Override
    public boolean isAttunity() {
        return false;
    }

    @Override
    public boolean isCloudscape() {
        return false;
    }

    @Override
    public boolean isDerby() {
        return false;
    }

    @Override
    public boolean isDB2() {
        return false;
    }

    @Override
    public boolean isDB2Z() {
        return false;
    }

    @Override
    public boolean isHANA() {
        return false;
    }

    @Override
    public boolean isH2() {
        return false;
    }

    @Override
    public boolean isDBase() {
        return false;
    }

    @Override
    public boolean isHSQL() {
        return false;
    }

    @Override
    public boolean isInformix() {
        return false;
    }

    @Override
    public boolean isMySQL() {
        return false;
    }

    @Override
    public boolean isODBC() {
        return false;
    }

    @Override
    public boolean isOracle() {
        return false;
    }

    @Override
    public boolean isOracle9() {
        return false;
    }

    @Override
    public boolean isOracle12() {
        return false;
    }

    public boolean isPervasive(){
        return false;
    }

    @Override
    public boolean isPostgreSQL(){
        return false;
    }

    @Override
    public boolean isPointBase() {
        return false;
    }

    @Override
    public boolean isSQLAnywhere() {
        return false;
    }

    public boolean isFirebird() {
        return false;
    }

    @Override
    public boolean isSQLServer() {
        return false;
    }

    @Override
    public boolean isSybase() {
        return false;
    }

    @Override
    public boolean isSymfoware() {
        return false;
    }

    @Override
    public boolean isTimesTen() {
        return false;
    }

    @Override
    public boolean isTimesTen7() {
        return false;
    }

    @Override
    public boolean isMaxDB() {
        return false;
    }

    /**
     * Allow the platform to initialize itself after login/init.
     */
    @Override
    public void initialize() {

    }

    /**
     * OBSOLETE:
     * Can override the default query for returning the sequence numbers.
     * This query must be a valid query that has one parameter which is
     * the sequence name.
     */
    public void setSelectSequenceNumberQuery(ValueReadQuery seqQuery) {
        if (getDefaultSequence() instanceof QuerySequence) {
            ((QuerySequence)getDefaultSequence()).setSelectQuery(seqQuery);
        } else {
            throw ValidationException.wrongSequenceType(Helper.getShortClassName(getDefaultSequence()), "setSelectQuery");
        }
    }

    /**
     *    Set the number of sequence values to preallocate.
     *    Preallocating sequence values can greatly improve insert performance.
     */
    public void setSequencePreallocationSize(int size) {
        getDefaultSequence().setPreallocationSize(size);
    }

    /**
     * Set the qualifier for the table. Required by some
     * databases such as Oracle and DB2
     */
    @Override
    public void setTableQualifier(String qualifier) {
        tableQualifier = qualifier;
    }

    /**
     * Can override the default query for returning a timestamp from the server.
     * See: getTimestampFromServer
     */
    @Override
    public void setTimestampQuery(ValueReadQuery tsQuery) {
        timestampQuery = tsQuery;
    }

    /**
     * This method sets the update sequence number query.  It
     * allows for other queries to be used instead of the default one.
     */
    public void setUpdateSequenceQuery(DataModifyQuery updateSequenceNumberQuery) {
        if (getDefaultSequence() instanceof QuerySequence) {
            ((QuerySequence)getDefaultSequence()).setUpdateQuery(updateSequenceNumberQuery);
        } else {
            throw ValidationException.wrongSequenceType(Helper.getShortClassName(getDefaultSequence()), "setUpdateQuery");
        }
    }

    @Override
    public String toString() {
        return Helper.getShortClassName(this.getClass());
    }

    /**
     * PUBLIC:
     * Return the list of Classes that can be converted to from the passed in javaClass.
     * @param javaClass - the class that is converted from
     * @return - a vector of classes
     */
    public Vector getDataTypesConvertedFrom(Class javaClass) {
        return getConversionManager().getDataTypesConvertedFrom(javaClass);
    }

    /**
     * PUBLIC:
     * Return the list of Classes that can be converted from to the passed in javaClass.
     * @param javaClass - the class that is converted to
     * @return - a vector of classes
     */
    public Vector getDataTypesConvertedTo(Class javaClass) {
        return getConversionManager().getDataTypesConvertedTo(javaClass);
    }

    /**
     * Get default sequence
     */
    @Override
    public Sequence getDefaultSequence() {
        if (!hasDefaultSequence()) {
            setDefaultSequence(createPlatformDefaultSequence());
        }
        return defaultSequence;
    }

    /**
     * Get default sequence
     */
    public boolean hasDefaultSequence() {
        return defaultSequence != null;
    }

    /**
     * Set default sequence. In case the passed sequence is of type DefaultSequence - use platformDefaultSequence
     * with name and size of the passed sequence.
     */
    @Override
    public void setDefaultSequence(Sequence sequence) {
        if (sequence instanceof DefaultSequence) {
            Sequence platformDefaultSequence = createPlatformDefaultSequence();
            if (platformDefaultSequence != null) {
                platformDefaultSequence.setName(sequence.getName());
                if (((DefaultSequence)sequence).hasPreallocationSize()) {
                    platformDefaultSequence.setPreallocationSize(sequence.getPreallocationSize());
                }
            }
            defaultSequence = platformDefaultSequence;
        } else {
            defaultSequence = sequence;
        }
    }

    /**
     * Add sequence corresponding to the name
     */
    @Override
    public void addSequence(Sequence sequence) {
        addSequence(sequence, false);
    }

    /**
     * Add sequence corresponding to the name.
     * Use this method with isSessionConnected parameter set to true
     * to add a sequence to connected session.
     * If the session is connected then the sequence is added only
     * if there is no sequence with the same name already in use.
     */
    @Override
    public void addSequence(Sequence sequence, boolean isSessionConnected) {
        synchronized(sequencesLock) {
            if (isSessionConnected) {
                if (this.sequences == null) {
                    this.sequences = new HashMap();
                    this.sequences.put(sequence.getName(), sequence);
                } else {
                    if (!this.sequences.containsKey(sequence.getName())) {
                        Map newSequences = (Map)((HashMap)this.sequences).clone();
                        newSequences.put(sequence.getName(), sequence);
                        this.sequences = newSequences;
                    }
                }
            } else {
                if (this.sequences == null) {
                    this.sequences = new HashMap();
                }
                this.sequences.put(sequence.getName(), sequence);
            }
        }
    }

    /**
     * Get sequence corresponding to the name
     */
    @Override
    public Sequence getSequence(String seqName) {
        if (seqName == null) {
            return getDefaultSequence();
        } else {
            if (this.sequences != null) {
                return this.sequences.get(seqName);
            } else {
                return null;
            }
        }
    }

    /**
     * INTERNAL:
     * Create platform-default Sequence
     */
    protected Sequence createPlatformDefaultSequence() {
        throw ValidationException.createPlatformDefaultSequenceUndefined(Helper.getShortClassName(this));
    }

    /**
     * Remove sequence corresponding to name.
     * Doesn't remove default sequence.
     */
    @Override
    public Sequence removeSequence(String seqName) {
        if (this.sequences != null) {
            synchronized(sequencesLock) {
                return this.sequences.remove(seqName);
            }
        } else {
            return null;
        }
    }

    /**
     * Remove all sequences, but the default one.
     */
    @Override
    public void removeAllSequences() {
        this.sequences = null;
    }

    /**
     * INTERNAL:
     * Returns a map of sequence names to Sequences (may be null).
     */
    @Override
    public Map<String, Sequence> getSequences() {
        return this.sequences;
    }

    /**
     * INTERNAL:
     * Used only for writing into XML or Java.
     */
    @Override
    public Map<String, Sequence> getSequencesToWrite() {
        if ((getSequences() == null) || getSequences().isEmpty()) {
            return null;
        }
        Map sequencesCopy = new HashMap(getSequences());
        Map sequencesToWrite = new HashMap();
        Iterator it = sequencesCopy.values().iterator();
        while (it.hasNext()) {
            Sequence sequence = (Sequence)it.next();
            if (!(sequence instanceof DefaultSequence) || ((DefaultSequence)sequence).hasPreallocationSize()) {
                sequencesToWrite.put(sequence.getName(), sequence);
            }
        }
        return sequencesToWrite;
    }

    /**
     * INTERNAL:
     * Used only for writing into XML or Java.
     */
    @Override
    public Sequence getDefaultSequenceToWrite() {
        if (usesPlatformDefaultSequence()) {
            return null;
        } else {
            return getDefaultSequence();
        }
    }

    /**
     * INTERNAL:
     * Sets sequences - for XML support only
     */
    @Override
    public void setSequences(Map sequences) {
        this.sequences = sequences;
    }

    /**
     * INTERNAL:
     * Indicates whether defaultSequence is the same as platform default sequence.
     */
    @Override
    public boolean usesPlatformDefaultSequence() {
        if (!hasDefaultSequence()) {
            return true;
        } else {
            return getDefaultSequence().equals(createPlatformDefaultSequence());
        }
    }

    /**
     * INTERNAL:
     */
    public ConnectionCustomizer createConnectionCustomizer(Accessor accessor, AbstractSession session) {
        return null;
    }

    /**
     * Allows query prepare to be disable in the platform.
     * This is required for some EIS platforms, that cannot prepare the call.
     */
    public boolean shouldPrepare(DatabaseQuery query) {
        return true;
    }

    /**
     * Return if the database requires the ORDER BY fields to be part of the select clause.
     */
    public boolean shouldSelectIncludeOrderBy() {
        return false;
    }

    /**
     * Return if the database requires the ORDER BY fields to be part of the select clause.
     */
    public boolean shouldSelectDistinctIncludeOrderBy() {
        return true;
    }

    /**
     * INTERNAL:
     * Indicates whether a separate transaction is required for NativeSequence.
     * This method is to be used *ONLY* by sequencing classes
     */
    public boolean shouldNativeSequenceUseTransaction() {
        return false;
    }

    /**
     * INTERNAL:
     * Indicates whether the platform supports identity.
     * This method is to be used *ONLY* by sequencing classes
     */
    public boolean supportsIdentity() {
        return false;
    }

    public boolean supportsNativeSequenceNumbers() {
        return this.supportsSequenceObjects() || this.supportsIdentity();
    }

    /**
     *  INTERNAL:
     *  Indicates whether the platform supports sequence objects.
     *  This method is to be used *ONLY* by sequencing classes
     */
    public boolean supportsSequenceObjects() {
        return false;
    }

    /**
     * INTERNAL:
     * Returns query used to read value generated by sequence object (like Oracle sequence).
     * This method is called when sequence object NativeSequence is connected,
     * the returned query used until the sequence is disconnected.
     * If the platform supportsSequenceObjects then (at least) one of buildSelectQueryForSequenceObject
     * methods should return non-null query.
     */
    public ValueReadQuery buildSelectQueryForSequenceObject() {
        return null;
    }

    /**
     * INTERNAL:
     * Returns query used to read value generated by sequence object (like Oracle sequence).
     * In case the other version of this method (taking no parameters) returns null,
     * this method is called every time sequence object NativeSequence reads.
     * If the platform supportsSequenceObjects then (at least) one of buildSelectQueryForSequenceObject
     * methods should return non-null query.
     */
    public ValueReadQuery buildSelectQueryForSequenceObject(String qualifiedSeqName, Integer size) {
        return null;
    }

    /**
     * INTERNAL:
     * Returns query used to read back the value generated by Identity.
     * This method is called when identity NativeSequence is connected,
     * the returned query used until the sequence is disconnected.
     * If the platform supportsIdentity then (at least) one of buildSelectQueryForIdentity
     * methods should return non-null query.
     */
    public ValueReadQuery buildSelectQueryForIdentity() {
        return null;
    }

    /**
     * INTERNAL:
     * Returns query used to read back the value generated by Identity.
     * In case the other version of this method (taking no parameters) returns null,
     * this method is called every time identity NativeSequence reads.
     * If the platform supportsIdentity then (at least) one of buildSelectQueryForIdentity
     * methods should return non-null query.
     */
    public ValueReadQuery buildSelectQueryForIdentity(String seqName, Integer size) {
        return null;
    }

    /**
     * INTERNAL:
     * Return the correct call type for the native query string.
     * This allows EIS platforms to use different types of native calls.
     */
    public DatasourceCall buildNativeCall(String queryString) {
        return new SQLCall(queryString);
    }

    /**
     * INTERNAL:
     * Initialize platform specific identity sequences.
     * @param session Active database session (in connected state).
     * @param defaultIdentityGenerator Default identity generator sequence name.
     * @since 2.7
     */
    @Override
    public void initIdentitySequences(final Session session, final String defaultIdentityGenerator) {
    }

    /**
     * INTERNAL:
     * Remove platform specific identity sequences for specified tables. Default identity sequences are restored.
     * @param session Active database session (in connected state).
     * @param defaultIdentityGenerator Default identity generator sequence name.
     * @param tableNames Set of table names to check for identity sequence removal.
     * @since 2.7
     */
    @Override
    public void removeIdentitySequences(
            final Session session, final String defaultIdentityGenerator, final Set<String> tableNames) {
    }

    /**
     * INTERNAL:
     * Override this method if the platform needs to use a custom function based on the DatabaseField
     * @return An expression for the given field set equal to a parameter matching the field
     */
    public Expression createExpressionFor(DatabaseField field, Expression builder) {
        Expression subExp1 = builder.getField(field);
        Expression subExp2 = builder.getParameter(field);
        return subExp1.equal(subExp2);
    }

    /**
     * INTERNAL:
     * Some database platforms have a limit for the number of parameters in an IN clause.
     */
    public int getINClauseLimit() {
        return 0;
    }
}
