/*
 * 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.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(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(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;
    }
}
