Package com.sun.jdo.spi.persistence.support.sqlstore.database

Source Code of com.sun.jdo.spi.persistence.support.sqlstore.database.DBVendorType

/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License").  You
* may not use this file except in compliance with the License. You can obtain
* a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
* or glassfish/bootstrap/legal/LICENSE.txt.  See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
* Sun designates this particular file as subject to the "Classpath" exception
* as provided by Sun in the GPL Version 2 section of the License file that
* accompanied this code.  If applicable, add the following below the License
* Header, with the fields enclosed by brackets [] replaced by your own
* identifying information: "Portions Copyrighted [year]
* [name of copyright owner]"
*
* Contributor(s):
*
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license."  If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above.  However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/


package com.sun.jdo.spi.persistence.support.sqlstore.database;

import com.sun.jdo.api.persistence.support.JDOFatalInternalException;
import com.sun.jdo.api.persistence.support.JDOFatalUserException;
import com.sun.jdo.api.persistence.support.JDOUserException;
import com.sun.jdo.api.persistence.support.SpecialDBOperation;
import com.sun.jdo.spi.persistence.support.sqlstore.LogHelperSQLStore;
import com.sun.jdo.spi.persistence.utility.FieldTypeEnumeration;
import com.sun.jdo.spi.persistence.utility.I18NHelper;
import com.sun.jdo.spi.persistence.utility.PropertyHelper;
import com.sun.jdo.spi.persistence.utility.database.DBVendorTypeHelper;
import com.sun.jdo.spi.persistence.utility.logging.Logger;

import java.io.IOException;
import java.sql.SQLException;
import java.sql.DatabaseMetaData;
import java.util.HashMap;
import java.util.Properties;
import java.util.ResourceBundle;



/**
*/
public class DBVendorType  {
    /**
     * Map from property name to property value.
     */
    private HashMap dbMap;

    /**
     * Instance of specialDBOperation for this vendor type. Please look at
     * newSpecialDBOperationInstance() to find out how this member is
     * initialized.
     */
    private SpecialDBOperation specialDBOperation;

    private static final SpecialDBOperation DEFAULT_SPECIAL_DB_OPERATION =
        new BaseSpecialDBOperation();

    /**
     * VendorType as returned from {@link DBVendorTypeHelper#getDBType(java.lang.String)}
     */
    private String vendorType;

    /**
     * VendorType as returned from {@link DBVendorTypeHelper#getEnumDBType(java.lang.String)}
     */
    private int enumVendorType;

    /**
     * The logger
     */
    private final static Logger logger;

    /**
     * I18N message handler
     */
    private final static ResourceBundle messages;

    /**
     * Default properties
     */
    private static Properties defaultProperties;

    private final static String EXT = ".properties"; // NOI18N
    private final static String SPACE = " "; // NOI18N
    private final static String NONE = ""; // NOI18N

    private final static String PATH = "com/sun/jdo/spi/persistence/support/sqlstore/database/"; // NOI18N
    private final static String PROPERTY_OVERRIDE_FILE = ".tpersistence.properties"; // NOI18N


    private final static String FOR_UPDATE = "FOR_UPDATE"; // NOI18N
    private final static String HOLDLOCK = "HOLDLOCK"; //NOI18N
    private final static String SUPPORTS_UPDATE_LOCK = "SUPPORTS_UPDATE_LOCK"; //NOI18N
    private final static String SUPPORTS_LOCK_COLUMN_LIST = "SUPPORTS_LOCK_COLUMN_LIST"; //NOI18N
    private final static String SUPPORTS_DISTINCT_WITH_UPDATE_LOCK = "SUPPORTS_DISTINCT_WITH_UPDATE_LOCK"; //NOI18N
    private final static String NATIVE_OUTER_JOIN = "NATIVE_OUTER_JOIN"; //NOI18N
    private final static String LEFT_JOIN = "LEFT_JOIN"; //NOI18N
    private final static String LEFT_JOIN_APPEND = "LEFT_JOIN_APPEND"; //NOI18N
    private final static String RIGHT_JOIN = "RIGHT_JOIN"; //NOI18N
    private final static String RIGHT_JOIN_PRE = "RIGHT_JOIN_PRE"; //NOI18N
    private final static String IS_NULL = "IS_NULL"; //NOI18N
    private final static String IS_NOT_NULL = "IS_NOT_NULL"; //NOI18N
    private final static String ANSI_TRIM = "ANSI_TRIM"; //NOI18N
    private final static String RTRIM = "RTRIM"; //NOI18N
    private final static String RTRIM_POST = "RTRIM_POST"; //NOI18N
    private final static String TABLE_LIST_START = "TABLE_LIST_START"; //NOI18N
    private final static String TABLE_LIST_END = "TABLE_LIST_END"; //NOI18N
    private final static String STRING_CONCAT = "STRING_CONCAT"; //NOI18N
    private final static String QUOTE_CHAR_START = "QUOTE_CHAR_START"; //NOI18N
    private final static String QUOTE_CHAR_END = "QUOTE_CHAR_END"; //NOI18N
    private final static String QUOTE_SPECIAL_ONLY = "QUOTE_SPECIAL_ONLY"; //NOI18N
    private final static String CHAR_LENGTH = "CHAR_LENGTH"; //NOI18N
    private final static String SQRT = "SQRT"; //NOI18N
    private final static String ABS = "ABS"; //NOI18N
    private final static String SUBSTRING = "SUBSTRING"; //NOI18N
    private final static String SUBSTRING_FROM = "SUBSTRING_FROM"; //NOI18N
    private final static String SUBSTRING_FOR = "SUBSTRING_FOR"; //NOI18N
    private final static String POSITION = "POSITION"; //NOI18N
    private final static String POSITION_SEP = "POSITION_SEP"; //NOI18N
    private final static String POSITION_SEARCH_SOURCE = "POSITION_SEARCH_SOURCE"; //NOI18N
    private final static String POSITION_THREE_ARGS = "POSITION_THREE_ARGS"; //NOI18N
    private final static String MAP_EMPTY_STRING_TO_NULL = "MAP_EMPTY_STRING_TO_NULL"; //NOI18N
    private final static String SPECIAL_DB_OPERATION = "SPECIAL_DB_OPERATION"; //NOI18N
    private final static String SUPPORTS_LIKE_ESCAPE = "SUPPORTS_LIKE_ESCAPE"; //NOI18N
    private final static String LEFT_LIKE_ESCAPE = "LEFT_LIKE_ESCAPE"; //NOI18N
    private final static String RIGHT_LIKE_ESCAPE = "RIGHT_LIKE_ESCAPE"; //NOI18N
    private final static String NULL_COMPARISON_FUNCTION_NAME = "NULL_COMPARISON_FUNCTION_NAME"; //NOI18N
    private final static String MOD_FUNCTION_NAME = "MOD_FUNCTION_NAME"; //NOI18N
    private final static String CONCAT_CAST = "CONCAT_CAST"; //NOI18N
    private final static String PARAMETER_CAST = "PARAMETER_CAST"; //NOI18N
    private final static String INLINE_NUMERIC = "INLINE_NUMERIC"; //NOI18N

    private static final String[] props = new String[] { FOR_UPDATE,
            HOLDLOCK, SUPPORTS_UPDATE_LOCK, SUPPORTS_LOCK_COLUMN_LIST,
            SUPPORTS_DISTINCT_WITH_UPDATE_LOCK,
            NATIVE_OUTER_JOIN, LEFT_JOIN, LEFT_JOIN_APPEND, RIGHT_JOIN, RIGHT_JOIN_PRE,
            IS_NULL, IS_NOT_NULL, ANSI_TRIM, RTRIM, RTRIM_POST,
            TABLE_LIST_START, TABLE_LIST_END,
            QUOTE_CHAR_START, QUOTE_CHAR_END, QUOTE_SPECIAL_ONLY,
            STRING_CONCAT, CHAR_LENGTH, SQRT, ABS,
            SUBSTRING, SUBSTRING_FROM, SUBSTRING_FOR,
            POSITION, POSITION_SEP, POSITION_SEARCH_SOURCE, POSITION_THREE_ARGS,
            MAP_EMPTY_STRING_TO_NULL, SPECIAL_DB_OPERATION,
            SUPPORTS_LIKE_ESCAPE, LEFT_LIKE_ESCAPE, RIGHT_LIKE_ESCAPE,
            NULL_COMPARISON_FUNCTION_NAME, MOD_FUNCTION_NAME,
            CONCAT_CAST, PARAMETER_CAST, INLINE_NUMERIC
    };

    /**
     * Initialize static fields.
     */
    static {
        logger = LogHelperSQLStore.getLogger();
        messages = I18NHelper.loadBundle(
            "com.sun.jdo.spi.persistence.support.sqlstore.Bundle", // NOI18N
            DBVendorType.class.getClassLoader());

        defaultProperties = initializeDefaultProperties();
    }

    /**
     * @param databaseMetaData Instance of DatabaseMetaData
     * @param identifier identifier of the caller creating a new instance
     * of SQLStoreManager.
     */
    public DBVendorType(DatabaseMetaData databaseMetaData, String identifier)
        throws SQLException {

        String vendorName  = databaseMetaData.getDatabaseProductName();
        String vendorType  = DBVendorTypeHelper.getDBType(vendorName);

        if (logger.isLoggable()) {
            Object[] items = new Object[] {vendorName,vendorType};
            logger.fine("sqlstore.database.dbvendor.vendorname", items); // NOI18N
        }

        this.vendorType     = vendorType;
        enumVendorType      = DBVendorTypeHelper.getEnumDBType(vendorType);
        dbMap               = getDBPropertiesMap(vendorType,vendorName);
        specialDBOperation  = newSpecialDBOperationInstance((String)dbMap.get(SPECIAL_DB_OPERATION),
                                databaseMetaData, identifier);
    }

    /**
     * get properties map for given vendorType and vendorName
     */
    private static HashMap getDBPropertiesMap(String vendorType, String vendorName) {
        //Initialize returned map to default
        HashMap dbHashMap = new HashMap(defaultProperties);
        Properties dbProperties = loadDBProperties(vendorType, vendorName);
        dbHashMap.putAll(dbProperties);

        return dbHashMap;
    }

    /**
     * Initialize default properties.
     */
    private static Properties initializeDefaultProperties() {
        //Load default properties if not already loaded
        if (defaultProperties == null) {
            // Load default (sql92) Properties
            defaultProperties = new Properties();
            try {
                loadFromResource(DBVendorTypeHelper.DEFAULT_DB, defaultProperties);
            } catch (IOException e) {
                throw new JDOFatalInternalException(I18NHelper.getMessage(messages,
                                "sqlstore.database.dbvendor.cantloadDefaultProperties"), // NOI18N
                                 e);
            }
        }

        return defaultProperties;
     }

    /**
     * Load properties for database specified by vendorType and vendorName
     */
    private static Properties loadDBProperties(String vendorType, String vendorName) {
        // Load actual Properties. Even if it is unknown db,
        Properties dbProperties = new Properties();
        if (!vendorType.equals(DBVendorTypeHelper.DEFAULT_DB)) {
            try {
                loadFromResource(vendorType, dbProperties);
            } catch (IOException e) {
                // else ignore
                if (logger.isLoggable()) {
                    logger.fine("sqlstore.database.dbvendor.init.default", vendorType); // NOI18N
                }
            }
        }
        overrideProperties(dbProperties, vendorName);
        return dbProperties;
    }

    /**
     * Overrides default properties with the ones provided
     * by the user
     */
    private static void overrideProperties(Properties dbProperties, String vendorName) {
        boolean debug = logger.isLoggable();

        Properties overridingProperties = new Properties();
        try {
            PropertyHelper.loadFromFile(overridingProperties, PROPERTY_OVERRIDE_FILE);
        } catch (Exception e) {
            if (debug) {
                logger.fine("sqlstore.database.dbvendor.overrideproperties"); // NOI18N
            }
            return;   // nothing to override
        }

        //Prepare a clean vendor name by replacing all ' '  and '/' with underscores.
        String cleanVendorName = vendorName.toLowerCase().replace(' ', '_');
        cleanVendorName = cleanVendorName.replace('/', '_');

        String propertyPrefix = "database." + cleanVendorName + "."; // prefix // NOI18N

        for (int i = 0; i < props.length; i++) {
            String o = overridingProperties.getProperty(propertyPrefix + props[i]);
            if (o != null) {
                if (debug) {
                    Object[] items = new Object[] {props[i],o};
                    logger.fine("sqlstore.database.dbvendor.overrideproperties.with", items); // NOI18N
                }
                dbProperties.setProperty(props[i], o);
            }
        }
    }

    /**
     * loads database properties list from the specified resource
     * into specified Properties object.
     * @param resourceName  Name of resource.
     * @param properties    Properties object to load
     */
    private static void loadFromResource(String resourceName, Properties properties)
            throws IOException {
        String fullResourceName = PATH + resourceName + EXT;
        PropertyHelper.loadFromResource(properties, fullResourceName, DBVendorType.class.getClassLoader());
    }

    /**
     * Returns new instance of class specified by specialDBOpClassName.
     * The class is required to implement interface SpecialDBOperation.
     * If specialDBOpClassName is null or cannot be loaded, then an instance
     * of BaseSpecialDBOperation is returned.
     * @param specialDBOpClassName Name of a class that implements
     * SpecialDBOperation
     * @param databaseMetaData DatabaseMetaData for the connection for which
     * this SpecialDBOperation is created
     * @param identifier Identifier of pmf used to obtain databaseMetaData.
     * This can be null in non managed environment.
     * @return An instance of SpecialDBOperation specified by specialDBOpClassName.
     */
    private SpecialDBOperation newSpecialDBOperationInstance(
        final String specialDBOpClassName, DatabaseMetaData databaseMetaData,
        String identifier) {
        SpecialDBOperation retInstance = null;
        if (specialDBOpClassName != null) {
            final ClassLoader loader = DBVendorType.class.getClassLoader();
            Class clz = (Class)java.security.AccessController.doPrivileged(
                new java.security.PrivilegedAction() {
                    public Object run() {
                        try {
                            if (loader != null) {
                                return Class.forName(specialDBOpClassName,
                                    true, loader);
                            } else {
                                return Class.forName(specialDBOpClassName);
                            }
                        } catch(Exception ex) {
                            if (logger.isLoggable()) {
                                logger.log(Logger.INFO,
                                    "core.configuration.cantloadclass", // NOI18N
                                    specialDBOpClassName);
                            }
                            return null;
                        }
                    }
                }
            );

            if (clz != null) {
                try {
                    retInstance = (SpecialDBOperation)clz.newInstance();
                    retInstance.initialize(databaseMetaData, identifier);
                } catch(Exception ex) {
                    throw new JDOFatalUserException(
                        I18NHelper.getMessage(messages,
                        "sqlstore.database.dbvendor.cantinstantiateclass", // NOI18N
                        specialDBOpClassName), ex);
                }
            }
        }
        return (retInstance != null)? retInstance : DEFAULT_SPECIAL_DB_OPERATION;
    }

    /**
     * Returns the string that represents "left join" clause
     * for this database
     */
    public String getLeftJoin() {
        String s = (String)dbMap.get(LEFT_JOIN);
        if (s == null)
            s = NONE;

        if (logger.isLoggable()) {
            logger.fine("sqlstore.database.dbvendor.getleftjoin", s); // NOI18N
        }

        return SPACE + s;
    }


    /**
     * Returns true if this database supports update lock
     */
    public boolean isUpdateLockSupported() {
        String s = (String)dbMap.get(SUPPORTS_UPDATE_LOCK);
        Boolean b = Boolean.valueOf(s);

        if (logger.isLoggable()) {
            logger.fine("sqlstore.database.dbvendor.isupdatelocksupported", b); // NOI18N
        }

        return b.booleanValue();
    }

    /**
     * Returns true if this database supports update 'of column list'
     */
    public boolean  isLockColumnListSupported() {
        String s = (String)dbMap.get(SUPPORTS_LOCK_COLUMN_LIST);
        Boolean b = Boolean.valueOf(s);

        if (logger.isLoggable()) {
            logger.fine("sqlstore.database.dbvendor.islockcolumnlistsupported", b); // NOI18N
        }

        return b.booleanValue();
    }

    /**
     * Returns true if this database supports distinct clause with update lock
     */
    public boolean isDistinctSupportedWithUpdateLock() {
        String s = (String)dbMap.get(SUPPORTS_DISTINCT_WITH_UPDATE_LOCK);
        Boolean b = Boolean.valueOf(s);

        if (logger.isLoggable()) {
            logger.fine("sqlstore.database.dbvendor.isdistinctupdatelocksupported", b); // NOI18N
        }

        return b.booleanValue();
    }


    /**
     * Returns the string that represents "holdlock" clause
     * for this database
     */
    public String getHoldlock() {
        String s = (String)dbMap.get(HOLDLOCK);
        if (s == null)
            s = NONE;

        if (logger.isLoggable()) {
            logger.fine("sqlstore.database.dbvendor.getholdlock", s); // NOI18N
        }

        return SPACE + s;
    }

    /**
     * Returns true if the this database needs native outer join semantics.
     */
    public boolean isNativeOuterJoin() {
        String s = (String)dbMap.get(NATIVE_OUTER_JOIN);
        Boolean b = Boolean.valueOf(s);

        if (logger.isLoggable()) {
            logger.fine("sqlstore.database.dbvendor.isNativeOuterJoin", b); // NOI18N
        }

        return b.booleanValue();
    }

    /**
     * Returns the string that represents postfix for "left join" clause
     * for this database
     */
    public String getLeftJoinPost() {
        String s = (String)dbMap.get(LEFT_JOIN_APPEND);
        if (s == null)
            s = NONE;

        if (logger.isLoggable()) {
            logger.fine("sqlstore.database.dbvendor.getleftjoinpost", s); // NOI18N
        }

        return SPACE + s;
    }

    /**
     * Returns the string that represents "right join" clause
     * for this database
     */
    public String getRightJoin() {
        String s = (String)dbMap.get(RIGHT_JOIN);
        if (s == null)
            s = NONE;

        if (logger.isLoggable()) {
            logger.fine("sqlstore.database.dbvendor.getrightjoin", s); // NOI18N
        }

        return SPACE + s;
    }

    /**
     * Returns the string that represents prefix for "right join" clause
     * for this database
     */
    public String getRightJoinPre() {
        String s = (String)dbMap.get(RIGHT_JOIN_PRE);
        if (s == null)
            s = NONE;

        if (logger.isLoggable()) {
            logger.fine("sqlstore.database.dbvendor.getrightjoinipre", s); // NOI18N
        }

        return SPACE + s;
    }

    /**
     * Returns the string that represents "is NULL" clause
     * for this database
     */
    public String getIsNull() {
        String s = (String)dbMap.get(IS_NULL);
        if (s == null)
            s = NONE;

        if (logger.isLoggable()) {
            logger.fine("sqlstore.database.dbvendor.getisnull", s); // NOI18N
        }

        return SPACE + s;
    }

    /**
     * Returns the string that represents "is not NULL" clause
     * for this database
     */
    public String getIsNotNull() {
        String s = (String)dbMap.get(IS_NOT_NULL);
        if (s == null)
            s = NONE;

        if (logger.isLoggable()) {
            logger.fine("sqlstore.database.dbvendor.getisnotnull", s); // NOI18N
        }

        return SPACE + s;
    }

    /**
     * Returns true if this database need ansi style rtrim semantics.
     */
    public boolean isAnsiTrim() {
        String s = (String)dbMap.get(ANSI_TRIM);
        Boolean b = Boolean.valueOf(s);

        if (logger.isLoggable()) {
            logger.fine("sqlstore.database.dbvendor.isAnsiTrim", b); // NOI18N
        }

        return b.booleanValue();
    }

    /**
     * Returns the string that represents "RTRIM" clause
     * for this database
     */
    public String getRtrim() {
        String s = (String)dbMap.get(RTRIM);
        if (s == null)
            s = NONE;

        if (logger.isLoggable()) {
            logger.fine("sqlstore.database.dbvendor.getrtrim", s); // NOI18N
        }

        return SPACE + s;
    }

    /**
     * Returns the string that represents postfix for "RTRIM" clause
     * for this database
     */
    public String getRtrimPost() {
        String s = (String)dbMap.get(RTRIM_POST);
        if (s == null)
            s = NONE;

        if (logger.isLoggable()) {
            logger.fine("sqlstore.database.dbvendor.getrtrimpost", s); // NOI18N
        }

        return SPACE + s;
    }

    /**
     * Returns the string that represents prefix for "Char_length" clause
     * for this database
     */
    public String getCharLength() {
        String s = (String)dbMap.get(CHAR_LENGTH);
        if (s == null)
            s = NONE;

        if (logger.isLoggable()) {
            logger.fine("sqlstore.database.dbvendor.getcharlength", s); // NOI18N
        }

        return SPACE + s;
    }

    /**
     * Returns the string that represents prefix for "Sqrt" clause
     * for this database
     */
    public String getSqrt() {
        String s = (String)dbMap.get(SQRT);
        if (s == null) {
           throw new JDOUserException(I18NHelper.getMessage(messages,
               "core.constraint.illegalop", // NOI18N
               "Sqrt"));
        }

        if (logger.isLoggable()) {
            logger.fine("sqlstore.database.dbvendor.getsqrt", s); // NOI18N
        }

        return SPACE + s;
    }

    /**
     * Returns the string that represents prefix for "abs" clause
     * for this database
     */
    public String getAbs() {
        String s = (String)dbMap.get(ABS);
        if (s == null) {
           throw new JDOUserException(I18NHelper.getMessage(messages,
               "core.constraint.illegalop", // NOI18N
               "Abs"));
        }

        if (logger.isLoggable()) {
            logger.fine("sqlstore.database.dbvendor.getabs", s); // NOI18N
        }

        return SPACE + s;
    }

    /**
     * Returns the string that represents "for update" clause
     * for this database
     */
    public String getForUpdate() {
        String s = (String)dbMap.get(FOR_UPDATE);
        if (s == null)
            s = NONE;

        if (logger.isLoggable()) {
            logger.fine("sqlstore.database.dbvendor.getforupdate", s); // NOI18N
        }

        return SPACE + s;
    }

    /**
     * Returns the string that represents start of table list
     * for this database
     */
    public String getTableListStart() {
        String s = (String)dbMap.get(TABLE_LIST_START);
        if (s == null)
            s = NONE;

        if (logger.isLoggable()) {
            logger.fine("sqlstore.database.dbvendor.gettableliststart", s); // NOI18N
        }

        return SPACE + s;
    }

    /**
     * Returns the string that represents end of table list
     * for this database
     */
    public String getTableListEnd() {
        String s = (String)dbMap.get(TABLE_LIST_END);
        if (s == null)
            s = NONE;

        if (logger.isLoggable()) {
            logger.fine("sqlstore.database.dbvendor.gettablelistend", s); // NOI18N
        }

        return SPACE + s;
    }

    /**
     * Returns the string that represents concatenation operation
     * for this database
     */
    public String getStringConcat() {
        String s = (String)dbMap.get(STRING_CONCAT);
        if (s == null)
            s = NONE;

        if (logger.isLoggable()) {
            logger.fine("sqlstore.database.dbvendor.getstringconcat", s); // NOI18N
        }

        return SPACE + s + SPACE;
    }

    /**
     * Returns the start identifier quote character for this database, or
     * an empty string, if there is none.
     */
    public String getQuoteCharStart() {
        String s = (String)dbMap.get(QUOTE_CHAR_START);
        if (s == null)
            s = NONE;

        if (logger.isLoggable()) {
            logger.fine("sqlstore.database.dbvendor.getquotecharstart", s); // NOI18N
        }

        return s;
    }

    /**
     * Returns the end identifier quote character for this database, or
     * an empty string, if there is none.
     */
    public String getQuoteCharEnd() {
        String s = (String)dbMap.get(QUOTE_CHAR_END);
        if (s == null)
            s = NONE;

        if (logger.isLoggable()) {
            logger.fine("sqlstore.database.dbvendor.getquotecharend", s); // NOI18N
        }

        return s;
    }

    /**
     * Returns true if only identifiers with special characters should be quoted
     * for this database
     */
    public boolean getQuoteSpecialOnly() {
        String s = (String)dbMap.get(QUOTE_SPECIAL_ONLY);
        Boolean b = Boolean.valueOf(s);

        if (logger.isLoggable()) {
            logger.fine("sqlstore.database.dbvendor.getquotespecialonly", b); // NOI18N
        }

        return b.booleanValue();
    }

    /**
     * Returns the string that represents prefix for "Substring" clause
     * for this database
     */
    public String getSubstring() {
        String s = (String)dbMap.get(SUBSTRING);
        if (s == null) {
           throw new JDOUserException(I18NHelper.getMessage(messages,
               "core.constraint.illegalop", // NOI18N
               "substring"));
        }

        if (logger.isLoggable()) {
            logger.fine("sqlstore.database.dbvendor.getsubstring", s); // NOI18N
        }

        return SPACE + s;
    }

    /**
     * Returns the string that represents from part for "Substring" clause
     * for this database
     */
    public String getSubstringFrom() {
        String s = (String)dbMap.get(SUBSTRING_FROM);
        if (s == null) {
           throw new JDOUserException(I18NHelper.getMessage(messages,
               "core.constraint.illegalop", // NOI18N
               "from part of substring"));
        }

        if (logger.isLoggable()) {
            logger.fine("sqlstore.database.dbvendor.getsubstringfrom", s); // NOI18N
        }

        return SPACE + s + SPACE;
    }

    /**
     * Returns the string that represents for part for "Substr" clause
     * for this database
     */
    public String getSubstringFor() {
        String s = (String)dbMap.get(SUBSTRING_FOR);
        if (s == null) {
           throw new JDOUserException(I18NHelper.getMessage(messages,
               "core.constraint.illegalop", // NOI18N
               "for part of substring"));
        }

        if (logger.isLoggable()) {
            logger.fine("sqlstore.database.dbvendor.getsubstringfor", s); // NOI18N
        }

        return SPACE + s + SPACE;
    }

    /**
     * Returns the string that represents "Position" clause
     * for this database
     */
    public String getPosition() {
        String s = (String)dbMap.get(POSITION);
        if (s == null) {
           throw new JDOUserException(I18NHelper.getMessage(messages,
               "core.constraint.illegalop", // NOI18N
               "position"));
        }

        if (logger.isLoggable()) {
            logger.fine("sqlstore.database.dbvendor.getposition", s); // NOI18N
        }

        return SPACE + s;
    }

    /**
     * Returns the string that represents separator part of "Position" clause
     * for this database
     */
    public String getPositionSep() {
        String s = (String)dbMap.get(POSITION_SEP);
        if (s == null) {
           throw new JDOUserException(I18NHelper.getMessage(messages,
               "core.constraint.illegalop", // NOI18N
               "in part of position"));
        }

        if (logger.isLoggable()) {
            logger.fine("sqlstore.database.dbvendor.getpositionin", s); // NOI18N
        }

        return SPACE + s;
    }

    /**
     * Returns true if first position argument is Search String and second
     * argument is Source String for this database
     */
    public boolean isPositionSearchSource() {
        String s = (String)dbMap.get(POSITION_SEARCH_SOURCE);
        Boolean b = Boolean.valueOf(s);

        if (logger.isLoggable()) {
            logger.fine("sqlstore.database.dbvendor.getpositionsrchsrc", b); // NOI18N
        }

        return b.booleanValue();
    }

    /**
     * Returns true if position has three argument for this database
     */
    public boolean isPositionThreeArgs() {
        String s = (String)dbMap.get(POSITION_THREE_ARGS);
        Boolean b = Boolean.valueOf(s);

        if (logger.isLoggable()) {
            logger.fine("sqlstore.database.dbvendor.getposition3args", b); // NOI18N
        }

        return b.booleanValue();
    }

    /**
     * Returns true if this database maps empty Strings to NULL
     */
    public boolean mapEmptyStringToNull() {
        String s = (String)dbMap.get(MAP_EMPTY_STRING_TO_NULL);
        Boolean b = Boolean.valueOf(s);

        if (logger.isLoggable()) {
            logger.fine("sqlstore.database.dbvendor.mapemptystrtonull", b); // NOI18N
        }

        return b.booleanValue();
    }

    /**
     * Returns true if this database supports "LIKE ESCAPE" clause
     */
    public boolean supportsLikeEscape() {
        String s = (String)dbMap.get(SUPPORTS_LIKE_ESCAPE);
        Boolean b = Boolean.valueOf(s);

        if (logger.isLoggable()) {
            logger.fine("sqlstore.database.dbvendor.supportslikeescape", b); // NOI18N
        }

        return b.booleanValue();
    }

    /**
     * Returns left string that represents "LIKE ESCAPE" clause
     * for this database
     */
    public String getLeftLikeEscape() {
        String s = (String)dbMap.get(LEFT_LIKE_ESCAPE);
        if (s == null)
            s = NONE;

        if (logger.isLoggable()) {
            logger.fine("sqlstore.database.dbvendor.getleftlikeescape", s); // NOI18N
        }

        return SPACE + s;
    }

    /**
     * Returns right string that represents "LIKE ESCAPE" clause
     * for this database
     */
    public String getRightLikeEscape() {
        String s = (String)dbMap.get(RIGHT_LIKE_ESCAPE);
        if (s == null)
            s = NONE;

        if (logger.isLoggable()) {
            logger.fine("sqlstore.database.dbvendor.getrightlikeescape", s); // NOI18N
        }

        return SPACE + s;
    }

    /**
     * Returns function name for comparing null value for this database
     */
    public String getNullComparisonFunctionName() {
        String s = (String)dbMap.get(NULL_COMPARISON_FUNCTION_NAME);
        if (s == null)
            s = NONE;
        else
            s = s.trim();
        if (logger.isLoggable()) {
            logger.fine("sqlstore.database.dbvendor.getNullComparisonFunctionName", s); // NOI18N
        }
        return s;
    }


    /**
     * Returns true if modulo operation uses function, false otherwise.
     */
    public boolean isModOperationUsingFunction() {
        return getModFunctionName().length() != 0;
    }

    /**
     * Returns function name for MOD.
     */
    public String getModFunctionName() {
        String s = (String)dbMap.get(MOD_FUNCTION_NAME);
        if (s == null) {
           throw new JDOUserException(I18NHelper.getMessage(messages,
               "core.constraint.illegalop", // NOI18N
               " % "));
        }

        if (logger.isLoggable()) {
            logger.fine("sqlstore.database.dbvendor.getModFunctionName", s); // NOI18N
        }

        return s;
    }

    /**
     * Returns cast name that surrounds concat operation.
     */
    public String getConcatCast() {
        String s = (String)dbMap.get(CONCAT_CAST);
        if (s == null)
            s = NONE;
        else
            s = s.trim();
        if (logger.isLoggable()) {
            logger.fine("sqlstore.database.dbvendor.getConcatCast", s); // NOI18N
        }
        return s;
    }

    /**
     * Returns true if parameters need to be casted for this database
     */
    public boolean isParameterCast() {
        String s = (String)dbMap.get(PARAMETER_CAST);
        Boolean b = Boolean.valueOf(s);

        if (logger.isLoggable()) {
            logger.fine("sqlstore.database.dbvendor.isParameterCast", b); // NOI18N
        }

        return b.booleanValue();
    }

    /**
     * Returns true if numeric parameters are inlined for this database
     */
    public boolean isInlineNumeric() {
        String s = (String)dbMap.get(INLINE_NUMERIC);
        Boolean b = Boolean.valueOf(s);

        if (logger.isLoggable()) {
            logger.fine("sqlstore.database.dbvendor.isInlineNumeric", b); // NOI18N
        }

        return b.booleanValue();
    }


    /**
     * Returns database vendor type
     */
    public String getName() {
        return vendorType;
    }

    /**
     * Returns a SpecialDBOperation object
     */
    public SpecialDBOperation getSpecialDBOperation() {
        if (logger.isLoggable()) {
            logger.fine("sqlstore.database.dbvendor.getSpecialDBOperation", specialDBOperation); // NOI18N
        }

        return specialDBOperation;
    }

    /**
     * Gets string used as parameter marker. Parameters must be
     * casted on DB2/Derby.
     * @param type type for which parameter marker is required.
     * @return parameter marker for <code>type</code>.
     */
    public String getParameterMarker(int type) {
        String paramMarker = "?"; // NOI18N
        if (isParameterCast()) {
            String castType = getCastType(type);
            if (castType != null) {
                paramMarker = "CAST (? AS " + castType + ")"; // NOI18N
            }
        }

        return paramMarker;
    }

    /**
     * Gets string used as parameter marker. Parameters must be
     * casted on DB2/Derby. The cast type should match the actual
     * JDBC call used to bind the parameter.
     * @param  type type for which cast type is required.
     * @return String used as cast type for input type.
     * <code>null</code> if cast type is not required.
     */
    private static String getCastType(int type) {
    //
    //DB2type      length(bits)    JavaType
    //----------------------------------------------
    //SMALLINT      16             boolean, byte, short
    //INTEGER       32             int, char(16 bit unsigned)
    //BIGINT        64             long
    //REAL          32             float
    //DOUBLE        64             double
    //
        String castType = null;
        switch(type) {
            case FieldTypeEnumeration.BOOLEAN_PRIMITIVE :
            case FieldTypeEnumeration.BOOLEAN :
                castType = "SMALLINT";
                break;

            // CHARACTER_PRIMITIVE and CHARACTER are bound
            // to a PreparedStatement as String.
            case FieldTypeEnumeration.CHARACTER_PRIMITIVE :
            case FieldTypeEnumeration.CHARACTER :
            case FieldTypeEnumeration.STRING :
                castType = "VARCHAR(32672)"; //Max length of varchar col on DB2
                break;

            case FieldTypeEnumeration.BYTE_PRIMITIVE :
            case FieldTypeEnumeration.BYTE :
                castType = "SMALLINT";
                break;

            case FieldTypeEnumeration.SHORT_PRIMITIVE :
            case FieldTypeEnumeration.SHORT :
                castType = "SMALLINT";
                break;

            case FieldTypeEnumeration.INTEGER_PRIMITIVE :
            case FieldTypeEnumeration.INTEGER :
                castType = "INTEGER";
                break;

            case FieldTypeEnumeration.LONG_PRIMITIVE :
            case FieldTypeEnumeration.LONG :
                castType = "BIGINT";
                break;

            case FieldTypeEnumeration.FLOAT_PRIMITIVE :
            case FieldTypeEnumeration.FLOAT :
                castType = "REAL";
                break;

            case FieldTypeEnumeration.DOUBLE_PRIMITIVE :
            case FieldTypeEnumeration.DOUBLE :
                castType = "DOUBLE";
                break;
    /* Decide on what should this be casted to ?
            case FieldTypeEnumeration.ENUMTYPE_BIGDECIMAL :
            case FieldTypeEnumeration.ENUMTYPE_BIGINTEGER :
            break;
    */
            case FieldTypeEnumeration.UTIL_DATE :
            case FieldTypeEnumeration.SQL_TIMESTAMP :
                castType = "TIMESTAMP";
                break;

            case FieldTypeEnumeration.SQL_DATE :
                castType = "DATE";
                break;

            case FieldTypeEnumeration.SQL_TIME :
                castType = "TIME";
                break;

        }
        return castType;
    }
}
TOP

Related Classes of com.sun.jdo.spi.persistence.support.sqlstore.database.DBVendorType

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.